aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java')
-rw-r--r--src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java82
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