Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 73 additions & 105 deletions rhino/src/main/java/org/mozilla/javascript/optimizer/Signatures.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package org.mozilla.javascript.optimizer;

import java.lang.invoke.MethodType;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;

/**
* This class defines the method signatures for the properties used by the invokedynamic
* instructions in the bytecode. This helps us identify what each bytecode operation means, and what
Expand All @@ -10,148 +15,133 @@
* each operation the first argument to make future optimizations easier.
*/
interface Signatures {
static String sig(Class<?> returnType, Class<?>... paramTypes) {
return MethodType.methodType(returnType, paramTypes).toMethodDescriptorString();
}

/**
* PROP:GET:{name}: Looks up the object property named "name". Falls back to
* ScriptRuntime.getObjectPropNoWarn.
*/
String PROP_GET =
"(Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ ")Ljava/lang/Object;";
String PROP_GET = sig(Object.class, Object.class, Context.class, Scriptable.class);

/**
* PROP:GETNOWARN:{name}: Looks up the object property named "name" and does not warn if it does
* not exist. Falls back to ScriptRuntime.getObjectProp.
*/
String PROP_GET_NOWARN =
"(Ljava/lang/Object;Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;)Ljava/lang/Object;";
String PROP_GET_NOWARN = sig(Object.class, Object.class, Context.class, Scriptable.class);

/**
* PROP:GET_SUPER:{name}: Looks up the super property named "name". Falls back to
* ScriptRuntime.getSuperProp.
*/
String PROP_GET_SUPER =
"(Ljava/lang/Object;" // superObj
+ "Lorg/mozilla/javascript/Context;" // cx
+ "Lorg/mozilla/javascript/Scriptable;" // scope
+ "Ljava/lang/Object;" // thisObj
+ "Z" // noWarn
+ ")Ljava/lang/Object;";
sig(
Object.class,
Object.class, // superObj
Context.class, // cx
Scriptable.class, // scope
Object.class, // thisObj
boolean.class // noWarn
);

/**
* PROP:GETWITHTHIS:{name}: Looks up an object property like PROP:GET, and sets "this" in the
* "last stored scriptable." Falls back to ScriptRuntime.getPropFunctionAndThis.
*/
String PROP_GET_THIS =
"(Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ ")Lorg/mozilla/javascript/ScriptRuntime$LookupResult;";
sig(ScriptRuntime.LookupResult.class, Object.class, Context.class, Scriptable.class);

/**
* PROP:GETINDEX: Get a property from an object based on a numeric index. Falls back to
* ScriptRuntime.getObjectIndex.
*/
String PROP_GET_INDEX =
"(Ljava/lang/Object;"
+ "D"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ ")Ljava/lang/Object;";
sig(Object.class, Object.class, double.class, Context.class, Scriptable.class);

/**
* PROP:GETELEMENT: Get a property from an object based on an element ID, which could be a
* string, number, or symbol. Falls back to ScriptRuntime.getObjectElem.
*/
String PROP_GET_ELEMENT =
"(Ljava/lang/Object;"
+ "Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ ")Ljava/lang/Object;";
sig(Object.class, Object.class, Object.class, Context.class, Scriptable.class);

/**
* PROP:GETELEMENTSUPER: Get a property from super based on an element ID, which could be a
* string, number, or symbol. Falls back to ScriptRuntime.getSuperElem.
*/
String PROP_GET_ELEMENT_SUPER =
"(Ljava/lang/Object;" // super
+ "Ljava/lang/Object;" // elem
+ "Lorg/mozilla/javascript/Context;" // cx
+ "Lorg/mozilla/javascript/Scriptable;" // scope
+ "Ljava/lang/Object;" // this
+ ")Ljava/lang/Object;";
sig(
Object.class,
Object.class,
Object.class,
Context.class,
Scriptable.class,
Object.class);

/**
* PROP:SET:{name}: Sets the named property on an object. Falls back to
* ScriptRuntime.setObjectProp.
*/
String PROP_SET =
"(Ljava/lang/Object;Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;Lorg/mozilla/javascript/Scriptable;)Ljava/lang/Object;";
sig(Object.class, Object.class, Object.class, Context.class, Scriptable.class);

/**
* PROP:SETSUPER:{name}: Sets the named property on super. Falls back to
* ScriptRuntime.setSuperProp.
*/
String PROP_SET_SUPER =
"("
+ "Ljava/lang/Object;" // superObj
+ "Ljava/lang/Object;" // value
+ "Lorg/mozilla/javascript/Context;" // cx
+ "Lorg/mozilla/javascript/Scriptable;" // scope
+ "Ljava/lang/Object;" // thisObj
+ ")Ljava/lang/Object;";
sig(
Object.class,
Object.class,
Object.class,
Context.class,
Scriptable.class,
Object.class);

/**
* PROP:SETINDEX: Set a property on an object based on a numeric index. Falls back to
* ScriptRuntime.setObjectIndex.
*/
String PROP_SET_INDEX =
"(Ljava/lang/Object;"
+ "D"
+ "Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ ")Ljava/lang/Object;";
sig(
Object.class,
Object.class,
double.class,
Object.class,
Context.class,
Scriptable.class);

/**
* PROP:SETELEMENT: Set a property on an object based on an identifier. Falls back to
* ScriptRuntime.setObjectElem.
*/
String PROP_SET_ELEMENT =
"(Ljava/lang/Object;"
+ "Ljava/lang/Object;"
+ "Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ ")Ljava/lang/Object;";
sig(
Object.class,
Object.class,
Object.class,
Object.class,
Context.class,
Scriptable.class);

/**
* PROP:SETELEMENTSUPER: Set a property on super based on an identifier. Falls back to
* ScriptRuntime.setSuperElem.
*/
String PROP_SET_ELEMENT_SUPER =
"(Ljava/lang/Object;" // super
+ "Ljava/lang/Object;" // elem
+ "Ljava/lang/Object;" // value
+ "Lorg/mozilla/javascript/Context;" // cx
+ "Lorg/mozilla/javascript/Scriptable;" // scope
+ "Ljava/lang/Object;" // this
+ ")Ljava/lang/Object;";
sig(
Object.class,
Object.class,
Object.class,
Object.class,
Context.class,
Scriptable.class,
Object.class);

/**
* NAME:GET:{name}: Looks up a the named value from the scope. Falls back to ScriptRuntime.name.
* Compared to that function, this version of the signature puts the "scope" first in the
* argument list rather than second. This makes it easier for future linkers to work because
* they can always assume that the "receiver" of an operation is the first argument.
*/
String NAME_GET =
"(Lorg/mozilla/javascript/Scriptable;"
+ "Lorg/mozilla/javascript/Context;"
+ ")Ljava/lang/Object;";
String NAME_GET = sig(Object.class, Scriptable.class, Context.class);

/**
* NAME:GETWITHTHIS:{name}: Looks up a name in the scope like NAME:GET, and sets "this" in the
Expand All @@ -160,66 +150,44 @@ interface Signatures {
* NAME:GETWITHTHISOPTIONAL:{name} has different semantics for an optional function call, but it
* uses this same signature.
*/
String NAME_GET_THIS =
"(Lorg/mozilla/javascript/Scriptable;"
+ "Lorg/mozilla/javascript/Context;"
+ ")Lorg/mozilla/javascript/ScriptRuntime$LookupResult;";
String NAME_GET_THIS = sig(ScriptRuntime.LookupResult.class, Scriptable.class, Context.class);

/** NAME:SET:{name}: Sets the named value in the scope. Falls back to ScriptRuntime.setName. */
String NAME_SET =
"(Lorg/mozilla/javascript/Scriptable;"
+ "Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ ")Ljava/lang/Object;";
sig(Object.class, Scriptable.class, Object.class, Context.class, Scriptable.class);

/**
* NAME:BIND:{name}: Bind the named value into the current scope. Falls back to
* ScriptRuntime.bind. Like some methods above, this version of the signature puts the scope
* first in the argument list so that future linkers can have a consistent place to find the
* "receiver".
*/
String NAME_BIND =
"(Lorg/mozilla/javascript/Scriptable;"
+ "Lorg/mozilla/javascript/Context;"
+ ")Lorg/mozilla/javascript/Scriptable;";
String NAME_BIND = sig(Scriptable.class, Scriptable.class, Context.class);

/**
* NAME:SETSTRICT:{name}: Sets the named value in the scope, and enforces strict mode. Falls
* back to ScriptRuntime.strictSetName.
*/
String NAME_SET_STRICT =
"(Lorg/mozilla/javascript/Scriptable;"
+ "Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ ")Ljava/lang/Object;";
sig(Object.class, Scriptable.class, Object.class, Context.class, Scriptable.class);

/**
* NAME:SETCONST:{name}: Sets the named constant in the scope. Falls back to
* ScriptRuntime.setConst.
*/
String NAME_SET_CONST =
"(Lorg/mozilla/javascript/Scriptable;"
+ "Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;"
+ ")Ljava/lang/Object;";
String NAME_SET_CONST = sig(Object.class, Scriptable.class, Object.class, Context.class);

/**
* MATH:ADD: Add the first two arguments on the stack, which could be numbers, strings, or
* really just about anything.
*/
String MATH_ADD =
"(Ljava/lang/Object;"
+ "Ljava/lang/Object;"
+ "Lorg/mozilla/javascript/Context;"
+ ")Ljava/lang/Object;";
String MATH_ADD = sig(Object.class, Object.class, Object.class, Context.class);

/** MATH:TOBOOLEAN: Make the object into a primitive boolean. */
String MATH_TO_BOOLEAN = "(Ljava/lang/Object;)Z";
String MATH_TO_BOOLEAN = sig(boolean.class, Object.class);

/** MATH:EQ: Are the two arguments equal? */
String MATH_EQ = "(Ljava/lang/Object;Ljava/lang/Object;)Z";
String MATH_EQ = sig(boolean.class, Object.class, Object.class);

/** MATH:SHALLOWEQ: Like EQ but not. */
String MATH_SHALLOW_EQ = MATH_EQ;
Expand All @@ -234,17 +202,17 @@ interface Signatures {
* <li>MATH:COMPARELE
* </ul>
*/
String MATH_COMPARE = "(Ljava/lang/Object;Ljava/lang/Object;)Z";
String MATH_COMPARE = sig(boolean.class, Object.class, Object.class);

/** MATH:TONUMBER: Convert the object to a Java "double". */
String MATH_TO_NUMBER = "(Ljava/lang/Object;)D";
String MATH_TO_NUMBER = sig(double.class, Object.class);

/** MATH:TONUMERIC: Convert the object to a Java "Number". */
String MATH_TO_NUMERIC = "(Ljava/lang/Object;)Ljava/lang/Number;";
String MATH_TO_NUMERIC = sig(Number.class, Object.class);

/** MATH:TOINT32: Convert the object to a Java "int". */
String MATH_TO_INT32 = "(Ljava/lang/Object;)I";
String MATH_TO_INT32 = sig(int.class, Object.class);

/** MATH:TOUINT32: Convert the object to a Java "long" that represents an unsigned integer. */
String MATH_TO_UINT32 = "(Ljava/lang/Object;)J";
String MATH_TO_UINT32 = sig(long.class, Object.class);
}