Bug 684110 - Simplify IsActiveWithOrBlock, tidy jsinterp.h (r=pbiggar)
authorLuke Wagner <luke@mozilla.com>
Fri, 02 Sep 2011 17:23:36 -0700
changeset 76511 e6e99374aae9dd467d465d5b1f28d9a6e4fca844
parent 76510 52e5861882de6562cc1101d1bb564de7e4c8a8c3
child 76512 9b82bc2b354e0bc0e8569846edcfb15a39acc6cd
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewerspbiggar
bugs684110
milestone9.0a1
Bug 684110 - Simplify IsActiveWithOrBlock, tidy jsinterp.h (r=pbiggar)
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/PolyIC.cpp
js/src/methodjit/StubCalls.cpp
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -397,20 +397,18 @@ CallThisObjectHook(JSContext *cx, JSObje
 {
     JSObject *thisp = obj->thisObject(cx);
     if (!thisp)
         return NULL;
     argv[-1].setObject(*thisp);
     return thisp;
 }
 
-namespace js {
-
 void
-ReportIncompatibleMethod(JSContext *cx, Value *vp, Class *clasp)
+js::ReportIncompatibleMethod(JSContext *cx, Value *vp, Class *clasp)
 {
     Value &thisv = vp[1];
 
 #ifdef DEBUG
     if (thisv.isObject()) {
         JS_ASSERT(thisv.toObject().getClass() != clasp);
     } else if (thisv.isString()) {
         JS_ASSERT(clasp != &StringClass);
@@ -443,17 +441,17 @@ ReportIncompatibleMethod(JSContext *cx, 
  *
  *   // in window w2
  *   var h = w1.g()
  *   alert(h() == w1)
  *
  * The alert should display "true".
  */
 bool
-BoxNonStrictThis(JSContext *cx, const CallReceiver &call)
+js::BoxNonStrictThis(JSContext *cx, const CallReceiver &call)
 {
     /*
      * Check for SynthesizeFrame poisoning and fast constructors which
      * didn't check their callee properly.
      */
     Value &thisv = call.thisv();
     JS_ASSERT(!thisv.isMagic());
 
@@ -471,18 +469,16 @@ BoxNonStrictThis(JSContext *cx, const Ca
     }
 
     if (!thisv.isObject())
         return !!js_PrimitiveToObject(cx, &thisv);
 
     return true;
 }
 
-}
-
 #if JS_HAS_NO_SUCH_METHOD
 
 const uint32 JSSLOT_FOUND_FUNCTION  = 0;
 const uint32 JSSLOT_SAVED_ID        = 1;
 
 static void
 no_such_method_trace(JSTracer *trc, JSObject *obj)
 {
@@ -519,18 +515,18 @@ Class js_NoSuchMethodClass = {
  * NoSuchMethod that invokes the method like:
  *
  *   this.__noSuchMethod__(id, args)
  *
  * where id is the name of the method that this invocation attempted to
  * call by name, and args is an Array containing this invocation's actual
  * parameters.
  */
-JSBool
-js_OnUnknownMethod(JSContext *cx, Value *vp)
+bool
+js::OnUnknownMethod(JSContext *cx, Value *vp)
 {
     JS_ASSERT(!vp[1].isPrimitive());
 
     JSObject *obj = &vp[1].toObject();
     jsid id = ATOM_TO_JSID(cx->runtime->atomState.noSuchMethodAtom);
     AutoValueRooter tvr(cx);
     if (!js_GetMethod(cx, obj, id, JSGET_NO_METHOD_BARRIER, tvr.addr()))
         return false;
@@ -581,20 +577,18 @@ NoSuchMethod(JSContext *cx, uintN argc, 
     args[1].setObject(*argsobj);
     JSBool ok = Invoke(cx, args);
     vp[0] = args.rval();
     return ok;
 }
 
 #endif /* JS_HAS_NO_SUCH_METHOD */
 
-namespace js {
-
 JS_REQUIRES_STACK bool
-RunScript(JSContext *cx, JSScript *script, StackFrame *fp)
+js::RunScript(JSContext *cx, JSScript *script, StackFrame *fp)
 {
     JS_ASSERT(script);
     JS_ASSERT(fp == cx->fp());
     JS_ASSERT(fp->script() == script);
 #ifdef JS_METHODJIT_SPEW
     JMCheckLogging();
 #endif
 
@@ -621,18 +615,18 @@ RunScript(JSContext *cx, JSScript *scrip
 }
 
 /*
  * Find a function reference and its 'this' value implicit first parameter
  * under argc arguments on cx's stack, and call the function.  Push missing
  * required arguments, allocate declared local variables, and pop everything
  * when done.  Then push the return value.
  */
-JS_REQUIRES_STACK bool
-InvokeKernel(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construct)
+bool
+js::InvokeKernel(JSContext *cx, const CallArgs &argsRef, MaybeConstruct construct)
 {
     /* N.B. Must be kept in sync with InvokeSessionGuard::start/invoke */
 
     CallArgs args = argsRef;
     JS_ASSERT(args.argc() <= StackSpace::ARGS_LENGTH_MAX);
 
     JS_ASSERT(!cx->compartment->activeAnalysis);
 
@@ -785,18 +779,18 @@ InvokeSessionGuard::start(JSContext *cx,
     if (ifg_.pushed())
         ifg_.pop();
     formals_ = actuals_ = args_.argv();
     nformals_ = (unsigned)-1;
     return true;
 }
 
 bool
-Invoke(JSContext *cx, const Value &thisv, const Value &fval, uintN argc, Value *argv,
-       Value *rval)
+js::Invoke(JSContext *cx, const Value &thisv, const Value &fval, uintN argc, Value *argv,
+           Value *rval)
 {
     LeaveTrace(cx);
 
     InvokeArgsGuard args;
     if (!cx->stack.pushInvokeArgs(cx, argc, &args))
         return false;
 
     args.calleev() = fval;
@@ -818,17 +812,17 @@ Invoke(JSContext *cx, const Value &thisv
     if (!Invoke(cx, args))
         return false;
 
     *rval = args.rval();
     return true;
 }
 
 bool
-InvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, Value *rval)
+js::InvokeConstructor(JSContext *cx, const Value &fval, uintN argc, Value *argv, Value *rval)
 {
     LeaveTrace(cx);
 
     InvokeArgsGuard args;
     if (!cx->stack.pushInvokeArgs(cx, argc, &args))
         return false;
 
     args.calleev() = fval;
@@ -838,18 +832,18 @@ InvokeConstructor(JSContext *cx, const V
     if (!InvokeConstructor(cx, args))
         return false;
 
     *rval = args.rval();
     return true;
 }
 
 bool
-InvokeGetterOrSetter(JSContext *cx, JSObject *obj, const Value &fval, uintN argc, Value *argv,
-                     Value *rval)
+js::InvokeGetterOrSetter(JSContext *cx, JSObject *obj, const Value &fval, uintN argc, Value *argv,
+                         Value *rval)
 {
     LeaveTrace(cx);
 
     /*
      * Invoke could result in another try to get or set the same id again, see
      * bug 355497.
      */
     JS_CHECK_RECURSION(cx, return false);
@@ -881,18 +875,18 @@ InitSharpSlots(JSContext *cx, StackFrame
         sharps[0].setUndefined();
         sharps[1].setUndefined();
     }
     return true;
 }
 #endif
 
 bool
-ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv,
-              ExecuteType type, StackFrame *evalInFrame, Value *result)
+js::ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const Value &thisv,
+                  ExecuteType type, StackFrame *evalInFrame, Value *result)
 {
     JS_ASSERT_IF(evalInFrame, type == EXECUTE_DEBUG);
 
     if (script->isEmpty()) {
         if (result)
             result->setUndefined();
         return true;
     }
@@ -923,17 +917,17 @@ ExecuteKernel(JSContext *cx, JSScript *s
         *result = fp->returnValue();
 
     Probes::stopExecution(cx, script);
 
     return !!ok;
 }
 
 bool
-Execute(JSContext *cx, JSScript *script, JSObject &scopeChainArg, Value *rval)
+js::Execute(JSContext *cx, JSScript *script, JSObject &scopeChainArg, Value *rval)
 {
     /* The scope chain could be anything, so innerize just in case. */
     JSObject *scopeChain = &scopeChainArg;
     OBJ_TO_INNER_OBJECT(cx, scopeChain);
     if (!scopeChain)
         return false;
 
     /* If we were handed a non-native object, complain bitterly. */
@@ -953,17 +947,17 @@ Execute(JSContext *cx, JSScript *script,
         return false;
     Value thisv = ObjectValue(*thisObj);
 
     return ExecuteKernel(cx, script, *scopeChain, thisv, EXECUTE_GLOBAL,
                          NULL /* evalInFrame */, rval);
 }
 
 bool
-CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs)
+js::CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs)
 {
     JSObject *obj2;
     JSProperty *prop;
     uintN oldAttrs;
     bool isFunction;
     const char *type, *name;
 
     if (!obj->lookupProperty(cx, id, &obj2, &prop))
@@ -1024,28 +1018,28 @@ CheckRedeclaration(JSContext *cx, JSObje
     if (!name)
         return false;
     JS_ALWAYS_FALSE(JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
                                                  JSMSG_REDECLARED_VAR, type, name));
     return false;
 }
 
 JSBool
-HasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
+js::HasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
 {
     Class *clasp = obj->getClass();
     if (clasp->hasInstance)
         return clasp->hasInstance(cx, obj, v, bp);
     js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
                         JSDVG_SEARCH_STACK, ObjectValue(*obj), NULL);
     return JS_FALSE;
 }
 
 bool
-LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *result)
+js::LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *result)
 {
 #if JS_HAS_XML_SUPPORT
     if (JS_UNLIKELY(lval.isObject() && lval.toObject().isXML()) ||
                     (rval.isObject() && rval.toObject().isXML())) {
         return js_TestXMLEquality(cx, lval, rval, result);
     }
 #endif
 
@@ -1106,17 +1100,17 @@ LooselyEqual(JSContext *cx, const Value 
     double l, r;
     if (!ToNumber(cx, lvalue, &l) || !ToNumber(cx, rvalue, &r))
         return false;
     *result = JSDOUBLE_COMPARE(l, ==, r, false);
     return true;
 }
 
 bool
-StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, JSBool *equal)
+js::StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, JSBool *equal)
 {
     Value lval = lref, rval = rref;
     if (SameType(lval, rval)) {
         if (lval.isString())
             return EqualStrings(cx, lval.toString(), rval.toString(), equal);
         if (lval.isDouble()) {
             *equal = JSDOUBLE_COMPARE(lval.toDouble(), ==, rval.toDouble(), JS_FALSE);
             return true;
@@ -1158,17 +1152,17 @@ IsNegativeZero(const Value &v)
 
 static inline bool
 IsNaN(const Value &v)
 {
     return v.isDouble() && JSDOUBLE_IS_NaN(v.toDouble());
 }
 
 bool
-SameValue(JSContext *cx, const Value &v1, const Value &v2, JSBool *same)
+js::SameValue(JSContext *cx, const Value &v1, const Value &v2, JSBool *same)
 {
     if (IsNegativeZero(v1)) {
         *same = IsNegativeZero(v2);
         return true;
     }
     if (IsNegativeZero(v2)) {
         *same = false;
         return true;
@@ -1176,35 +1170,35 @@ SameValue(JSContext *cx, const Value &v1
     if (IsNaN(v1) && IsNaN(v2)) {
         *same = true;
         return true;
     }
     return StrictlyEqual(cx, v1, v2, same);
 }
 
 JSType
-TypeOfValue(JSContext *cx, const Value &vref)
+js::TypeOfValue(JSContext *cx, const Value &vref)
 {
     Value v = vref;
     if (v.isNumber())
         return JSTYPE_NUMBER;
     if (v.isString())
         return JSTYPE_STRING;
     if (v.isNull())
         return JSTYPE_OBJECT;
     if (v.isUndefined())
         return JSTYPE_VOID;
     if (v.isObject())
         return v.toObject().typeOf(cx);
     JS_ASSERT(v.isBoolean());
     return JSTYPE_BOOLEAN;
 }
 
-JS_REQUIRES_STACK bool
-InvokeConstructorKernel(JSContext *cx, const CallArgs &argsRef)
+bool
+js::InvokeConstructorKernel(JSContext *cx, const CallArgs &argsRef)
 {
     JS_ASSERT(!FunctionClass.construct);
     CallArgs args = argsRef;
 
     if (args.calleev().isObject()) {
         JSObject *callee = &args.callee();
         Class *clasp = callee->getClass();
         if (clasp == &FunctionClass) {
@@ -1234,18 +1228,18 @@ InvokeConstructorKernel(JSContext *cx, c
     }
 
 error:
     js_ReportIsNotFunction(cx, &args.calleev(), JSV2F_CONSTRUCT);
     return false;
 }
 
 bool
-InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval,
-                               uintN argc, Value *argv, Value *rval)
+js::InvokeConstructorWithGivenThis(JSContext *cx, JSObject *thisobj, const Value &fval,
+                                   uintN argc, Value *argv, Value *rval)
 {
     LeaveTrace(cx);
 
     InvokeArgsGuard args;
     if (!cx->stack.pushInvokeArgs(cx, argc, &args))
         return JS_FALSE;
 
     args.calleev() = fval;
@@ -1270,17 +1264,17 @@ InvokeConstructorWithGivenThis(JSContext
         ok = Invoke(cx, args, CONSTRUCT);
     }
 
     *rval = args.rval();
     return ok;
 }
 
 bool
-ValueToId(JSContext *cx, const Value &v, jsid *idp)
+js::ValueToId(JSContext *cx, const Value &v, jsid *idp)
 {
     int32_t i;
     if (ValueFitsInInt32(v, &i) && INT_FITS_IN_JSID(i)) {
         *idp = INT_TO_JSID(i);
         return true;
     }
 
 #if JS_HAS_XML_SUPPORT
@@ -1291,24 +1285,22 @@ ValueToId(JSContext *cx, const Value &v,
             return JS_TRUE;
         }
     }
 #endif
 
     return js_ValueToStringId(cx, v, idp);
 }
 
-} /* namespace js */
-
 /*
  * Enter the new with scope using an object at sp[-1] and associate the depth
  * of the with block with sp + stackIndex.
  */
-JS_REQUIRES_STACK JSBool
-js_EnterWith(JSContext *cx, jsint stackIndex, JSOp op, size_t oplen)
+static bool
+EnterWith(JSContext *cx, jsint stackIndex, JSOp op, size_t oplen)
 {
     StackFrame *fp = cx->fp();
     Value *sp = cx->regs().sp;
     JS_ASSERT(stackIndex < 0);
     JS_ASSERT(fp->base() <= sp + stackIndex);
 
     JSObject *obj;
     if (sp[-1].isObject()) {
@@ -1332,74 +1324,72 @@ js_EnterWith(JSContext *cx, jsint stackI
                                          sp + stackIndex - fp->base());
     if (!withobj)
         return JS_FALSE;
 
     fp->setScopeChainNoCallObj(*withobj);
     return JS_TRUE;
 }
 
-JS_REQUIRES_STACK void
-js_LeaveWith(JSContext *cx)
+static void
+LeaveWith(JSContext *cx)
 {
     JSObject *withobj;
 
     withobj = &cx->fp()->scopeChain();
     JS_ASSERT(withobj->getClass() == &WithClass);
     JS_ASSERT(withobj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp()));
     JS_ASSERT(OBJ_BLOCK_DEPTH(cx, withobj) >= 0);
     withobj->setPrivate(NULL);
     cx->fp()->setScopeChainNoCallObj(*withobj->getParent());
 }
 
-JS_REQUIRES_STACK Class *
-js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth)
-{
-    Class *clasp;
-
-    clasp = obj->getClass();
-    if ((clasp == &WithClass || clasp == &BlockClass) &&
-        obj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp()) &&
-        OBJ_BLOCK_DEPTH(cx, obj) >= stackDepth) {
-        return clasp;
-    }
-    return NULL;
+bool
+js::IsActiveWithOrBlock(JSContext *cx, JSObject &obj, int stackDepth)
+{
+    return (obj.isWith() || obj.isBlock()) &&
+           obj.getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp()) &&
+           OBJ_BLOCK_DEPTH(cx, &obj) >= stackDepth;
 }
 
 /*
  * Unwind block and scope chains to match the given depth. The function sets
  * fp->sp on return to stackDepth.
  */
-JS_REQUIRES_STACK JSBool
-js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind)
-{
-    Class *clasp;
-
+bool
+js::UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind)
+{
     JS_ASSERT(stackDepth >= 0);
     JS_ASSERT(cx->fp()->base() + stackDepth <= cx->regs().sp);
 
     StackFrame *fp = cx->fp();
     for (;;) {
-        clasp = js_IsActiveWithOrBlock(cx, &fp->scopeChain(), stackDepth);
-        if (!clasp)
+        JSObject &scopeChain = fp->scopeChain();
+        if (!IsActiveWithOrBlock(cx, scopeChain, stackDepth))
             break;
-        if (clasp == &BlockClass) {
+        if (scopeChain.isBlock()) {
             /* Don't fail until after we've updated all stacks. */
             normalUnwind &= js_PutBlockObject(cx, normalUnwind);
         } else {
-            js_LeaveWith(cx);
+            LeaveWith(cx);
         }
     }
 
     cx->regs().sp = fp->base() + stackDepth;
     return normalUnwind;
 }
 
-JSBool
-js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, Value *vp, Value *vp2)
+/*
+ * Find the results of incrementing or decrementing *vp. For pre-increments,
+ * both *vp and *vp2 will contain the result on return. For post-increments,
+ * vp will contain the original value converted to a number and vp2 will get
+ * the result. Both vp and vp2 must be roots.
+ */
+static bool
+DoIncDec(JSContext *cx, const JSCodeSpec *cs, Value *vp, Value *vp2)
 {
     if (cs->format & JOF_POST) {
         double d;
         if (!ToNumber(cx, *vp, &d))
             return JS_FALSE;
         vp->setNumber(d);
         (cs->format & JOF_INC) ? ++d : --d;
         vp2->setNumber(d);
@@ -1712,20 +1702,18 @@ TypeCheckNextBytecode(JSContext *cx, JSS
     if (cx->typeInferenceEnabled() &&
         *regs.pc != JSOP_TRAP &&
         n == analyze::GetBytecodeLength(regs.pc)) {
         TypeScript::CheckBytecode(cx, script, regs.pc, regs.sp);
     }
 #endif
 }
 
-namespace js {
-
-JS_REQUIRES_STACK JS_NEVER_INLINE bool
-Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
+JS_NEVER_INLINE bool
+js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
 {
 #ifdef MOZ_TRACEVIS
     TraceVisStateObj tvso(cx, S_INTERP);
 #endif
     JSAutoResolveFlags rf(cx, RESOLVE_INFER);
 
     JS_ASSERT(!cx->compartment->activeAnalysis);
 
@@ -2368,17 +2356,17 @@ BEGIN_CASE(JSOP_POPN)
 END_CASE(JSOP_POPN)
 
 BEGIN_CASE(JSOP_SETRVAL)
 BEGIN_CASE(JSOP_POPV)
     POP_RETURN_VALUE();
 END_CASE(JSOP_POPV)
 
 BEGIN_CASE(JSOP_ENTERWITH)
-    if (!js_EnterWith(cx, -1, JSOP_ENTERWITH, JSOP_ENTERWITH_LENGTH))
+    if (!EnterWith(cx, -1, JSOP_ENTERWITH, JSOP_ENTERWITH_LENGTH))
         goto error;
 
     /*
      * We must ensure that different "with" blocks have different stack depth
      * associated with them. This allows the try handler search to properly
      * recover the scope chain. Thus we must keep the stack at least at the
      * current level.
      *
@@ -2386,17 +2374,17 @@ BEGIN_CASE(JSOP_ENTERWITH)
      * enter/leave balance in [leavewith].
      */
     regs.sp[-1].setObject(regs.fp()->scopeChain());
 END_CASE(JSOP_ENTERWITH)
 
 BEGIN_CASE(JSOP_LEAVEWITH)
     JS_ASSERT(regs.sp[-1].toObject() == regs.fp()->scopeChain());
     regs.sp--;
-    js_LeaveWith(cx);
+    LeaveWith(cx);
 END_CASE(JSOP_LEAVEWITH)
 
 BEGIN_CASE(JSOP_RETURN)
     POP_RETURN_VALUE();
     /* FALL THROUGH */
 
 BEGIN_CASE(JSOP_RETRVAL)    /* fp return value already set */
 BEGIN_CASE(JSOP_STOP)
@@ -2427,17 +2415,17 @@ BEGIN_CASE(JSOP_STOP)
     }
 #endif
 
     interpReturnOK = true;
     if (entryFrame != regs.fp())
   inline_return:
     {
         JS_ASSERT(!regs.fp()->hasImacropc());
-        JS_ASSERT(!js_IsActiveWithOrBlock(cx, &regs.fp()->scopeChain(), 0));
+        JS_ASSERT(!IsActiveWithOrBlock(cx, regs.fp()->scopeChain(), 0));
         interpReturnOK = ScriptEpilogue(cx, regs.fp(), interpReturnOK);
 
         /* The JIT inlines ScriptEpilogue. */
 #ifdef JS_METHODJIT
   jit_return:
 #endif
 
         /* The results of lowered call/apply frames need to be shifted. */
@@ -3506,17 +3494,17 @@ do_incop:
         /*
          * We must set regs.sp[-1] to tmp for both post and pre increments
          * as the setter overwrites regs.sp[-1].
          */
         ref.setInt32(tmp);
     } else {
         /* We need an extra root for the result. */
         PUSH_NULL();
-        if (!js_DoIncDec(cx, cs, &regs.sp[-2], &regs.sp[-1]))
+        if (!DoIncDec(cx, cs, &regs.sp[-2], &regs.sp[-1]))
             goto error;
 
         {
             JSAutoResolveFlags rf(cx, setPropFlags);
             if (!obj->setProperty(cx, id, &regs.sp[-1], script->strictModeCode))
                 goto error;
         }
 
@@ -3578,17 +3566,17 @@ BEGIN_CASE(JSOP_LOCALINC)
     int32_t tmp;
     if (JS_LIKELY(vp->isInt32() && CanIncDecWithoutOverflow(tmp = vp->toInt32()))) {
         vp->getInt32Ref() = tmp + incr;
         JS_ASSERT(JSOP_INCARG_LENGTH == js_CodeSpec[op].length);
         SKIP_POP_AFTER_SET(JSOP_INCARG_LENGTH, 0);
         PUSH_INT32(tmp + incr2);
     } else {
         PUSH_COPY(*vp);
-        if (!js_DoIncDec(cx, &js_CodeSpec[op], &regs.sp[-1], vp))
+        if (!DoIncDec(cx, &js_CodeSpec[op], &regs.sp[-1], vp))
             goto error;
         TypeScript::MonitorOverflow(cx, script, regs.pc);
     }
     len = JSOP_INCARG_LENGTH;
     JS_ASSERT(len == js_CodeSpec[op].length);
     DO_NEXT_OP(len);
 }
 
@@ -3784,17 +3772,17 @@ BEGIN_CASE(JSOP_CALLPROP)
             regs.sp[-2] = rval;
             assertSameCompartment(cx, regs.sp[-1], regs.sp[-2]);
         }
     }
 #if JS_HAS_NO_SUCH_METHOD
     if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) {
         LOAD_ATOM(0, atom);
         regs.sp[-2].setString(atom);
-        if (!js_OnUnknownMethod(cx, regs.sp - 2))
+        if (!OnUnknownMethod(cx, regs.sp - 2))
             goto error;
     }
 #endif
     TypeScript::Monitor(cx, script, regs.pc, rval);
 }
 END_CASE(JSOP_CALLPROP)
 
 BEGIN_CASE(JSOP_UNBRAND)
@@ -4060,20 +4048,20 @@ BEGIN_CASE(JSOP_CALLELEM)
     FETCH_ELEMENT_ID(thisObj, -1, id);
 
     /* Get the method. */
     if (!js_GetMethod(cx, thisObj, id, JSGET_NO_METHOD_BARRIER, &regs.sp[-2]))
         goto error;
 
 #if JS_HAS_NO_SUCH_METHOD
     if (JS_UNLIKELY(regs.sp[-2].isPrimitive()) && thisv.isObject()) {
-        /* For js_OnUnknownMethod, sp[-2] is the index, and sp[-1] is the object missing it. */
+        /* For OnUnknownMethod, sp[-2] is the index, and sp[-1] is the object missing it. */
         regs.sp[-2] = regs.sp[-1];
         regs.sp[-1].setObject(*thisObj);
-        if (!js_OnUnknownMethod(cx, regs.sp - 2))
+        if (!OnUnknownMethod(cx, regs.sp - 2))
             goto error;
     } else
 #endif
     {
         regs.sp[-1] = thisv;
     }
 
     if (!JSID_IS_INT(id))
@@ -5800,27 +5788,27 @@ BEGIN_CASE(JSOP_FILTER)
 END_VARLEN_CASE
 }
 
 BEGIN_CASE(JSOP_ENDFILTER)
 {
     bool cond = !regs.sp[-1].isMagic();
     if (cond) {
         /* Exit the "with" block left from the previous iteration. */
-        js_LeaveWith(cx);
+        LeaveWith(cx);
     }
     if (!js_StepXMLListFilter(cx, cond))
         goto error;
     if (!regs.sp[-1].isNull()) {
         /*
          * Decrease sp after EnterWith returns as we use sp[-1] there to root
          * temporaries.
          */
         JS_ASSERT(IsXML(regs.sp[-1]));
-        if (!js_EnterWith(cx, -2, JSOP_ENDFILTER, JSOP_ENDFILTER_LENGTH))
+        if (!EnterWith(cx, -2, JSOP_ENDFILTER, JSOP_ENDFILTER_LENGTH))
             goto error;
         regs.sp--;
         len = GET_JUMP_OFFSET(regs.pc);
         JS_ASSERT(len < 0);
         BRANCH(len);
     }
     regs.sp--;
 }
@@ -6204,17 +6192,17 @@ END_CASE(JSOP_ARRAYPUSH)
 
             /*
              * Set pc to the first bytecode after the the try note to point
              * to the beginning of catch or finally or to [enditer] closing
              * the for-in loop.
              */
             regs.pc = (script)->main() + tn->start + tn->length;
 
-            JSBool ok = js_UnwindScope(cx, tn->stackDepth, JS_TRUE);
+            JSBool ok = UnwindScope(cx, tn->stackDepth, JS_TRUE);
             JS_ASSERT(regs.sp == regs.fp()->base() + tn->stackDepth);
             if (!ok) {
                 /*
                  * Restart the handler search with updated pc and stack depth
                  * to properly notify the debugger.
                  */
                 goto error;
             }
@@ -6274,22 +6262,22 @@ END_CASE(JSOP_ARRAYPUSH)
             regs.fp()->clearReturnValue();
         }
 #endif
     }
 
   forced_return:
     /*
      * Unwind the scope making sure that interpReturnOK stays false even when
-     * js_UnwindScope returns true.
+     * UnwindScope returns true.
      *
      * When a trap handler returns JSTRAP_RETURN, we jump here with
      * interpReturnOK set to true bypassing any finally blocks.
      */
-    interpReturnOK &= js_UnwindScope(cx, 0, interpReturnOK || cx->isExceptionPending());
+    interpReturnOK &= UnwindScope(cx, 0, interpReturnOK || cx->isExceptionPending());
     JS_ASSERT(regs.sp == regs.fp()->base());
 
     if (entryFrame != regs.fp())
         goto inline_return;
 
   exit:
     interpReturnOK = ScriptEpilogueOrGeneratorYield(cx, regs.fp(), interpReturnOK);
     regs.fp()->setFinishedInInterpreter();
@@ -6313,17 +6301,17 @@ END_CASE(JSOP_ARRAYPUSH)
         AbortRecording(cx, "recording out of Interpret");
 # ifdef JS_METHODJIT
     if (TRACE_PROFILER(cx))
         AbortProfiling(cx);
 # endif
 #endif
 
     JS_ASSERT_IF(!regs.fp()->isGeneratorFrame(),
-                 !js_IsActiveWithOrBlock(cx, &regs.fp()->scopeChain(), 0));
+                 !IsActiveWithOrBlock(cx, regs.fp()->scopeChain(), 0));
 
 #ifdef JS_METHODJIT
     /*
      * This path is used when it's guaranteed the method can be finished
      * inside the JIT.
      */
   leave_on_safe_point:
 #endif
@@ -6333,10 +6321,8 @@ END_CASE(JSOP_ARRAYPUSH)
   atom_not_defined:
     {
         JSAutoByteString printable;
         if (js_AtomToPrintableString(cx, atomNotDefined, &printable))
             js_ReportIsNotDefined(cx, printable.ptr());
     }
     goto error;
 }
-
-} /* namespace js */
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -355,39 +355,24 @@ class InterpreterFrames {
     InterpreterFrames *older;
 
   private:
     JSContext *context;
     FrameRegs *regs;
     const InterruptEnablerBase &enabler;
 };
 
-} /* namespace js */
-
-extern JS_REQUIRES_STACK JSBool
-js_EnterWith(JSContext *cx, jsint stackIndex, JSOp op, size_t oplen);
-
-extern JS_REQUIRES_STACK void
-js_LeaveWith(JSContext *cx);
-
-/*
- * Find the results of incrementing or decrementing *vp. For pre-increments,
- * both *vp and *vp2 will contain the result on return. For post-increments,
- * vp will contain the original value converted to a number and vp2 will get
- * the result. Both vp and vp2 must be roots.
- */
-extern JSBool
-js_DoIncDec(JSContext *cx, const JSCodeSpec *cs, js::Value *vp, js::Value *vp2);
-
 /*
  * Unwind block and scope chains to match the given depth. The function sets
  * fp->sp on return to stackDepth.
  */
-extern JS_REQUIRES_STACK JSBool
-js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind);
+extern bool
+UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind);
 
-extern JSBool
-js_OnUnknownMethod(JSContext *cx, js::Value *vp);
+extern bool
+OnUnknownMethod(JSContext *cx, js::Value *vp);
 
-extern JS_REQUIRES_STACK js::Class *
-js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth);
+extern bool
+IsActiveWithOrBlock(JSContext *cx, JSObject &obj, int stackDepth);
+
+}  /* namespace js */
 
 #endif /* jsinterp_h___ */
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -110,17 +110,17 @@ top:
             //       bytecode compiler cannot throw, so this is not possible.
             if (offset - tn->start > tn->length)
                 continue;
             if (tn->stackDepth > cx->regs().sp - fp->base())
                 continue;
 
             jsbytecode *pc = script->main() + tn->start + tn->length;
             cx->regs().pc = pc;
-            JSBool ok = js_UnwindScope(cx, tn->stackDepth, JS_TRUE);
+            JSBool ok = UnwindScope(cx, tn->stackDepth, JS_TRUE);
             JS_ASSERT(cx->regs().sp == fp->base() + tn->stackDepth);
 
             switch (tn->kind) {
                 case JSTRY_CATCH:
                   JS_ASSERT(js_GetOpcode(cx, fp->script(), pc) == JSOP_ENTERBLOCK);
 
 #if JS_HAS_GENERATORS
                   /* Catch cannot intercept the closing of a generator. */
@@ -173,17 +173,17 @@ top:
 
 /*
  * Clean up a frame and return.
  */
 static void
 InlineReturn(VMFrame &f)
 {
     JS_ASSERT(f.fp() != f.entryfp);
-    JS_ASSERT(!js_IsActiveWithOrBlock(f.cx, &f.fp()->scopeChain(), 0));
+    JS_ASSERT(!IsActiveWithOrBlock(f.cx, f.fp()->scopeChain(), 0));
     f.cx->stack.popInlineFrame(f.regs);
 
     DebugOnly<JSOp> op = js_GetOpcode(f.cx, f.fp()->script(), f.regs.pc);
     JS_ASSERT(op == JSOP_CALL ||
               op == JSOP_NEW ||
               op == JSOP_EVAL ||
               op == JSOP_FUNCALL ||
               op == JSOP_FUNAPPLY);
@@ -598,17 +598,17 @@ js_InternalThrow(VMFrame &f)
             break;
 
         // The JIT guarantees that ScriptEpilogue() has always been run
         // upon exiting to its caller. This is important for consistency,
         // where execution modes make similar guarantees about prologues
         // and epilogues. RunTracer(), Interpret(), and Invoke() all
         // rely on this property.
         JS_ASSERT(!f.fp()->finishedInInterpreter());
-        js_UnwindScope(cx, 0, cx->isExceptionPending());
+        UnwindScope(cx, 0, cx->isExceptionPending());
         ScriptEpilogue(f.cx, f.fp(), false);
 
         // Don't remove the last frame, this is the responsibility of
         // JaegerShot()'s caller. We only guarantee that ScriptEpilogue()
         // has been run.
         if (f.entryfp == f.fp())
             break;
 
@@ -777,17 +777,17 @@ HandleErrorInExcessFrame(VMFrame &f, Sta
             }
         }
 
         /* Don't unwind if this was the entry frame. */
         if (fp == stopFp)
             break;
 
         /* Unwind and return. */
-        returnOK &= bool(js_UnwindScope(cx, 0, returnOK || cx->isExceptionPending()));
+        returnOK &= UnwindScope(cx, 0, returnOK || cx->isExceptionPending());
         returnOK = ScriptEpilogue(cx, fp, returnOK);
         InlineReturn(f);
     }
 
     JS_ASSERT(&f.regs == &cx->regs());
     JS_ASSERT_IF(!returnOK, cx->fp() == stopFp);
 
     return returnOK;
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -2044,17 +2044,17 @@ ic::CallProp(VMFrame &f, ic::PICInfo *pi
             regs.sp[-1] = lval;
             regs.sp[-2] = rval;
         }
     }
 
 #if JS_HAS_NO_SUCH_METHOD
     if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) {
         regs.sp[-2].setString(JSID_TO_STRING(id));
-        if (!js_OnUnknownMethod(cx, regs.sp - 2))
+        if (!OnUnknownMethod(cx, regs.sp - 2))
             THROW();
     }
 #endif
 
     types::TypeScript::Monitor(f.cx, f.script(), f.pc(), regs.sp[-2]);
 
     if (monitor.recompiled())
         return;
@@ -2800,17 +2800,17 @@ ic::CallElement(VMFrame &f, ic::GetEleme
     /* Get or set the element. */
     if (!js_GetMethod(cx, thisObj, id, JSGET_NO_METHOD_BARRIER, &f.regs.sp[-2]))
         THROW();
 
 #if JS_HAS_NO_SUCH_METHOD
     if (JS_UNLIKELY(f.regs.sp[-2].isPrimitive()) && thisv.isObject()) {
         f.regs.sp[-2] = f.regs.sp[-1];
         f.regs.sp[-1].setObject(*thisObj);
-        if (!js_OnUnknownMethod(cx, f.regs.sp - 2))
+        if (!OnUnknownMethod(cx, f.regs.sp - 2))
             THROW();
     } else
 #endif
     {
         f.regs.sp[-1] = thisv;
     }
     if (!JSID_IS_INT(id))
         types::TypeScript::MonitorUnknown(f.cx, f.script(), f.pc());
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -547,17 +547,17 @@ stubs::CallElem(VMFrame &f)
     /* Get or set the element. */
     if (!js_GetMethod(cx, thisObj, id, JSGET_NO_METHOD_BARRIER, &regs.sp[-2]))
         THROW();
 
 #if JS_HAS_NO_SUCH_METHOD
     if (JS_UNLIKELY(regs.sp[-2].isPrimitive()) && thisv.isObject()) {
         regs.sp[-2] = regs.sp[-1];
         regs.sp[-1].setObject(*thisObj);
-        if (!js_OnUnknownMethod(cx, regs.sp - 2))
+        if (!OnUnknownMethod(cx, regs.sp - 2))
             THROW();
     } else
 #endif
     {
         regs.sp[-1] = thisv;
     }
     if (!JSID_IS_INT(id))
         TypeScript::MonitorUnknown(cx, f.script(), f.pc());
@@ -1735,17 +1735,17 @@ stubs::CallProp(VMFrame &f, JSAtom *orig
             }
             regs.sp[-1] = lval;
             regs.sp[-2] = rval;
         }
     }
 #if JS_HAS_NO_SUCH_METHOD
     if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) {
         regs.sp[-2].setString(origAtom);
-        if (!js_OnUnknownMethod(cx, regs.sp - 2))
+        if (!OnUnknownMethod(cx, regs.sp - 2))
             THROW();
     }
 #endif
     TypeScript::Monitor(cx, f.script(), f.pc(), rval);
 }
 
 void JS_FASTCALL
 stubs::Iter(VMFrame &f, uint32 flags)