src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
Print this page
@@ -45,37 +45,49 @@
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;
+ /** Function flags */
+ protected int flags;
- private final boolean isConstructor;
+ 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 isStrict is the function strict
- * @param isBuiltin is the function built in
- * @param isConstructor is the function a constructor
+ * @param flags the function flags
*/
- ScriptFunctionData(final String name, final int arity, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
+ ScriptFunctionData(final String name, final int arity, final int flags) {
this.name = name;
this.arity = arity;
this.code = new CompiledFunctions();
- this.isStrict = isStrict;
- this.isBuiltin = isBuiltin;
- this.isConstructor = isConstructor;
+ this.flags = flags;
}
final int getArity() {
return arity;
}
@@ -103,34 +115,34 @@
/**
* Is this a ScriptFunction generated with strict semantics?
* @return true if strict, false otherwise
*/
public boolean isStrict() {
- return isStrict;
+ return (flags & IS_STRICT) != 0;
}
boolean isBuiltin() {
- return isBuiltin;
+ return (flags & IS_BUILTIN) != 0;
}
boolean isConstructor() {
- return isConstructor;
+ return (flags & IS_CONSTRUCTOR) != 0;
}
boolean needsCallee() {
- // we don't know if we need a callee or not unless we are generated
- ensureCodeGenerated();
- return code.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 !isStrict && !isBuiltin;
+ return (flags & USES_THIS) != 0 && (flags & IS_STRICT_OR_BUILTIN) == 0;
}
String toSource() {
return "function " + (name == null ? "" : name) + "() { [native code] }";
}
@@ -200,10 +212,19 @@
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,10 +278,12 @@
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,12 +294,11 @@
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;
+ return new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, boundFlags);
}
/**
* Compose a constructor given a primordial constructor handle.
*