src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java

Print this page

        

@@ -28,129 +28,89 @@
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+
+import jdk.nashorn.internal.runtime.ScriptFunctionData;
 import jdk.nashorn.internal.codegen.objects.FunctionObjectCreator;
 import jdk.nashorn.internal.runtime.GlobalFunctions;
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.runtime.Source;
 import jdk.nashorn.internal.runtime.linker.Lookup;
 import jdk.nashorn.internal.runtime.linker.MethodHandleFactory;
 
 /**
  * Concrete implementation of ScriptFunction. This sets correct map for the
  * function objects -- to expose properties like "prototype", "length" etc.
  */
 public class ScriptFunctionImpl extends ScriptFunction {
-    // per-function object flags
-    private static final int IS_STRICT  = 0b0000_0001;
-    private static final int IS_BUILTIN = 0b0000_0010;
-    private static final int HAS_CALLEE = 0b0000_0100;
-
-    // set this function to be a builtin function
-    private void setIsBuiltin() {
-        flags |= IS_BUILTIN;
-    }
-
-    // set this function to be a ECMAScript strict function
-    private void setIsStrict() {
-        flags |= IS_STRICT;
-    }
 
     private static final MethodHandle BOUND_FUNCTION    = findOwnMH("boundFunction",    Object.class, ScriptFunction.class, Object.class, Object[].class, Object.class, Object[].class);
     private static final MethodHandle BOUND_CONSTRUCTOR = findOwnMH("boundConstructor", Object.class, ScriptFunction.class, Object[].class, Object.class, Object[].class);
 
     private static final PropertyMap nasgenmap$;
 
-    private int flags;
-
     /**
-     * Constructor
-     *
-     * Called by Nasgen generated code, no membercount, use the default map
-     * Creates builtin functions only
+     * Constructor called by Nasgen generated code, no membercount, use the default map.
+     * Creates builtin functions only.
      *
      * @param name name of function
      * @param invokeHandle handle for invocation
      * @param specs specialized versions of this method, if available, null otherwise
      */
     ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs) {
-        this(name, invokeHandle, nasgenmap$, specs);
+        super(name, invokeHandle, nasgenmap$, null, specs, false, true);
+        init();
     }
 
     /**
-     * Constructor
-     *
-     * Called by Nasgen generated code, no membercount, use the default map
-     * Creates builtin functions only
+     * Constructor called by Nasgen generated code, no membercount, use the map passed as argument.
+     * Creates builtin functions only.
      *
      * @param name name of function
-     * @param methodHandle handle for invocation
+     * @param invokeHandle handle for invocation
      * @param map initial property map
      * @param specs specialized versions of this method, if available, null otherwise
      */
-    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final PropertyMap map, final MethodHandle[] specs) {
-        super(name, methodHandle, (nasgenmap$ == map) ? nasgenmap$ : map.addAll(nasgenmap$), null, null, 0, false, specs);
-        this.setIsBuiltin();
+    ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs) {
+        super(name, invokeHandle, map.addAll(nasgenmap$), null, specs, false, true);
         init();
     }
 
     /**
-     * Constructor
-     *
-     * Called by Global.newScriptFunction (runtime)
+     * Constructor called by Global.newScriptFunction (runtime).
      *
      * @param name name of function
      * @param methodHandle handle for invocation
      * @param scope scope object
-     * @param strict are we in strict mode
      * @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
      */
-    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final boolean strict, final MethodHandle[] specs) {
-        super(name, methodHandle, getMap(strict), scope, specs);
-        if (strict) {
-            this.setIsStrict();
-        }
+    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean strict, final boolean builtin) {
+        super(name, methodHandle, getMap(strict), scope, specs, strict, builtin);
         init();
     }
 
     /**
-     * Constructor
-     *
-     * Called by (compiler) generated code for {@link ScriptObject}s. Code is
-     * generated by {@link FunctionObjectCreator}
+     * Constructor called by (compiler) generated code for {@link ScriptObject}s.
+     * Code is generated by {@link FunctionObjectCreator}
      *
-     * TODO this is a horrible constructor - can we do it with fewer args?
-     *
-     * @param name name of function
+     * @param data static function data
      * @param methodHandle handle for invocation
      * @param scope scope object
-     * @param source source
-     * @param token token
      * @param allocator instance constructor for function
-     * @param allocatorMap initial map that constructor will keep reference to for future instantiations
-     * @param needCallee does the function use the {@code callee} variable
-     * @param strict are we in strict mode
      */
-    public ScriptFunctionImpl(
-            final String name,
-            final MethodHandle methodHandle,
-            final ScriptObject scope,
-            final Source source,
-            final long token,
-            final MethodHandle allocator,
-            final PropertyMap allocatorMap,
-            final boolean needCallee,
-            final boolean strict) {
-        super(name, methodHandle, getMap(strict), scope, source, token, allocator, allocatorMap, needCallee, null);
-        if (strict) {
-            this.setIsStrict();
+    public ScriptFunctionImpl(final ScriptFunctionData data, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle allocator) {
+        super(data, getMap(data.isStrict()), scope);
+        // Set method handles in script data
+        if (data.getInvoker() == null) {
+            data.setMethodHandles(methodHandle, allocator);
         }
         init();
     }
 
     static {

@@ -165,14 +125,14 @@
     private static ScriptFunction typeErrorThrower;
 
     static synchronized ScriptFunction getTypeErrorThrower() {
         if (typeErrorThrower == null) {
             //name handle
-            final ScriptFunctionImpl func = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_SETTER, null, false, null);
+            final ScriptFunctionImpl func = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_SETTER, null, null, false, false);
             // clear constructor handle...
-            func.constructHandle = null;
-            func.prototype       = UNDEFINED;
+            func.setConstructHandle(null);
+            func.setPrototype(UNDEFINED);
             typeErrorThrower     = func;
         }
 
         return typeErrorThrower;
     }

@@ -214,51 +174,29 @@
 
     static ScriptFunctionImpl newAnonymousFunction() {
         return new AnonymousFunction();
     }
 
-    @Override
-    public final boolean isStrict() {
-        return (flags & IS_STRICT) != 0;
-    }
-
-    @Override
-    public final boolean hasCalleeParameter() {
-        return (flags & HAS_CALLEE) != 0;
-    }
-
-    @Override
-    protected void setHasCalleeParameter() {
-        flags |= HAS_CALLEE;
-    }
-
-    @Override
-    public final boolean isBuiltin() {
-        return (flags & IS_BUILTIN) != 0;
-    }
-
     /**
-     * Factory method for non-constructor functions
+     * Factory method for non-constructor built-in functions
      *
      * @param name   function name
      * @param methodHandle handle for invocation
      * @param specs  specialized versions of function if available, null otherwise
      * @param strict are we in strict mode
      * @return new ScriptFunction
      */
     public static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs, final boolean strict) {
-        final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, strict, specs);
-
-        func.setIsBuiltin();
+        final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, strict, true);
         func.setConstructHandle(null);
         func.setPrototype(UNDEFINED);
 
         return func;
     }
 
     /**
-     * Factory method for non-constructor functions
+     * Factory method for non-constructor built-in functions
      *
      * @param name   function name
      * @param methodHandle handle for invocation
      * @param specs  specialized versions of function if available, null otherwise
      * @return new ScriptFunction

@@ -266,11 +204,11 @@
     public static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs) {
         return makeFunction(name, methodHandle, specs, false);
     }
 
     /**
-     * Factory method for non-constructor functions
+     * Factory method for non-constructor built-in functions
      *
      * @param name   function name
      * @param methodHandle handle for invocation
      * @return new ScriptFunction
      */