Skip to content

Commit

Permalink
Optimize order of arguments to permit optimizations
Browse files Browse the repository at this point in the history
Make sure that the "target" of each operation is always first. For
now, at least, do this without changing ScriptRuntime.
  • Loading branch information
gbrail committed Oct 4, 2024
1 parent 5c85ebc commit 670bc40
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -984,8 +984,8 @@ private void generateExpression(Node node, Node parent) {

case Token.NAME:
{
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
cfw.addALoad(contextLocal);
addDynamicInvoke("NAME:GET:" + node.getString(), Signatures.NAME_GET);
}
break;
Expand Down Expand Up @@ -1473,8 +1473,8 @@ private void generateExpression(Node node, Node parent) {
child = child.getNext();
}
// Generate code for "ScriptRuntime.bind(varObj, "s")"
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
cfw.addALoad(contextLocal);
addDynamicInvoke("NAME:BIND:" + node.getString(), Signatures.NAME_BIND);
}
break;
Expand Down Expand Up @@ -2644,8 +2644,8 @@ private void generateFunctionAndThisObj(Node node, Node parent) {
case Token.NAME:
{
String name = node.getString();
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
cfw.addALoad(contextLocal);
addDynamicInvoke("NAME:GETWITHTHIS:" + name, Signatures.NAME_GET_THIS);
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
import jdk.dynalink.linker.GuardingDynamicLinker;
import jdk.dynalink.linker.LinkRequest;
import jdk.dynalink.linker.LinkerServices;
import org.mozilla.javascript.Callable;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;

/**
* This linker is the last one in the chain, and as such it must be able to link every type of
Expand Down Expand Up @@ -125,18 +128,30 @@ private GuardedInvocation getNameInvocation(
Operation op,
String name)
throws NoSuchMethodException, IllegalAccessException {
MethodType tt;
MethodHandle mh = null;

// Like above for properties, the name to handle is not on the Java stack,
// but is something that we parsed from the name of the invokedynamic operation.
if (RhinoOperation.BIND.equals(op)) {
mh = bindStringParameter(lookup, mType, ScriptRuntime.class, "bind", 2, name);
tt =
MethodType.methodType(
Scriptable.class, Context.class, Scriptable.class, String.class);
mh = lookup.findStatic(ScriptRuntime.class, "bind", tt);
mh = MethodHandles.insertArguments(mh, 2, name);
mh = MethodHandles.permuteArguments(mh, mType, 1, 0);
} else if (StandardOperation.GET.equals(op)) {
mh = bindStringParameter(lookup, mType, ScriptRuntime.class, "name", 2, name);
tt = MethodType.methodType(Object.class, Context.class, Scriptable.class, String.class);
mh = lookup.findStatic(ScriptRuntime.class, "name", tt);
mh = MethodHandles.insertArguments(mh, 2, name);
mh = MethodHandles.permuteArguments(mh, mType, 1, 0);
} else if (RhinoOperation.GETWITHTHIS.equals(op)) {
mh =
bindStringParameter(
lookup, mType, ScriptRuntime.class, "getNameFunctionAndThis", 0, name);
tt =
MethodType.methodType(
Callable.class, String.class, Context.class, Scriptable.class);
mh = lookup.findStatic(ScriptRuntime.class, "getNameFunctionAndThis", tt);
mh = MethodHandles.insertArguments(mh, 0, name);
mh = MethodHandles.permuteArguments(mh, mType, 1, 0);
} else if (StandardOperation.SET.equals(op)) {
mh = bindStringParameter(lookup, mType, ScriptRuntime.class, "setName", 4, name);
} else if (RhinoOperation.SETSTRICT.equals(op)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
* instructions in the bytecode. This helps us identify what each bytecode operation means, and what
* the method signature should be. The method signatures here don't necessarily map 1:1 with
* ScriptRuntime operations -- the runtime will insert the value of the "name" part of the operation
* name before making the call.
* name before making the call. Also, many of the "name" operations have a different signature than
* the ScriptRuntime equivalents because in these signatures we are trying to make the "target" of
* each operation the first argument to make future optimizations easier.
*/
interface Signatures {
/**
Expand Down Expand Up @@ -92,17 +94,17 @@ interface Signatures {
* NAME:GET:{name}: Looks up a the named value from the scope. Falls back to ScriptRuntime.name.
*/
String NAME_GET =
"(Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
"(Lorg/mozilla/javascript/Scriptable;"
+ "Lorg/mozilla/javascript/Context;"
+ ")Ljava/lang/Object;";

/**
* NAME:GETWITHTHIS:{name}: Looks up a name in the scope like NAME:GET, and sets "this" in the
* "last stored scriptable." Falls back to ScriptRuntime.getNameFunctionAndThis.
*/
String NAME_GET_THIS =
"(Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
"(Lorg/mozilla/javascript/Scriptable;"
+ "Lorg/mozilla/javascript/Context;"
+ ")Lorg/mozilla/javascript/Callable;";

/** NAME:SET:{name}: Sets the named value in the scope. Falls back to ScriptRuntime.setName. */
Expand All @@ -118,8 +120,8 @@ interface Signatures {
* ScriptRuntime.bind.
*/
String NAME_BIND =
"(Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
"(Lorg/mozilla/javascript/Scriptable;"
+ "Lorg/mozilla/javascript/Context;"
+ ")Lorg/mozilla/javascript/Scriptable;";

/**
Expand Down

0 comments on commit 670bc40

Please sign in to comment.