Bug 739520 - rm JSOP_SETLOCALPOP (r=bhackett)
authorLuke Wagner <luke@mozilla.com>
Mon, 26 Mar 2012 22:29:55 -0700
changeset 93849 e44e3729a05203aa3c7116f3d642711dc3ad665d
parent 93848 d15eb9db765a7a6cb6177fcbc01fbe5e7ab3d201
child 93850 73937a6fd8289d05bc1971bbbef839dba577b6b6
push idunknown
push userunknown
push dateunknown
reviewersbhackett
bugs739520
milestone14.0a1
Bug 739520 - rm JSOP_SETLOCALPOP (r=bhackett)
js/src/frontend/BytecodeEmitter.cpp
js/src/jsanalyze.cpp
js/src/jsanalyze.h
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsopcode.cpp
js/src/jsopcode.tbl
js/src/methodjit/Compiler.cpp
js/src/methodjit/LoopState.cpp
js/src/vm/Xdr.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -2895,17 +2895,19 @@ EmitDestructuringLHS(JSContext *cx, Byte
           case JSOP_SETCONST:
             if (!EmitElemOp(cx, pn, JSOP_ENUMCONSTELEM, bce))
                 return JS_FALSE;
             break;
 
           case JSOP_SETLOCAL:
           {
             uint16_t slot = pn->pn_cookie.slot();
-            EMIT_UINT16_IMM_OP(JSOP_SETLOCALPOP, slot);
+            EMIT_UINT16_IMM_OP(JSOP_SETLOCAL, slot);
+            if (Emit1(cx, bce, JSOP_POP) < 0)
+                return JS_FALSE;
             break;
           }
 
           case JSOP_SETARG:
           {
             uint16_t slot = pn->pn_cookie.slot();
             EMIT_UINT16_IMM_OP(pn->getOp(), slot);
             if (Emit1(cx, bce, JSOP_POP) < 0)
@@ -3929,17 +3931,19 @@ EmitCatch(JSContext *cx, BytecodeEmitter
         if (Emit1(cx, bce, JSOP_POP) < 0)
             return false;
         break;
 #endif
 
       case PNK_NAME:
         /* Inline and specialize BindNameToSlot for pn2. */
         JS_ASSERT(!pn2->pn_cookie.isFree());
-        EMIT_UINT16_IMM_OP(JSOP_SETLOCALPOP, pn2->pn_cookie.slot());
+        EMIT_UINT16_IMM_OP(JSOP_SETLOCAL, pn2->pn_cookie.slot());
+        if (Emit1(cx, bce, JSOP_POP) < 0)
+            return false;
         break;
 
       default:
         JS_ASSERT(0);
     }
 
     /* Emit the guard expression, if there is one. */
     if (pn->pn_kid2) {
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -512,18 +512,17 @@ ScriptAnalysis::analyzeBytecode(JSContex
             break;
           }
 
           case JSOP_CALLLOCAL:
           case JSOP_INCLOCAL:
           case JSOP_DECLOCAL:
           case JSOP_LOCALINC:
           case JSOP_LOCALDEC:
-          case JSOP_SETLOCAL:
-          case JSOP_SETLOCALPOP: {
+          case JSOP_SETLOCAL: {
             uint32_t local = GET_SLOTNO(pc);
             if (local >= script->nfixed) {
                 localsAliasStack_ = true;
                 break;
             }
             break;
           }
 
@@ -820,18 +819,17 @@ ScriptAnalysis::analyzeLifetimes(JSConte
           case JSOP_THIS: {
             uint32_t slot = GetBytecodeSlot(script, pc);
             if (!slotEscapes(slot))
                 addVariable(cx, lifetimes[slot], offset, saved, savedCount);
             break;
           }
 
           case JSOP_SETARG:
-          case JSOP_SETLOCAL:
-          case JSOP_SETLOCALPOP: {
+          case JSOP_SETLOCAL: {
             uint32_t slot = GetBytecodeSlot(script, pc);
             if (!slotEscapes(slot))
                 killVariable(cx, lifetimes[slot], offset, saved, savedCount);
             break;
           }
 
           case JSOP_INCARG:
           case JSOP_DECARG:
--- a/js/src/jsanalyze.h
+++ b/js/src/jsanalyze.h
@@ -252,17 +252,16 @@ ExtendedDef(jsbytecode *pc)
 {
     switch ((JSOp)*pc) {
       case JSOP_SETARG:
       case JSOP_INCARG:
       case JSOP_DECARG:
       case JSOP_ARGINC:
       case JSOP_ARGDEC:
       case JSOP_SETLOCAL:
-      case JSOP_SETLOCALPOP:
       case JSOP_INCLOCAL:
       case JSOP_DECLOCAL:
       case JSOP_LOCALINC:
       case JSOP_LOCALDEC:
         return true;
       default:
         return false;
     }
@@ -380,17 +379,16 @@ static inline uint32_t GetBytecodeSlot(J
       case JSOP_DECARG:
       case JSOP_ARGINC:
       case JSOP_ARGDEC:
         return ArgSlot(GET_SLOTNO(pc));
 
       case JSOP_GETLOCAL:
       case JSOP_CALLLOCAL:
       case JSOP_SETLOCAL:
-      case JSOP_SETLOCALPOP:
       case JSOP_INCLOCAL:
       case JSOP_DECLOCAL:
       case JSOP_LOCALINC:
       case JSOP_LOCALDEC:
         return LocalSlot(script, GET_SLOTNO(pc));
 
       case JSOP_THIS:
         return ThisSlot();
@@ -403,17 +401,16 @@ static inline uint32_t GetBytecodeSlot(J
 
 /* Slot opcodes which update SSA information. */
 static inline bool
 BytecodeUpdatesSlot(JSOp op)
 {
     switch (op) {
       case JSOP_SETARG:
       case JSOP_SETLOCAL:
-      case JSOP_SETLOCALPOP:
       case JSOP_INCARG:
       case JSOP_DECARG:
       case JSOP_ARGINC:
       case JSOP_ARGDEC:
       case JSOP_INCLOCAL:
       case JSOP_DECLOCAL:
       case JSOP_LOCALINC:
       case JSOP_LOCALDEC:
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -3616,18 +3616,17 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
             pushed[0].addType(cx, Type::UnknownType());
         }
         if (op == JSOP_CALLARG || op == JSOP_CALLLOCAL)
             pushed[0].addPropagateThis(cx, script, pc, Type::UndefinedType());
         break;
       }
 
       case JSOP_SETARG:
-      case JSOP_SETLOCAL:
-      case JSOP_SETLOCALPOP: {
+      case JSOP_SETLOCAL: {
         uint32_t slot = GetBytecodeSlot(script, pc);
         if (!trackSlot(slot) && slot < TotalSlots(script)) {
             TypeSet *types = TypeScript::SlotTypes(script, slot);
             poppedTypes(pc, 0)->addSubset(cx, types);
         }
 
         /*
          * For assignments to non-escaping locals/args, we don't need to update
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1709,16 +1709,17 @@ ADD_EMPTY_CASE(JSOP_UNUSED22)
 ADD_EMPTY_CASE(JSOP_UNUSED23)
 ADD_EMPTY_CASE(JSOP_UNUSED24)
 ADD_EMPTY_CASE(JSOP_UNUSED25)
 ADD_EMPTY_CASE(JSOP_UNUSED26)
 ADD_EMPTY_CASE(JSOP_UNUSED27)
 ADD_EMPTY_CASE(JSOP_UNUSED28)
 ADD_EMPTY_CASE(JSOP_UNUSED29)
 ADD_EMPTY_CASE(JSOP_UNUSED30)
+ADD_EMPTY_CASE(JSOP_UNUSED31)
 ADD_EMPTY_CASE(JSOP_CONDSWITCH)
 ADD_EMPTY_CASE(JSOP_TRY)
 #if JS_HAS_XML_SUPPORT
 ADD_EMPTY_CASE(JSOP_STARTXML)
 ADD_EMPTY_CASE(JSOP_STARTXMLEXPR)
 #endif
 ADD_EMPTY_CASE(JSOP_LOOPHEAD)
 ADD_EMPTY_CASE(JSOP_LOOPENTRY)
@@ -3453,24 +3454,16 @@ BEGIN_CASE(JSOP_THROW)
     JS_ASSERT(!cx->isExceptionPending());
     CHECK_BRANCH();
     Value v;
     POP_COPY_TO(v);
     cx->setPendingException(v);
     /* let the code at error try to catch the exception. */
     goto error;
 }
-BEGIN_CASE(JSOP_SETLOCALPOP)
-    /*
-     * The stack must have a block with at least one local slot below the
-     * exception object.
-     */
-    JS_ASSERT((size_t) (regs.sp - regs.fp()->base()) >= 2);
-    POP_COPY_TO(regs.fp()->localSlot(GET_UINT16(regs.pc)));
-END_CASE(JSOP_SETLOCALPOP)
 
 BEGIN_CASE(JSOP_INSTANCEOF)
 {
     const Value &rref = regs.sp[-1];
     if (rref.isPrimitive()) {
         js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS, -1, rref, NULL);
         goto error;
     }
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -1975,43 +1975,38 @@ DecompileDestructuringLHS(SprintStack *s
         }
         break;
       }
 
       case JSOP_SETARG:
       case JSOP_SETLOCAL:
         LOCAL_ASSERT(!letNames);
         LOCAL_ASSERT(pc[oplen] == JSOP_POP || pc[oplen] == JSOP_POPN);
-        /* FALL THROUGH */
-      case JSOP_SETLOCALPOP:
-        LOCAL_ASSERT(!letNames);
         if (op == JSOP_SETARG) {
             atom = GetArgOrVarAtom(jp, GET_SLOTNO(pc));
             LOCAL_ASSERT(atom);
             if (!QuoteString(&ss->sprinter, atom, 0))
                 return NULL;
         } else if (IsVarSlot(jp, pc, &i)) {
             atom = GetArgOrVarAtom(jp, i);
             LOCAL_ASSERT(atom);
             if (!QuoteString(&ss->sprinter, atom, 0))
                 return NULL;
         } else {
             lval = GetLocal(ss, i);
             if (!lval || ss->sprinter.put(lval) < 0)
                 return NULL;
         }
-        if (op != JSOP_SETLOCALPOP) {
-            pc += oplen;
-            if (pc == endpc)
-                return pc;
-            LOAD_OP_DATA(pc);
-            if (op == JSOP_POPN)
-                return pc;
-            LOCAL_ASSERT(op == JSOP_POP);
-        }
+        pc += oplen;
+        if (pc == endpc)
+            return pc;
+        LOAD_OP_DATA(pc);
+        if (op == JSOP_POPN)
+            return pc;
+        LOCAL_ASSERT(op == JSOP_POP);
         break;
 
       default: {
         LOCAL_ASSERT(!letNames);
         /*
          * We may need to auto-parenthesize the left-most value decompiled
          * here, so add back PAREN_SLOP temporarily.  Then decompile until the
          * opcode that would reduce the stack depth to (ss->top-1), which we
@@ -3277,18 +3272,20 @@ Decompile(SprintStack *ss, jsbytecode *p
                         if (!pc)
                             return NULL;
                         LOCAL_ASSERT(*pc == JSOP_POP);
                         pc += JSOP_POP_LENGTH;
                         lval = PopStr(ss, JSOP_NOP);
                         js_puts(jp, lval);
                     } else {
 #endif
-                        LOCAL_ASSERT(*pc == JSOP_SETLOCALPOP);
-                        pc += JSOP_SETLOCALPOP_LENGTH;
+                        LOCAL_ASSERT(*pc == JSOP_SETLOCAL);
+                        pc += JSOP_SETLOCAL_LENGTH;
+                        LOCAL_ASSERT(*pc == JSOP_POP);
+                        pc += JSOP_POP_LENGTH;
                         LOCAL_ASSERT(blockObj.slotCount() >= 1);
                         if (!QuoteString(&jp->sprinter, atoms[0], 0))
                             return NULL;
 #if JS_HAS_DESTRUCTURING
                     }
 #endif
 
                     /*
@@ -3545,17 +3542,16 @@ Decompile(SprintStack *ss, jsbytecode *p
                 }
 #endif
 
                 rval = GetLocal(ss, i);
                 todo = Sprint(&ss->sprinter, ss_format, VarPrefix(sn), rval);
                 break;
 
               case JSOP_SETLOCAL:
-              case JSOP_SETLOCALPOP:
                 if (IsVarSlot(jp, pc, &i)) {
                     atom = GetArgOrVarAtom(jp, i);
                     LOCAL_ASSERT(atom);
                     goto do_setname;
                 }
                 lval = GetLocal(ss, i);
                 rval = PopStrDupe(ss, op, &rvalpc);
                 goto do_setlval;
@@ -4241,24 +4237,16 @@ Decompile(SprintStack *ss, jsbytecode *p
                     Sprint(&ss->sprinter, "%s %s= ", lval, token);
                     SprintOpcode(ss, rval, rvalpc, pc, todo);
                 } else {
                     sn = js_GetSrcNote(jp->script, pc);
                     const char *prefix = VarPrefix(sn);
                     Sprint(&ss->sprinter, "%s%s = ", prefix, lval);
                     SprintOpcode(ss, rval, rvalpc, pc, todo);
                 }
-                if (op == JSOP_SETLOCALPOP) {
-                    if (!PushOff(ss, todo, saveop))
-                        return NULL;
-                    rval = POP_STR();
-                    LOCAL_ASSERT(*rval != '\0');
-                    js_printf(jp, "\t%s;\n", rval);
-                    todo = -2;
-                }
                 break;
 
               case JSOP_NEW:
               case JSOP_CALL:
               case JSOP_EVAL:
               case JSOP_FUNCALL:
               case JSOP_FUNAPPLY:
               {
--- a/js/src/jsopcode.tbl
+++ b/js/src/jsopcode.tbl
@@ -343,21 +343,17 @@ OPDEF(JSOP_DEFCONST,  128,"defconst",   
 OPDEF(JSOP_DEFVAR,    129,"defvar",     NULL,         5,  0,  0,  0,  JOF_ATOM|JOF_DECLARING)
 
 /* Push a closure for a named or anonymous function expression. */
 OPDEF(JSOP_LAMBDA,    130, "lambda",    NULL,         5,  0,  1, 19,  JOF_OBJECT)
 
 /* Used for named function expression self-naming, if lightweight. */
 OPDEF(JSOP_CALLEE,    131, "callee",    NULL,         1,  0,  1, 19,  JOF_BYTE)
 
-/*
- * Like JSOP_SETLOCAL, but specialized to avoid requiring JSOP_POP immediately
- * after to throw away the exception value.
- */
-OPDEF(JSOP_SETLOCALPOP, 132, "setlocalpop", NULL,     3,  1,  0,  3,  JOF_LOCAL|JOF_NAME|JOF_SET)
+OPDEF(JSOP_UNUSED31,  132, "unused31",  NULL,         1,  0,  0,  0,  JOF_BYTE)
 
 /* Pick an element from the stack. */
 OPDEF(JSOP_PICK,        133, "pick",      NULL,       2,  0,  0,  0,  JOF_UINT8|JOF_TMPSLOT2)
 
 /*
  * Exception handling no-op, for more economical byte-coding than SRC_TRYFIN
  * srcnote-annotated JSOP_NOPs and to simply stack balance handling.
  */
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -2863,25 +2863,16 @@ mjit::Compiler::generateMethod()
             if (pop) {
                 frame.pop();
                 PC += JSOP_SETLOCAL_LENGTH + JSOP_POP_LENGTH;
                 break;
             }
           }
           END_CASE(JSOP_SETLOCAL)
 
-          BEGIN_CASE(JSOP_SETLOCALPOP)
-          {
-            uint32_t slot = GET_SLOTNO(PC);
-            frame.storeLocal(slot, true);
-            frame.pop();
-            updateVarType();
-          }
-          END_CASE(JSOP_SETLOCALPOP)
-
           BEGIN_CASE(JSOP_UINT16)
             frame.push(Value(Int32Value((int32_t) GET_UINT16(PC))));
           END_CASE(JSOP_UINT16)
 
           BEGIN_CASE(JSOP_NEWINIT)
             if (!jsop_newinit())
                 return Compile_Error;
           END_CASE(JSOP_NEWINIT)
--- a/js/src/methodjit/LoopState.cpp
+++ b/js/src/methodjit/LoopState.cpp
@@ -1912,17 +1912,16 @@ LoopState::analyzeLoopBody(unsigned fram
           case JSOP_SETARG:
           case JSOP_INCARG:
           case JSOP_DECARG:
           case JSOP_ARGINC:
           case JSOP_ARGDEC:
           case JSOP_THIS:
           case JSOP_GETLOCAL:
           case JSOP_SETLOCAL:
-          case JSOP_SETLOCALPOP:
           case JSOP_INCLOCAL:
           case JSOP_DECLOCAL:
           case JSOP_LOCALINC:
           case JSOP_LOCALDEC:
           case JSOP_IFEQ:
           case JSOP_IFNE:
           case JSOP_AND:
           case JSOP_OR:
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -50,17 +50,17 @@ namespace js {
  * Bytecode version number. Increment the subtrahend whenever JS bytecode
  * changes incompatibly.
  *
  * This version number is XDR'd near the front of xdr bytecode and
  * aborts deserialization if there is a mismatch between the current
  * and saved versions. If deserialization fails, the data should be
  * invalidated if possible.
  */
-static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 112);
+static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 113);
 
 class XDRBuffer {
   public:
     XDRBuffer(JSContext *cx)
       : context(cx), base(NULL), cursor(NULL), limit(NULL) { }
 
     JSContext *cx() const {
         return context;