Add JSTreeContext::asCodeGenerator that performs the relevant cast, asserting while doing so. r=jimb over IRC
authorJeff Walden <jwalden@mit.edu>
Wed, 08 Dec 2010 11:32:43 -0800
changeset 59218 89a4b9b69ae5934a43dc34cfc9db49f5a6140b5e
parent 59217 9a9e6e0179295f5f47398e1607d2ea408c9ce976
child 59219 3fe1860a15b35fc08e732ae8dc8a17d22b736015
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersjimb
milestone2.0b8pre
Add JSTreeContext::asCodeGenerator that performs the relevant cast, asserting while doing so. r=jimb over IRC
js/src/jsemit.cpp
js/src/jsemit.h
js/src/jsparse.cpp
--- a/js/src/jsemit.cpp
+++ b/js/src/jsemit.cpp
@@ -1732,17 +1732,17 @@ LookupCompileTimeConstant(JSContext *cx,
                         *constp = obj->getSlot(shape->slot);
                     }
                 }
 
                 if (shape)
                     break;
             }
         }
-    } while ((cg = (JSCodeGenerator *) cg->parent) != NULL);
+    } while (cg->parent && (cg = cg->parent->asCodeGenerator()));
     return JS_TRUE;
 }
 
 static inline bool
 FitsWithoutBigIndex(uintN index)
 {
     return index < JS_BIT(16);
 }
@@ -2327,19 +2327,18 @@ BindNameToSlot(JSContext *cx, JSCodeGene
 #ifdef DEBUG
         JSStackFrame *caller = cg->parser->callerFrame;
 #endif
         JS_ASSERT(caller->isScriptFrame());
 
         JSTreeContext *tc = cg;
         while (tc->staticLevel != level)
             tc = tc->parent;
-        JS_ASSERT(tc->compiling());
-
-        JSCodeGenerator *evalcg = (JSCodeGenerator *) tc;
+
+        JSCodeGenerator *evalcg = tc->asCodeGenerator();
         JS_ASSERT(evalcg->compileAndGo());
         JS_ASSERT(caller->isFunctionFrame());
         JS_ASSERT(cg->parser->callerVarObj == evalcg->scopeChain());
 
         /*
          * Don't generate upvars on the left side of a for loop. See
          * bug 470758 and bug 520513.
          */
@@ -4599,17 +4598,17 @@ js_EmitTree(JSContext *cx, JSCodeGenerat
         JSCodeGenerator *cg2 =
             new (cg2space) JSCodeGenerator(cg->parser,
                                            cg->codePool, cg->notePool,
                                            pn->pn_pos.begin.lineno);
 
         if (!cg2->init())
             return JS_FALSE;
 
-        cg2->flags = pn->pn_funbox->tcflags | TCF_IN_FUNCTION;
+        cg2->flags = pn->pn_funbox->tcflags | TCF_COMPILING | TCF_IN_FUNCTION;
 #if JS_HAS_SHARP_VARS
         if (cg2->flags & TCF_HAS_SHARPS) {
             cg2->sharpSlotBase = fun->sharpSlotBase(cx);
             if (cg2->sharpSlotBase < 0)
                 return JS_FALSE;
         }
 #endif
         cg2->setFunction(fun);
--- a/js/src/jsemit.h
+++ b/js/src/jsemit.h
@@ -387,17 +387,19 @@ struct JSTreeContext {              /* t
 
     // Return true there is a generator function within |skip| lexical scopes
     // (going upward) from this context's lexical scope. Always return true if
     // this context is itself a generator.
     bool skipSpansGenerator(unsigned skip);
 
     bool compileAndGo() const { return flags & TCF_COMPILE_N_GO; }
     bool inFunction() const { return flags & TCF_IN_FUNCTION; }
+
     bool compiling() const { return flags & TCF_COMPILING; }
+    inline JSCodeGenerator *asCodeGenerator();
 
     bool usesArguments() const {
         return flags & TCF_FUN_USES_ARGUMENTS;
     }
 
     void noteCallsEval() {
         flags |= TCF_FUN_CALLS_EVAL;
     }
@@ -589,17 +591,17 @@ struct JSCodeGenerator : public JSTreeCo
     JSAtomList      globalMap;      /* per-script map of global name to globalUses vector */
 
     /* Vectors of pn_cookie slot values. */
     typedef js::Vector<uint32, 8, js::ContextAllocPolicy> SlotVector;
     SlotVector      closedArgs;
     SlotVector      closedVars;
 
     uint16          traceIndex;     /* index for the next JSOP_TRACE instruction */
-    
+
     /*
      * Initialize cg to allocate bytecode space from codePool, source note
      * space from notePool, and all other arena-allocated temporaries from
      * parser->context->tempPool.
      */
     JSCodeGenerator(js::Parser *parser,
                     JSArenaPool *codePool, JSArenaPool *notePool,
                     uintN lineno);
@@ -663,16 +665,23 @@ struct JSCodeGenerator : public JSTreeCo
 #define CG_PROLOG_LIMIT(cg)     ((cg)->prolog.limit)
 #define CG_PROLOG_NEXT(cg)      ((cg)->prolog.next)
 #define CG_PROLOG_CODE(cg,poff) (CG_PROLOG_BASE(cg) + (poff))
 #define CG_PROLOG_OFFSET(cg)    (CG_PROLOG_NEXT(cg) - CG_PROLOG_BASE(cg))
 
 #define CG_SWITCH_TO_MAIN(cg)   ((cg)->current = &(cg)->main)
 #define CG_SWITCH_TO_PROLOG(cg) ((cg)->current = &(cg)->prolog)
 
+inline JSCodeGenerator *
+JSTreeContext::asCodeGenerator()
+{
+    JS_ASSERT(compiling());
+    return static_cast<JSCodeGenerator *>(this);
+}
+
 /*
  * Emit one bytecode.
  */
 extern ptrdiff_t
 js_Emit1(JSContext *cx, JSCodeGenerator *cg, JSOp op);
 
 /*
  * Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1).
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -3154,17 +3154,17 @@ Parser::functionDef(JSAtom *funAtom, Fun
         pn->pn_body->pn_pos = body->pn_pos;
     } else {
         pn->pn_body = body;
     }
 
     if (!outertc->inFunction() && topLevel && funAtom && !lambda &&
         outertc->compiling()) {
         JS_ASSERT(pn->pn_cookie.isFree());
-        if (!DefineGlobal(pn, (JSCodeGenerator *)outertc, funAtom))
+        if (!DefineGlobal(pn, outertc->asCodeGenerator(), funAtom))
             return false;
     }
 
     pn->pn_blockid = outertc->blockid();
 
     if (!LeaveFunction(pn, &funtc, funAtom, lambda))
         return NULL;
 
@@ -3578,17 +3578,17 @@ static bool
 BindGvar(JSParseNode *pn, JSTreeContext *tc)
 {
     JS_ASSERT(pn->pn_op == JSOP_NAME);
     JS_ASSERT(!tc->inFunction());
 
     if (!tc->compiling() || tc->parser->callerFrame)
         return true;
 
-    JSCodeGenerator *cg = (JSCodeGenerator *) tc;
+    JSCodeGenerator *cg = tc->asCodeGenerator();
 
     if (pn->pn_dflags & PND_CONST)
         return true;
 
     return DefineGlobal(pn, cg, pn->pn_atom);
 }
 
 static JSBool