зеркало из https://github.com/mozilla/pjs.git
When marking parse tree nodes as special calls, use explicit integer id to specify node type, note a generic boolean flag. It would allow for simpler code during special calls evaluation.
This commit is contained in:
Родитель
6db53c35e3
Коммит
0ec8c3be9c
|
@ -415,7 +415,9 @@ public class Interpreter {
|
|||
child = child.getNext();
|
||||
childCount++;
|
||||
}
|
||||
if (node.getIntProp(Node.SPECIALCALL_PROP, 0) != 0) {
|
||||
int callType = node.getIntProp(Node.SPECIALCALL_PROP,
|
||||
Node.NON_SPECIALCALL);
|
||||
if (callType != Node.NON_SPECIALCALL) {
|
||||
// embed line number and source filename
|
||||
iCodeTop = addByte(TokenStream.CALLSPECIAL, iCodeTop);
|
||||
iCodeTop = addShort(itsLineNumber, iCodeTop);
|
||||
|
|
|
@ -313,6 +313,11 @@ public class Node implements Cloneable {
|
|||
LEFT = 1,
|
||||
RIGHT = 2;
|
||||
|
||||
public static final int // this value of the SPECIALCALL_PROP specifies
|
||||
NON_SPECIALCALL = 0,
|
||||
SPECIALCALL_EVAL = 1,
|
||||
SPECIALCALL_WITH = 2;
|
||||
|
||||
private static final String propToString(int propType) {
|
||||
if (Context.printTrees) {
|
||||
// If Context.printTrees is false, the compiler
|
||||
|
|
|
@ -316,17 +316,23 @@ public class NodeTransformer {
|
|||
break;
|
||||
}
|
||||
|
||||
case TokenStream.CALL:
|
||||
if (isSpecialCallName(tree, node))
|
||||
node.putIntProp(Node.SPECIALCALL_PROP, 1);
|
||||
case TokenStream.CALL: {
|
||||
int callType = getSpecialCallType(tree, node);
|
||||
if (callType != Node.NON_SPECIALCALL) {
|
||||
node.putIntProp(Node.SPECIALCALL_PROP, callType);
|
||||
}
|
||||
visitCall(node, tree);
|
||||
break;
|
||||
}
|
||||
|
||||
case TokenStream.NEW:
|
||||
if (isSpecialCallName(tree, node))
|
||||
node.putIntProp(Node.SPECIALCALL_PROP, 1);
|
||||
case TokenStream.NEW: {
|
||||
int callType = getSpecialCallType(tree, node);
|
||||
if (callType != Node.NON_SPECIALCALL) {
|
||||
node.putIntProp(Node.SPECIALCALL_PROP, callType);
|
||||
}
|
||||
visitNew(node, tree);
|
||||
break;
|
||||
}
|
||||
|
||||
case TokenStream.DOT:
|
||||
{
|
||||
|
@ -521,25 +527,30 @@ public class NodeTransformer {
|
|||
* Return true if the node is a call to a function that requires
|
||||
* access to the enclosing activation object.
|
||||
*/
|
||||
private boolean isSpecialCallName(Node tree, Node node) {
|
||||
private int getSpecialCallType(Node tree, Node node) {
|
||||
Node left = node.getFirstChild();
|
||||
boolean isSpecial = false;
|
||||
int type = Node.NON_SPECIALCALL;
|
||||
if (left.getType() == TokenStream.NAME) {
|
||||
String name = left.getString();
|
||||
isSpecial = name.equals("eval") || name.equals("With");
|
||||
if (name.equals("eval")) {
|
||||
type = Node.SPECIALCALL_EVAL;
|
||||
} else if (name.equals("With")) {
|
||||
type = Node.SPECIALCALL_WITH;
|
||||
}
|
||||
} else {
|
||||
if (left.getType() == TokenStream.GETPROP) {
|
||||
String name = left.getLastChild().getString();
|
||||
isSpecial = name.equals("exec");
|
||||
if (name.equals("eval")) {
|
||||
type = Node.SPECIALCALL_EVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isSpecial) {
|
||||
if (type != Node.NON_SPECIALCALL) {
|
||||
// Calls to these functions require activation objects.
|
||||
if (inFunction)
|
||||
((FunctionNode) tree).setRequiresActivation(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return type;
|
||||
}
|
||||
|
||||
private void
|
||||
|
|
|
@ -92,7 +92,6 @@ public class ScriptRuntime {
|
|||
ContextClass = classOrNull("org.mozilla.javascript.Context"),
|
||||
FunctionClass = classOrNull("org.mozilla.javascript.Function"),
|
||||
NativeGlobalClass = classOrNull("org.mozilla.javascript.NativeGlobal"),
|
||||
NativeScriptClass = classOrNull("org.mozilla.javascript.NativeScript"),
|
||||
NativeWithClass = classOrNull("org.mozilla.javascript.NativeWith"),
|
||||
ScriptableClass = classOrNull("org.mozilla.javascript.Scriptable"),
|
||||
ScriptableObjectClass = classOrNull(
|
||||
|
|
|
@ -1888,12 +1888,13 @@ public class Codegen extends Interpreter {
|
|||
if (firstArgDone && (type == TokenStream.NEW))
|
||||
constructArgArray(childCount - argSkipCount);
|
||||
|
||||
boolean isSpecialCall = node.getIntProp(Node.SPECIALCALL_PROP, 0) != 0;
|
||||
int callType = node.getIntProp(Node.SPECIALCALL_PROP,
|
||||
Node.NON_SPECIALCALL);
|
||||
boolean isSimpleCall = false;
|
||||
String simpleCallName = null;
|
||||
if (!firstArgDone && type != TokenStream.NEW) {
|
||||
simpleCallName = getSimpleCallName(node);
|
||||
if (simpleCallName != null && !isSpecialCall) {
|
||||
if (simpleCallName != null && callType == Node.NON_SPECIALCALL) {
|
||||
isSimpleCall = true;
|
||||
push(simpleCallName);
|
||||
aload(variableObjectLocal);
|
||||
|
@ -1955,7 +1956,7 @@ public class Codegen extends Interpreter {
|
|||
String methodName;
|
||||
String callSignature;
|
||||
|
||||
if (isSpecialCall) {
|
||||
if (callType != Node.NON_SPECIALCALL) {
|
||||
className = "org/mozilla/javascript/ScriptRuntime";
|
||||
if (type == TokenStream.NEW) {
|
||||
methodName = "newObjectSpecial";
|
||||
|
|
Загрузка…
Ссылка в новой задаче