src/jdk/nashorn/internal/runtime/ScriptFunction.java

Print this page

        

@@ -64,10 +64,12 @@
     /** Method handle for allocate function for this ScriptFunction */
     static final MethodHandle ALLOCATE = findOwnMH("allocate", Object.class);
 
     private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", Object.class, Object.class);
 
+    private static final MethodHandle GLOBALFILTER = findOwnMH("globalFilter", Object.class, Object.class);
+
     /** method handle to scope getter for this ScriptFunction */
     public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
 
     private static final MethodHandle IS_FUNCTION_MH  = findOwnMH("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class);
 

@@ -89,25 +91,21 @@
      * @param name          function name
      * @param methodHandle  method handle to function (if specializations are present, assumed to be most generic)
      * @param map           property map
      * @param scope         scope
      * @param specs         specialized version of this function - other method handles
-     * @param strict        is this a strict mode function?
-     * @param builtin       is this a built in function?
-     * @param isConstructor is this a constructor?
+     * @param flags         {@link ScriptFunctionData} flags
      */
     protected ScriptFunction(
             final String name,
             final MethodHandle methodHandle,
             final PropertyMap map,
             final ScriptObject scope,
             final MethodHandle[] specs,
-            final boolean strict,
-            final boolean builtin,
-            final boolean isConstructor) {
+            final int flags) {
 
-        this(new FinalScriptFunctionData(name, methodHandle, specs, strict, builtin, isConstructor), map, scope);
+        this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope);
     }
 
     /**
      * Constructor
      *

@@ -478,10 +476,17 @@
             return obj;
         }
         return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(obj);
     }
 
+
+    @SuppressWarnings("unused")
+    private static Object globalFilter(final Object object) {
+        // replace whatever we get with the current global object
+        return Context.getGlobalTrusted();
+    }
+
     /**
      * dyn:call call site signature: (callee, thiz, [args...])
      * generated method signature:   (callee, thiz, [args...])
      *
      * cases:

@@ -493,52 +498,47 @@
      *   (4) for normal this-calls, drop callee.
      */
     @Override
     protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
         final MethodType type = desc.getMethodType();
+        final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
 
         if (request.isCallSiteUnstable()) {
-            // (this, callee, args...) => (this, callee, args[])
-            final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class,
-                    type.parameterCount() - 2);
+            // (callee, this, args...) => (callee, this, args[])
+            final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, type.parameterCount() - 2);
 
             // If call site is statically typed to take a ScriptFunction, we don't need a guard, otherwise we need a
             // generic "is this a ScriptFunction?" guard.
             return new GuardedInvocation(collector, ScriptFunction.class.isAssignableFrom(desc.getMethodType().parameterType(0))
                     ? null : NashornGuards.getScriptFunctionGuard());
         }
 
         MethodHandle boundHandle;
         MethodHandle guard = null;
 
-        final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
-
         if (data.needsCallee()) {
             final MethodHandle callHandle = getBestInvoker(type, request.getArguments());
-            if (scopeCall) {
+            if (scopeCall && needsWrappedThis()) {
                 // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
-                // (callee, this, args...) => (callee, args...)
-                boundHandle = MH.insertArguments(callHandle, 1, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
-                // (callee, args...) => (callee, [this], args...)
-                boundHandle = MH.dropArguments(boundHandle, 1, Object.class);
-
+                // (callee, this, args...) => (callee, [this], args...)
+                boundHandle = MH.filterArguments(callHandle, 1, GLOBALFILTER);
             } else {
                 // It's already (callee, this, args...), just what we need
                 boundHandle = callHandle;
             }
         } else {
             final MethodHandle callHandle = getBestInvoker(type.dropParameterTypes(0, 1), request.getArguments());
             if (data.isBuiltin() && "extend".equals(data.getName())) {
                 // NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the
                 // current lookup as its "this" so it can do security-sensitive creation of adapter classes.
                 boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc.getLookup()), 0, Object.class, Object.class);
-            } else if (scopeCall) {
+            } else if (scopeCall && needsWrappedThis()) {
                 // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
-                // (this, args...) => (args...)
-                boundHandle = MH.bindTo(callHandle, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
-                // (args...) => ([callee], [this], args...)
-                boundHandle = MH.dropArguments(boundHandle, 0, Object.class, Object.class);
+                // (this, args...) => ([this], args...)
+                boundHandle = MH.filterArguments(callHandle, 0, GLOBALFILTER);
+                // ([this], args...) => ([callee], [this], args...)
+                boundHandle = MH.dropArguments(boundHandle, 0, Object.class);
             } else {
                 // (this, args...) => ([callee], this, args...)
                 boundHandle = MH.dropArguments(callHandle, 0, Object.class);
             }
         }