From 020cc5086d1d003e6785fe2884372316e1a54805 Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Sat, 22 Jan 2005 00:06:00 +0000 Subject: [PATCH] Removal of GETVAR SETVAR -> NAME SETNAME transformations during code generation for functions with activation records as NodeTransformer never introduce VAR node if activation would be created. git-svn-id: svn://10.0.0.236/trunk@168164 18797224-902f-48f8-a5cc-f745e15eee43 --- .../src/org/mozilla/javascript/IRFactory.java | 5 +- .../org/mozilla/javascript/Interpreter.java | 149 +++++++----------- .../mozilla/javascript/optimizer/Codegen.java | 126 +++++++-------- 3 files changed, 117 insertions(+), 163 deletions(-) diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java b/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java index b9a52042cec..3427028099d 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java @@ -378,8 +378,9 @@ final class IRFactory // function's name to the function value. fnNode.addVar(name); Node setFn = new Node(Token.EXPR_VOID, - new Node(Token.SETVAR, Node.newString(name), - new Node(Token.THISFN))); + new Node(Token.SETNAME, + Node.newString(Token.BINDNAME, name), + new Node(Token.THISFN))); statements.addChildrenToFront(setFn); } } diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java b/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java index 5cd43247b08..d40c292c250 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java @@ -78,90 +78,87 @@ public class Interpreter Icode_ELEM_INC_DEC = -10, Icode_REF_INC_DEC = -11, - // helper codes to deal with activation - Icode_SCOPE = -12, - // load/save scope from/to local - Icode_SCOPE_LOAD = -13, - Icode_SCOPE_SAVE = -14, + Icode_SCOPE_LOAD = -12, + Icode_SCOPE_SAVE = -13, - Icode_TYPEOFNAME = -15, + Icode_TYPEOFNAME = -14, // helper for function calls - Icode_NAME_AND_THIS = -16, - Icode_PROP_AND_THIS = -17, - Icode_ELEM_AND_THIS = -18, - Icode_VALUE_AND_THIS = -19, + Icode_NAME_AND_THIS = -15, + Icode_PROP_AND_THIS = -16, + Icode_ELEM_AND_THIS = -17, + Icode_VALUE_AND_THIS = -18, // Create closure object for nested functions - Icode_CLOSURE_EXPR = -20, - Icode_CLOSURE_STMT = -21, + Icode_CLOSURE_EXPR = -19, + Icode_CLOSURE_STMT = -20, // Special calls - Icode_CALLSPECIAL = -22, + Icode_CALLSPECIAL = -21, // To return undefined value - Icode_RETUNDEF = -23, + Icode_RETUNDEF = -22, // Exception handling implementation - Icode_GOSUB = -24, - Icode_STARTSUB = -25, - Icode_RETSUB = -26, + Icode_GOSUB = -23, + Icode_STARTSUB = -24, + Icode_RETSUB = -25, // To indicating a line number change in icodes. - Icode_LINE = -27, + Icode_LINE = -26, // To store shorts and ints inline - Icode_SHORTNUMBER = -28, - Icode_INTNUMBER = -29, + Icode_SHORTNUMBER = -27, + Icode_INTNUMBER = -28, // To create and populate array to hold values for [] and {} literals - Icode_LITERAL_NEW = -30, - Icode_LITERAL_SET = -31, + Icode_LITERAL_NEW = -29, + Icode_LITERAL_SET = -30, // Array literal with skipped index like [1,,2] - Icode_SPARE_ARRAYLIT = -32, + Icode_SPARE_ARRAYLIT = -31, // Load index register to prepare for the following index operation - Icode_REG_IND_C0 = -33, - Icode_REG_IND_C1 = -34, - Icode_REG_IND_C2 = -35, - Icode_REG_IND_C3 = -36, - Icode_REG_IND_C4 = -37, - Icode_REG_IND_C5 = -38, - Icode_REG_IND1 = -39, - Icode_REG_IND2 = -40, - Icode_REG_IND4 = -41, + Icode_REG_IND_C0 = -32, + Icode_REG_IND_C1 = -33, + Icode_REG_IND_C2 = -34, + Icode_REG_IND_C3 = -35, + Icode_REG_IND_C4 = -36, + Icode_REG_IND_C5 = -37, + Icode_REG_IND1 = -38, + Icode_REG_IND2 = -39, + Icode_REG_IND4 = -40, // Load string register to prepare for the following string operation - Icode_REG_STR_C0 = -42, - Icode_REG_STR_C1 = -43, - Icode_REG_STR_C2 = -44, - Icode_REG_STR_C3 = -45, - Icode_REG_STR1 = -46, - Icode_REG_STR2 = -47, - Icode_REG_STR4 = -48, + Icode_REG_STR_C0 = -41, + Icode_REG_STR_C1 = -42, + Icode_REG_STR_C2 = -43, + Icode_REG_STR_C3 = -44, + Icode_REG_STR1 = -45, + Icode_REG_STR2 = -46, + Icode_REG_STR4 = -47, // Version of getvar/setvar that read var index directly from bytecode - Icode_GETVAR1 = -49, - Icode_SETVAR1 = -50, + Icode_GETVAR1 = -48, + Icode_SETVAR1 = -49, // Load unefined - Icode_UNDEF = -51, - Icode_ZERO = -52, - Icode_ONE = -53, + Icode_UNDEF = -50, + Icode_ZERO = -51, + Icode_ONE = -52, // entrance and exit from .() - Icode_ENTERDQ = -54, - Icode_LEAVEDQ = -55, + Icode_ENTERDQ = -53, + Icode_LEAVEDQ = -54, - Icode_TAIL_CALL = -56, + Icode_TAIL_CALL = -55, // Clear local to allow GC its context - Icode_LOCAL_CLEAR = -57, + Icode_LOCAL_CLEAR = -56, // Last icode - MIN_ICODE = -57; + MIN_ICODE = -56; // data for parsing @@ -361,7 +358,6 @@ public class Interpreter case Icode_PROP_INC_DEC: return "PROP_INC_DEC"; case Icode_ELEM_INC_DEC: return "ELEM_INC_DEC"; case Icode_REF_INC_DEC: return "REF_INC_DEC"; - case Icode_SCOPE: return "SCOPE"; case Icode_SCOPE_LOAD: return "SCOPE_LOAD"; case Icode_SCOPE_SAVE: return "SCOPE_SAVE"; case Icode_TYPEOFNAME: return "TYPEOFNAME"; @@ -1179,36 +1175,22 @@ public class Interpreter case Token.GETVAR: { + if (itsData.itsNeedsActivation) Kit.codeBug(); String name = node.getString(); - if (itsData.itsNeedsActivation) { - // SETVAR handled this by turning into a SETPROP, but - // we can't do that to a GETVAR without manufacturing - // bogus children. Instead we use a special op to - // push the current scope. - addIcode(Icode_SCOPE); - stackChange(1); - addStringOp(Token.GETPROP, name); - } else { - int index = scriptOrFn.getParamOrVarIndex(name); - addVarOp(Token.GETVAR, index); - stackChange(1); - } + int index = scriptOrFn.getParamOrVarIndex(name); + addVarOp(Token.GETVAR, index); + stackChange(1); } break; case Token.SETVAR: { - if (itsData.itsNeedsActivation) { - child.setType(Token.BINDNAME); - node.setType(Token.SETNAME); - visitExpression(node, 0); - } else { - String name = child.getString(); - child = child.getNext(); - visitExpression(child, 0); - int index = scriptOrFn.getParamOrVarIndex(name); - addVarOp(Token.SETVAR, index); - } + if (itsData.itsNeedsActivation) Kit.codeBug(); + String name = child.getString(); + child = child.getNext(); + visitExpression(child, 0); + int index = scriptOrFn.getParamOrVarIndex(name); + addVarOp(Token.SETVAR, index); } break; @@ -1339,18 +1321,12 @@ public class Interpreter int childType = child.getType(); switch (childType) { case Token.GETVAR : { + if (itsData.itsNeedsActivation) Kit.codeBug(); String name = child.getString(); - if (itsData.itsNeedsActivation) { - addIcode(Icode_SCOPE); - stackChange(1); - addStringOp(Icode_PROP_INC_DEC, name); - addUint8(incrDecrMask); - } else { - int i = scriptOrFn.getParamOrVarIndex(name); - addVarOp(Icode_VAR_INC_DEC, i); - addUint8(incrDecrMask); - stackChange(1); - } + int i = scriptOrFn.getParamOrVarIndex(name); + addVarOp(Icode_VAR_INC_DEC, i); + addUint8(incrDecrMask); + stackChange(1); break; } case Token.NAME : { @@ -3273,9 +3249,6 @@ switch (op) { stack[stackTop] = Ref.popTarget(cx); continue Loop; } - case Icode_SCOPE : - stack[++stackTop] = frame.scope; - continue Loop; case Icode_SCOPE_LOAD : indexReg += frame.localShift; frame.scope = (Scriptable)stack[indexReg]; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java index 4a00fbd7106..b364da7b740 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java @@ -3172,6 +3172,7 @@ Else pass the JS object in the aReg and 0.0 in the dReg. Node child = node.getFirstChild(); switch (child.getType()) { case Token.GETVAR: + if (!hasVarsInRegs) Kit.codeBug(); if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) { boolean post = ((incrDecrMask & Node.POST_FLAG) != 0); int varIndex = fnCurrent.getVarIndex(child); @@ -3190,8 +3191,7 @@ Else pass the JS object in the aReg and 0.0 in the dReg. cfw.add(ByteCode.DUP2); } cfw.addDStore(reg); - break; - } else if (hasVarsInRegs) { + } else { boolean post = ((incrDecrMask & Node.POST_FLAG) != 0); int varIndex = fnCurrent.getVarIndex(child); short reg = varRegisters[varIndex]; @@ -3213,7 +3213,7 @@ Else pass the JS object in the aReg and 0.0 in the dReg. cfw.addAStore(reg); break; } - // fallthrough + break; case Token.NAME: cfw.addALoad(variableObjectLocal); cfw.addPush(child.getString()); // push name @@ -3631,86 +3631,66 @@ Else pass the JS object in the aReg and 0.0 in the dReg. private void visitGetVar(Node node) { - if (hasVarsInRegs) { - int varIndex = fnCurrent.getVarIndex(node); - short reg = varRegisters[varIndex]; - if (varIsDirectCallParameter(varIndex)) { - // Remember that here the isNumber flag means that we - // want to use the incoming parameter in a Number - // context, so test the object type and convert the - // value as necessary. - if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) { - dcpLoadAsNumber(reg); - } else { - dcpLoadAsObject(reg); - } - } else if (fnCurrent.isNumberVar(varIndex)) { - cfw.addDLoad(reg); + if (!hasVarsInRegs) Kit.codeBug(); + int varIndex = fnCurrent.getVarIndex(node); + short reg = varRegisters[varIndex]; + if (varIsDirectCallParameter(varIndex)) { + // Remember that here the isNumber flag means that we + // want to use the incoming parameter in a Number + // context, so test the object type and convert the + // value as necessary. + if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) { + dcpLoadAsNumber(reg); } else { - cfw.addALoad(reg); + dcpLoadAsObject(reg); } + } else if (fnCurrent.isNumberVar(varIndex)) { + cfw.addDLoad(reg); } else { - cfw.addALoad(variableObjectLocal); - cfw.addPush(node.getString()); - cfw.addALoad(contextLocal); - addScriptRuntimeInvoke( - "getObjectProp", - "(Lorg/mozilla/javascript/Scriptable;" - +"Ljava/lang/String;" - +"Lorg/mozilla/javascript/Context;" - +")Ljava/lang/Object;"); + cfw.addALoad(reg); } } private void visitSetVar(Node node, Node child, boolean needValue) { - if (hasVarsInRegs) { - int varIndex = fnCurrent.getVarIndex(node); - generateExpression(child.getNext(), node); - boolean isNumber = (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1); - short reg = varRegisters[varIndex]; - if (varIsDirectCallParameter(varIndex)) { - if (isNumber) { - if (needValue) cfw.add(ByteCode.DUP2); - cfw.addALoad(reg); - cfw.add(ByteCode.GETSTATIC, - "java/lang/Void", - "TYPE", - "Ljava/lang/Class;"); - int isNumberLabel = cfw.acquireLabel(); - int beyond = cfw.acquireLabel(); - cfw.add(ByteCode.IF_ACMPEQ, isNumberLabel); - short stack = cfw.getStackTop(); - addDoubleWrap(); - cfw.addAStore(reg); - cfw.add(ByteCode.GOTO, beyond); - cfw.markLabel(isNumberLabel, stack); - cfw.addDStore(reg + 1); - cfw.markLabel(beyond); - } - else { - if (needValue) cfw.add(ByteCode.DUP); - cfw.addAStore(reg); - } - } else { - if (isNumber) { - cfw.addDStore(reg); - if (needValue) cfw.addDLoad(reg); - } - else { - cfw.addAStore(reg); - if (needValue) cfw.addALoad(reg); - } + if (!hasVarsInRegs) Kit.codeBug(); + int varIndex = fnCurrent.getVarIndex(node); + generateExpression(child.getNext(), node); + boolean isNumber = (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1); + short reg = varRegisters[varIndex]; + if (varIsDirectCallParameter(varIndex)) { + if (isNumber) { + if (needValue) cfw.add(ByteCode.DUP2); + cfw.addALoad(reg); + cfw.add(ByteCode.GETSTATIC, + "java/lang/Void", + "TYPE", + "Ljava/lang/Class;"); + int isNumberLabel = cfw.acquireLabel(); + int beyond = cfw.acquireLabel(); + cfw.add(ByteCode.IF_ACMPEQ, isNumberLabel); + short stack = cfw.getStackTop(); + addDoubleWrap(); + cfw.addAStore(reg); + cfw.add(ByteCode.GOTO, beyond); + cfw.markLabel(isNumberLabel, stack); + cfw.addDStore(reg + 1); + cfw.markLabel(beyond); + } + else { + if (needValue) cfw.add(ByteCode.DUP); + cfw.addAStore(reg); + } + } else { + if (isNumber) { + cfw.addDStore(reg); + if (needValue) cfw.addDLoad(reg); + } + else { + cfw.addAStore(reg); + if (needValue) cfw.addALoad(reg); } - return; } - - // default: just treat like any other name lookup - child.setType(Token.BINDNAME); - node.setType(Token.SETNAME); - visitSetName(node, child); - if (!needValue) - cfw.add(ByteCode.POP); } private void visitGetProp(Node node, Node child)