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);
}
}