diff --git a/js/rhino/src/org/mozilla/javascript/Interpreter.java b/js/rhino/src/org/mozilla/javascript/Interpreter.java index 86545288ddc..874af833aa4 100644 --- a/js/rhino/src/org/mozilla/javascript/Interpreter.java +++ b/js/rhino/src/org/mozilla/javascript/Interpreter.java @@ -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,164 +1294,147 @@ 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) { - } - } - } + int iCodeLength = idata.itsICodeTop; + byte iCode[] = idata.itsICode; + String[] strings = idata.itsStringTable; + PrintStream out = System.out; + out.println("ICode dump, for " + idata.itsName + + ", length = " + iCodeLength); + out.println("MaxStack = " + idata.itsMaxStack); - private static void dumpICode(InterpreterData idata) { - if (Token.printICode) { - try { - int iCodeLength = idata.itsICodeTop; - byte iCode[] = idata.itsICode; - String[] strings = idata.itsStringTable; + for (int pc = 0; pc < iCodeLength; ) { + out.flush(); + out.print(" [" + pc + "] "); + int token = iCode[pc] & 0xff; + String tname = icodeToName(token); + int old_pc = pc; + ++pc; + int icodeLength = icodeTokenLength(token); + switch (token) { + default: + if (icodeLength != 1) Context.codeBug(); + out.println(tname); + break; - out = new PrintWriter(new FileOutputStream("icode.txt", true)); - out.println("ICode dump, for " + idata.itsName - + ", length = " + iCodeLength); - out.println("MaxStack = " + idata.itsMaxStack); - - for (int pc = 0; pc < iCodeLength; ) { - out.flush(); - out.print(" [" + pc + "] "); - int token = iCode[pc] & 0xff; - String tname = icodeToName(token); - int old_pc = pc; - ++pc; - int icodeLength = icodeTokenLength(token); - switch (token) { - default: - if (icodeLength != 1) Context.codeBug(); - out.println(tname); - break; - - case Icode_GOSUB : - case Token.GOTO : - case Token.IFEQ : - case Token.IFNE : { - int newPC = getTarget(iCode, pc); - out.println(tname + " " + newPC); - pc += 2; - break; - } - case Icode_RETSUB : - case Token.ENUMINIT : - case Token.ENUMNEXT : - case Icode_VARINC : - case Icode_VARDEC : - case Token.GETVAR : - case Token.SETVAR : - case Token.NEWTEMP : - case Token.USETEMP : { - int slot = (iCode[pc] & 0xFF); - out.println(tname + " " + slot); - pc++; - break; - } - case Icode_CALLSPECIAL : { - int callType = iCode[pc] & 0xFF; - 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); - pc += 8; - break; - } - case Token.REGEXP : { - int i = getIndex(iCode, pc); - Object regexp = idata.itsRegExpLiterals[i]; - out.println(tname + " " + regexp); - pc += 2; - break; - } - case Icode_CLOSURE : { - int i = getIndex(iCode, pc); - InterpreterData data2 = idata.itsNestedFunctions[i]; - out.println(tname + " " + data2); - pc += 2; - break; - } - case Token.NEW : - case Token.CALL : { - int count = getIndex(iCode, pc + 2); - String name = strings[getIndex(iCode, pc)]; - out.println(tname + " " + count + " \"" - + name + '"'); - pc += 4; - break; - } - case Icode_SHORTNUMBER : { - int value = getShort(iCode, pc); - out.println(tname + " " + value); - pc += 2; - break; - } - case Icode_INTNUMBER : { - int value = getInt(iCode, pc); - out.println(tname + " " + value); - pc += 4; - break; - } - case Token.NUMBER : { - int index = getIndex(iCode, pc); - double value = idata.itsDoubleTable[index]; - out.println(tname + " " + value); - pc += 2; - break; - } - case Icode_TYPEOFNAME : - case Token.GETBASE : - case Token.BINDNAME : - case Token.SETNAME : - case Token.NAME : - case Icode_NAMEINC : - case Icode_NAMEDEC : - case Token.STRING : { - String str = strings[getIndex(iCode, pc)]; - out.println(tname + " \"" + str + '"'); - pc += 2; - break; - } - case Icode_LINE : { - int line = getShort(iCode, pc); - out.println(tname + " : " + line); - pc += 2; - break; - } + case Icode_GOSUB : + case Token.GOTO : + case Token.IFEQ : + case Token.IFNE : { + int newPC = getTarget(iCode, pc); + out.println(tname + " " + newPC); + pc += 2; + break; } - if (old_pc + icodeLength != pc) Context.codeBug(); - } - - int[] table = idata.itsExceptionTable; - if (table != null) { - out.println("Exception handlers: " - +table.length / EXCEPTION_SLOT_SIZE); - for (int i = 0; i != table.length; - i += EXCEPTION_SLOT_SIZE) - { - int tryStart = table[i + EXCEPTION_TRY_START_SLOT]; - int tryEnd = table[i + EXCEPTION_TRY_END_SLOT]; - int catchStart = table[i + EXCEPTION_CATCH_SLOT]; - int finallyStart = table[i + EXCEPTION_FINALLY_SLOT]; - int withDepth = table[i + EXCEPTION_WITH_DEPTH_SLOT]; - - out.println(" "+tryStart+"\t "+tryEnd+"\t " - +catchStart+"\t "+finallyStart - +"\t "+withDepth); + case Icode_RETSUB : + case Token.ENUMINIT : + case Token.ENUMNEXT : + case Icode_VARINC : + case Icode_VARDEC : + case Token.GETVAR : + case Token.SETVAR : + case Token.NEWTEMP : + case Token.USETEMP : { + int slot = (iCode[pc] & 0xFF); + out.println(tname + " " + slot); + pc++; + break; + } + case Icode_CALLSPECIAL : { + int callType = iCode[pc] & 0xFF; + 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); + pc += 8; + break; + } + case Token.REGEXP : { + int i = getIndex(iCode, pc); + Object regexp = idata.itsRegExpLiterals[i]; + out.println(tname + " " + regexp); + pc += 2; + break; + } + case Icode_CLOSURE : { + int i = getIndex(iCode, pc); + InterpreterData data2 = idata.itsNestedFunctions[i]; + out.println(tname + " " + data2); + pc += 2; + break; + } + case Token.NEW : + case Token.CALL : { + int count = getIndex(iCode, pc + 2); + String name = strings[getIndex(iCode, pc)]; + out.println(tname+' '+count+" \""+name+'"'); + pc += 4; + break; + } + case Icode_SHORTNUMBER : { + int value = getShort(iCode, pc); + out.println(tname + " " + value); + pc += 2; + break; + } + case Icode_INTNUMBER : { + int value = getInt(iCode, pc); + out.println(tname + " " + value); + pc += 4; + break; + } + case Token.NUMBER : { + int index = getIndex(iCode, pc); + double value = idata.itsDoubleTable[index]; + out.println(tname + " " + value); + pc += 2; + break; + } + case Icode_TYPEOFNAME : + case Token.GETBASE : + case Token.BINDNAME : + case Token.SETNAME : + case Token.NAME : + case Icode_NAMEINC : + case Icode_NAMEDEC : + case Token.STRING : { + String str = strings[getIndex(iCode, pc)]; + out.println(tname + " \"" + str + '"'); + pc += 2; + break; + } + case Icode_LINE : { + int line = getShort(iCode, pc); + out.println(tname + " : " + line); + pc += 2; + break; } } - - out.close(); + if (old_pc + icodeLength != pc) Context.codeBug(); } - catch (IOException x) {} + + int[] table = idata.itsExceptionTable; + if (table != null) { + out.println("Exception handlers: " + +table.length / EXCEPTION_SLOT_SIZE); + for (int i = 0; i != table.length; + i += EXCEPTION_SLOT_SIZE) + { + int tryStart = table[i + EXCEPTION_TRY_START_SLOT]; + int tryEnd = table[i + EXCEPTION_TRY_END_SLOT]; + int catchStart = table[i + EXCEPTION_CATCH_SLOT]; + int finallyStart = table[i + EXCEPTION_FINALLY_SLOT]; + int withDepth = table[i + EXCEPTION_WITH_DEPTH_SLOT]; + + out.println(" "+tryStart+"\t "+tryEnd+"\t " + +catchStart+"\t "+finallyStart + +"\t "+withDepth); + } + } + 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]; diff --git a/js/rhino/src/org/mozilla/javascript/Token.java b/js/rhino/src/org/mozilla/javascript/Token.java index 573e55d4b1e..a183599f78a 100644 --- a/js/rhino/src/org/mozilla/javascript/Token.java +++ b/js/rhino/src/org/mozilla/javascript/Token.java @@ -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";