src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
Print this page
*** 45,81 ****
protected final String name;
/** All versions of this function that have been generated to code */
protected final CompiledFunctions code;
! private int arity;
!
! private final boolean isStrict;
!
! private final boolean isBuiltin;
! private final boolean isConstructor;
private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class);
private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class);
/**
* Constructor
*
* @param name script function name
* @param arity arity
! * @param isStrict is the function strict
! * @param isBuiltin is the function built in
! * @param isConstructor is the function a constructor
*/
! ScriptFunctionData(final String name, final int arity, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
this.name = name;
this.arity = arity;
this.code = new CompiledFunctions();
! this.isStrict = isStrict;
! this.isBuiltin = isBuiltin;
! this.isConstructor = isConstructor;
}
final int getArity() {
return arity;
}
--- 45,93 ----
protected final String name;
/** All versions of this function that have been generated to code */
protected final CompiledFunctions code;
! /** Function flags */
! protected int flags;
! private int arity;
private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class);
private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class);
+ /** Is this a strict mode function? */
+ public static final int IS_STRICT = 0b0000_0001;
+ /** Is this a built-in function? */
+ public static final int IS_BUILTIN = 0b0000_0010;
+ /** Is this a constructor function? */
+ public static final int IS_CONSTRUCTOR = 0b0000_0100;
+ /** Does this function expect a callee argument? */
+ public static final int NEEDS_CALLEE = 0b0000_1000;
+ /** Does this function make use of the this-object argument? */
+ public static final int USES_THIS = 0b0001_0000;
+
+ /** Flag for strict or built-in functions */
+ public static final int IS_STRICT_OR_BUILTIN = IS_STRICT | IS_BUILTIN;
+ /** Flag for built-in constructors */
+ public static final int IS_BUILTIN_CONSTRUCTOR = IS_BUILTIN | IS_CONSTRUCTOR;
+ /** Flag for strict constructors */
+ public static final int IS_STRICT_CONSTRUCTOR = IS_STRICT | IS_CONSTRUCTOR;
+
+
/**
* Constructor
*
* @param name script function name
* @param arity arity
! * @param flags the function flags
*/
! ScriptFunctionData(final String name, final int arity, final int flags) {
this.name = name;
this.arity = arity;
this.code = new CompiledFunctions();
! this.flags = flags;
}
final int getArity() {
return arity;
}
*** 103,136 ****
/**
* Is this a ScriptFunction generated with strict semantics?
* @return true if strict, false otherwise
*/
public boolean isStrict() {
! return isStrict;
}
boolean isBuiltin() {
! return isBuiltin;
}
boolean isConstructor() {
! return isConstructor;
}
boolean needsCallee() {
! // we don't know if we need a callee or not unless we are generated
! ensureCodeGenerated();
! return code.needsCallee();
}
/**
* Returns true if this is a non-strict, non-built-in function that requires non-primitive this argument
* according to ECMA 10.4.3.
* @return true if this argument must be an object
*/
boolean needsWrappedThis() {
! return !isStrict && !isBuiltin;
}
String toSource() {
return "function " + (name == null ? "" : name) + "() { [native code] }";
}
--- 115,148 ----
/**
* Is this a ScriptFunction generated with strict semantics?
* @return true if strict, false otherwise
*/
public boolean isStrict() {
! return (flags & IS_STRICT) != 0;
}
boolean isBuiltin() {
! return (flags & IS_BUILTIN) != 0;
}
boolean isConstructor() {
! return (flags & IS_CONSTRUCTOR) != 0;
}
boolean needsCallee() {
! // we don't know if we need a callee or not unless code has been compiled
! ensureCompiled();
! return (flags & NEEDS_CALLEE) != 0;
}
/**
* Returns true if this is a non-strict, non-built-in function that requires non-primitive this argument
* according to ECMA 10.4.3.
* @return true if this argument must be an object
*/
boolean needsWrappedThis() {
! return (flags & USES_THIS) != 0 && (flags & IS_STRICT_OR_BUILTIN) == 0;
}
String toSource() {
return "function " + (name == null ? "" : name) + "() { [native code] }";
}
*** 200,209 ****
--- 212,230 ----
protected void ensureCodeGenerated() {
//empty
}
/**
+ * If we can have lazy code generation, this is a hook to ensure that the code has been compiled.
+ * This does not guarantee the code been installed in this {@code ScriptFunctionData} instance;
+ * use {@link #ensureCodeGenerated()} to install the actual method handles.
+ */
+ protected void ensureCompiled() {
+ //empty
+ }
+
+ /**
* Return a generic Object/Object invoker for this method. It will ensure code
* is generated, get the most generic of all versions of this function and adapt it
* to Objects.
*
* TODO this is only public because {@link JavaAdapterFactory} can't supply us with
*** 257,266 ****
--- 278,289 ----
ScriptFunctionData makeBoundFunctionData(final ScriptFunction fn, final Object self, final Object[] args) {
ensureCodeGenerated();
final Object[] allArgs = args == null ? ScriptRuntime.EMPTY_ARRAY : args;
final int length = args == null ? 0 : args.length;
+ // Clear the callee and this flags
+ final int boundFlags = flags & ~NEEDS_CALLEE & ~USES_THIS;
CompiledFunctions boundList = new CompiledFunctions();
if (code.size() == 1) {
// only one variant - bind that
boundList.add(bind(code.first(), fn, self, allArgs));
*** 271,282 ****
final MethodHandle genInvoker = getGenericInvoker();
final CompiledFunction inv = new CompiledFunction(genInvoker.type(), genInvoker, getGenericConstructor());
boundList.add(bind(inv, fn, self, allArgs));
}
! ScriptFunctionData boundData = new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, isStrict(), isBuiltin(), isConstructor());
! return boundData;
}
/**
* Compose a constructor given a primordial constructor handle.
*
--- 294,304 ----
final MethodHandle genInvoker = getGenericInvoker();
final CompiledFunction inv = new CompiledFunction(genInvoker.type(), genInvoker, getGenericConstructor());
boundList.add(bind(inv, fn, self, allArgs));
}
! return new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, boundFlags);
}
/**
* Compose a constructor given a primordial constructor handle.
*