зеркало из https://github.com/mozilla/pjs.git
1. Add Token.NOT as a byte code instead of generating if code to push false/true as "!" is frequent enough and interpreter does not have optimized mode to remove most of its usage in logical context.
2. When dumping icode, print it to System.out instead of icode.txt file for more convenient development.
This commit is contained in:
Родитель
0fa5242f20
Коммит
8a7aea78a4
|
@ -290,14 +290,7 @@ public class Interpreter
|
|||
|
||||
private void badTree(Node node)
|
||||
{
|
||||
try {
|
||||
out = new PrintWriter(new FileOutputStream("icode.txt", true));
|
||||
out.println("Un-handled node : " + node.toString());
|
||||
out.close();
|
||||
}
|
||||
catch (IOException x) {}
|
||||
throw new RuntimeException("Un-handled node : "
|
||||
+ node.toString());
|
||||
throw new RuntimeException("Un-handled node: "+node.toString());
|
||||
}
|
||||
|
||||
private int generateICode(Node node, int iCodeTop)
|
||||
|
@ -624,19 +617,9 @@ public class Interpreter
|
|||
iCodeTop = addToken(Token.POP, iCodeTop);
|
||||
iCodeTop = addToken(Token.UNDEFINED, iCodeTop);
|
||||
break;
|
||||
case Token.NOT : {
|
||||
int trueJumpStart = iCodeTop;
|
||||
iCodeTop = addForwardGoto(Token.IFEQ,
|
||||
iCodeTop);
|
||||
iCodeTop = addToken(Token.TRUE, iCodeTop);
|
||||
int beyondJumpStart = iCodeTop;
|
||||
iCodeTop = addForwardGoto(Token.GOTO,
|
||||
iCodeTop);
|
||||
resolveForwardGoto(trueJumpStart, iCodeTop);
|
||||
iCodeTop = addToken(Token.FALSE, iCodeTop);
|
||||
resolveForwardGoto(beyondJumpStart, iCodeTop);
|
||||
case Token.NOT :
|
||||
iCodeTop = addToken(Token.NOT, iCodeTop);
|
||||
break;
|
||||
}
|
||||
case Token.BITNOT :
|
||||
iCodeTop = addToken(Token.BITNOT, iCodeTop);
|
||||
break;
|
||||
|
@ -825,12 +808,17 @@ public class Interpreter
|
|||
case Token.POP :
|
||||
case Token.POPV :
|
||||
iCodeTop = updateLineNumber(node, iCodeTop);
|
||||
case Token.ENTERWITH :
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
iCodeTop = addToken(type, iCodeTop);
|
||||
itsStackDepth--;
|
||||
break;
|
||||
|
||||
case Token.ENTERWITH :
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
iCodeTop = addToken(Token.ENTERWITH, iCodeTop);
|
||||
itsStackDepth--;
|
||||
break;
|
||||
|
||||
case Token.GETTHIS :
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
iCodeTop = addToken(Token.GETTHIS, iCodeTop);
|
||||
|
@ -1306,26 +1294,13 @@ public class Interpreter
|
|||
return "";
|
||||
}
|
||||
|
||||
static PrintWriter out;
|
||||
static {
|
||||
private static void dumpICode(InterpreterData idata)
|
||||
{
|
||||
if (Token.printICode) {
|
||||
try {
|
||||
out = new PrintWriter(new FileOutputStream("icode.txt"));
|
||||
out.close();
|
||||
}
|
||||
catch (IOException x) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void dumpICode(InterpreterData idata) {
|
||||
if (Token.printICode) {
|
||||
try {
|
||||
int iCodeLength = idata.itsICodeTop;
|
||||
byte iCode[] = idata.itsICode;
|
||||
String[] strings = idata.itsStringTable;
|
||||
|
||||
out = new PrintWriter(new FileOutputStream("icode.txt", true));
|
||||
PrintStream out = System.out;
|
||||
out.println("ICode dump, for " + idata.itsName
|
||||
+ ", length = " + iCodeLength);
|
||||
out.println("MaxStack = " + idata.itsMaxStack);
|
||||
|
@ -1372,8 +1347,8 @@ public class Interpreter
|
|||
boolean isNew = (iCode[pc + 1] != 0);
|
||||
int line = getShort(iCode, pc+2);
|
||||
int count = getIndex(iCode, pc + 4);
|
||||
out.println(tname + " " + callType + " " + isNew
|
||||
+ " " + count + " " + line);
|
||||
out.println(tname+" "+callType+" "+isNew
|
||||
+" "+count+" "+line);
|
||||
pc += 8;
|
||||
break;
|
||||
}
|
||||
|
@ -1395,8 +1370,7 @@ public class Interpreter
|
|||
case Token.CALL : {
|
||||
int count = getIndex(iCode, pc + 2);
|
||||
String name = strings[getIndex(iCode, pc)];
|
||||
out.println(tname + " " + count + " \""
|
||||
+ name + '"');
|
||||
out.println(tname+' '+count+" \""+name+'"');
|
||||
pc += 4;
|
||||
break;
|
||||
}
|
||||
|
@ -1460,10 +1434,7 @@ public class Interpreter
|
|||
+"\t "+withDepth);
|
||||
}
|
||||
}
|
||||
|
||||
out.close();
|
||||
}
|
||||
catch (IOException x) {}
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1498,8 +1469,9 @@ public class Interpreter
|
|||
case Token.LSH :
|
||||
case Token.RSH :
|
||||
case Token.URSH :
|
||||
case Token.NEG :
|
||||
case Token.NOT :
|
||||
case Token.POS :
|
||||
case Token.NEG :
|
||||
case Token.SUB :
|
||||
case Token.MUL :
|
||||
case Token.DIV :
|
||||
|
@ -2014,16 +1986,9 @@ public class Interpreter
|
|||
break;
|
||||
}
|
||||
case Token.IFNE : {
|
||||
Object val = stack[stackTop];
|
||||
boolean valBln;
|
||||
if (val != DBL_MRK) {
|
||||
valBln = !ScriptRuntime.toBoolean(val);
|
||||
} else {
|
||||
double valDbl = sDbl[stackTop];
|
||||
valBln = !(valDbl == valDbl && valDbl != 0.0);
|
||||
}
|
||||
boolean valBln = stack_boolean(stack, sDbl, stackTop);
|
||||
--stackTop;
|
||||
if (valBln) {
|
||||
if (!valBln) {
|
||||
if (instructionThreshold != 0) {
|
||||
instructionCount += pc + 3 - pcPrevBranch;
|
||||
if (instructionCount > instructionThreshold) {
|
||||
|
@ -2038,14 +2003,7 @@ public class Interpreter
|
|||
break;
|
||||
}
|
||||
case Token.IFEQ : {
|
||||
boolean valBln;
|
||||
Object val = stack[stackTop];
|
||||
if (val != DBL_MRK) {
|
||||
valBln = ScriptRuntime.toBoolean(val);
|
||||
} else {
|
||||
double valDbl = sDbl[stackTop];
|
||||
valBln = (valDbl == valDbl && valDbl != 0.0);
|
||||
}
|
||||
boolean valBln = stack_boolean(stack, sDbl, stackTop);
|
||||
--stackTop;
|
||||
if (valBln) {
|
||||
if (instructionThreshold != 0) {
|
||||
|
@ -2234,6 +2192,11 @@ public class Interpreter
|
|||
sDbl[stackTop] = lDbl % rDbl;
|
||||
break;
|
||||
}
|
||||
case Token.NOT : {
|
||||
stack[stackTop] = stack_boolean(stack, sDbl, stackTop)
|
||||
? Boolean.FALSE : Boolean.TRUE;
|
||||
break;
|
||||
}
|
||||
case Token.BINDNAME : {
|
||||
String name = strings[getIndex(iCode, pc + 1)];
|
||||
stack[++stackTop] = ScriptRuntime.bind(scope, name);
|
||||
|
@ -2782,6 +2745,25 @@ public class Interpreter
|
|||
return (x != DBL_MRK) ? ScriptRuntime.toNumber(x) : stackDbl[i];
|
||||
}
|
||||
|
||||
private static boolean stack_boolean(Object[] stack, double[] stackDbl,
|
||||
int i)
|
||||
{
|
||||
Object x = stack[i];
|
||||
if (x == DBL_MRK) {
|
||||
double d = stackDbl[i];
|
||||
return d == d && d != 0.0;
|
||||
} else if (x instanceof Boolean) {
|
||||
return ((Boolean)x).booleanValue();
|
||||
} else if (x == null || x == Undefined.instance) {
|
||||
return false;
|
||||
} else if (x instanceof Number) {
|
||||
double d = ((Number)x).doubleValue();
|
||||
return (d == d && d != 0.0);
|
||||
} else {
|
||||
return ScriptRuntime.toBoolean(x);
|
||||
}
|
||||
}
|
||||
|
||||
private static void do_add(Object[] stack, double[] stackDbl, int stackTop)
|
||||
{
|
||||
Object rhs = stack[stackTop + 1];
|
||||
|
|
|
@ -99,89 +99,90 @@ public class Token
|
|||
MUL = 24,
|
||||
DIV = 25,
|
||||
MOD = 26,
|
||||
BITNOT = 27,
|
||||
NEG = 28,
|
||||
NEW = 29,
|
||||
DELPROP = 30,
|
||||
TYPEOF = 31,
|
||||
GETPROP = 32,
|
||||
SETPROP = 33,
|
||||
GETELEM = 34,
|
||||
SETELEM = 35,
|
||||
CALL = 36,
|
||||
NAME = 37,
|
||||
NUMBER = 38,
|
||||
STRING = 39,
|
||||
ZERO = 40,
|
||||
ONE = 41,
|
||||
NULL = 42,
|
||||
THIS = 43,
|
||||
FALSE = 44,
|
||||
TRUE = 45,
|
||||
SHEQ = 46, // shallow equality (===)
|
||||
SHNE = 47, // shallow inequality (!==)
|
||||
REGEXP = 48,
|
||||
POP = 49,
|
||||
POS = 50,
|
||||
BINDNAME = 51,
|
||||
THROW = 52,
|
||||
IN = 53,
|
||||
INSTANCEOF = 54,
|
||||
GETTHIS = 55,
|
||||
NEWTEMP = 56,
|
||||
USETEMP = 57,
|
||||
GETBASE = 58,
|
||||
GETVAR = 59,
|
||||
SETVAR = 60,
|
||||
UNDEFINED = 61,
|
||||
NEWSCOPE = 62,
|
||||
ENUMINIT = 63,
|
||||
ENUMNEXT = 64,
|
||||
THISFN = 65,
|
||||
NOT = 27,
|
||||
BITNOT = 28,
|
||||
POS = 29,
|
||||
NEG = 30,
|
||||
NEW = 31,
|
||||
DELPROP = 32,
|
||||
TYPEOF = 33,
|
||||
GETPROP = 34,
|
||||
SETPROP = 35,
|
||||
GETELEM = 36,
|
||||
SETELEM = 37,
|
||||
CALL = 38,
|
||||
NAME = 39,
|
||||
NUMBER = 40,
|
||||
STRING = 41,
|
||||
ZERO = 42,
|
||||
ONE = 43,
|
||||
NULL = 44,
|
||||
THIS = 45,
|
||||
FALSE = 46,
|
||||
TRUE = 47,
|
||||
SHEQ = 48, // shallow equality (===)
|
||||
SHNE = 49, // shallow inequality (!==)
|
||||
REGEXP = 50,
|
||||
POP = 51,
|
||||
BINDNAME = 52,
|
||||
THROW = 53,
|
||||
IN = 54,
|
||||
INSTANCEOF = 55,
|
||||
GETTHIS = 56,
|
||||
NEWTEMP = 57,
|
||||
USETEMP = 58,
|
||||
GETBASE = 59,
|
||||
GETVAR = 60,
|
||||
SETVAR = 61,
|
||||
UNDEFINED = 62,
|
||||
NEWSCOPE = 63,
|
||||
ENUMINIT = 64,
|
||||
ENUMNEXT = 65,
|
||||
THISFN = 66,
|
||||
|
||||
LAST_BYTECODE_TOKEN = 65,
|
||||
LAST_BYTECODE_TOKEN = 66,
|
||||
// End of interpreter bytecodes
|
||||
|
||||
TRY = 66,
|
||||
SEMI = 67, // semicolon
|
||||
LB = 68, // left and right brackets
|
||||
RB = 69,
|
||||
LC = 70, // left and right curlies (braces)
|
||||
RC = 71,
|
||||
LP = 72, // left and right parentheses
|
||||
RP = 73,
|
||||
COMMA = 74, // comma operator
|
||||
ASSIGN = 75, // assignment ops (= += -= etc.)
|
||||
HOOK = 76, // conditional (?:)
|
||||
COLON = 77,
|
||||
OR = 78, // logical or (||)
|
||||
AND = 79, // logical and (&&)
|
||||
EQOP = 80, // equality ops (== !=)
|
||||
RELOP = 81, // relational ops (< <= > >=)
|
||||
SHOP = 82, // shift ops (<< >> >>>)
|
||||
UNARYOP = 83, // unary prefix operator
|
||||
INC = 84, // increment/decrement (++ --)
|
||||
DEC = 85,
|
||||
DOT = 86, // member operator (.)
|
||||
PRIMARY = 87, // true, false, null, this
|
||||
FUNCTION = 88, // function keyword
|
||||
EXPORT = 89, // export keyword
|
||||
IMPORT = 90, // import keyword
|
||||
IF = 91, // if keyword
|
||||
ELSE = 92, // else keyword
|
||||
SWITCH = 93, // switch keyword
|
||||
CASE = 94, // case keyword
|
||||
DEFAULT = 95, // default keyword
|
||||
WHILE = 96, // while keyword
|
||||
DO = 97, // do keyword
|
||||
FOR = 98, // for keyword
|
||||
BREAK = 99, // break keyword
|
||||
CONTINUE = 100, // continue keyword
|
||||
VAR = 101, // var keyword
|
||||
WITH = 102, // with keyword
|
||||
CATCH = 103, // catch keyword
|
||||
FINALLY = 104, // finally keyword
|
||||
RESERVED = 105, // reserved keywords
|
||||
TRY = 67,
|
||||
SEMI = 68, // semicolon
|
||||
LB = 69, // left and right brackets
|
||||
RB = 70,
|
||||
LC = 71, // left and right curlies (braces)
|
||||
RC = 72,
|
||||
LP = 73, // left and right parentheses
|
||||
RP = 74,
|
||||
COMMA = 75, // comma operator
|
||||
ASSIGN = 76, // assignment ops (= += -= etc.)
|
||||
HOOK = 77, // conditional (?:)
|
||||
COLON = 78,
|
||||
OR = 79, // logical or (||)
|
||||
AND = 80, // logical and (&&)
|
||||
EQOP = 81, // equality ops (== !=)
|
||||
RELOP = 82, // relational ops (< <= > >=)
|
||||
SHOP = 83, // shift ops (<< >> >>>)
|
||||
UNARYOP = 84, // unary prefix operator
|
||||
INC = 85, // increment/decrement (++ --)
|
||||
DEC = 86,
|
||||
DOT = 87, // member operator (.)
|
||||
PRIMARY = 88, // true, false, null, this
|
||||
FUNCTION = 89, // function keyword
|
||||
EXPORT = 90, // export keyword
|
||||
IMPORT = 91, // import keyword
|
||||
IF = 92, // if keyword
|
||||
ELSE = 93, // else keyword
|
||||
SWITCH = 94, // switch keyword
|
||||
CASE = 95, // case keyword
|
||||
DEFAULT = 96, // default keyword
|
||||
WHILE = 97, // while keyword
|
||||
DO = 98, // do keyword
|
||||
FOR = 99, // for keyword
|
||||
BREAK = 100, // break keyword
|
||||
CONTINUE = 101, // continue keyword
|
||||
VAR = 102, // var keyword
|
||||
WITH = 103, // with keyword
|
||||
CATCH = 104, // catch keyword
|
||||
FINALLY = 105, // finally keyword
|
||||
RESERVED = 106, // reserved keywords
|
||||
|
||||
/** Added by Mike - these are JSOPs in the jsref, but I
|
||||
* don't have them yet in the java implementation...
|
||||
|
@ -190,8 +191,7 @@ public class Token
|
|||
* Most of these go in the 'op' field when returning
|
||||
* more general token types, eg. 'DIV' as the op of 'ASSIGN'.
|
||||
*/
|
||||
NOP = 106, // NOP
|
||||
NOT = 107, // etc.
|
||||
NOP = 107, // NOP
|
||||
PRE = 108, // for INC, DEC nodes.
|
||||
POST = 109,
|
||||
|
||||
|
@ -254,7 +254,9 @@ public class Token
|
|||
case MUL: return "mul";
|
||||
case DIV: return "div";
|
||||
case MOD: return "mod";
|
||||
case NOT: return "not";
|
||||
case BITNOT: return "bitnot";
|
||||
case POS: return "pos";
|
||||
case NEG: return "neg";
|
||||
case NEW: return "new";
|
||||
case DELPROP: return "delprop";
|
||||
|
@ -277,7 +279,6 @@ public class Token
|
|||
case SHNE: return "shne";
|
||||
case REGEXP: return "object";
|
||||
case POP: return "pop";
|
||||
case POS: return "pos";
|
||||
case BINDNAME: return "bindname";
|
||||
case THROW: return "throw";
|
||||
case IN: return "in";
|
||||
|
@ -334,7 +335,6 @@ public class Token
|
|||
case FINALLY: return "finally";
|
||||
case RESERVED: return "reserved";
|
||||
case NOP: return "nop";
|
||||
case NOT: return "not";
|
||||
case PRE: return "pre";
|
||||
case POST: return "post";
|
||||
case VOID: return "void";
|
||||
|
|
Загрузка…
Ссылка в новой задаче