aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java')
-rw-r--r--src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java40
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();