diff options
Diffstat (limited to 'src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java')
-rw-r--r-- | src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java | 82 |
1 files changed, 68 insertions, 14 deletions
diff --git a/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java b/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java index f16cf41c..c868aab2 100644 --- a/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java +++ b/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java @@ -25,9 +25,9 @@ package jdk.nashorn.internal.runtime; -import static jdk.nashorn.internal.lookup.Lookup.MH; - import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; +import java.util.List; /** * This is a subclass that represents a script function that may not be regenerated. @@ -35,6 +35,8 @@ import java.lang.invoke.MethodHandle; */ final class FinalScriptFunctionData extends ScriptFunctionData { + private static final long serialVersionUID = -930632846167768864L; + /** * Constructor - used for bind * @@ -43,9 +45,10 @@ final class FinalScriptFunctionData extends ScriptFunctionData { * @param functions precompiled code * @param flags {@link ScriptFunctionData} flags */ - FinalScriptFunctionData(final String name, final int arity, final CompiledFunctions functions, final int flags) { + FinalScriptFunctionData(final String name, final int arity, final List<CompiledFunction> functions, final int flags) { super(name, arity, flags); code.addAll(functions); + assert !needsCallee(); } /** @@ -57,33 +60,84 @@ final class FinalScriptFunctionData extends ScriptFunctionData { * @param specs specializations * @param flags {@link ScriptFunctionData} flags */ - FinalScriptFunctionData(final String name, final MethodHandle mh, final MethodHandle[] specs, final int flags) { - super(name, arity(mh), flags); + FinalScriptFunctionData(final String name, final MethodHandle mh, final Specialization[] specs, final int flags) { + super(name, methodHandleArity(mh), flags); addInvoker(mh); if (specs != null) { - for (final MethodHandle spec : specs) { - addInvoker(spec); + for (final Specialization spec : specs) { + addInvoker(spec.getMethodHandle(), spec); + } + } + } + + @Override + boolean isRecompilable() { + return false; + } + + @Override + protected boolean needsCallee() { + final boolean needsCallee = code.getFirst().needsCallee(); + assert allNeedCallee(needsCallee); + return needsCallee; + } + + private boolean allNeedCallee(final boolean needCallee) { + for (final CompiledFunction inv : code) { + if(inv.needsCallee() != needCallee) { + return false; } } + return true; } - private void addInvoker(final MethodHandle mh) { + @Override + MethodType getGenericType() { + // We need to ask the code for its generic type. We can't just rely on this function data's arity, as it's not + // actually correct for lots of built-ins. E.g. ECMAScript 5.1 section 15.5.3.2 prescribes that + // Script.fromCharCode([char0[, char1[, ...]]]) has a declared arity of 1 even though it's a variable arity + // method. + int max = 0; + for(final CompiledFunction fn: code) { + final MethodType t = fn.type(); + if(ScriptFunctionData.isVarArg(t)) { + // 2 for (callee, this, args[]) + return MethodType.genericMethodType(2, true); + } + final int paramCount = t.parameterCount() - (ScriptFunctionData.needsCallee(t) ? 1 : 0); + if(paramCount > max) { + max = paramCount; + } + } + // +1 for callee + return MethodType.genericMethodType(max + 1); + } + + private CompiledFunction addInvoker(final MethodHandle mh, final Specialization specialization) { + assert !needsCallee(mh); + + final CompiledFunction invoker; if (isConstructor(mh)) { // only nasgen constructors: (boolean, self, args) are subject to binding a boolean newObj. isConstructor // is too conservative a check. However, isConstructor(mh) always implies isConstructor param assert isConstructor(); - final MethodHandle invoker = MH.insertArguments(mh, 0, false); - final MethodHandle constructor = composeConstructor(MH.insertArguments(mh, 0, true)); - code.add(new CompiledFunction(mh.type(), invoker, constructor)); + invoker = CompiledFunction.createBuiltInConstructor(mh); } else { - code.add(new CompiledFunction(mh.type(), mh)); + invoker = new CompiledFunction(mh, null, specialization); } + code.add(invoker); + + return invoker; + } + + private CompiledFunction addInvoker(final MethodHandle mh) { + return addInvoker(mh, null); } - private static int arity(final MethodHandle mh) { + private static int methodHandleArity(final MethodHandle mh) { if (isVarArg(mh)) { - return -1; + return MAX_ARITY; } //drop self, callee and boolean constructor flag to get real arity |