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. *