diff options
Diffstat (limited to 'src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java')
-rw-r--r-- | src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java index 46b353f1..23a13f25 100644 --- a/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java +++ b/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java @@ -42,6 +42,10 @@ import jdk.nashorn.internal.lookup.Lookup; * function objects -- to expose properties like "prototype", "length" etc. */ public class ScriptFunctionImpl extends ScriptFunction { + + /** Reference to constructor prototype. */ + private Object prototype; + // property map for strict mode functions private static final PropertyMap strictmodemap$; // property map for bound functions @@ -49,6 +53,9 @@ public class ScriptFunctionImpl extends ScriptFunction { // property map for non-strict, non-bound functions. private static final PropertyMap nasgenmap$; + // Marker object for lazily initialized prototype object + private static final Object LAZY_PROTOTYPE = new Object(); + /** * Constructor called by Nasgen generated code, no membercount, use the default map. * Creates builtin functions only. @@ -83,8 +90,8 @@ public class ScriptFunctionImpl extends ScriptFunction { * @param methodHandle handle for invocation * @param scope scope object * @param specs specialized versions of this method, if available, null otherwise - * @param strict are we in strict mode - * @param builtin is this a built-in function + * @param isStrict are we in strict mode + * @param isBuiltin is this a built-in function * @param isConstructor can the function be used as a constructor (most can; some built-ins are restricted). */ ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) { @@ -125,11 +132,17 @@ public class ScriptFunctionImpl extends ScriptFunction { // function object representing TypeErrorThrower private static ScriptFunction typeErrorThrower; + /* + * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object + */ static synchronized ScriptFunction getTypeErrorThrower() { if (typeErrorThrower == null) { - //name handle - final ScriptFunctionImpl func = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_SETTER, null, null, false, false, false); + // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3 + final ScriptFunctionImpl func = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, false, false, false); func.setPrototype(UNDEFINED); + // Non-constructor built-in functions do not have "prototype" property + func.deleteOwnProperty(func.getMap().findProperty("prototype")); + func.preventExtensions(); typeErrorThrower = func; } @@ -152,7 +165,7 @@ public class ScriptFunctionImpl extends ScriptFunction { } private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) { - // Bond function map is same as strict function map, but additionally lacks the "prototype" property, see + // Bound function map is same as strict function map, but additionally lacks the "prototype" property, see // ECMAScript 5.1 section 15.3.4.5 return strictModeMap.deleteProperty(strictModeMap.findProperty("prototype")); } @@ -182,6 +195,8 @@ public class ScriptFunctionImpl extends ScriptFunction { static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs) { final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, false, true, false); func.setPrototype(UNDEFINED); + // Non-constructor built-in functions do not have "prototype" property + func.deleteOwnProperty(func.getMap().findProperty("prototype")); return func; } @@ -227,10 +242,23 @@ public class ScriptFunctionImpl extends ScriptFunction { return Global.objectPrototype(); } + @Override + public final Object getPrototype() { + if (prototype == LAZY_PROTOTYPE) { + prototype = new PrototypeObject(this); + } + return prototype; + } + + @Override + public final void setPrototype(final Object prototype) { + this.prototype = prototype; + } + // Internals below.. private void init() { this.setProto(Global.instance().getFunctionPrototype()); - this.setPrototype(new PrototypeObject(this)); + this.prototype = LAZY_PROTOTYPE; if (isStrict()) { final ScriptFunction func = getTypeErrorThrower(); |