[JAEGER] Merge from Tracemonkey part 1: don't change visibility of JSStackFrame members yet
authorDavid Mandelin <dmandelin@mozilla.com>
Mon, 16 Aug 2010 15:37:15 -0700
changeset 53439 3a51962c5475713e1002c793b94f7e67c89afd10
parent 53438 4ed66568e4608ad8bdd3a2ffef02d954852611dc (current diff)
parent 51056 13e72485d2863d82800c8d1e6954ef6e628a12e7 (diff)
child 53440 7ab1cd2e5a8ba40f64fdfbd46d2c97f16fd4e20a
push idunknown
push userunknown
push dateunknown
milestone2.0b4pre
[JAEGER] Merge from Tracemonkey part 1: don't change visibility of JSStackFrame members yet
content/base/src/nsContentUtils.cpp
dom/base/nsJSEnvironment.cpp
js/src/jsapi.cpp
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jsdbgapi.cpp
js/src/jsemit.cpp
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsiter.cpp
js/src/jsobj.cpp
js/src/jsopcode.cpp
js/src/jsparse.cpp
js/src/jsparse.h
js/src/jspropertycache.cpp
js/src/jsrecursion.cpp
js/src/jsscript.cpp
js/src/jstracer.cpp
js/src/jsxml.cpp
js/src/shell/js.cpp
js/src/xpconnect/src/XPCSystemOnlyWrapper.cpp
js/src/xpconnect/src/xpcconvert.cpp
js/src/xpconnect/wrappers/AccessCheck.cpp
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5381,33 +5381,33 @@ nsContentUtils::CanAccessNativeAnon()
       // No code at all is running. So we must be arriving here as the result
       // of C++ code asking us to do something. Allow access.
       return PR_TRUE;
     }
 
     // Some code is running, we can't make the assumption, as above, but we
     // can't use a native frame, so clear fp.
     fp = nsnull;
-  } else if (!fp->script) {
+  } else if (!fp->hasScript()) {
     fp = nsnull;
   }
 
   PRBool privileged;
   if (NS_SUCCEEDED(sSecurityManager->IsSystemPrincipal(principal, &privileged)) &&
       privileged) {
     // Chrome things are allowed to touch us.
     return PR_TRUE;
   }
 
   // XXX HACK EWW! Allow chrome://global/ access to these things, even
   // if they've been cloned into less privileged contexts.
   static const char prefix[] = "chrome://global/";
   const char *filename;
-  if (fp && fp->script &&
-      (filename = fp->script->filename) &&
+  if (fp && fp->hasScript() &&
+      (filename = fp->getScript()->filename) &&
       !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
     return PR_TRUE;
   }
 
   // Before we throw, check for UniversalXPConnect.
   nsresult rv = sSecurityManager->IsCapabilityEnabled("UniversalXPConnect", &privileged);
   if (NS_SUCCEEDED(rv) && privileged) {
     return PR_TRUE;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1217,17 +1217,17 @@ nsJSContext::DOMOperationCallback(JSCont
   else if ((buttonPressed == 2) && debugPossible) {
     // Debug the script
     jsval rval;
     switch(cx->debugHooks->debuggerHandler(cx, script, ::JS_GetFramePC(cx, fp),
                                            &rval,
                                            cx->debugHooks->
                                            debuggerHandlerData)) {
       case JSTRAP_RETURN:
-        fp->rval = js::Valueify(rval);
+        fp->setReturnValue(js::Valueify(rval));
         return JS_TRUE;
       case JSTRAP_ERROR:
         cx->throwing = JS_FALSE;
         return JS_FALSE;
       case JSTRAP_THROW:
         JS_SetPendingException(cx, rval);
         return JS_FALSE;
       case JSTRAP_CONTINUE:
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4298,17 +4298,17 @@ js_generic_native_method_dispatcher(JSCo
     memmove(argv - 1, argv, argc * sizeof(jsval));
 
     /*
      * Follow Function.prototype.apply and .call by using the global object as
      * the 'this' param if no args.
      */
     if (!ComputeThisFromArgv(cx, argv))
         return JS_FALSE;
-    js_GetTopStackFrame(cx)->thisv = argv[-1];
+    js_GetTopStackFrame(cx)->setThisValue(argv[-1]);
     JS_ASSERT(cx->fp->argv == argv);
 
     /* Clear the last parameter in case too few arguments were passed. */
     argv[--argc].setUndefined();
 
     return fs->call(cx, &argv[-1].toObject(), argc, Jsvalify(argv), Jsvalify(rval));
 }
 
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -345,31 +345,31 @@ StackSpace::getSynthesizedSlowNativeFram
     seg = new(start) StackSegment;
     fp = reinterpret_cast<JSStackFrame *>(seg + 1);
 }
 
 JS_REQUIRES_STACK void
 StackSpace::pushSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *seg, JSStackFrame *fp,
                                            JSFrameRegs &regs)
 {
-    JS_ASSERT(!fp->script && FUN_SLOW_NATIVE(fp->fun));
+    JS_ASSERT(!fp->hasScript() && FUN_SLOW_NATIVE(fp->getFunction()));
     fp->down = cx->fp;
     seg->setPreviousInMemory(currentSegment);
     currentSegment = seg;
     cx->pushSegmentAndFrame(seg, fp, regs);
     seg->setInitialVarObj(NULL);
 }
 
 JS_REQUIRES_STACK void
 StackSpace::popSynthesizedSlowNativeFrame(JSContext *cx)
 {
     JS_ASSERT(isCurrentAndActive(cx));
     JS_ASSERT(cx->hasActiveSegment());
     JS_ASSERT(currentSegment->getInitialFrame() == cx->fp);
-    JS_ASSERT(!cx->fp->script && FUN_SLOW_NATIVE(cx->fp->fun));
+    JS_ASSERT(!cx->fp->hasScript() && FUN_SLOW_NATIVE(cx->fp->getFunction()));
     cx->popSegmentAndFrame();
     currentSegment = currentSegment->getPreviousInMemory();
 }
 
 void
 FrameRegsIter::initSlow()
 {
     if (!curseg) {
@@ -1338,17 +1338,17 @@ static void
 PopulateReportBlame(JSContext *cx, JSErrorReport *report)
 {
     /*
      * Walk stack until we find a frame that is associated with some script
      * rather than a native frame.
      */
     for (JSStackFrame *fp = js_GetTopStackFrame(cx); fp; fp = fp->down) {
         if (fp->pc(cx)) {
-            report->filename = fp->script->filename;
+            report->filename = fp->getScript()->filename;
             report->lineno = js_FramePCToLineNumber(cx, fp);
             break;
         }
     }
 }
 
 /*
  * We don't post an exception in this case, since doing so runs into
@@ -1432,17 +1432,17 @@ checkReportFlags(JSContext *cx, uintN *f
 {
     if (JSREPORT_IS_STRICT_MODE_ERROR(*flags)) {
         /*
          * Error in strict code; warning with strict option; okay otherwise.
          * We assume that if the top frame is a native, then it is strict if
          * the nearest scripted frame is strict, see bug 536306.
          */
         JSStackFrame *fp = js_GetScriptedCaller(cx, NULL);
-        if (fp && fp->script->strictModeCode)
+        if (fp && fp->getScript()->strictModeCode)
             *flags &= ~JSREPORT_WARNING;
         else if (JS_HAS_STRICT_OPTION(cx))
             *flags |= JSREPORT_WARNING;
         else
             return true;
     } else if (JSREPORT_IS_STRICT(*flags)) {
         /* Warning/error only when JSOPTION_STRICT is set. */
         if (!JS_HAS_STRICT_OPTION(cx))
@@ -1906,17 +1906,17 @@ js_TriggerAllOperationCallbacks(JSRuntim
 }
 
 JSStackFrame *
 js_GetScriptedCaller(JSContext *cx, JSStackFrame *fp)
 {
     if (!fp)
         fp = js_GetTopStackFrame(cx);
     while (fp) {
-        if (fp->script)
+        if (fp->hasScript())
             return fp;
         fp = fp->down;
     }
     return NULL;
 }
 
 jsbytecode*
 js_GetCurrentBytecodePC(JSContext* cx)
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -2093,18 +2093,18 @@ struct JSContext
     js::StackSegment *containingSegment(const JSStackFrame *target);
 
     /*
      * Search the call stack for the nearest frame with static level targetLevel.
      */
     JSStackFrame *findFrameAtLevel(uintN targetLevel) {
         JSStackFrame *fp = this->fp;
         while (true) {
-            JS_ASSERT(fp && fp->script);
-            if (fp->script->staticLevel == targetLevel)
+            JS_ASSERT(fp && fp->hasScript());
+            if (fp->getScript()->staticLevel == targetLevel)
                 break;
             fp = fp->down;
         }
         return fp;
     }
  
 #ifdef JS_THREADSAFE
     JSThread            *thread;
@@ -2378,24 +2378,24 @@ js_TraceRegExpStatics(JSTracer *trc, JSC
 {
     acx->regExpStatics.mark(trc);
 }
 
 JS_ALWAYS_INLINE JSObject *
 JSStackFrame::varobj(js::StackSegment *seg) const
 {
     JS_ASSERT(seg->contains(this));
-    return fun ? maybeCallObj() : seg->getInitialVarObj();
+    return hasFunction() ? maybeCallObj() : seg->getInitialVarObj();
 }
 
 JS_ALWAYS_INLINE JSObject *
 JSStackFrame::varobj(JSContext *cx) const
 {
     JS_ASSERT(cx->activeSegment()->contains(this));
-    return fun ? maybeCallObj() : cx->activeSegment()->getInitialVarObj();
+    return hasFunction() ? maybeCallObj() : cx->activeSegment()->getInitialVarObj();
 }
 
 JS_ALWAYS_INLINE jsbytecode *
 JSStackFrame::pc(JSContext *cx) const
 {
     JS_ASSERT(cx->containingSegment(this) != NULL);
     return (cx->fp == this) ? cx->regs->pc : savedPC;
 }
@@ -2427,25 +2427,26 @@ class AutoCheckRequestDepth {
 
 #else
 # define CHECK_REQUEST(cx)       ((void)0)
 #endif
 
 static inline uintN
 FramePCOffset(JSContext *cx, JSStackFrame* fp)
 {
-    return uintN((fp->hasIMacroPC() ? fp->getIMacroPC() : fp->pc(cx)) - fp->script->code);
+    jsbytecode *pc = fp->hasIMacroPC() ? fp->getIMacroPC() : fp->pc(cx);
+    return uintN(pc - fp->getScript()->code);
 }
 
 static inline JSAtom **
 FrameAtomBase(JSContext *cx, JSStackFrame *fp)
 {
     return fp->hasIMacroPC()
            ? COMMON_ATOMS_START(&cx->runtime->atomState)
-           : fp->script->atomMap.vector;
+           : fp->getScript()->atomMap.vector;
 }
 
 namespace js {
 
 class AutoGCRooter {
   public:
     AutoGCRooter(JSContext *cx, ptrdiff_t tag)
       : down(cx->autoGCRooters), tag(tag), context(cx)
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -395,19 +395,19 @@ FrameRegsIter::FrameRegsIter(JSContext *
 
 inline Value *
 FrameRegsIter::contiguousDownFrameSP(JSStackFrame *up)
 {
     JS_ASSERT(up->argv);
     Value *sp = up->argv + up->argc;
 #ifdef DEBUG
     JS_ASSERT(sp <= up->argEnd());
-    JS_ASSERT(sp >= (up->down->script ? up->down->base() : up->down->slots()));
-    if (up->fun) {
-        uint16 nargs = up->fun->nargs;
+    JS_ASSERT(sp >= (up->down->hasScript() ? up->down->base() : up->down->slots()));
+    if (up->hasFunction()) {
+        uint16 nargs = up->getFunction()->nargs;
         uintN argc = up->argc;
         uintN missing = argc < nargs ? nargs - argc : 0;
         JS_ASSERT(sp == up->argEnd() - missing);
     } else {
         JS_ASSERT(sp == up->argEnd());
     }
 #endif
     return sp;
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -771,18 +771,18 @@ js_watch_set(JSContext *cx, JSObject *ob
                 /* Initialize slots/frame. */
                 Value *vp = frame.getvp();
                 MakeValueRangeGCSafe(vp, vplen);
                 vp[0].setObject(*closure);
                 vp[1].setNull();  // satisfy LeaveTree assert
                 JSStackFrame *fp = frame.getFrame();
                 PodZero(fp);
                 MakeValueRangeGCSafe(fp->slots(), nfixed);
-                fp->script = script;
-                fp->fun = fun;
+                fp->setScript(script);
+                fp->setFunction(fun);
                 fp->argv = vp + 2;
                 fp->setScopeChain(closure->getParent());
                 fp->setArgsObj(NULL);
 
                 /* Initialize regs. */
                 regs.pc = script ? script->code : NULL;
                 regs.sp = fp->slots() + nfixed;
 
@@ -1189,17 +1189,17 @@ JS_FrameIterator(JSContext *cx, JSStackF
 {
     *iteratorp = (*iteratorp == NULL) ? js_GetTopStackFrame(cx) : (*iteratorp)->down;
     return *iteratorp;
 }
 
 JS_PUBLIC_API(JSScript *)
 JS_GetFrameScript(JSContext *cx, JSStackFrame *fp)
 {
-    return fp->script;
+    return fp->maybeScript();
 }
 
 JS_PUBLIC_API(jsbytecode *)
 JS_GetFramePC(JSContext *cx, JSStackFrame *fp)
 {
     return fp->pc(cx);
 }
 
@@ -1209,26 +1209,26 @@ JS_GetScriptedCaller(JSContext *cx, JSSt
     return js_GetScriptedCaller(cx, fp);
 }
 
 JS_PUBLIC_API(JSPrincipals *)
 JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp)
 {
     JSSecurityCallbacks *callbacks;
 
-    if (fp->fun) {
+    if (fp->hasFunction()) {
         callbacks = JS_GetSecurityCallbacks(cx);
         if (callbacks && callbacks->findObjectPrincipals) {
-            if (FUN_OBJECT(fp->fun) != fp->callee())
+            if (FUN_OBJECT(fp->getFunction()) != fp->callee())
                 return callbacks->findObjectPrincipals(cx, fp->callee());
             /* FALL THROUGH */
         }
     }
-    if (fp->script)
-        return fp->script->principals;
+    if (fp->hasScript())
+        return fp->getScript()->principals;
     return NULL;
 }
 
 JSPrincipals *
 js_EvalFramePrincipals(JSContext *cx, JSObject *callee, JSStackFrame *caller)
 {
     JSPrincipals *principals, *callerPrincipals;
     JSSecurityCallbacks *callbacks;
@@ -1251,17 +1251,17 @@ JS_PUBLIC_API(JSPrincipals *)
 JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller)
 {
     return js_EvalFramePrincipals(cx, fp->callee(), caller);
 }
 
 JS_PUBLIC_API(void *)
 JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp)
 {
-    if (fp->hasAnnotation() && fp->script) {
+    if (fp->hasAnnotation() && fp->hasScript()) {
         JSPrincipals *principals = JS_StackFramePrincipals(cx, fp);
 
         if (principals && principals->globalPrivilegesEnabled(cx, principals)) {
             /*
              * Give out an annotation only if privileges have not been revoked
              * or disabled globally.
              */
             return fp->getAnnotation();
@@ -1286,17 +1286,17 @@ JS_GetFramePrincipalArray(JSContext *cx,
     if (!principals)
         return NULL;
     return principals->getPrincipalArray(cx, principals);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp)
 {
-    return !fp->script;
+    return !fp->hasScript();
 }
 
 /* this is deprecated, use JS_GetFrameScopeChain instead */
 JS_PUBLIC_API(JSObject *)
 JS_GetFrameObject(JSContext *cx, JSStackFrame *fp)
 {
     return fp->maybeScopeChain();
 }
@@ -1311,17 +1311,17 @@ JS_GetFrameScopeChain(JSContext *cx, JSS
     return js_GetScopeChain(cx, fp);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp)
 {
     JS_ASSERT(cx->stack().contains(fp));
 
-    if (! fp->fun)
+    if (!fp->hasFunction())
         return NULL;
 
     /* Force creation of argument object if not yet created */
     (void) js_GetArgsObject(cx, fp);
 
     /*
      * XXX ill-defined: null return here means error was reported, unlike a
      *     null returned above or in the #else
@@ -1336,27 +1336,27 @@ JS_GetFrameThis(JSContext *cx, JSStackFr
         return NULL;
     else
         return fp->getThisObject(cx);
 }
 
 JS_PUBLIC_API(JSFunction *)
 JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp)
 {
-    return fp->fun;
+    return fp->maybeFunction();
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp)
 {
-    if (!fp->fun)
+    if (!fp->hasFunction())
         return NULL;
 
     JS_ASSERT(fp->callee()->isFunction());
-    JS_ASSERT(fp->callee()->getPrivate() == fp->fun);
+    JS_ASSERT(fp->callee()->getPrivate() == fp->getFunction());
     return fp->callee();
 }
 
 JS_PUBLIC_API(JSBool)
 JS_IsConstructorFrame(JSContext *cx, JSStackFrame *fp)
 {
     return (fp->flags & JSFRAME_CONSTRUCTING) != 0;
 }
@@ -1382,23 +1382,23 @@ JS_PUBLIC_API(JSBool)
 JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp)
 {
     return (fp->flags & JSFRAME_DEBUGGER) != 0;
 }
 
 JS_PUBLIC_API(jsval)
 JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp)
 {
-    return Jsvalify(fp->rval);
+    return Jsvalify(fp->getReturnValue());
 }
 
 JS_PUBLIC_API(void)
 JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval)
 {
-    fp->rval = Valueify(rval);
+    fp->setReturnValue(Valueify(rval));
 }
 
 /************************************************************************/
 
 JS_PUBLIC_API(const char *)
 JS_GetScriptFilename(JSContext *cx, JSScript *script)
 {
     return script->filename;
@@ -1657,17 +1657,17 @@ SetupFakeFrame(JSContext *cx, ExecuteFra
 
     Value *vp = frame.getvp();
     PodZero(vp, vplen);
     vp[0].setObject(*scopeobj);
     vp[1].setNull();  // satisfy LeaveTree assert
 
     JSStackFrame *fp = frame.getFrame();
     PodZero(fp);
-    fp->fun = fun;
+    fp->setFunction(fun);
     fp->argv = vp + 2;
     fp->setScopeChain(scopeobj->getGlobal());
 
     regs.pc = NULL;
     regs.sp = fp->slots();
 
     cx->stack().pushExecuteFrame(cx, frame, regs, NULL);
     return true;
@@ -1891,18 +1891,18 @@ JS_GetScriptTotalSize(JSContext *cx, JSS
 }
 
 JS_PUBLIC_API(uint32)
 JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp)
 {
     if (!fp)
         fp = js_GetTopStackFrame(cx);
     while (fp) {
-        if (fp->script)
-            return JS_GetScriptFilenameFlags(fp->script);
+        if (fp->hasScript())
+            return JS_GetScriptFilenameFlags(fp->getScript());
         fp = fp->down;
     }
     return 0;
  }
 
 JS_PUBLIC_API(uint32)
 JS_GetScriptFilenameFlags(JSScript *script)
 {
--- a/js/src/jsemit.cpp
+++ b/js/src/jsemit.cpp
@@ -1885,17 +1885,17 @@ EmitEnterBlock(JSContext *cx, JSParseNod
  * node, and cg->parser->callerFrame having a non-null fun member, and the
  * static level of cg at least one greater than the eval-calling function's
  * static level.
  */
 static bool
 MakeUpvarForEval(JSParseNode *pn, JSCodeGenerator *cg)
 {
     JSContext *cx = cg->parser->context;
-    JSFunction *fun = cg->parser->callerFrame->fun;
+    JSFunction *fun = cg->parser->callerFrame->getFunction();
     uintN upvarLevel = fun->u.i.script->staticLevel;
 
     JSFunctionBox *funbox = cg->funbox;
     if (funbox) {
         /*
          * Treat top-level function definitions as escaping (i.e., as funargs),
          * required since we compile each such top level function or statement
          * and throw away the AST, so we can't yet see all funarg uses of this
@@ -2070,18 +2070,18 @@ BindNameToSlot(JSContext *cx, JSCodeGene
 
             /*
              * Don't generate upvars on the left side of a for loop. See
              * bug 470758.
              */
             if (cg->flags & TCF_IN_FOR_INIT)
                 return JS_TRUE;
 
-            JS_ASSERT(caller->script);
-            if (!caller->fun)
+            JS_ASSERT(caller->hasScript());
+            if (!caller->hasFunction())
                 return JS_TRUE;
 
             /*
              * Make sure the variable object used by the compiler to initialize
              * parent links matches the caller's varobj. Compile-n-go compiler-
              * created function objects have the top-level cg's scopeChain set
              * as their parent by Parser::newFunction.
              */
@@ -2100,17 +2100,17 @@ BindNameToSlot(JSContext *cx, JSCodeGene
             if (op != JSOP_NAME)
                 return JS_TRUE;
 
             /*
              * Generator functions may be resumed from any call stack, which
              * defeats the display optimization to static link searching used
              * by JSOP_{GET,CALL}UPVAR.
              */
-            JSFunction *fun = cg->parser->callerFrame->fun;
+            JSFunction *fun = cg->parser->callerFrame->getFunction();
             JS_ASSERT(cg->staticLevel >= fun->u.i.script->staticLevel);
             unsigned skip = cg->staticLevel - fun->u.i.script->staticLevel;
             if (cg->skipSpansGenerator(skip))
                 return JS_TRUE;
 
             return MakeUpvarForEval(pn, cg);
         }
 
@@ -2196,26 +2196,26 @@ BindNameToSlot(JSContext *cx, JSCodeGene
         JS_ASSERT(cg->staticLevel >= level);
         if (op != JSOP_NAME)
             return JS_TRUE;
 
 #ifdef DEBUG
         JSStackFrame *caller = cg->parser->callerFrame;
 #endif
         JS_ASSERT(caller);
-        JS_ASSERT(caller->script);
+        JS_ASSERT(caller->hasScript());
 
         JSTreeContext *tc = cg;
         while (tc->staticLevel != level)
             tc = tc->parent;
         JS_ASSERT(tc->compiling());
 
         JSCodeGenerator *evalcg = (JSCodeGenerator *) tc;
         JS_ASSERT(evalcg->compileAndGo());
-        JS_ASSERT(caller->fun && cg->parser->callerVarObj == evalcg->scopeChain);
+        JS_ASSERT(caller->hasFunction() && cg->parser->callerVarObj == evalcg->scopeChain);
 
         /*
          * Don't generate upvars on the left side of a for loop. See
          * bug 470758 and bug 520513.
          */
         if (evalcg->flags & TCF_IN_FOR_INIT)
             return JS_TRUE;
 
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -288,17 +288,17 @@ InitExnPrivate(JSContext *cx, JSObject *
                   : NULL;
     older = JS_SetErrorReporter(cx, NULL);
     state = JS_SaveExceptionState(cx);
 
     callerid = ATOM_TO_JSID(cx->runtime->atomState.callerAtom);
     stackDepth = 0;
     valueCount = 0;
     for (fp = js_GetTopStackFrame(cx); fp; fp = fp->down) {
-        if (fp->fun && fp->argv) {
+        if (fp->hasFunction() && fp->argv) {
             Value v = NullValue();
             if (checkAccess &&
                 !checkAccess(cx, fp->callee(), callerid, JSACC_READ, &v)) {
                 break;
             }
             valueCount += fp->argc;
         }
         ++stackDepth;
@@ -329,31 +329,31 @@ InitExnPrivate(JSContext *cx, JSObject *
     priv->message = message;
     priv->filename = filename;
     priv->lineno = lineno;
     priv->stackDepth = stackDepth;
 
     values = GetStackTraceValueBuffer(priv);
     elem = priv->stackElems;
     for (fp = js_GetTopStackFrame(cx); fp != fpstop; fp = fp->down) {
-        if (!fp->fun) {
+        if (!fp->hasFunction()) {
             elem->funName = NULL;
             elem->argc = 0;
         } else {
-            elem->funName = fp->fun->atom
-                            ? ATOM_TO_STRING(fp->fun->atom)
+            elem->funName = fp->getFunction()->atom
+                            ? ATOM_TO_STRING(fp->getFunction()->atom)
                             : cx->runtime->emptyString;
             elem->argc = fp->argc;
             memcpy(values, fp->argv, fp->argc * sizeof(jsval));
             values += fp->argc;
         }
         elem->ulineno = 0;
         elem->filename = NULL;
-        if (fp->script) {
-            elem->filename = fp->script->filename;
+        if (fp->hasScript()) {
+            elem->filename = fp->getScript()->filename;
             if (fp->pc(cx))
                 elem->ulineno = js_FramePCToLineNumber(cx, fp);
         }
         ++elem;
     }
     JS_ASSERT(priv->stackElems + stackDepth == elem);
     JS_ASSERT(GetStackTraceValueBuffer(priv) + valueCount == values);
 
@@ -744,17 +744,17 @@ Exception(JSContext *cx, JSObject *obj, 
         filename = js_ValueToString(cx, argv[1]);
         if (!filename)
             return JS_FALSE;
         argv[1].setString(filename);
         fp = NULL;
     } else {
         fp = js_GetScriptedCaller(cx, NULL);
         if (fp) {
-            filename = FilenameToString(cx, fp->script->filename);
+            filename = FilenameToString(cx, fp->getScript()->filename);
             if (!filename)
                 return JS_FALSE;
         } else {
             filename = cx->runtime->emptyString;
         }
     }
 
     /* Set the 'lineNumber' property. */
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -197,18 +197,18 @@ PutArguments(JSContext *cx, JSObject *ar
 
 JSObject *
 js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
 {
     /*
      * We must be in a function activation; the function must be lightweight
      * or else fp must have a variable object.
      */
-    JS_ASSERT(fp->fun);
-    JS_ASSERT_IF(fp->fun->flags & JSFUN_HEAVYWEIGHT,
+    JS_ASSERT(fp->hasFunction());
+    JS_ASSERT_IF(fp->getFunction()->flags & JSFUN_HEAVYWEIGHT,
                  fp->varobj(cx->containingSegment(fp)));
 
     /* Skip eval and debugger frames. */
     while (fp->flags & JSFRAME_SPECIAL)
         fp = fp->down;
 
     /* Create an arguments object for fp only if it lacks one. */
     if (fp->hasArgsObj())
@@ -774,17 +774,17 @@ NewDeclEnvObject(JSContext *cx, JSStackF
     envobj->map = cx->runtime->emptyDeclEnvScope->hold();
     return envobj;
 }
 
 JSObject *
 js_GetCallObject(JSContext *cx, JSStackFrame *fp)
 {
     /* Create a call object for fp only if it lacks one. */
-    JS_ASSERT(fp->fun);
+    JS_ASSERT(fp->hasFunction());
     if (fp->hasCallObj())
         return fp->getCallObj();
 
 #ifdef DEBUG
     /* A call object should be a frame's outermost scope chain element.  */
     Class *classp = fp->getScopeChain()->getClass();
     if (classp == &js_WithClass || classp == &js_BlockClass)
         JS_ASSERT(fp->getScopeChain()->getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
@@ -793,17 +793,18 @@ js_GetCallObject(JSContext *cx, JSStackF
 #endif
 
     /*
      * Create the call object, using the frame's enclosing scope as its
      * parent, and link the call to its stack frame. For a named function
      * expression Call's parent points to an environment object holding
      * function's name.
      */
-    JSAtom *lambdaName = (fp->fun->flags & JSFUN_LAMBDA) ? fp->fun->atom : NULL;
+    JSAtom *lambdaName =
+        (fp->getFunction()->flags & JSFUN_LAMBDA) ? fp->getFunction()->atom : NULL;
     if (lambdaName) {
         JSObject *envobj = NewDeclEnvObject(cx, fp);
         if (!envobj)
             return NULL;
 
         /* Root envobj before js_DefineNativeProperty (-> JSClass.addProperty). */
         fp->setScopeChain(envobj);
         JS_ASSERT(fp->argv);
@@ -811,23 +812,23 @@ js_GetCallObject(JSContext *cx, JSStackF
                                      fp->calleeValue(),
                                      CalleeGetter, NULL,
                                      JSPROP_PERMANENT | JSPROP_READONLY,
                                      0, 0, NULL)) {
             return NULL;
         }
     }
 
-    JSObject *callobj = NewCallObject(cx, fp->fun, fp->getScopeChain());
+    JSObject *callobj = NewCallObject(cx, fp->getFunction(), fp->getScopeChain());
     if (!callobj)
         return NULL;
 
     callobj->setPrivate(fp);
     JS_ASSERT(fp->argv);
-    JS_ASSERT(fp->fun == GET_FUNCTION_PRIVATE(cx, fp->callee()));
+    JS_ASSERT(fp->getFunction() == GET_FUNCTION_PRIVATE(cx, fp->callee()));
     callobj->setSlot(JSSLOT_CALLEE, fp->calleeValue());
     fp->setCallObj(callobj);
 
     /*
      * Push callobj on the top of the scope chain, and make it the
      * variables object.
      */
     fp->setScopeChain(callobj);
@@ -875,17 +876,17 @@ js_PutCallObject(JSContext *cx, JSStackF
 
     /* Get the arguments object to snapshot fp's actual argument values. */
     if (fp->hasArgsObj()) {
         if (!(fp->flags & JSFRAME_OVERRIDE_ARGS))
             callobj->setSlot(JSSLOT_CALL_ARGUMENTS, ObjectOrNullValue(fp->getArgsObj()));
         js_PutArgsObject(cx, fp);
     }
 
-    JSFunction *fun = fp->fun;
+    JSFunction *fun = fp->getFunction();
     JS_ASSERT(fun == js_GetCallObjectFunction(callobj));
     uintN n = fun->countArgsAndVars();
 
     /*
      * Since for a call object all fixed slots happen to be taken, we can copy
      * arguments and variables straight into JSObject.dslots.
      */
     JS_STATIC_ASSERT(JS_INITIAL_NSLOTS - JSSLOT_PRIVATE ==
@@ -1267,21 +1268,23 @@ JS_PUBLIC_DATA(Class) js_CallClass = {
     NULL,           /* xdrObject   */
     NULL,           /* hasInstance */
     JS_CLASS_TRACE(args_or_call_trace)
 };
 
 bool
 JSStackFrame::getValidCalleeObject(JSContext *cx, Value *vp)
 {
-    if (!fun) {
+    if (!hasFunction()) {
         *vp = argv ? argv[-2] : UndefinedValue();
         return true;
     }
 
+    JSFunction *fun = getFunction();
+
     /*
      * See the equivalent condition in args_getProperty for ARGS_CALLEE, but
      * note that here we do not want to throw, since this escape can happen via
      * a foo.caller reference alone, without any debugger or indirect eval. And
      * alas, it seems foo.caller is still used on the Web.
      */
     if (fun->needsWrapper()) {
         JSObject *wrapper = WrapEscapingClosure(cx, this, fun);
@@ -1294,21 +1297,21 @@ JSStackFrame::getValidCalleeObject(JSCon
     JSObject *funobj = &calleeObject();
     vp->setObject(*funobj);
 
     /*
      * Check for an escape attempt by a joined function object, which must go
      * through the frame's |this| object's method read barrier for the method
      * atom by which it was uniquely associated with a property.
      */
-    if (thisv.isObject()) {
+    if (getThisValue().isObject()) {
         JS_ASSERT(GET_FUNCTION_PRIVATE(cx, funobj) == fun);
 
         if (fun == funobj && fun->methodAtom()) {
-            JSObject *thisp = &thisv.toObject();
+            JSObject *thisp = &getThisValue().toObject();
             JS_ASSERT(thisp->canHaveMethodBarrier());
 
             JSScope *scope = thisp->scope();
             if (scope->hasMethodBarrier()) {
                 JSScopeProperty *sprop = scope->lookup(ATOM_TO_JSID(fun->methodAtom()));
 
                 /*
                  * The method property might have been deleted while the method
@@ -1410,17 +1413,17 @@ fun_getProperty(JSContext *cx, JSObject 
         obj = obj->getProto();
         if (!obj)
             return true;
     }
 
     /* Find fun's top-most activation record. */
     JSStackFrame *fp;
     for (fp = js_GetTopStackFrame(cx);
-         fp && (fp->fun != fun || (fp->flags & JSFRAME_SPECIAL));
+         fp && (fp->maybeFunction() != fun || (fp->flags & JSFRAME_SPECIAL));
          fp = fp->down) {
         continue;
     }
 
     switch (slot) {
       case FUN_ARGUMENTS:
         /* Warn if strict about f.arguments or equivalent unqualified uses. */
         if (!JS_ReportErrorFlagsAndNumber(cx,
@@ -1457,17 +1460,17 @@ fun_getProperty(JSContext *cx, JSObject 
             /* Censor the caller if it is from another compartment. */
             if (vp->toObject().getCompartment(cx) != cx->compartment)
                 vp->setNull();
         }
         break;
 
       default:
         /* XXX fun[0] and fun.arguments[0] are equivalent. */
-        if (fp && fp->fun && (uintN)slot < fp->fun->nargs)
+        if (fp && fp->hasFunction() && (uintN)slot < fp->getFunction()->nargs)
             *vp = fp->argv[slot];
         break;
     }
 
     return true;
 }
 
 struct LazyFunctionProp {
@@ -2212,17 +2215,18 @@ Function(JSContext *cx, JSObject *obj, u
     /*
      * Function is static and not called directly by other functions in this
      * file, therefore it is callable only as a native function by js_Invoke.
      * Find the scripted caller, possibly skipping other native frames such as
      * are built for Function.prototype.call or .apply activations that invoke
      * Function indirectly from a script.
      */
     fp = js_GetTopStackFrame(cx);
-    JS_ASSERT(!fp->script && fp->fun && fp->fun->u.n.native == Function);
+    JS_ASSERT(!fp->hasScript() && fp->hasFunction() &&
+              fp->getFunction()->u.n.native == Function);
     caller = js_GetScriptedCaller(cx, fp);
     if (caller) {
         principals = JS_EvalFramePrincipals(cx, fp, caller);
         filename = js_ComputeFilename(cx, caller, principals, &lineno);
     } else {
         filename = NULL;
         lineno = 0;
         principals = NULL;
@@ -2546,18 +2550,18 @@ js_NewFlatClosure(JSContext *cx, JSFunct
         closure->dslots[i] = GetUpvar(cx, level, uva->vector[i]);
 
     return closure;
 }
 
 JSObject *
 js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun)
 {
-    JS_ASSERT(cx->fp->fun->flags & JSFUN_HEAVYWEIGHT);
-    JS_ASSERT(!cx->fp->fun->optimizedClosure());
+    JS_ASSERT(cx->fp->getFunction()->flags & JSFUN_HEAVYWEIGHT);
+    JS_ASSERT(!cx->fp->getFunction()->optimizedClosure());
     JS_ASSERT(FUN_FLAT_CLOSURE(fun));
 
     return WrapEscapingClosure(cx, cx->fp, fun);
 }
 
 JSFunction *
 js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, Native native,
                   uintN nargs, uintN attrs)
@@ -2667,17 +2671,17 @@ js_ReportIsNotFunction(JSContext *cx, co
      */
     ptrdiff_t spindex = 0;
 
     FrameRegsIter i(cx);
     while (!i.done() && !i.pc())
         ++i;
 
     if (!i.done()) {
-        uintN depth = js_ReconstructStackDepth(cx, i.fp()->script, i.pc());
+        uintN depth = js_ReconstructStackDepth(cx, i.fp()->getScript(), i.pc());
         Value *simsp = i.fp()->base() + depth;
         JS_ASSERT(simsp <= i.sp());
         if (i.fp()->base() <= vp && vp < simsp)
             spindex = vp - simsp;
     }
 
     if (!spindex)
         spindex = ((flags & JSV2F_SEARCH_STACK) ? JSDVG_SEARCH_STACK : JSDVG_IGNORE_STACK);
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2267,22 +2267,22 @@ gc_lock_traversal(const GCLocks::Entry &
 
 void
 js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp)
 {
     if (fp->hasCallObj())
         JS_CALL_OBJECT_TRACER(trc, fp->getCallObj(), "call");
     if (fp->hasArgsObj())
         JS_CALL_OBJECT_TRACER(trc, fp->getArgsObj(), "arguments");
-    if (fp->script)
-        js_TraceScript(trc, fp->script);
+    if (fp->hasScript())
+        js_TraceScript(trc, fp->getScript());
 
     /* Allow for primitive this parameter due to JSFUN_THISP_* flags. */
-    MarkValue(trc, fp->thisv, "this");
-    MarkValue(trc, fp->rval, "rval");
+    MarkValue(trc, fp->getThisValue(), "this");
+    MarkValue(trc, fp->getReturnValue(), "rval");
     if (fp->hasScopeChain())
         JS_CALL_OBJECT_TRACER(trc, fp->getScopeChain(), "scope chain");
 }
 
 void
 JSWeakRoots::mark(JSTracer *trc)
 {
 #ifdef DEBUG
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -107,35 +107,35 @@ js_GetScopeChain(JSContext *cx, JSStackF
 {
     JSObject *sharedBlock = fp->maybeBlockChain();
 
     if (!sharedBlock) {
         /*
          * Don't force a call object for a lightweight function call, but do
          * insist that there is a call object for a heavyweight function call.
          */
-        JS_ASSERT(!fp->fun ||
-                  !(fp->fun->flags & JSFUN_HEAVYWEIGHT) ||
+        JS_ASSERT(!fp->hasFunction() ||
+                  !(fp->getFunction()->flags & JSFUN_HEAVYWEIGHT) ||
                   fp->hasCallObj());
         JS_ASSERT(fp->hasScopeChain());
         return fp->getScopeChain();
     }
 
     /* We don't handle cloning blocks on trace.  */
     LeaveTrace(cx);
 
     /*
      * We have one or more lexical scopes to reflect into fp->scopeChain, so
      * make sure there's a call object at the current head of the scope chain,
      * if this frame is a call frame.
      *
      * Also, identify the innermost compiler-allocated block we needn't clone.
      */
     JSObject *limitBlock, *limitClone;
-    if (fp->fun && !fp->hasCallObj()) {
+    if (fp->hasFunction() && !fp->hasCallObj()) {
         JS_ASSERT_IF(fp->getScopeChain()->getClass() == &js_BlockClass,
                      fp->getScopeChain()->getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
         if (!js_GetCallObject(cx, fp))
             return NULL;
 
         /* We know we must clone everything on blockChain. */
         limitBlock = limitClone = NULL;
     } else {
@@ -530,30 +530,34 @@ InvokeCommon(JSContext *cx, JSFunction *
     JSStackFrame *fp = frame.getFrame();
 
     /* Initialize missing missing arguments and new local variables. */
     Value *missing = args.argv() + args.argc();
     SetValueRangeToUndefined(missing, nmissing);
     SetValueRangeToUndefined(fp->slots(), nvars);
 
     /* Initialize frame. */
-    fp->thisv = args.thisv();
+    fp->setThisValue(args.thisv());
     fp->setCallObj(NULL);
     fp->setArgsObj(NULL);
-    fp->script = script;
-    fp->fun = fun;
+    fp->setScript(script);
+    fp->setFunction(fun);
     fp->argc = args.argc();
     fp->argv = args.argv();
-    fp->rval = (flags & JSINVOKE_CONSTRUCT) ? fp->thisv : UndefinedValue();
     fp->setAnnotation(NULL);
     fp->setScopeChain(NULL);
     fp->setBlockChain(NULL);
     fp->flags = flags;
     JS_ASSERT(!fp->hasIMacroPC());
 
+    if (flags & JSINVOKE_CONSTRUCT)
+        fp->setReturnValue(fp->getThisValue());
+    else
+        fp->clearReturnValue();
+
     /* Initialize regs. */
     JSFrameRegs &regs = frame.getRegs();
     if (script) {
         regs.pc = script->code;
         regs.sp = fp->slots() + script->nfixed;
     } else {
         regs.pc = NULL;
         regs.sp = fp->slots();
@@ -614,41 +618,41 @@ InvokeCommon(JSContext *cx, JSFunction *
 
     /* Call the function, either a native method or an interpreted script. */
     JSBool ok;
     if (native) {
 #ifdef DEBUG_NOT_THROWING
         JSBool alreadyThrowing = cx->throwing;
 #endif
         /* Primitive |this| should not be passed to slow natives. */
-        JSObject *thisp = fun ? fp->getThisObject(cx) : fp->thisv.toObjectOrNull();
+        JSObject *thisp = fun ? fp->getThisObject(cx) : fp->getThisValue().toObjectOrNull();
         ok = callJSNative(cx, native, thisp, fp->argc, fp->argv, &fp->rval);
 
         JS_ASSERT(cx->fp == fp);
         JS_RUNTIME_METER(cx->runtime, nativeCalls);
 #ifdef DEBUG_NOT_THROWING
         if (ok && !alreadyThrowing)
             ASSERT_NOT_THROWING(cx);
 #endif
     } else {
         JS_ASSERT(script);
         AutoPreserveEnumerators preserve(cx);
         ok = RunScript(cx, script, fun, fp->getScopeChain());
     }
 
-    DTrace::exitJSFun(cx, fp, fun, fp->rval);
+    DTrace::exitJSFun(cx, fp, fun, fp->getReturnValue());
 
     if (hookData) {
         hook = cx->debugHooks->callHook;
         if (hook)
             hook(cx, fp, JS_FALSE, &ok, hookData);
     }
 
     fp->putActivationObjects(cx);
-    args.rval() = fp->rval;
+    args.rval() = fp->getReturnValue();
     return ok;
 }
 
 static JSBool
 DoConstruct(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
 {
 
     Class *clasp = argv[-2].toObject().getClass();
@@ -661,17 +665,17 @@ DoConstruct(JSContext *cx, JSObject *obj
 
 static JSBool
 DoSlowCall(JSContext *cx, uintN argc, Value *vp)
 {
     JSStackFrame *fp = cx->fp;
     JSObject *obj = fp->getThisObject(cx);
     if (!obj)
         return false;
-    JS_ASSERT(ObjectValue(*obj) == fp->thisv);
+    JS_ASSERT(ObjectValue(*obj) == fp->getThisValue());
 
     JSObject *callee = &JS_CALLEE(cx, vp).toObject();
     Class *clasp = callee->getClass();
     JS_ASSERT(!(clasp->flags & Class::CALL_IS_FAST));
     if (!clasp->call) {
         js_ReportIsNotFunction(cx, &vp[0], 0);
         return JS_FALSE;
     }
@@ -852,21 +856,21 @@ Execute(JSContext *cx, JSObject *chain, 
     /* Initialize fixed slots (GVAR ops expecte NULL). */
     SetValueRangeToNull(fp->slots(), script->nfixed);
 
 #if JS_HAS_SHARP_VARS
     JS_STATIC_ASSERT(SHARP_NSLOTS == 2);
     if (script->hasSharps) {
         JS_ASSERT(script->nfixed >= SHARP_NSLOTS);
         Value *sharps = &fp->slots()[script->nfixed - SHARP_NSLOTS];
-        if (down && down->script && down->script->hasSharps) {
-            JS_ASSERT(down->script->nfixed >= SHARP_NSLOTS);
-            int base = (down->fun && !(down->flags & JSFRAME_SPECIAL))
-                       ? down->fun->sharpSlotBase(cx)
-                       : down->script->nfixed - SHARP_NSLOTS;
+        if (down && down->hasScript() && down->getScript()->hasSharps) {
+            JS_ASSERT(down->getFixedCount() >= SHARP_NSLOTS);
+            int base = (down->getFunction() && !(down->flags & JSFRAME_SPECIAL))
+                       ? down->getFunction()->sharpSlotBase(cx)
+                       : down->getFixedCount() - SHARP_NSLOTS;
             if (base < 0)
                 return false;
             sharps[0] = down->slots()[base];
             sharps[1] = down->slots()[base + 1];
         } else {
             sharps[0].setUndefined();
             sharps[1].setUndefined();
         }
@@ -874,18 +878,18 @@ Execute(JSContext *cx, JSObject *chain, 
 #endif
 
     /* Initialize frame. */
     JSObject *initialVarObj;
     if (down) {
         /* Propagate arg state for eval and the debugger API. */
         fp->setCallObj(down->maybeCallObj());
         fp->setArgsObj(NULL);
-        fp->fun = (script->staticLevel > 0) ? down->fun : NULL;
-        fp->thisv = down->thisv;
+        fp->setFunction((script->staticLevel > 0) ? down->maybeFunction() : NULL);
+        fp->setThisValue(down->getThisValue());
         fp->flags = flags;
         fp->argc = down->argc;
         fp->argv = down->argv;
         fp->setAnnotation(down->maybeAnnotation());
         fp->setScopeChain(chain);
 
         /*
          * We want to call |down->varobj()|, but this requires knowing the
@@ -895,18 +899,18 @@ Execute(JSContext *cx, JSObject *chain, 
          * linear search. Luckily, this only happens with EvaluateInFrame.
          */
         initialVarObj = (down == cx->fp)
                         ? down->varobj(cx)
                         : down->varobj(cx->containingSegment(down));
     } else {
         fp->setCallObj(NULL);
         fp->setArgsObj(NULL);
-        fp->fun = NULL;
-        /* Ininitialize fp->thisv after pushExecuteFrame. */
+        fp->setFunction(NULL);
+        fp->setThisValue(UndefinedValue());  /* Make GC-safe until initialized below. */
         fp->flags = flags;
         fp->argc = 0;
         fp->argv = NULL;
         fp->setAnnotation(NULL);
 
         JSObject *innerizedChain = chain;
         OBJ_TO_INNER_OBJECT(cx, innerizedChain);
         if (!innerizedChain)
@@ -915,43 +919,43 @@ Execute(JSContext *cx, JSObject *chain, 
 
         initialVarObj = (cx->options & JSOPTION_VAROBJFIX)
                         ? chain->getGlobal()
                         : chain;
     }
     JS_ASSERT(!initialVarObj->getOps()->defineProperty);
 
     JS_ASSERT(!fp->hasIMacroPC());
-    fp->script = script;
-    fp->rval.setUndefined();
+    fp->setScript(script);
+    fp->clearReturnValue();
     fp->setBlockChain(NULL);
 
     /* Initialize regs. */
     regs.pc = script->code;
     regs.sp = fp->base();
 
     /* Officially push |fp|. |frame|'s destructor pops. */
     cx->stack().pushExecuteFrame(cx, frame, regs, initialVarObj);
 
     /* Now that the frame has been pushed, we can call the thisObject hook. */
     if (!down) {
         JSObject *thisp = chain->thisObject(cx);
         if (!thisp)
             return false;
-        fp->thisv.setObject(*thisp);
+        fp->setThisValue(ObjectValue(*thisp));
     }
 
     void *hookData = NULL;
     if (JSInterpreterHook hook = cx->debugHooks->executeHook)
         hookData = hook(cx, fp, JS_TRUE, 0, cx->debugHooks->executeHookData);
 
     AutoPreserveEnumerators preserve(cx);
     JSBool ok = RunScript(cx, script, NULL, fp->getScopeChain());
     if (result)
-        *result = fp->rval;
+        *result = fp->getReturnValue();
 
     if (hookData) {
         if (JSInterpreterHook hook = cx->debugHooks->executeHook)
             hook(cx, fp, JS_FALSE, &ok, hookData);
     }
 
     return !!ok;
 }
@@ -1405,26 +1409,26 @@ js::GetUpvar(JSContext *cx, uintN closur
     JS_ASSERT(closureLevel >= cookie.level() && cookie.level() > 0);
     const uintN targetLevel = closureLevel - cookie.level();
     JS_ASSERT(targetLevel < UpvarCookie::UPVAR_LEVEL_LIMIT);
 
     JSStackFrame *fp = cx->findFrameAtLevel(targetLevel);
     uintN slot = cookie.slot();
     Value *vp;
 
-    if (!fp->fun || (fp->flags & JSFRAME_EVAL)) {
-        vp = fp->slots() + fp->script->nfixed;
-    } else if (slot < fp->fun->nargs) {
+    if (!fp->hasFunction() || (fp->flags & JSFRAME_EVAL)) {
+        vp = fp->slots() + fp->getFixedCount();
+    } else if (slot < fp->getArgumentCount()) {
         vp = fp->argv;
     } else if (slot == UpvarCookie::CALLEE_SLOT) {
         vp = &fp->argv[-2];
         slot = 0;
     } else {
-        slot -= fp->fun->nargs;
-        JS_ASSERT(slot < fp->script->nslots);
+        slot -= fp->getArgumentCount();
+        JS_ASSERT(slot < fp->getSlotCount());
         vp = fp->slots();
     }
 
     return vp[slot];
 }
 
 #ifdef DEBUG
 
@@ -1442,20 +1446,20 @@ js_TraceOpcode(JSContext *cx)
     JS_ASSERT(tracefp);
     fp = cx->fp;
     regs = cx->regs;
 
     /*
      * Operations in prologues don't produce interesting values, and
      * js_DecompileValueGenerator isn't set up to handle them anyway.
      */
-    if (cx->tracePrevPc && regs->pc >= fp->script->main) {
+    if (cx->tracePrevPc && regs->pc >= fp->getScript()->main) {
         JSOp tracePrevOp = JSOp(*cx->tracePrevPc);
         ndefs = js_GetStackDefs(cx, &js_CodeSpec[tracePrevOp], tracePrevOp,
-                                fp->script, cx->tracePrevPc);
+                                fp->getScript(), cx->tracePrevPc);
 
         /*
          * If there aren't that many elements on the stack, then we have
          * probably entered a new frame, and printing output would just be
          * misleading.
          */
         if (ndefs != 0 &&
             ndefs < regs->sp - fp->slots()) {
@@ -1482,19 +1486,20 @@ js_TraceOpcode(JSContext *cx)
                 js_FileEscapedString(tracefp, str, 0);
             }
             fputc(' ', tracefp);
         }
         fputc('\n', tracefp);
     }
 
     fprintf(tracefp, "%4u: ",
-            js_PCToLineNumber(cx, fp->script, fp->hasIMacroPC() ? fp->getIMacroPC() : regs->pc));
-    js_Disassemble1(cx, fp->script, regs->pc,
-                    regs->pc - fp->script->code,
+            js_PCToLineNumber(cx, fp->getScript(),
+                              fp->hasIMacroPC() ? fp->getIMacroPC() : regs->pc));
+    js_Disassemble1(cx, fp->getScript(), regs->pc,
+                    regs->pc - fp->getScript()->code,
                     JS_FALSE, tracefp);
     op = (JSOp) *regs->pc;
     nuses = js_GetStackUses(&js_CodeSpec[op], op, regs->pc);
     if (nuses != 0) {
         for (n = -nuses; n < 0; n++) {
             char *bytes = DecompileValueGenerator(cx, n, regs->sp[n], NULL);
             if (bytes) {
                 fprintf(tracefp, "%s %s",
@@ -1825,16 +1830,17 @@ namespace reprmeter {
 #define PUSH_BOOLEAN(b)          regs.sp++->setBoolean(b)
 #define PUSH_DOUBLE(d)           regs.sp++->setDouble(d)
 #define PUSH_INT32(i)            regs.sp++->setInt32(i)
 #define PUSH_STRING(s)           regs.sp++->setString(s)
 #define PUSH_OBJECT(obj)         regs.sp++->setObject(obj)
 #define PUSH_OBJECT_OR_NULL(obj) regs.sp++->setObjectOrNull(obj)
 #define PUSH_HOLE()              regs.sp++->setMagic(JS_ARRAY_HOLE)
 #define POP_COPY_TO(v)           v = *--regs.sp
+#define POP_RETURN_VALUE()       fp->setReturnValue(*--regs.sp)
 
 #define POP_BOOLEAN(cx, vp, b)                                                \
     JS_BEGIN_MACRO                                                            \
         vp = &regs.sp[-1];                                                    \
         if (vp->isNull()) {                                                   \
             b = false;                                                        \
         } else if (vp->isBoolean()) {                                         \
             b = vp->toBoolean();                                              \
@@ -2245,17 +2251,17 @@ Interpret(JSContext *cx, JSStackFrame *e
 #else
     JS_CHECK_RECURSION(cx, return JS_FALSE);
 #endif
 
     JSRuntime *const rt = cx->runtime;
 
     /* Set registerized frame pointer and derived script pointer. */
     JSStackFrame *fp = cx->fp;
-    JSScript *script = fp->script;
+    JSScript *script = fp->getScript();
     JS_ASSERT(!script->isEmpty());
     JS_ASSERT(script->length > 1);
     JS_ASSERT(fp->thisv.isObjectOrNull());
     JS_ASSERT_IF(!fp->fun, !fp->thisv.isNull());
 
     if (!entryFrame)
         entryFrame = fp;
 
@@ -2312,17 +2318,17 @@ Interpret(JSContext *cx, JSStackFrame *e
 #endif
 #else
 #define MONITOR_BRANCH_TRACEVIS
 #endif
 
 #define RESTORE_INTERP_VARS()                                                 \
     JS_BEGIN_MACRO                                                            \
         fp = cx->fp;                                                          \
-        script = fp->script;                                                  \
+        script = fp->getScript();                                             \
         atoms = FrameAtomBase(cx, fp);                                        \
         currentVersion = (JSVersion) script->version;                         \
         JS_ASSERT(cx->regs == &regs);                                         \
         if (cx->throwing)                                                     \
             goto error;                                                       \
     JS_END_MACRO
 
 #define MONITOR_BRANCH(reason)                                                \
@@ -2544,17 +2550,17 @@ Interpret(JSContext *cx, JSStackFrame *e
             Value rval;
             switch (hook(cx, script, regs.pc, Jsvalify(&rval),
                          cx->debugHooks->interruptHookData)) {
               case JSTRAP_ERROR:
                 goto error;
               case JSTRAP_CONTINUE:
                 break;
               case JSTRAP_RETURN:
-                fp->rval = rval;
+                fp->setReturnValue(rval);
                 interpReturnOK = JS_TRUE;
                 goto forced_return;
               case JSTRAP_THROW:
                 cx->throwing = JS_TRUE;
                 cx->exception = rval;
                 goto error;
               default:;
             }
@@ -2661,17 +2667,17 @@ BEGIN_CASE(JSOP_POPN)
     }
 #endif
 }
 END_CASE(JSOP_POPN)
 
 BEGIN_CASE(JSOP_SETRVAL)
 BEGIN_CASE(JSOP_POPV)
     ASSERT_NOT_THROWING(cx);
-    POP_COPY_TO(fp->rval);
+    POP_RETURN_VALUE();
 END_CASE(JSOP_POPV)
 
 BEGIN_CASE(JSOP_ENTERWITH)
     if (!js_EnterWith(cx, -1))
         goto error;
 
     /*
      * We must ensure that different "with" blocks have different stack depth
@@ -2687,20 +2693,20 @@ END_CASE(JSOP_ENTERWITH)
 
 BEGIN_CASE(JSOP_LEAVEWITH)
     JS_ASSERT(&regs.sp[-1].toObject() == fp->getScopeChain());
     regs.sp--;
     js_LeaveWith(cx);
 END_CASE(JSOP_LEAVEWITH)
 
 BEGIN_CASE(JSOP_RETURN)
-    POP_COPY_TO(fp->rval);
+    POP_RETURN_VALUE();
     /* FALL THROUGH */
 
-BEGIN_CASE(JSOP_RETRVAL)    /* fp->rval already set */
+BEGIN_CASE(JSOP_RETRVAL)    /* fp return value already set */
 BEGIN_CASE(JSOP_STOP)
 {
     /*
      * When the inlined frame exits with an exception or an error, ok will be
      * false after the inline_return label.
      */
     ASSERT_NOT_THROWING(cx);
     CHECK_BRANCH();
@@ -2729,19 +2735,19 @@ BEGIN_CASE(JSOP_STOP)
                      !(fp->flags & JSFRAME_RECORDING));
         atoms = script->atomMap.vector;
         op = JSOp(*regs.pc);
         DO_OP();
     }
 #endif
 
     JS_ASSERT(regs.sp == fp->base());
-    if ((fp->flags & JSFRAME_CONSTRUCTING) && fp->rval.isPrimitive()) {
-        JS_ASSERT(!fp->thisv.isPrimitive());
-        fp->rval = fp->thisv;
+    if ((fp->flags & JSFRAME_CONSTRUCTING) && fp->getReturnValue().isPrimitive()) {
+        JS_ASSERT(!fp->getThisValue().isPrimitive());
+        fp->setReturnValue(fp->getThisValue());
     }
 
     interpReturnOK = true;
     if (entryFrame != fp)
   inline_return:
     {
         JS_ASSERT(!fp->hasBlockChain());
         JS_ASSERT(!js_IsActiveWithOrBlock(cx, fp->getScopeChain(), 0));
@@ -2755,50 +2761,50 @@ BEGIN_CASE(JSOP_STOP)
         /*
          * If fp has a call object, sync values and clear the back-
          * pointer. This can happen for a lightweight function if it calls eval
          * unexpectedly (in a way that is hidden from the compiler). See bug
          * 325540.
          */
         fp->putActivationObjects(cx);
 
-        DTrace::exitJSFun(cx, fp, fp->fun, fp->rval);
+        DTrace::exitJSFun(cx, fp, fp->getFunction(), fp->getReturnValue());
 
         /* Restore context version only if callee hasn't set version. */
         if (JS_LIKELY(cx->version == currentVersion)) {
             currentVersion = fp->getCallerVersion();
             if (currentVersion != cx->version)
                 js_SetVersion(cx, currentVersion);
         }
 
         /*
          * If inline-constructing, replace primitive rval with the new object
          * passed in via |this|, and instrument this constructor invocation.
          */
         if (fp->flags & JSFRAME_CONSTRUCTING) {
-            if (fp->rval.isPrimitive()) {
-                JS_ASSERT(!fp->thisv.isPrimitive());
-                fp->rval = fp->thisv;
+            if (fp->getReturnValue().isPrimitive()) {
+                JS_ASSERT(!fp->getThisValue().isPrimitive());
+                fp->setReturnValue(fp->getThisValue());
             }
             JS_RUNTIME_METER(cx->runtime, constructs);
         }
 
         JSStackFrame *down = fp->down;
         Value *newsp = fp->argv - 1;
 
         /* Pop the frame. */
         cx->stack().popInlineFrame(cx, fp, down);
 
         /* Propagate return value before fp is lost. */
         regs.sp = newsp;
-        regs.sp[-1] = fp->rval;
+        regs.sp[-1] = fp->getReturnValue();
 
         /* Sync interpreter registers. */
         fp = cx->fp;
-        script = fp->script;
+        script = fp->getScript();
         atoms = FrameAtomBase(cx, fp);
 
         /* Resume execution in the calling frame. */
         JS_ASSERT(inlineCallCount);
         inlineCallCount--;
         if (JS_LIKELY(interpReturnOK)) {
             JS_ASSERT(js_CodeSpec[js_GetOpcode(cx, script, regs.pc)].length
                       == JSOP_CALL_LENGTH);
@@ -3041,28 +3047,28 @@ BEGIN_CASE(JSOP_ENDITER)
         goto error;
 }
 END_CASE(JSOP_ENDITER)
 
 BEGIN_CASE(JSOP_FORARG)
 {
     JS_ASSERT(regs.sp - 1 >= fp->base());
     uintN slot = GET_ARGNO(regs.pc);
-    JS_ASSERT(slot < fp->fun->nargs);
+    JS_ASSERT(slot < fp->getArgumentCount());
     JS_ASSERT(regs.sp[-1].isObject());
     if (!IteratorNext(cx, &regs.sp[-1].toObject(), &fp->argv[slot]))
         goto error;
 }
 END_CASE(JSOP_FORARG)
 
 BEGIN_CASE(JSOP_FORLOCAL)
 {
     JS_ASSERT(regs.sp - 1 >= fp->base());
     uintN slot = GET_SLOTNO(regs.pc);
-    JS_ASSERT(slot < fp->script->nslots);
+    JS_ASSERT(slot < fp->getSlotCount());
     JS_ASSERT(regs.sp[-1].isObject());
     if (!IteratorNext(cx, &regs.sp[-1].toObject(), &fp->slots()[slot]))
         goto error;
 }
 END_CASE(JSOP_FORLOCAL)
 
 BEGIN_CASE(JSOP_FORNAME)
 {
@@ -3974,17 +3980,17 @@ BEGIN_CASE(JSOP_ARGDEC)
 BEGIN_CASE(JSOP_INCARG)
     incr =  1; incr2 =  1; goto do_arg_incop;
 BEGIN_CASE(JSOP_ARGINC)
     incr =  1; incr2 =  0;
 
   do_arg_incop:
     // If we initialize in the declaration, MSVC complains that the labels skip init.
     slot = GET_ARGNO(regs.pc);
-    JS_ASSERT(slot < fp->fun->nargs);
+    JS_ASSERT(slot < fp->getArgumentCount());
     METER_SLOT_OP(op, slot);
     vp = fp->argv + slot;
     goto do_int_fast_incop;
 
 BEGIN_CASE(JSOP_DECLOCAL)
     incr = -1; incr2 = -1; goto do_local_incop;
 BEGIN_CASE(JSOP_LOCALDEC)
     incr = -1; incr2 =  0; goto do_local_incop;
@@ -3995,17 +4001,17 @@ BEGIN_CASE(JSOP_LOCALINC)
 
   /*
    * do_local_incop comes right before do_int_fast_incop as we want to
    * avoid an extra jump for variable cases as local++ is more frequent
    * than arg++.
    */
   do_local_incop:
     slot = GET_SLOTNO(regs.pc);
-    JS_ASSERT(slot < fp->script->nslots);
+    JS_ASSERT(slot < fp->getSlotCount());
     vp = fp->slots() + slot;
     METER_SLOT_OP(op, slot);
     vp = fp->slots() + slot;
 
   do_int_fast_incop:
     int32_t tmp;
     if (JS_LIKELY(vp->isInt32() && CanIncDecWithoutOverflow(tmp = vp->toInt32()))) {
         vp->getInt32Ref() = tmp + incr;
@@ -4020,17 +4026,17 @@ BEGIN_CASE(JSOP_LOCALINC)
     len = JSOP_INCARG_LENGTH;
     JS_ASSERT(len == js_CodeSpec[op].length);
     DO_NEXT_OP(len);
 }
 
 BEGIN_CASE(JSOP_THIS)
     if (!fp->getThisObject(cx))
         goto error;
-    PUSH_COPY(fp->thisv);
+    PUSH_COPY(fp->getThisValue());
 END_CASE(JSOP_THIS)
 
 BEGIN_CASE(JSOP_UNBRANDTHIS)
 {
     JSObject *obj = fp->getThisObject(cx);
     if (!obj)
         goto error;
     if (!obj->unbrand(cx))
@@ -4050,17 +4056,17 @@ BEGIN_CASE(JSOP_GETTHISPROP)
     i = 0;
     PUSH_NULL();
     goto do_getprop_with_obj;
 
 BEGIN_CASE(JSOP_GETARGPROP)
 {
     i = ARGNO_LEN;
     uint32 slot = GET_ARGNO(regs.pc);
-    JS_ASSERT(slot < fp->fun->nargs);
+    JS_ASSERT(slot < fp->getArgumentCount());
     PUSH_COPY(fp->argv[slot]);
     goto do_getprop_body;
 }
 
 BEGIN_CASE(JSOP_GETLOCALPROP)
 {
     i = SLOTNO_LEN;
     uint32 slot = GET_SLOTNO(regs.pc);
@@ -4717,28 +4723,28 @@ BEGIN_CASE(JSOP_APPLY)
                 newfp = stack.getInlineFrame(cx, regs.sp, 0, nfixed);
                 if (!newfp)
                     goto error;
             }
 
             /* Initialize stack frame. */
             newfp->setCallObj(NULL);
             newfp->setArgsObj(NULL);
-            newfp->script = newscript;
-            newfp->fun = fun;
+            newfp->setScript(newscript);
+            newfp->setFunction(fun);
             newfp->argc = argc;
             newfp->argv = vp + 2;
-            newfp->rval.setUndefined();
+            newfp->clearReturnValue();
             newfp->setAnnotation(NULL);
             newfp->setScopeChain(obj->getParent());
             newfp->flags = flags;
             newfp->setBlockChain(NULL);
             JS_ASSERT(!JSFUN_BOUND_METHOD_TEST(fun->flags));
             JS_ASSERT_IF(!vp[1].isPrimitive(), IsSaneThisObject(vp[1].toObject()));
-            newfp->thisv = vp[1];
+            newfp->setThisValue(vp[1]);
             JS_ASSERT(!newfp->hasIMacroPC());
 
             /* Push void to initialize local variables. */
             Value *newsp = newfp->base();
             SetValueRangeToUndefined(newfp->slots(), newsp);
 
             /* Switch version if currentVersion wasn't overridden. */
             newfp->setCallerVersion((JSVersion) cx->version);
@@ -5219,17 +5225,17 @@ END_VARLEN_CASE
 BEGIN_CASE(JSOP_TRAP)
 {
     Value rval;
     JSTrapStatus status = JS_HandleTrap(cx, script, regs.pc, Jsvalify(&rval));
     switch (status) {
       case JSTRAP_ERROR:
         goto error;
       case JSTRAP_RETURN:
-        fp->rval = rval;
+        fp->setReturnValue(rval);
         interpReturnOK = JS_TRUE;
         goto forced_return;
       case JSTRAP_THROW:
         cx->throwing = JS_TRUE;
         cx->exception = rval;
         goto error;
       default:
         break;
@@ -5270,28 +5276,28 @@ BEGIN_CASE(JSOP_ARGCNT)
     PUSH_COPY(rval);
 }
 END_CASE(JSOP_ARGCNT)
 
 BEGIN_CASE(JSOP_GETARG)
 BEGIN_CASE(JSOP_CALLARG)
 {
     uint32 slot = GET_ARGNO(regs.pc);
-    JS_ASSERT(slot < fp->fun->nargs);
+    JS_ASSERT(slot < fp->getArgumentCount());
     METER_SLOT_OP(op, slot);
     PUSH_COPY(fp->argv[slot]);
     if (op == JSOP_CALLARG)
         PUSH_NULL();
 }
 END_CASE(JSOP_GETARG)
 
 BEGIN_CASE(JSOP_SETARG)
 {
     uint32 slot = GET_ARGNO(regs.pc);
-    JS_ASSERT(slot < fp->fun->nargs);
+    JS_ASSERT(slot < fp->getArgumentCount());
     METER_SLOT_OP(op, slot);
     fp->argv[slot] = regs.sp[-1];
 }
 END_SET_CASE(JSOP_SETARG)
 
 BEGIN_CASE(JSOP_GETLOCAL)
 {
     uint32 slot = GET_SLOTNO(regs.pc);
@@ -5331,17 +5337,17 @@ BEGIN_CASE(JSOP_CALLUPVAR)
     if (op == JSOP_CALLUPVAR)
         PUSH_NULL();
 }
 END_CASE(JSOP_GETUPVAR)
 
 BEGIN_CASE(JSOP_GETUPVAR_DBG)
 BEGIN_CASE(JSOP_CALLUPVAR_DBG)
 {
-    JSFunction *fun = fp->fun;
+    JSFunction *fun = fp->getFunction();
     JS_ASSERT(FUN_KIND(fun) == JSFUN_INTERPRETED);
     JS_ASSERT(fun->u.i.wrapper);
 
     /* Scope for tempPool mark and local names allocation in it. */
     JSObject *obj, *obj2;
     JSProperty *prop;
     jsid id;
     JSAtom *atom;
@@ -6213,17 +6219,17 @@ BEGIN_CASE(JSOP_INITELEM)
 }
 END_CASE(JSOP_INITELEM)
 
 #if JS_HAS_SHARP_VARS
 
 BEGIN_CASE(JSOP_DEFSHARP)
 {
     uint32 slot = GET_UINT16(regs.pc);
-    JS_ASSERT(slot + 1 < fp->script->nfixed);
+    JS_ASSERT(slot + 1 < fp->getFixedCount());
     const Value &lref = fp->slots()[slot];
     JSObject *obj;
     if (lref.isObject()) {
         obj = &lref.toObject();
     } else {
         JS_ASSERT(lref.isUndefined());
         obj = js_NewArrayObject(cx, 0, NULL);
         if (!obj)
@@ -6243,17 +6249,17 @@ BEGIN_CASE(JSOP_DEFSHARP)
     if (!obj->defineProperty(cx, id, rref, NULL, NULL, JSPROP_ENUMERATE))
         goto error;
 }
 END_CASE(JSOP_DEFSHARP)
 
 BEGIN_CASE(JSOP_USESHARP)
 {
     uint32 slot = GET_UINT16(regs.pc);
-    JS_ASSERT(slot + 1 < fp->script->nfixed);
+    JS_ASSERT(slot + 1 < fp->getFixedCount());
     const Value &lref = fp->slots()[slot];
     jsint i = (jsint) GET_UINT16(regs.pc + UINT16_LEN);
     Value rval;
     if (lref.isUndefined()) {
         rval.setUndefined();
     } else {
         JSObject *obj = &fp->slots()[slot].toObject();
         jsid id = INT_TO_JSID(i);
@@ -6270,17 +6276,17 @@ BEGIN_CASE(JSOP_USESHARP)
     }
     PUSH_COPY(rval);
 }
 END_CASE(JSOP_USESHARP)
 
 BEGIN_CASE(JSOP_SHARPINIT)
 {
     uint32 slot = GET_UINT16(regs.pc);
-    JS_ASSERT(slot + 1 < fp->script->nfixed);
+    JS_ASSERT(slot + 1 < fp->getFixedCount());
     Value *vp = &fp->slots()[slot];
     Value rval = vp[1];
 
     /*
      * We peek ahead safely here because empty initialisers get zero
      * JSOP_SHARPINIT ops, and non-empty ones get two: the first comes
      * immediately after JSOP_NEWINIT followed by one or more property
      * initialisers; and the second comes directly before JSOP_ENDINIT.
@@ -6432,17 +6438,17 @@ BEGIN_CASE(JSOP_DEBUGGER)
     if (handler) {
         Value rval;
         switch (handler(cx, script, regs.pc, Jsvalify(&rval), cx->debugHooks->debuggerHandlerData)) {
         case JSTRAP_ERROR:
             goto error;
         case JSTRAP_CONTINUE:
             break;
         case JSTRAP_RETURN:
-            fp->rval = rval;
+            fp->setReturnValue(rval);
             interpReturnOK = JS_TRUE;
             goto forced_return;
         case JSTRAP_THROW:
             cx->throwing = JS_TRUE;
             cx->exception = rval;
             goto error;
         default:;
         }
@@ -6822,31 +6828,31 @@ END_CASE(JSOP_LEAVEBLOCK)
 BEGIN_CASE(JSOP_GENERATOR)
 {
     ASSERT_NOT_THROWING(cx);
     regs.pc += JSOP_GENERATOR_LENGTH;
     JSObject *obj = js_NewGenerator(cx);
     if (!obj)
         goto error;
     JS_ASSERT(!fp->hasCallObj() && !fp->hasArgsObj());
-    fp->rval.setObject(*obj);
+    fp->setReturnValue(ObjectValue(*obj));
     interpReturnOK = true;
     if (entryFrame != fp)
         goto inline_return;
     goto exit;
 }
 
 BEGIN_CASE(JSOP_YIELD)
     ASSERT_NOT_THROWING(cx);
     if (cx->generatorFor(fp)->state == JSGEN_CLOSING) {
         js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD,
                             JSDVG_SEARCH_STACK, fp->argv[-2], NULL);
         goto error;
     }
-    fp->rval = regs.sp[-1];
+    fp->setReturnValue(regs.sp[-1]);
     fp->flags |= JSFRAME_YIELDING;
     regs.pc += JSOP_YIELD_LENGTH;
     interpReturnOK = JS_TRUE;
     goto exit;
 
 BEGIN_CASE(JSOP_ARRAYPUSH)
 {
     uint32 slot = GET_UINT16(regs.pc);
@@ -6965,17 +6971,17 @@ END_CASE(JSOP_ARRAYPUSH)
             Value rval;
             switch (handler(cx, script, regs.pc, Jsvalify(&rval),
                             cx->debugHooks->throwHookData)) {
               case JSTRAP_ERROR:
                 cx->throwing = JS_FALSE;
                 goto error;
               case JSTRAP_RETURN:
                 cx->throwing = JS_FALSE;
-                fp->rval = rval;
+                fp->setReturnValue(rval);
                 interpReturnOK = JS_TRUE;
                 goto forced_return;
               case JSTRAP_THROW:
                 cx->exception = rval;
               case JSTRAP_CONTINUE:
               default:;
             }
             CHECK_INTERRUPT_HANDLER();
@@ -7030,17 +7036,17 @@ END_CASE(JSOP_ARRAYPUSH)
                  * Restart the handler search with updated pc and stack depth
                  * to properly notify the debugger.
                  */
                 goto error;
             }
 
             switch (tn->kind) {
               case JSTRY_CATCH:
-                JS_ASSERT(js_GetOpcode(cx, fp->script, regs.pc) == JSOP_ENTERBLOCK);
+                JS_ASSERT(js_GetOpcode(cx, fp->getScript(), regs.pc) == JSOP_ENTERBLOCK);
 
 #if JS_HAS_GENERATORS
                 /* Catch cannot intercept the closing of a generator. */
                 if (JS_UNLIKELY(cx->exception.isMagic(JS_GENERATOR_CLOSING)))
                     break;
 #endif
 
                 /*
@@ -7059,17 +7065,17 @@ END_CASE(JSOP_ARRAYPUSH)
                 PUSH_BOOLEAN(true);
                 PUSH_COPY(cx->exception);
                 cx->throwing = JS_FALSE;
                 len = 0;
                 DO_NEXT_OP(len);
 
               case JSTRY_ITER: {
                 /* This is similar to JSOP_ENDITER in the interpreter loop. */
-                JS_ASSERT(js_GetOpcode(cx, fp->script, regs.pc) == JSOP_ENDITER);
+                JS_ASSERT(js_GetOpcode(cx, fp->getScript(), regs.pc) == JSOP_ENDITER);
                 AutoValueRooter tvr(cx, cx->exception);
                 cx->throwing = false;
                 ok = js_CloseIterator(cx, &regs.sp[-1].toObject());
                 regs.sp -= 1;
                 if (!ok)
                     goto error;
                 cx->throwing = true;
                 cx->exception = tvr.value();
@@ -7083,17 +7089,17 @@ END_CASE(JSOP_ARRAYPUSH)
          * is an asynchronous return from a generator.
          */
         interpReturnOK = JS_FALSE;
 #if JS_HAS_GENERATORS
         if (JS_UNLIKELY(cx->throwing &&
                         cx->exception.isMagic(JS_GENERATOR_CLOSING))) {
             cx->throwing = JS_FALSE;
             interpReturnOK = JS_TRUE;
-            fp->rval.setUndefined();
+            fp->clearReturnValue();
         }
 #endif
     }
 
   forced_return:
     /*
      * Unwind the scope making sure that interpReturnOK stays false even when
      * js_UnwindScope returns true.
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -146,17 +146,17 @@ struct JSStackFrame
         return (js::Value *)this;
     }
 
     js::Value *slots() const {
         return (js::Value *)(this + 1);
     }
 
     js::Value *base() const {
-        return slots() + script->nfixed;
+        return slots() + getScript()->nfixed;
     }
 
     /* Call object accessors */
 
     bool hasCallObj() const {
         return callobj != NULL;
     }
 
@@ -282,16 +282,43 @@ struct JSStackFrame
     JSObject* maybeBlockChain() const {
         return blockChain;
     }
 
     void setBlockChain(JSObject *obj) {
         blockChain = obj;
     }
 
+    /* IMacroPC accessors. */
+
+    bool hasIMacroPC() const { return flags & JSFRAME_IN_IMACRO; }
+
+    /*
+     * @pre     hasIMacroPC
+     * @return  The PC at which an imacro started executing (guaranteed non-null. The PC of the
+     *          executing imacro must be in regs.pc, so the displaced
+     *          original value is stored here.
+     */
+    jsbytecode *getIMacroPC() const {
+        JS_ASSERT(flags & JSFRAME_IN_IMACRO);
+        return imacpc;
+    }
+
+    /* @return  The imacro pc if hasIMacroPC; otherwise, NULL. */
+    jsbytecode *maybeIMacroPC() const { return hasIMacroPC() ? getIMacroPC() : NULL; }
+
+    void clearIMacroPC() { flags &= ~JSFRAME_IN_IMACRO; }
+
+    void setIMacroPC(jsbytecode *newIMacPC) {
+        JS_ASSERT(newIMacPC);
+        JS_ASSERT(!(flags & JSFRAME_IN_IMACRO));
+        imacpc = newIMacPC;
+        flags |= JSFRAME_IN_IMACRO;
+    }
+
     /* Annotation accessors */
 
     bool hasAnnotation() const {
         return annotation != NULL;
     }
 
     void* getAnnotation() const {
         JS_ASSERT(hasAnnotation());
@@ -330,41 +357,100 @@ struct JSStackFrame
     JSVersion getCallerVersion() const {
         return callerVersion;
     }
 
     void setCallerVersion(JSVersion version) {
         callerVersion = version;
     }
 
-    /* IMacroPC accessors. */
+    /* Script accessors */
+
+    bool hasScript() const {
+        return script != NULL;
+    }
 
-    bool hasIMacroPC() const { return flags & JSFRAME_IN_IMACRO; }
+    JSScript* getScript() const {
+        JS_ASSERT(hasScript());
+        return script;
+    }
+
+    JSScript* maybeScript() const {
+        return script;
+    }
+
+    size_t getFixedCount() const {
+        return getScript()->nfixed;
+    }
 
-    /*
-     * @pre     hasIMacroPC
-     * @return  The PC at which an imacro started executing (guaranteed non-null. The PC of the
-     *          executing imacro must be in regs.pc, so the displaced
-     *          original value is stored here.
-     */
-    jsbytecode *getIMacroPC() const {
-        JS_ASSERT(flags & JSFRAME_IN_IMACRO);
-        return imacpc;
+    size_t getSlotCount() const {
+        return getScript()->nslots;
+    }
+
+    void setScript(JSScript *s) {
+        script = s;
+    }
+
+    static size_t offsetScript() {
+        return offsetof(JSStackFrame, script);
+    }
+
+    /* Function accessors */
+
+    bool hasFunction() const {
+        return fun != NULL;
+    }
+
+    JSFunction* getFunction() const {
+        JS_ASSERT(hasFunction());
+        return fun;
     }
 
-    /* @return  The imacro pc if hasIMacroPC; otherwise, NULL. */
-    jsbytecode *maybeIMacroPC() const { return hasIMacroPC() ? getIMacroPC() : NULL; }
+    JSFunction* maybeFunction() const {
+        return fun;
+    }
+
+    size_t getArgumentCount() const {
+        return getFunction()->nargs;
+    }
 
-    void clearIMacroPC() { flags &= ~JSFRAME_IN_IMACRO; }
+    void setFunction(JSFunction *f) {
+        fun = f;
+    }
+
+    /* This-value accessors */
+
+    const js::Value& getThisValue() {
+        return thisv;
+    }
 
-    void setIMacroPC(jsbytecode *newIMacPC) {
-        JS_ASSERT(newIMacPC);
-        JS_ASSERT(!(flags & JSFRAME_IN_IMACRO));
-        imacpc = newIMacPC;
-        flags |= JSFRAME_IN_IMACRO;
+    void setThisValue(const js::Value &v) {
+        thisv = v;
+    }
+
+    /* Return-value accessors */
+
+    const js::Value& getReturnValue() {
+        return rval;
+    }
+
+    void setReturnValue(const js::Value &v) {
+        rval = v;
+    }
+
+    void clearReturnValue() {
+        rval.setUndefined();
+    }
+
+    js::Value* addressReturnValue() {
+        return &rval;
+    }
+
+    static size_t offsetReturnValue() {
+        return offsetof(JSStackFrame, rval);
     }
 
     /* Other accessors */
 
     void putActivationObjects(JSContext *cx) {
         /*
          * The order of calls here is important as js_PutCallObject needs to
          * access argsobj.
@@ -422,33 +508,40 @@ struct JSStackFrame
         JS_ASSERT_IF(flags & JSFRAME_FLOATING_GENERATOR, isGenerator());
         return !!(flags & JSFRAME_FLOATING_GENERATOR);
     }
 
     bool isDummyFrame() const { return !!(flags & JSFRAME_DUMMY); }
 
   private:
     JSObject *computeThisObject(JSContext *cx);
+	
+    /* Contains static assertions for member alignment, don't call. */
+    inline void staticAsserts();
 };
 
 namespace js {
 
 JS_STATIC_ASSERT(sizeof(JSStackFrame) % sizeof(Value) == 0);
 static const size_t VALUES_PER_STACK_FRAME = sizeof(JSStackFrame) / sizeof(Value);
 
-JS_STATIC_ASSERT(offsetof(JSStackFrame, rval) % sizeof(Value) == 0);
-JS_STATIC_ASSERT(offsetof(JSStackFrame, thisv) % sizeof(Value) == 0);
+} /* namespace js */
 
-} /* namespace js */
+inline void
+JSStackFrame::staticAsserts()
+{
+    JS_STATIC_ASSERT(offsetof(JSStackFrame, rval) % sizeof(js::Value) == 0);
+    JS_STATIC_ASSERT(offsetof(JSStackFrame, thisv) % sizeof(js::Value) == 0);
+}
 
 static JS_INLINE uintN
 GlobalVarCount(JSStackFrame *fp)
 {
-    JS_ASSERT(!fp->fun);
-    return fp->script->nfixed;
+    JS_ASSERT(!fp->hasFunction());
+    return fp->getScript()->nfixed;
 }
 
 /*
  * Refresh and return fp->scopeChain.  It may be stale if block scopes are
  * active but not yet reflected by objects in the scope chain.  If a block
  * scope contains a with, eval, XML filtering predicate, or similar such
  * dynamically scoped construct, then compile-time block scope at fp->blocks
  * must reflect at runtime.
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -1137,72 +1137,72 @@ js_NewGenerator(JSContext *cx)
 {
     JSObject *obj = NewBuiltinClassInstance(cx, &js_GeneratorClass);
     if (!obj)
         return NULL;
 
     /* Load and compute stack slot counts. */
     JSStackFrame *fp = cx->fp;
     uintN argc = fp->argc;
-    uintN nargs = JS_MAX(argc, fp->fun->nargs);
+    uintN nargs = JS_MAX(argc, fp->getArgumentCount());
     uintN vplen = 2 + nargs;
 
     /* Compute JSGenerator size. */
     uintN nbytes = sizeof(JSGenerator) +
                    (-1 + /* one Value included in JSGenerator */
                     vplen +
                     VALUES_PER_STACK_FRAME +
-                    fp->script->nslots) * sizeof(Value);
+                    fp->getSlotCount()) * sizeof(Value);
 
     JSGenerator *gen = (JSGenerator *) cx->malloc(nbytes);
     if (!gen)
         return NULL;
 
     /* Cut up floatingStack space. */
     Value *vp = gen->floatingStack;
     JSStackFrame *newfp = reinterpret_cast<JSStackFrame *>(vp + vplen);
     Value *slots = newfp->slots();
 
     /* Initialize JSGenerator. */
     gen->obj = obj;
     gen->state = JSGEN_NEWBORN;
     gen->savedRegs.pc = cx->regs->pc;
-    JS_ASSERT(cx->regs->sp == fp->slots() + fp->script->nfixed);
-    gen->savedRegs.sp = slots + fp->script->nfixed;
+    JS_ASSERT(cx->regs->sp == fp->slots() + fp->getFixedCount());
+    gen->savedRegs.sp = slots + fp->getFixedCount();
     gen->vplen = vplen;
     gen->enumerators = NULL;
     gen->liveFrame = newfp;
 
     /* Copy generator's stack frame copy in from |cx->fp|. */
     newfp->setCallObj(fp->maybeCallObj());
     if (fp->hasCallObj()) {      /* Steal call object. */
         fp->getCallObj()->setPrivate(newfp);
         fp->setCallObj(NULL);
     }
     newfp->setArgsObj(fp->maybeArgsObj());
     if (fp->hasArgsObj()) {      /* Steal args object. */
         fp->getArgsObj()->setPrivate(newfp);
         fp->setArgsObj(NULL);
     }
-    newfp->script = fp->script;
-    newfp->fun = fp->fun;
-    newfp->thisv = fp->thisv;
+    newfp->setScript(fp->getScript());
+    newfp->setFunction(fp->getFunction());
+    newfp->setThisValue(fp->getThisValue());
     newfp->argc = fp->argc;
     newfp->argv = vp + 2;
-    newfp->rval = fp->rval;
+    newfp->setReturnValue(fp->getReturnValue());
     newfp->setAnnotation(NULL);
     newfp->setScopeChain(fp->maybeScopeChain());
     JS_ASSERT(!fp->hasBlockChain());
     newfp->setBlockChain(NULL);
     newfp->flags = fp->flags | JSFRAME_GENERATOR | JSFRAME_FLOATING_GENERATOR;
     JS_ASSERT(!newfp->hasIMacroPC());
 
     /* Copy in arguments and slots. */
     memcpy(vp, fp->argv - 2, vplen * sizeof(Value));
-    memcpy(slots, fp->slots(), fp->script->nfixed * sizeof(Value));
+    memcpy(slots, fp->slots(), fp->getFixedCount() * sizeof(Value));
 
     obj->setPrivate(gen);
     return obj;
 }
 
 JSGenerator *
 js_FloatingFrameToGenerator(JSStackFrame *fp)
 {
@@ -1225,17 +1225,17 @@ typedef enum JSGeneratorOp {
  */
 static JS_REQUIRES_STACK JSBool
 SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj,
                 JSGenerator *gen, const Value &arg)
 {
     if (gen->state == JSGEN_RUNNING || gen->state == JSGEN_CLOSING) {
         js_ReportValueError(cx, JSMSG_NESTING_GENERATOR,
                             JSDVG_SEARCH_STACK, ObjectOrNullValue(obj),
-                            JS_GetFunctionId(gen->getFloatingFrame()->fun));
+                            JS_GetFunctionId(gen->getFloatingFrame()->getFunction()));
         return JS_FALSE;
     }
 
     /* Check for OOM errors here, where we can fail easily. */
     if (!cx->ensureGeneratorStackSpace())
         return JS_FALSE;
 
     JS_ASSERT(gen->state ==  JSGEN_NEWBORN || gen->state == JSGEN_OPEN);
@@ -1264,17 +1264,17 @@ SendToGenerator(JSContext *cx, JSGenerat
         break;
     }
 
     JSStackFrame *genfp = gen->getFloatingFrame();
     JSBool ok;
     {
         Value *genVp = gen->floatingStack;
         uintN vplen = gen->vplen;
-        uintN nfixed = genfp->script->nslots;
+        uintN nfixed = genfp->getSlotCount();
 
         /*
          * Get a pointer to new frame/slots. This memory is not "claimed", so
          * the code before pushExecuteFrame must not reenter the interpreter.
          */
         ExecuteFrameGuard frame;
         if (!cx->stack().getExecuteFrame(cx, cx->fp, vplen, nfixed, frame)) {
             gen->state = JSGEN_CLOSED;
@@ -1288,17 +1288,17 @@ SendToGenerator(JSContext *cx, JSGenerat
          * Copy and rebase stack frame/args/slots. The "floating" flag must
          * only be set on the generator's frame. See args_or_call_trace.
          */
         uintN usedBefore = gen->savedRegs.sp - genVp;
         memcpy(vp, genVp, usedBefore * sizeof(Value));
         fp->flags &= ~JSFRAME_FLOATING_GENERATOR;
         fp->argv = vp + 2;
         gen->savedRegs.sp = fp->slots() + (gen->savedRegs.sp - genfp->slots());
-        JS_ASSERT(uintN(gen->savedRegs.sp - fp->slots()) <= fp->script->nslots);
+        JS_ASSERT(uintN(gen->savedRegs.sp - fp->slots()) <= fp->getSlotCount());
 
 #ifdef DEBUG
         JSObject *callobjBefore = fp->maybeCallObj();
         JSObject *argsobjBefore = fp->maybeArgsObj();
 #endif
 
         /*
          * Repoint Call, Arguments, Block and With objects to the new live
@@ -1333,37 +1333,37 @@ SendToGenerator(JSContext *cx, JSGenerat
             fp->getArgsObj()->setPrivate(genfp);
         if (fp->hasCallObj())
             fp->getCallObj()->setPrivate(genfp);
 
         JS_ASSERT_IF(argsobjBefore, argsobjBefore == fp->maybeArgsObj());
         JS_ASSERT_IF(callobjBefore, callobjBefore == fp->maybeCallObj());
 
         /* Copy and rebase stack frame/args/slots. Restore "floating" flag. */
-        JS_ASSERT(uintN(gen->savedRegs.sp - fp->slots()) <= fp->script->nslots);
+        JS_ASSERT(uintN(gen->savedRegs.sp - fp->slots()) <= fp->getSlotCount());
         uintN usedAfter = gen->savedRegs.sp - vp;
         memcpy(genVp, vp, usedAfter * sizeof(Value));
         genfp->flags |= JSFRAME_FLOATING_GENERATOR;
         genfp->argv = genVp + 2;
         gen->savedRegs.sp = genfp->slots() + (gen->savedRegs.sp - fp->slots());
-        JS_ASSERT(uintN(gen->savedRegs.sp - genfp->slots()) <= genfp->script->nslots);
+        JS_ASSERT(uintN(gen->savedRegs.sp - genfp->slots()) <= genfp->getSlotCount());
     }
 
     if (gen->getFloatingFrame()->flags & JSFRAME_YIELDING) {
         /* Yield cannot fail, throw or be called on closing. */
         JS_ASSERT(ok);
         JS_ASSERT(!cx->throwing);
         JS_ASSERT(gen->state == JSGEN_RUNNING);
         JS_ASSERT(op != JSGENOP_CLOSE);
         genfp->flags &= ~JSFRAME_YIELDING;
         gen->state = JSGEN_OPEN;
         return JS_TRUE;
     }
 
-    genfp->rval.setUndefined();
+    genfp->clearReturnValue();
     gen->state = JSGEN_CLOSED;
     if (ok) {
         /* Returned, explicitly or by falling off the end. */
         if (op == JSGENOP_CLOSE)
             return JS_TRUE;
         return js_ThrowStopIteration(cx);
     }
 
@@ -1442,17 +1442,17 @@ generator_op(JSContext *cx, JSGeneratorO
             JS_ASSERT(op == JSGENOP_CLOSE);
             return JS_TRUE;
         }
     }
 
     bool undef = ((op == JSGENOP_SEND || op == JSGENOP_THROW) && argc != 0);
     if (!SendToGenerator(cx, op, obj, gen, undef ? vp[2] : UndefinedValue()))
         return JS_FALSE;
-    *vp = gen->getFloatingFrame()->rval;
+    *vp = gen->getFloatingFrame()->getReturnValue();
     return JS_TRUE;
 }
 
 static JSBool
 generator_send(JSContext *cx, uintN argc, Value *vp)
 {
     return generator_op(cx, JSGENOP_SEND, vp, argc);
 }
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -946,32 +946,32 @@ js_ComputeFilename(JSContext *cx, JSStac
                    JSPrincipals *principals, uintN *linenop)
 {
     uint32 flags;
 #ifdef DEBUG
     JSSecurityCallbacks *callbacks = JS_GetSecurityCallbacks(cx);
 #endif
 
     JS_ASSERT(principals || !(callbacks  && callbacks->findObjectPrincipals));
-    flags = JS_GetScriptFilenameFlags(caller->script);
+    flags = JS_GetScriptFilenameFlags(caller->getScript());
     if ((flags & JSFILENAME_PROTECTED) &&
         principals &&
         strcmp(principals->codebase, "[System Principal]")) {
         *linenop = 0;
         return principals->codebase;
     }
 
     jsbytecode *pc = caller->pc(cx);
-    if (pc && js_GetOpcode(cx, caller->script, pc) == JSOP_EVAL) {
-        JS_ASSERT(js_GetOpcode(cx, caller->script, pc + JSOP_EVAL_LENGTH) == JSOP_LINENO);
+    if (pc && js_GetOpcode(cx, caller->getScript(), pc) == JSOP_EVAL) {
+        JS_ASSERT(js_GetOpcode(cx, caller->getScript(), pc + JSOP_EVAL_LENGTH) == JSOP_LINENO);
         *linenop = GET_UINT16(pc + JSOP_EVAL_LENGTH);
     } else {
         *linenop = js_FramePCToLineNumber(cx, caller);
     }
-    return caller->script->filename;
+    return caller->getScript()->filename;
 }
 
 #ifndef EVAL_CACHE_CHAIN_LIMIT
 # define EVAL_CACHE_CHAIN_LIMIT 4
 #endif
 
 static inline JSScript **
 EvalCacheHash(JSContext *cx, JSString *str)
@@ -1048,28 +1048,28 @@ obj_eval(JSContext *cx, uintN argc, Valu
         return JS_TRUE;
     }
 
     /*
      * We once supported a second argument to eval to use as the scope chain
      * when evaluating the code string.  Warn when such uses are seen so that
      * authors will know that support for eval(s, o) has been removed.
      */
-    if (argc > 1 && !caller->script->warnedAboutTwoArgumentEval) {
+    if (argc > 1 && !caller->getScript()->warnedAboutTwoArgumentEval) {
         static const char TWO_ARGUMENT_WARNING[] =
             "Support for eval(code, scopeObject) has been removed. "
             "Use |with (scopeObject) eval(code);| instead.";
         if (!JS_ReportWarning(cx, TWO_ARGUMENT_WARNING))
             return JS_FALSE;
-        caller->script->warnedAboutTwoArgumentEval = true;
+        caller->getScript()->warnedAboutTwoArgumentEval = true;
     }
 
     /* From here on, control must exit through label out with ok set. */
     MUST_FLOW_THROUGH("out");
-    uintN staticLevel = caller->script->staticLevel + 1;
+    uintN staticLevel = caller->getScript()->staticLevel + 1;
 
     /*
      * Bring fp->scopeChain up to date. We're either going to use
      * it (direct call) or save it and restore it (indirect call).
      */
     JSObject *callerScopeChain = js_GetScopeChain(cx, caller);
     if (!callerScopeChain)
         return JS_FALSE;
@@ -1136,17 +1136,17 @@ obj_eval(JSContext *cx, uintN argc, Valu
      *
      * An eval cache entry should never be considered a hit unless its
      * strictness matches that of the new eval code. The existing code takes
      * care of this, because hits are qualified by the function from which
      * eval was called, whose strictness doesn't change. Scripts produced by
      * calls to eval from global code are not cached.
      */
     JSScript **bucket = EvalCacheHash(cx, str);
-    if (!indirectCall && caller->fun) {
+    if (!indirectCall && caller->hasFunction()) {
         uintN count = 0;
         JSScript **scriptp = bucket;
 
         EVAL_CACHE_METER(probe);
         while ((script = *scriptp) != NULL) {
             if (script->savedCallerFun &&
                 script->staticLevel == staticLevel &&
                 script->version == cx->version &&
@@ -1154,17 +1154,17 @@ obj_eval(JSContext *cx, uintN argc, Valu
                  (principals->subsume(principals, script->principals) &&
                   script->principals->subsume(script->principals, principals)))) {
                 /*
                  * Get the prior (cache-filling) eval's saved caller function.
                  * See Compiler::compileScript in jsparse.cpp.
                  */
                 JSFunction *fun = script->getFunction(0);
 
-                if (fun == caller->fun) {
+                if (fun == caller->getFunction()) {
                     /*
                      * Get the source string passed for safekeeping in the
                      * atom map by the prior eval to Compiler::compileScript.
                      */
                     JSString *src = ATOM_TO_STRING(script->atomMap.vector[0]);
 
                     if (src == str || js_EqualStrings(src, str)) {
                         /*
@@ -2689,17 +2689,17 @@ JS_DEFINE_CALLINFO_3(extern, CONSTRUCTOR
 JS_REQUIRES_STACK JSBool
 Detecting(JSContext *cx, jsbytecode *pc)
 {
     JSScript *script;
     jsbytecode *endpc;
     JSOp op;
     JSAtom *atom;
 
-    script = cx->fp->script;
+    script = cx->fp->getScript();
     endpc = script->code + script->length;
     for (;; pc += js_CodeSpec[op].length) {
         JS_ASSERT_IF(!cx->fp->hasIMacroPC(), script->code <= pc && pc < endpc);
 
         /* General case: a branch or equality op follows the access. */
         op = js_GetOpcode(cx, script, pc);
         if (js_CodeSpec[op].format & JOF_DETECTING)
             return JS_TRUE;
@@ -2763,26 +2763,26 @@ js_InferFlags(JSContext *cx, uintN defau
     jsbytecode *pc;
     const JSCodeSpec *cs;
     uint32 format;
     uintN flags = 0;
 
     JSStackFrame *const fp = js_GetTopStackFrame(cx);
     if (!fp || !(pc = cx->regs->pc))
         return defaultFlags;
-    cs = &js_CodeSpec[js_GetOpcode(cx, fp->script, pc)];
+    cs = &js_CodeSpec[js_GetOpcode(cx, fp->getScript(), pc)];
     format = cs->format;
     if (JOF_MODE(format) != JOF_NAME)
         flags |= JSRESOLVE_QUALIFIED;
     if ((format & (JOF_SET | JOF_FOR)) ||
         (fp->flags & JSFRAME_ASSIGNING)) {
         flags |= JSRESOLVE_ASSIGNING;
     } else if (cs->length >= 0) {
         pc += cs->length;
-        if (pc < cx->fp->script->code + cx->fp->script->length && Detecting(cx, pc))
+        if (pc < cx->fp->getScript()->code + cx->fp->getScript()->length && Detecting(cx, pc))
             flags |= JSRESOLVE_DETECTING;
     }
     if (format & JOF_DECLARING)
         flags |= JSRESOLVE_DECLARING;
     return flags;
 }
 
 /*
@@ -2974,17 +2974,17 @@ js_PutBlockObject(JSContext *cx, JSBool 
     /* The block and its locals must be on the current stack for GC safety. */
     uintN depth = OBJ_BLOCK_DEPTH(cx, obj);
     JS_ASSERT(depth <= (size_t) (cx->regs->sp - fp->base()));
     JS_ASSERT(count <= (size_t) (cx->regs->sp - fp->base() - depth));
 
     /* See comments in CheckDestructuring from jsparse.cpp. */
     JS_ASSERT(count >= 1);
 
-    depth += fp->script->nfixed;
+    depth += fp->getFixedCount();
     obj->fslots[JSSLOT_BLOCK_DEPTH + 1] = fp->slots()[depth];
     if (normalUnwind && count > 1) {
         --count;
         memcpy(obj->dslots, fp->slots() + depth + 1, count * sizeof(Value));
     }
 
     /* We must clear the private slot even with errors. */
     obj->setPrivate(NULL);
@@ -3003,18 +3003,18 @@ block_getProperty(JSContext *cx, JSObjec
     JS_ASSERT(obj->getClass() == &js_BlockClass);
     JS_ASSERT(OBJ_IS_CLONED_BLOCK(obj));
     uintN index = (uintN) JSID_TO_INT(id);
     JS_ASSERT(index < OBJ_BLOCK_COUNT(cx, obj));
 
     JSStackFrame *fp = (JSStackFrame *) obj->getPrivate();
     if (fp) {
         fp = js_LiveFrameIfGenerator(fp);
-        index += fp->script->nfixed + OBJ_BLOCK_DEPTH(cx, obj);
-        JS_ASSERT(index < fp->script->nslots);
+        index += fp->getFixedCount() + OBJ_BLOCK_DEPTH(cx, obj);
+        JS_ASSERT(index < fp->getSlotCount());
         *vp = fp->slots()[index];
         return true;
     }
 
     /* Values are in reserved slots immediately following DEPTH. */
     uint32 slot = JSSLOT_BLOCK_DEPTH + 1 + index;
     JS_LOCK_OBJ(cx, obj);
     JS_ASSERT(slot < obj->numSlots());
@@ -3029,18 +3029,18 @@ block_setProperty(JSContext *cx, JSObjec
     JS_ASSERT(obj->getClass() == &js_BlockClass);
     JS_ASSERT(OBJ_IS_CLONED_BLOCK(obj));
     uintN index = (uintN) JSID_TO_INT(id);
     JS_ASSERT(index < OBJ_BLOCK_COUNT(cx, obj));
 
     JSStackFrame *fp = (JSStackFrame *) obj->getPrivate();
     if (fp) {
         fp = js_LiveFrameIfGenerator(fp);
-        index += fp->script->nfixed + OBJ_BLOCK_DEPTH(cx, obj);
-        JS_ASSERT(index < fp->script->nslots);
+        index += fp->getFixedCount() + OBJ_BLOCK_DEPTH(cx, obj);
+        JS_ASSERT(index < fp->getSlotCount());
         fp->slots()[index] = *vp;
         return true;
     }
 
     /* Values are in reserved slots immediately following DEPTH. */
     uint32 slot = JSSLOT_BLOCK_DEPTH + 1 + index;
     JS_LOCK_OBJ(cx, obj);
     JS_ASSERT(slot < obj->numSlots());
@@ -4772,17 +4772,17 @@ js_GetPropertyHelper(JSContext *cx, JSOb
         jsbytecode *pc;
         if (vp->isUndefined() && ((pc = js_GetCurrentBytecodePC(cx)) != NULL)) {
             JSOp op;
             uintN flags;
 
             op = (JSOp) *pc;
             if (op == JSOP_TRAP) {
                 JS_ASSERT_NOT_ON_TRACE(cx);
-                op = JS_GetTrapOpcode(cx, cx->fp->script, pc);
+                op = JS_GetTrapOpcode(cx, cx->fp->getScript(), pc);
             }
             if (op == JSOP_GETXPROP) {
                 flags = JSREPORT_ERROR;
             } else {
                 if (!JS_HAS_STRICT_OPTION(cx) ||
                     (op != JSOP_GETPROP && op != JSOP_GETELEM) ||
                     js_CurrentPCIsInImacro(cx)) {
                     return JS_TRUE;
@@ -4864,17 +4864,17 @@ js_GetMethod(JSContext *cx, JSObject *ob
 JS_FRIEND_API(bool)
 js_CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname)
 {
     JSStackFrame *const fp = js_GetTopStackFrame(cx);
     if (!fp)
         return true;
 
     /* If neither cx nor the code is strict, then no check is needed. */
-    if (!(fp->script && fp->script->strictModeCode) &&
+    if (!(fp->hasScript() && fp->getScript()->strictModeCode) &&
         !JS_HAS_STRICT_OPTION(cx)) {
         return true;
     }
 
     const char *bytes = js_GetStringBytes(cx, propname);
     return bytes &&
            JS_ReportErrorFlagsAndNumber(cx,
                                         (JSREPORT_WARNING | JSREPORT_STRICT
@@ -5261,18 +5261,18 @@ js_DeleteProperty(JSContext *cx, JSObjec
             JSObject *funobj;
 
             if (IsFunctionObject(v, &funobj)) {
                 JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
 
                 if (fun != funobj) {
                     for (JSStackFrame *fp = cx->fp; fp; fp = fp->down) {
                         if (fp->callee() == fun &&
-                            fp->thisv.isObject() &&
-                            &fp->thisv.toObject() == obj) {
+                            fp->getThisValue().isObject() &&
+                            &fp->getThisValue().toObject() == obj) {
                             fp->setCalleeObject(*funobj);
                         }
                     }
                 }
             }
         }
     }
 
@@ -6366,21 +6366,23 @@ js_DumpStackFrame(JSContext *cx, JSStack
         if (fp->argv) {
             fprintf(stderr, "callee: ");
             dumpValue(fp->argv[-2]);
         } else {
             fprintf(stderr, "global frame, no callee");
         }
         fputc('\n', stderr);
 
-        if (fp->script)
-            fprintf(stderr, "file %s line %u\n", fp->script->filename, (unsigned) fp->script->lineno);
+        if (fp->hasScript()) {
+            fprintf(stderr, "file %s line %u\n",
+                    fp->getScript()->filename, (unsigned) fp->getScript()->lineno);
+        }
 
         if (jsbytecode *pc = i.pc()) {
-            if (!fp->script) {
+            if (!fp->hasScript()) {
                 fprintf(stderr, "*** pc && !script, skipping frame\n\n");
                 continue;
             }
             if (fp->hasIMacroPC()) {
                 fprintf(stderr, "  pc in imacro at %p\n  called from ", pc);
                 pc = fp->getIMacroPC();
             } else {
                 fprintf(stderr, "  ");
@@ -6396,19 +6398,19 @@ js_DumpStackFrame(JSContext *cx, JSStack
                 fprintf(stderr, "    %p: ", (void *) p);
                 dumpValue(*p);
                 fputc('\n', stderr);
             }
         }
         fprintf(stderr, "  argv:  %p (argc: %u)\n", (void *) fp->argv, (unsigned) fp->argc);
         MaybeDumpObject("callobj", fp->maybeCallObj());
         MaybeDumpObject("argsobj", fp->maybeArgsObj());
-        MaybeDumpValue("this", fp->thisv);
+        MaybeDumpValue("this", fp->getThisValue());
         fprintf(stderr, "  rval: ");
-        dumpValue(fp->rval);
+        dumpValue(fp->getReturnValue());
         fputc('\n', stderr);
 
         fprintf(stderr, "  flags:");
         if (fp->flags == 0)
             fprintf(stderr, " none");
         if (fp->flags & JSFRAME_CONSTRUCTING)
             fprintf(stderr, " constructing");
         if (fp->flags & JSFRAME_ASSIGNING)
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -274,17 +274,17 @@ JS_FRIEND_API(JSBool)
 js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp)
 {
     return js_DisassembleAtPC(cx, script, lines, fp, NULL);
 }
 
 JS_FRIEND_API(JSBool)
 js_DumpPC(JSContext *cx)
 {
-    return js_DisassembleAtPC(cx, cx->fp->script, true, stdout, cx->regs->pc);
+    return js_DisassembleAtPC(cx, cx->fp->getScript(), true, stdout, cx->regs->pc);
 }
 
 JSBool
 js_DumpScript(JSContext *cx, JSScript *script)
 {
     return js_Disassemble(cx, script, true, stdout);
 }
 
@@ -2878,18 +2878,18 @@ Decompile(SprintStack *ss, jsbytecode *p
                      * pushed a frame trying to call Construct on an
                      * object that's not a constructor, causing us to be
                      * called with an intervening frame on the stack.
                      */
                     JSStackFrame *fp = js_GetTopStackFrame(cx);
                     if (fp) {
                         while (!(fp->flags & JSFRAME_EVAL))
                             fp = fp->down;
-                        JS_ASSERT(fp->script == jp->script);
-                        JS_ASSERT(fp->down->fun == jp->fun);
+                        JS_ASSERT(fp->getScript() == jp->script);
+                        JS_ASSERT(fp->down->getFunction() == jp->fun);
                         JS_ASSERT(FUN_INTERPRETED(jp->fun));
                         JS_ASSERT(jp->script != jp->fun->u.i.script);
                         JS_ASSERT(jp->script->upvarsOffset != 0);
                     }
 #endif
                     uva = jp->script->upvars();
                     index = uva->vector[index].slot();
                 }
@@ -5112,24 +5112,24 @@ js_DecompileValueGenerator(JSContext *cx
     JS_ASSERT(spindex < 0 ||
               spindex == JSDVG_IGNORE_STACK ||
               spindex == JSDVG_SEARCH_STACK);
 
     LeaveTrace(cx);
     
     /* Get scripted caller */
     FrameRegsIter i(cx);
-    while (!i.done() && !i.fp()->script)
+    while (!i.done() && !i.fp()->hasScript())
         ++i;
 
-    if (i.done() || !i.pc() || i.fp()->script->nslots == 0)
+    if (i.done() || !i.pc() || i.fp()->getSlotCount() == 0)
         goto do_fallback;
 
     fp = i.fp();
-    script = fp->script;
+    script = fp->getScript();
     pc = fp->hasIMacroPC() ? fp->getIMacroPC() : i.pc();
     JS_ASSERT(pc >= script->main && pc < script->code + script->length);
 
     if (spindex != JSDVG_IGNORE_STACK) {
         jsbytecode **pcstack;
 
         /*
          * Prepare computing pcstack containing pointers to opcodes that
@@ -5200,17 +5200,17 @@ js_DecompileValueGenerator(JSContext *cx
         /*
          * FIXME: bug 489843. Stack reconstruction may have returned a pc
          * value *inside* an imacro; this would confuse the decompiler.
          */
         char *name;
         if (savedIMacroPC && size_t(pc - script->code) >= script->length)
             name = FAILED_EXPRESSION_DECOMPILER;
         else
-            name = DecompileExpression(cx, script, fp->fun, pc);
+            name = DecompileExpression(cx, script, fp->maybeFunction(), pc);
 
         if (savedIMacroPC) {
             if (fp == cx->fp)
                 cx->regs->pc = savedIMacroPC;
             else
                 fp->savedPC = savepc;
             fp->setIMacroPC(savedIMacroPC);
         }
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -787,18 +787,18 @@ Compiler::compileScript(JSContext *cx, J
     cg.flags |= tcflags;
     cg.scopeChain = scopeChain;
     compiler.globalScope = &globalScope;
     if (!SetStaticLevel(&cg, staticLevel))
         goto out;
 
     /* If this is a direct call to eval, inherit the caller's strictness.  */
     if (callerFrame &&
-        callerFrame->script &&
-        callerFrame->script->strictModeCode) {
+        callerFrame->hasScript() &&
+        callerFrame->getScript()->strictModeCode) {
         cg.flags |= TCF_STRICT_MODE_CODE;
         tokenStream.setStrictMode();
     }
 
     /*
      * If funbox is non-null after we create the new script, callerFrame->fun
      * was saved in the 0th object table entry.
      */
@@ -811,23 +811,23 @@ Compiler::compileScript(JSContext *cx, J
              * Save eval program source in script->atomMap.vector[0] for the
              * eval cache (see obj_eval in jsobj.cpp).
              */
             JSAtom *atom = js_AtomizeString(cx, source, 0);
             if (!atom || !cg.atomList.add(&parser, atom))
                 goto out;
         }
 
-        if (callerFrame && callerFrame->fun) {
+        if (callerFrame && callerFrame->hasFunction()) {
             /*
              * An eval script in a caller frame needs to have its enclosing
              * function captured in case it refers to an upvar, and someone
              * wishes to decompile it while it's running.
              */
-            funbox = parser.newObjectBox(FUN_OBJECT(callerFrame->fun));
+            funbox = parser.newObjectBox(FUN_OBJECT(callerFrame->getFunction()));
             if (!funbox)
                 goto out;
             funbox->emitLink = cg.objectList.lastbox;
             cg.objectList.lastbox = funbox;
             cg.objectList.length++;
         }
     }
 
--- a/js/src/jsparse.h
+++ b/js/src/jsparse.h
@@ -962,17 +962,17 @@ struct Parser : private js::AutoGCRooter
       : js::AutoGCRooter(cx, PARSER), context(cx),
         aleFreeList(NULL), tokenStream(cx), principals(NULL), callerFrame(cfp),
         callerVarObj(cfp ? cfp->varobj(cx->containingSegment(cfp)) : NULL),
         nodeList(NULL), functionCount(0), traceListHead(NULL), tc(NULL),
         keepAtoms(cx->runtime)
     {
         js::PodArrayZero(tempFreeList);
         setPrincipals(prin);
-        JS_ASSERT_IF(cfp, cfp->script);
+        JS_ASSERT_IF(cfp, cfp->hasScript());
     }
 
     ~Parser();
 
     friend void js::AutoGCRooter::trace(JSTracer *trc);
     friend struct ::JSTreeContext;
     friend struct Compiler;
 
--- a/js/src/jspropertycache.cpp
+++ b/js/src/jspropertycache.cpp
@@ -123,17 +123,17 @@ PropertyCache::fill(JSContext *cx, JSObj
         return JS_NO_PROP_CACHE_FILL;
     }
 
     /*
      * Optimize the cached vword based on our parameters and the current pc's
      * opcode format flags.
      */
     pc = cx->regs->pc;
-    op = js_GetOpcode(cx, cx->fp->script, pc);
+    op = js_GetOpcode(cx, cx->fp->getScript(), pc);
     cs = &js_CodeSpec[op];
     kshape = 0;
 
     do {
         /*
          * Check for a prototype "plain old method" callee computation. What
          * is a plain old method? It's a function-valued property with stub
          * getter, so get of a function is idempotent.
@@ -317,32 +317,33 @@ GetAtomFromBytecode(JSContext *cx, jsbyt
 
     // The method JIT's implementation of instanceof contains an internal lookup
     // of the prototype property.
     if (op == JSOP_INSTANCEOF)
         return cx->runtime->atomState.classPrototypeAtom;
 
     ptrdiff_t pcoff = (JOF_TYPE(cs.format) == JOF_SLOTATOM) ? SLOTNO_LEN : 0;
     JSAtom *atom;
-    GET_ATOM_FROM_BYTECODE(cx->fp->script, pc, pcoff, atom);
+    GET_ATOM_FROM_BYTECODE(cx->fp->getScript(), pc, pcoff, atom);
     return atom;
 }
 
 JS_REQUIRES_STACK JSAtom *
 PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject **pobjp,
                         PropertyCacheEntry *entry)
 {
     JSObject *obj, *pobj, *tmp;
     uint32 vcap;
 
     JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
-    JS_ASSERT(uintN((cx->fp->hasIMacroPC() ? cx->fp->getIMacroPC() : pc) - cx->fp->script->code)
-              < cx->fp->script->length);
+    JS_ASSERT(
+        uintN((cx->fp->hasIMacroPC() ? cx->fp->getIMacroPC() : pc) - cx->fp->getScript()->code)
+        < cx->fp->getScript()->length);
 
-    JSOp op = js_GetOpcode(cx, cx->fp->script, pc);
+    JSOp op = js_GetOpcode(cx, cx->fp->getScript(), pc);
     const JSCodeSpec &cs = js_CodeSpec[op];
 
     obj = *objp;
     vcap = entry->vcap;
 
     if (entry->kpc != pc) {
         PCMETER(kpcmisses++);
 
--- a/js/src/jsrecursion.cpp
+++ b/js/src/jsrecursion.cpp
@@ -208,17 +208,17 @@ DownFrameSP(JSContext *cx)
     JS_ASSERT(i.fp() == cx->fp->down);
     return i.sp();
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::upRecursion()
 {
     JS_ASSERT((JSOp)*cx->fp->down->savedPC == JSOP_CALL);
-    JS_ASSERT(js_CodeSpec[js_GetOpcode(cx, cx->fp->down->script,
+    JS_ASSERT(js_CodeSpec[js_GetOpcode(cx, cx->fp->down->getScript(),
               cx->fp->down->savedPC)].length == JSOP_CALL_LENGTH);
 
     JS_ASSERT(callDepth == 0);
 
     /*
      * If some operation involving interpreter frame slurping failed, go to
      * that code right away, and don't bother with emitting the up-recursive
      * guards again.
@@ -385,17 +385,17 @@ public:
  * SLURP_FAIL means that the interpreter frame has been popped, the return
  * value has been written to the native stack, but there was a type mismatch
  * while unboxing the interpreter slots.
  */
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
 {
     /* Missing - no go */
-    if (cx->fp->argc != cx->fp->fun->nargs)
+    if (cx->fp->argc != cx->fp->getArgumentCount())
         RETURN_STOP_A("argc != nargs");
 
     LIns* argv_ins;
     unsigned frameDepth;
     unsigned downPostSlots;
 
     FrameRegsIter i(cx);
     LIns* fp_ins =
@@ -427,19 +427,19 @@ TraceRecorder::slurpDownFrames(jsbytecod
              * Guard on the script being the same. This might seem unnecessary,
              * but it lets the recursive loop end cleanly if it doesn't match.
              * With only the pc check, it is harder to differentiate between
              * end-of-recursion and recursion-returns-to-different-pc.
              */
             guard(true,
                   lir->ins2(LIR_eqp,
                             addName(lir->insLoad(LIR_ldp, fp_ins,
-                                                 offsetof(JSStackFrame, script), ACCSET_OTHER),
+                                                 JSStackFrame::offsetScript(), ACCSET_OTHER),
                                     "script"),
-                            INS_CONSTPTR(cx->fp->down->script)),
+                            INS_CONSTPTR(cx->fp->down->getScript())),
                   RECURSIVE_LOOP_EXIT);
         }
 
         /* fp->down->savedPC should be == pc. */
         guard(true,
               lir->ins2(LIR_eqp,
                         addName(lir->insLoad(LIR_ldp, fp_ins, offsetof(JSStackFrame, savedPC),  
                                              ACCSET_OTHER),
@@ -586,40 +586,40 @@ TraceRecorder::slurpDownFrames(jsbytecod
 
     JSStackFrame *const fp = i.fp();
 
     /* callee */
     slurpSlot(argv_ins, -2 * ptrdiff_t(sizeof(Value)), &fp->argv[-2], &info);
     /* this */
     slurpSlot(argv_ins, -1 * ptrdiff_t(sizeof(Value)), &fp->argv[-1], &info);
     /* args[0..n] */
-    for (unsigned i = 0; i < JS_MAX(fp->argc, fp->fun->nargs); i++)
+    for (unsigned i = 0; i < JS_MAX(fp->argc, fp->getArgumentCount()); i++)
         slurpSlot(argv_ins, i * sizeof(Value), &fp->argv[i], &info);
     /* argsobj */
     slurpFrameObjPtrSlot(fp_ins, JSStackFrame::offsetArgsObj(), fp->addressArgsObj(), &info);
     /* scopeChain */
     slurpFrameObjPtrSlot(fp_ins, JSStackFrame::offsetScopeChain(), fp->addressScopeChain(), &info);
     /* vars */
     LIns* slots_ins = addName(lir->ins2(LIR_addp, fp_ins, INS_CONSTWORD(sizeof(JSStackFrame))),
                               "slots");
-    for (unsigned i = 0; i < fp->script->nfixed; i++)
+    for (unsigned i = 0; i < fp->getFixedCount(); i++)
         slurpSlot(slots_ins, i * sizeof(Value), &fp->slots()[i], &info);
     /* stack vals */
-    unsigned nfixed = fp->script->nfixed;
+    unsigned nfixed = fp->getFixedCount();
     Value* stack = fp->base();
     LIns* stack_ins = addName(lir->ins2(LIR_addp,
                                         slots_ins,
                                         INS_CONSTWORD(nfixed * sizeof(Value))),
                               "stackBase");
 
     size_t limit = size_t(i.sp() - fp->base());
     if (anchor && anchor->exitType == RECURSIVE_SLURP_FAIL_EXIT)
         limit--;
     else
-        limit -= fp->fun->nargs + 2;
+        limit -= fp->getArgumentCount() + 2;
     for (size_t i = 0; i < limit; i++)
         slurpSlot(stack_ins, i * sizeof(Value), &stack[i], &info);
 
     JS_ASSERT(info.curSlot == downPostSlots);
 
     /* Jump back to the start */
     exit = copy(exit);
     exit->exitType = UNSTABLE_LOOP_EXIT;
@@ -668,24 +668,25 @@ public:
         return visitStackSlots((Value *)p, 1, fp);
     }
 };
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::downRecursion()
 {
     JSStackFrame* fp = cx->fp;
-    if ((jsbytecode*)fragment->ip < fp->script->code ||
-        (jsbytecode*)fragment->ip >= fp->script->code + fp->script->length) {
+    JSScript *script = fp->getScript();
+    if ((jsbytecode*)fragment->ip < script->code ||
+        (jsbytecode*)fragment->ip >= script->code + script->length) {
         RETURN_STOP_A("inner recursive call must compile first");
     }
 
     /* Adjust the stack by the budget the down-frame needs. */
     int slots = NativeStackSlots(cx, 1) - NativeStackSlots(cx, 0);
-    JS_ASSERT(unsigned(slots) == NativeStackSlots(cx, 1) - fp->argc - 2 - fp->script->nfixed - 2);
+    JS_ASSERT(unsigned(slots) == NativeStackSlots(cx, 1) - fp->argc - 2 - fp->getFixedCount() - 2);
 
     /* Guard that there is enough stack space. */
     JS_ASSERT(tree->maxNativeStackSlots >= tree->nativeStackBase / sizeof(double));
     int guardSlots = slots + tree->maxNativeStackSlots -
                      tree->nativeStackBase / sizeof(double);
     LIns* sp_top = lir->ins2(LIR_addp, lirbuf->sp, lir->insImmWord(guardSlots * sizeof(double)));
     guard(true, lir->ins2(LIR_ltp, sp_top, eos_ins), OOM_EXIT);
 
@@ -717,21 +718,21 @@ TraceRecorder::downRecursion()
      * recursive loop. Otherwise something special happened. For example, a
      * recursive call that is unwinding could nest back down recursively again.
      * In this case, we build a fragment that ideally we'll never invoke
      * directly, but link from a down-recursive branch. The UNLINKED_EXIT tells
      * closeLoop() that the peer trees should match the recursive pc, not the
      * tree pc.
      */
     VMSideExit* exit;
-    if ((jsbytecode*)fragment->root->ip == fp->script->code)
+    if ((jsbytecode*)fragment->root->ip == script->code)
         exit = snapshot(UNSTABLE_LOOP_EXIT);
     else
         exit = snapshot(RECURSIVE_UNLINKED_EXIT);
-    exit->recursive_pc = fp->script->code;
+    exit->recursive_pc = script->code;
     debug_only_print0(LC_TMTracer, "Compiling down-recursive function call.\n");
     JS_ASSERT(tree->recursion != Recursion_Disallowed);
     tree->recursion = Recursion_Detected;
     return closeLoop(exit);
 }
 
 #if JS_BITS_PER_WORD == 32
 JS_REQUIRES_STACK inline LIns*
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1396,17 +1396,18 @@ js_GetSrcNoteCached(JSContext *cx, JSScr
     }
 
     return result;
 }
 
 uintN
 js_FramePCToLineNumber(JSContext *cx, JSStackFrame *fp)
 {
-    return js_PCToLineNumber(cx, fp->script, fp->hasIMacroPC() ? fp->getIMacroPC() : fp->pc(cx));
+    return js_PCToLineNumber(cx, fp->getScript(),
+                             fp->hasIMacroPC() ? fp->getIMacroPC() : fp->pc(cx));
 }
 
 uintN
 js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
 {
     JSOp op;
     JSFunction *fun;
     uintN lineno;
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -1089,17 +1089,17 @@ Tracker::set(const void* v, LIns* i)
     if (!p)
         p = addTrackerPage(v);
     p->map[getTrackerPageOffset(v)] = i;
 }
 
 static inline jsuint
 argSlots(JSStackFrame* fp)
 {
-    return JS_MAX(fp->argc, fp->fun->nargs);
+    return JS_MAX(fp->argc, fp->getArgumentCount());
 }
 
 static inline bool
 hasInt32Repr(const Value &v)
 {
     if (!v.isNumber())
         return false;
     if (v.isInt32())
@@ -1183,32 +1183,32 @@ HashAccum(uintptr_t& h, uintptr_t i, uin
 {
     h = ((h << 5) + h + (mask & i)) & mask;
 }
 
 static JS_REQUIRES_STACK inline int
 StackSlotHash(JSContext* cx, unsigned slot, const void* pc)
 {
     uintptr_t h = HASH_SEED;
-    HashAccum(h, uintptr_t(cx->fp->script), ORACLE_MASK);
+    HashAccum(h, uintptr_t(cx->fp->getScript()), ORACLE_MASK);
     HashAccum(h, uintptr_t(pc), ORACLE_MASK);
     HashAccum(h, uintptr_t(slot), ORACLE_MASK);
     return int(h);
 }
 
 static JS_REQUIRES_STACK inline int
 GlobalSlotHash(JSContext* cx, unsigned slot)
 {
     uintptr_t h = HASH_SEED;
     JSStackFrame* fp = cx->fp;
 
     while (fp->down)
         fp = fp->down;
 
-    HashAccum(h, uintptr_t(fp->script), ORACLE_MASK);
+    HashAccum(h, uintptr_t(fp->maybeScript()), ORACLE_MASK);
     HashAccum(h, uintptr_t(fp->getScopeChain()->getGlobal()->shape()), ORACLE_MASK);
     HashAccum(h, uintptr_t(slot), ORACLE_MASK);
     return int(h);
 }
 
 static inline int
 PCHash(jsbytecode* pc)
 {
@@ -1530,21 +1530,21 @@ TreeFragment::initialize(JSContext* cx, 
     this->globalSlots = globalSlots;
 
     /* Capture the coerced type of each active slot in the type map. */
     this->typeMap.captureTypes(cx, globalObj, *globalSlots, 0 /* callDepth */, speculate);
     this->nStackTypes = this->typeMap.length() - globalSlots->length();
     this->spOffsetAtEntry = cx->regs->sp - cx->fp->base();
 
 #ifdef DEBUG
-    this->treeFileName = cx->fp->script->filename;
+    this->treeFileName = cx->fp->getScript()->filename;
     this->treeLineNumber = js_FramePCToLineNumber(cx, cx->fp);
     this->treePCOffset = FramePCOffset(cx, cx->fp);
 #endif
-    this->script = cx->fp->script;
+    this->script = cx->fp->getScript();
     this->recursion = Recursion_None;
     this->gcthings.clear();
     this->sprops.clear();
     this->unstableExits = NULL;
     this->sideExits.clear();
 
     /* Determine the native frame layout at the entry point. */
     this->nativeStackBase = (nStackTypes - (cx->regs->sp - cx->fp->base())) *
@@ -1823,27 +1823,27 @@ VisitFrameSlots(Visitor &visitor, JSCont
             return false;
         // We want to import and track |JSObject *scopeChain|, but the tracker
         // requires type |Value|. But the bits are the same, so we can import
         // it with a cast and the (identity function) unboxing will be OK.
         visitor.setStackSlotKind("scopeChain");
         if (!visitor.visitFrameObjPtr(fp->addressScopeChain(), fp))
             return false;
         visitor.setStackSlotKind("var");
-        if (!visitor.visitStackSlots(fp->slots(), fp->script->nfixed, fp))
+        if (!visitor.visitStackSlots(fp->slots(), fp->getFixedCount(), fp))
             return false;
     }
 
     visitor.setStackSlotKind("stack");
     Value *base = fp->base();
-    JS_ASSERT(sp >= base && sp <= fp->slots() + fp->script->nslots);
+    JS_ASSERT(sp >= base && sp <= fp->slots() + fp->getSlotCount());
     if (!visitor.visitStackSlots(base, size_t(sp - base), fp))
         return false;
     if (up) {
-        int missing = up->fun->nargs - up->argc;
+        int missing = up->getArgumentCount() - up->argc;
         if (missing > 0) {
             visitor.setStackSlotKind("missing");
             if (!visitor.visitStackSlots(sp, size_t(missing), fp))
                 return false;
         }
     }
     return true;
 }
@@ -1995,28 +1995,28 @@ NativeStackSlots(JSContext *cx, unsigned
     for (;; ++i) {
         /*
          * Duplicate native stack layout computation: see VisitFrameSlots
          * header comment.
          */
         JSStackFrame *const fp = i.fp();
         slots += i.sp() - fp->base();
         if (fp->argv)
-            slots += fp->script->nfixed + SPECIAL_FRAME_SLOTS;
+            slots += fp->getFixedCount() + SPECIAL_FRAME_SLOTS;
         if (depth-- == 0) {
             if (fp->argv)
                 slots += 2/*callee,this*/ + argSlots(fp);
 #ifdef DEBUG
             CountSlotsVisitor visitor;
             VisitStackSlots(visitor, cx, callDepth);
             JS_ASSERT(visitor.count() == slots && !visitor.stopped());
 #endif
             return slots;
         }
-        int missing = fp->fun->nargs - fp->argc;
+        int missing = fp->getArgumentCount() - fp->argc;
         if (missing > 0)
             slots += missing;
     }
     JS_NOT_REACHED("NativeStackSlots");
 }
 
 class CaptureTypesVisitor : public SlotVisitorBase
 {
@@ -2239,17 +2239,17 @@ TraceRecorder::TraceRecorder(JSContext* 
     lirbuf(new (tempAlloc()) LirBuffer(tempAlloc())),
     mark(*traceMonitor->traceAlloc),
     numSideExitsBefore(tree->sideExits.length()),
     tracker(),
     nativeFrameTracker(),
     global_dslots(NULL),
     callDepth(anchor ? anchor->calldepth : 0),
     atoms(FrameAtomBase(cx, cx->fp)),
-    consts(cx->fp->script->constOffset ? cx->fp->script->consts()->vector : NULL),
+    consts(cx->fp->getScript()->constOffset ? cx->fp->getScript()->consts()->vector : NULL),
     cfgMerges(&tempAlloc()),
     trashSelf(false),
     whichTreesToTrash(&tempAlloc()),
     guardedShapeTable(cx),
     rval_ins(NULL),
     native_rval_ins(NULL),
     newobj_ins(NULL),
     pendingSpecializedNative(NULL),
@@ -2484,17 +2484,17 @@ TraceRecorder::finishAbort(const char* r
 
     AUDIT(recorderAborted);
 #ifdef DEBUG
     debug_only_printf(LC_TMAbort,
                       "Abort recording of tree %s:%d@%d at %s:%d@%d: %s.\n",
                       tree->treeFileName,
                       tree->treeLineNumber,
                       tree->treePCOffset,
-                      cx->fp->script->filename,
+                      cx->fp->getScript()->filename,
                       js_FramePCToLineNumber(cx, cx->fp),
                       FramePCOffset(cx, cx->fp),
                       reason);
 #endif
     Backoff(cx, (jsbytecode*) fragment->root->ip, fragment->root);
 
     /*
      * If this is the primary trace and we didn't succeed compiling, trash the
@@ -2629,17 +2629,17 @@ TraceRecorder::nativeStackOffsetImpl(con
     size_t offset = visitor.count() * sizeof(double);
 
     /*
      * If it's not in a pending frame, it must be on the stack of the current
      * frame above sp but below fp->slots() + script->nslots.
      */
     if (!visitor.stopped()) {
         const Value *vp = (const Value *)p;
-        JS_ASSERT(size_t(vp - cx->fp->slots()) < cx->fp->script->nslots);
+        JS_ASSERT(size_t(vp - cx->fp->slots()) < cx->fp->getSlotCount());
         offset += size_t(vp - cx->regs->sp) * sizeof(double);
     }
     return offset;
 }
 
 JS_REQUIRES_STACK inline ptrdiff_t
 TraceRecorder::nativeStackOffset(const Value* p) const
 {
@@ -3230,23 +3230,23 @@ GetUpvarVarOnTrace(JSContext* cx, uint32
 
 /*
  * For this traits type, 'slot' is an index into the stack area (within slots,
  * after nfixed) of a frame with no function. (On trace, the top-level frame is
  * the only one that can have no function.)
  */
 struct UpvarStackTraits {
     static Value interp_get(JSStackFrame* fp, int32 slot) {
-        return fp->slots()[slot + fp->script->nfixed];
+        return fp->slots()[slot + fp->getFixedCount()];
     }
 
     static uint32 native_slot(uint32 argc, int32 slot) {
         /*
          * Locals are not imported by the tracer when the frame has no
-         * function, so we do not add fp->script->nfixed.
+         * function, so we do not add fp->getFixedCount().
          */
         JS_ASSERT(argc == 0);
         return slot;
     }
 };
 
 uint32 JS_FASTCALL
 GetUpvarStackOnTrace(JSContext* cx, uint32 upvarLevel, int32 slot, uint32 callDepth,
@@ -3453,34 +3453,34 @@ FlushNativeStackFrame(JSContext* cx, uns
         for (; n != 0; fp = fp->down) {
             --n;
             if (fp->argv) {
                 if (fp->hasArgsObj() && fp->getArgsObj()->getPrivate() == JS_ARGUMENT_OBJECT_ON_TRACE)
                     fp->getArgsObj()->setPrivate(fp);
 
                 JS_ASSERT(fp->argv[-1].isObjectOrNull());
                 JS_ASSERT(fp->callee()->isFunction());
-                JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee()) == fp->fun);
-
-                if (FUN_INTERPRETED(fp->fun) &&
-                    (fp->fun->flags & JSFUN_HEAVYWEIGHT)) {
+                JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee()) == fp->getFunction());
+
+                if (FUN_INTERPRETED(fp->getFunction()) &&
+                    (fp->getFunction()->flags & JSFUN_HEAVYWEIGHT)) {
                     // Iff these fields are NULL, then |fp| was synthesized on trace exit, so
                     // we need to update the frame fields.
                     if (!fp->hasCallObj())
                         fp->setCallObj(fp->getScopeChain());
 
                     // Iff scope chain's private is NULL, then |fp->scopeChain| was created
                     // on trace for a call, so we set the private field now. (Call objects
                     // that correspond to returned frames also have a NULL private, but such
                     // a call object would not occur as the |scopeChain| member of a frame,
                     // so we cannot be in that case here.)
                     if (!fp->getScopeChain()->getPrivate())
                         fp->getScopeChain()->setPrivate(fp);
                 }
-                fp->thisv = fp->argv[-1];
+                fp->setThisValue(fp->argv[-1]);
             }
         }
     }
     debug_only_print0(LC_TMTracer, "\n");
     return visitor.getTypeMap() - mp;
 }
 
 /* Emit load instructions onto the trace that read the initial stack state. */
@@ -3522,29 +3522,31 @@ TraceRecorder::importImpl(LIns* base, pt
 #ifdef DEBUG
     char name[64];
     JS_ASSERT(strlen(prefix) < 11);
     void* mark = NULL;
     jsuword* localNames = NULL;
     const char* funName = NULL;
     if (*prefix == 'a' || *prefix == 'v') {
         mark = JS_ARENA_MARK(&cx->tempPool);
-        if (fp->fun->hasLocalNames())
-            localNames = js_GetLocalNameArray(cx, fp->fun, &cx->tempPool);
-        funName = fp->fun->atom ? js_AtomToPrintableString(cx, fp->fun->atom) : "<anonymous>";
+        if (fp->getFunction()->hasLocalNames())
+            localNames = js_GetLocalNameArray(cx, fp->getFunction(), &cx->tempPool);
+        funName = fp->getFunction()->atom
+                ? js_AtomToPrintableString(cx, fp->getFunction()->atom)
+                : "<anonymous>";
     }
     if (!strcmp(prefix, "argv")) {
-        if (index < fp->fun->nargs) {
+        if (index < fp->getArgumentCount()) {
             JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(localNames[index]);
             JS_snprintf(name, sizeof name, "$%s.%s", funName, js_AtomToPrintableString(cx, atom));
         } else {
             JS_snprintf(name, sizeof name, "$%s.<arg%d>", funName, index);
         }
     } else if (!strcmp(prefix, "vars")) {
-        JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(localNames[fp->fun->nargs + index]);
+        JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(localNames[fp->getArgumentCount() + index]);
         JS_snprintf(name, sizeof name, "$%s.%s", funName, js_AtomToPrintableString(cx, atom));
     } else {
         JS_snprintf(name, sizeof name, "$%s%d", prefix, index);
     }
 
     if (mark)
         JS_ARENA_RELEASE(&cx->tempPool, mark);
     addName(ins, name);
@@ -3808,17 +3810,17 @@ TraceRecorder::attemptImport(const Value
 {
     if (LIns* i = getFromTracker(p))
         return i;
 
     /* If the variable was not known, it could require a lazy import. */
     CountSlotsVisitor countVisitor(p);
     VisitStackSlots(countVisitor, cx, callDepth);
 
-    if (countVisitor.stopped() || size_t(p - cx->fp->slots()) < cx->fp->script->nslots)
+    if (countVisitor.stopped() || size_t(p - cx->fp->slots()) < cx->fp->getSlotCount())
         return get(p);
 
     return NULL;
 }
 
 inline nanojit::LIns*
 TraceRecorder::getFromTrackerImpl(const void* p)
 {
@@ -4126,17 +4128,17 @@ public:
 };
 
 #if defined JS_JIT_SPEW
 JS_REQUIRES_STACK static void
 TreevisLogExit(JSContext* cx, VMSideExit* exit)
 {
     debug_only_printf(LC_TMTreeVis, "TREEVIS ADDEXIT EXIT=%p TYPE=%s FRAG=%p PC=%p FILE=\"%s\""
                       " LINE=%d OFFS=%d", (void*)exit, getExitName(exit->exitType),
-                      (void*)exit->from, (void*)cx->regs->pc, cx->fp->script->filename,
+                      (void*)exit->from, (void*)cx->regs->pc, cx->fp->getScript()->filename,
                       js_FramePCToLineNumber(cx, cx->fp), FramePCOffset(cx, cx->fp));
     debug_only_print0(LC_TMTreeVis, " STACK=\"");
     for (unsigned i = 0; i < exit->numStackSlots; i++)
         debug_only_printf(LC_TMTreeVis, "%c", TypeToChar(exit->stackTypeMap()[i]));
     debug_only_print0(LC_TMTreeVis, "\" GLOBALS=\"");
     for (unsigned i = 0; i < exit->numGlobalSlots; i++)
         debug_only_printf(LC_TMTreeVis, "%c", TypeToChar(exit->globalTypeMap()[i]));
     debug_only_print0(LC_TMTreeVis, "\"\n");
@@ -4481,17 +4483,17 @@ TraceRecorder::compile()
     if (anchor && anchor->exitType != CASE_EXIT)
         ++tree->branchCount;
     if (outOfMemory())
         return ARECORD_STOP;
 
     /* :TODO: windows support */
 #if defined DEBUG && !defined WIN32
     /* Associate a filename and line number with the fragment. */
-    const char* filename = cx->fp->script->filename;
+    const char* filename = cx->fp->getScript()->filename;
     char* label = (char*)js_malloc((filename ? strlen(filename) : 7) + 16);
     sprintf(label, "%s:%u", filename ? filename : "<stdin>",
             js_FramePCToLineNumber(cx, cx->fp));
     lirbuf->printer->addrNameMap->addAddrRange(fragment, sizeof(Fragment), 0, label);
     js_free(label);
 #endif
 
     Assembler *assm = traceMonitor->assembler;
@@ -4993,17 +4995,17 @@ TraceRecorder::closeLoop(SlotMap& slotMa
      * If this is a newly formed tree, and the outer tree has not been compiled yet, we
      * should try to compile the outer tree again.
      */
     if (outer)
         AttemptCompilation(cx, globalObj, outer, outerArgc);
 #ifdef JS_JIT_SPEW
     debug_only_printf(LC_TMMinimal,
                       "Recording completed at  %s:%u@%u via closeLoop (FragID=%06u)\n",
-                      cx->fp->script->filename,
+                      cx->fp->getScript()->filename,
                       js_FramePCToLineNumber(cx, cx->fp),
                       FramePCOffset(cx, cx->fp),
                       fragment->profFragID);
     debug_only_print0(LC_TMMinimal, "\n");
 #endif
 
     return finishSuccessfully();
 }
@@ -5167,17 +5169,17 @@ TraceRecorder::endLoop(VMSideExit* exit)
      * If this is a newly formed tree, and the outer tree has not been compiled
      * yet, we should try to compile the outer tree again.
      */
     if (outer)
         AttemptCompilation(cx, globalObj, outer, outerArgc);
 #ifdef JS_JIT_SPEW
     debug_only_printf(LC_TMMinimal,
                       "Recording completed at  %s:%u@%u via endLoop (FragID=%06u)\n",
-                      cx->fp->script->filename,
+                      cx->fp->getScript()->filename,
                       js_FramePCToLineNumber(cx, cx->fp),
                       FramePCOffset(cx, cx->fp),
                       fragment->profFragID);
     debug_only_print0(LC_TMTracer, "\n");
 #endif
 
     return finishSuccessfully();
 }
@@ -5406,17 +5408,17 @@ TraceRecorder::emitTreeCall(TreeFragment
 }
 
 /* Add a if/if-else control-flow merge point to the list of known merge points. */
 JS_REQUIRES_STACK void
 TraceRecorder::trackCfgMerges(jsbytecode* pc)
 {
     /* If we hit the beginning of an if/if-else, then keep track of the merge point after it. */
     JS_ASSERT((*pc == JSOP_IFEQ) || (*pc == JSOP_IFEQX));
-    jssrcnote* sn = js_GetSrcNote(cx->fp->script, pc);
+    jssrcnote* sn = js_GetSrcNote(cx->fp->getScript(), pc);
     if (sn != NULL) {
         if (SN_TYPE(sn) == SRC_IF) {
             cfgMerges.add((*pc == JSOP_IFEQ)
                           ? pc + GET_JUMP_OFFSET(pc)
                           : pc + GET_JUMPX_OFFSET(pc));
         } else if (SN_TYPE(sn) == SRC_IF_ELSE)
             cfgMerges.add(pc + js_GetSrcNoteOffset(sn, 0));
     }
@@ -5655,18 +5657,18 @@ SynthesizeFrame(JSContext* cx, const Fra
     VOUCH_DOES_NOT_REQUIRE_STACK();
 
     JSFunction* fun = GET_FUNCTION_PRIVATE(cx, callee);
     JS_ASSERT(FUN_INTERPRETED(fun));
 
     /* Assert that we have a correct sp distance from cx->fp->slots in fi. */
     JSStackFrame* const fp = cx->fp;
     JS_ASSERT_IF(!fi.imacpc,
-                 js_ReconstructStackDepth(cx, fp->script, fi.pc) ==
-                 uintN(fi.spdist - fp->script->nfixed));
+                 js_ReconstructStackDepth(cx, fp->getScript(), fi.pc) ==
+                 uintN(fi.spdist - fp->getFixedCount()));
 
     /* Simulate js_Interpret locals for when |cx->fp == fp|. */
     JSScript* newscript = fun->u.i.script;
     Value* sp = fp->slots() + fi.spdist;
     uintN argc = fi.get_argc();
     Value* vp = sp - (2 + argc);
 
     /* Fixup |fp| using |fi|. */
@@ -5696,38 +5698,38 @@ SynthesizeFrame(JSContext* cx, const Fra
             v->setUndefined();
     } else {
         newfp = stack.getInlineFrame(cx, sp, 0, nslots);
     }
 
     /* Initialize the new stack frame. */
     newfp->setCallObj(NULL);
     newfp->setArgsObj(NULL);
-    newfp->script = newscript;
-    newfp->fun = fun;
+    newfp->setScript(newscript);
+    newfp->setFunction(fun);
     newfp->argc = argc;
     newfp->argv = argv;
 #ifdef DEBUG
     // Initialize argv[-1] to a known-bogus value so we'll catch it if
     // someone forgets to initialize it later.
     newfp->argv[-1].setMagic(JS_THIS_POISON);
 #endif
-    newfp->rval = UndefinedValue();
+    newfp->clearReturnValue();
     newfp->setAnnotation(NULL);
     newfp->setScopeChain(NULL); // will be updated in FlushNativeStackFrame
     newfp->flags = fi.is_constructing() ? JSFRAME_CONSTRUCTING : 0;
     newfp->setBlockChain(NULL);
-    newfp->thisv.setNull(); // will be updated in FlushNativeStackFrame
+    newfp->setThisValue(NullValue()); // will be updated in FlushNativeStackFrame
     JS_ASSERT(!newfp->hasIMacroPC());
 
     /*
      * Note that fp->script is still the caller's script; set the callee
      * inline frame's idea of caller version from its version.
      */
-    newfp->setCallerVersion((JSVersion) fp->script->version);
+    newfp->setCallerVersion((JSVersion) fp->getScript()->version);
 
     /* Push inline frame. (Copied from js_Interpret.) */
     stack.pushInlineFrame(cx, fp, fi.pc, newfp);
 
     /* Initialize regs after pushInlineFrame snapshots pc. */
     cx->regs->pc = newscript->code;
     cx->regs->sp = newfp->base();
 
@@ -5745,17 +5747,17 @@ SynthesizeFrame(JSContext* cx, const Fra
     /*
      * Duplicate native stack layout computation: see VisitFrameSlots header comment.
      *
      * FIXME - We must count stack slots from caller's operand stack up to (but
      * not including) callee's, including missing arguments. Could we shift
      * everything down to the caller's fp->slots (where vars start) and avoid
      * some of the complexity?
      */
-    return (fi.spdist - newfp->down->script->nfixed) +
+    return (fi.spdist - newfp->down->getFixedCount()) +
            ((fun->nargs > newfp->argc) ? fun->nargs - newfp->argc : 0) +
            newscript->nfixed + SPECIAL_FRAME_SLOTS;
 }
 
 JS_REQUIRES_STACK static void
 SynthesizeSlowNativeFrame(TracerState& state, JSContext *cx, VMSideExit *exit)
 {
     /*
@@ -5771,22 +5773,22 @@ SynthesizeSlowNativeFrame(TracerState& s
     JSObject *callee = &state.nativeVp[0].toObject();
     JSFunction *fun = GET_FUNCTION_PRIVATE(cx, callee);
     JS_ASSERT(!fun->isInterpreted() && !fun->isFastNative());
     JS_ASSERT(fun->u.n.extra == 0);
 #endif
 
     fp->setCallObj(NULL);
     fp->setArgsObj(NULL);
-    fp->script = NULL;
-    fp->thisv = state.nativeVp[1];
+    fp->setScript(NULL);
+    fp->setThisValue(state.nativeVp[1]);
     fp->argc = state.nativeVpLen - 2;
     fp->argv = state.nativeVp + 2;
-    fp->fun = GET_FUNCTION_PRIVATE(cx, fp->callee());
-    fp->rval = UndefinedValue();
+    fp->setFunction(GET_FUNCTION_PRIVATE(cx, fp->callee()));
+    fp->clearReturnValue();
     fp->setAnnotation(NULL);
     fp->setScopeChain(cx->fp->getScopeChain());
     fp->setBlockChain(NULL);
     fp->flags = exit->constructing() ? JSFRAME_CONSTRUCTING : 0;
     JS_ASSERT(!fp->hasIMacroPC());
 
     state.bailedSlowNativeRegs = *cx->regs;
 
@@ -5994,17 +5996,17 @@ CreateBranchFragment(JSContext* cx, Tree
     uint32_t profFragID = (LogController.lcbits & LC_FragProfile)
                           ? (++(tm->lastFragID)) : 0;
     )
 
     VMFragment* f = new (*tm->dataAlloc) VMFragment(cx->regs->pc verbose_only(, profFragID));
 
     debug_only_printf(LC_TMTreeVis, "TREEVIS CREATEBRANCH ROOT=%p FRAG=%p PC=%p FILE=\"%s\""
                       " LINE=%d ANCHOR=%p OFFS=%d\n",
-                      (void*)root, (void*)f, (void*)cx->regs->pc, cx->fp->script->filename,
+                      (void*)root, (void*)f, (void*)cx->regs->pc, cx->fp->getScript()->filename,
                       js_FramePCToLineNumber(cx, cx->fp), (void*)anchor,
                       FramePCOffset(cx, cx->fp));
     verbose_only( tm->branches = new (*tm->dataAlloc) Seq<Fragment*>(f, tm->branches); )
 
     f->root = root;
     if (anchor)
         anchor->target = f;
     return f;
@@ -6157,17 +6159,17 @@ TraceRecorder::recordLoopEdge(JSContext*
     SlotList* globalSlots = NULL;
     if (!CheckGlobalObjectShape(cx, tm, globalObj, &globalShape, &globalSlots)) {
         JS_ASSERT(!tm->recorder);
         return MONITOR_NOT_RECORDING;
     }
 
     debug_only_printf(LC_TMTracer,
                       "Looking for type-compatible peer (%s:%d@%d)\n",
-                      cx->fp->script->filename,
+                      cx->fp->getScript()->filename,
                       js_FramePCToLineNumber(cx, cx->fp),
                       FramePCOffset(cx, cx->fp));
 
     // Find a matching inner tree. If none can be found, compile one.
     TreeFragment* f = r->findNestedCompatiblePeer(first);
     if (!f || !f->code()) {
         AUDIT(noCompatInnerTrees);
 
@@ -6200,19 +6202,19 @@ TraceRecorder::attemptTreeCall(TreeFragm
      * because it could accidentally pop frames owned by the parent call, and
      * there is no way to deal with this yet. We could have to set a "start of
      * poppable rp stack" variable, and if that unequals "real start of rp stack",
      * it would be illegal to pop frames.
      * --
      * In the interim, just do tree calls knowing that they won't go into
      * recursive trees that can pop parent frames.
      */
-    if (f->script == cx->fp->script) {
+    if (f->script == cx->fp->getScript()) {
         if (f->recursion >= Recursion_Unwinds) {
-            Blacklist(cx->fp->script->code);
+            Blacklist(cx->fp->getScript()->code);
             AbortRecording(cx, "Inner tree is an unsupported type of recursion");
             return ARECORD_ABORTED;
         }
         f->recursion = Recursion_Disallowed;
     }
 
     adjustCallerTypes(f);
     prepareTreeCall(f);
@@ -6730,17 +6732,17 @@ ExecuteTree(JSContext* cx, TreeFragment*
     unsigned ngslots = f->globalSlots->length();
     uint16* gslots = f->globalSlots->data();
 
     BuildNativeFrame(cx, globalObj, 0 /* callDepth */, ngslots, gslots,
                      f->typeMap.data(), global, stack);
 
     AUDIT(traceTriggered);
     debug_only_printf(LC_TMTracer, "entering trace at %s:%u@%u, execs: %u code: %p\n",
-           cx->fp->script->filename,
+                      cx->fp->getScript()->filename,
            js_FramePCToLineNumber(cx, cx->fp),
            FramePCOffset(cx, cx->fp),
            f->execs,
            f->code());
 
     debug_only_stmt(uint32 globalSlots = globalObj->numSlots();)
     debug_only_stmt(*(uint64*)&tm->storage->global()[globalSlots] = 0xdeadbeefdeadbeefLL;)
 
@@ -6849,21 +6851,21 @@ LeaveTree(TraceMonitor *tm, TracerState&
          * Deep-bail case.
          *
          * A _FAIL native already called LeaveTree. We already reconstructed
          * the interpreter stack, in pre-call state, with pc pointing to the
          * CALL/APPLY op, for correctness. Then we continued in native code.
          *
          * First, if we just returned from a slow native, pop its stack frame.
          */
-        if (!cx->fp->script) {
+        if (!cx->fp->hasScript()) {
             JS_ASSERT(cx->regs == &state.bailedSlowNativeRegs);
             cx->stack().popSynthesizedSlowNativeFrame(cx);
         }
-        JS_ASSERT(cx->fp->script);
+        JS_ASSERT(cx->fp->hasScript());
 
         if (!(bs & BUILTIN_ERROR)) {
             /*
              * The builtin or native deep-bailed but finished successfully
              * (no exception or error).
              *
              * After it returned, the JIT code stored the results of the
              * builtin or native at the top of the native stack and then
@@ -6899,18 +6901,18 @@ LeaveTree(TraceMonitor *tm, TracerState&
                 op = JSOP_POP;
             }
 
             const JSCodeSpec& cs = js_CodeSpec[op];
             regs->sp -= (cs.format & JOF_INVOKE) ? GET_ARGC(regs->pc) + 2 : cs.nuses;
             regs->sp += cs.ndefs;
             regs->pc += cs.length;
             JS_ASSERT_IF(!cx->fp->hasIMacroPC(),
-                         cx->fp->slots() + cx->fp->script->nfixed +
-                         js_ReconstructStackDepth(cx, cx->fp->script, regs->pc) ==
+                         cx->fp->slots() + cx->fp->getFixedCount() +
+                         js_ReconstructStackDepth(cx, cx->fp->getScript(), regs->pc) ==
                          regs->sp);
 
             /*
              * If there's a tree call around the point that we deep exited at,
              * then state.sp and state.rp were restored to their original
              * values before the tree call and sp might be less than deepBailSp,
              * which we sampled when we were told to deep bail.
              */
@@ -6959,17 +6961,17 @@ LeaveTree(TraceMonitor *tm, TracerState&
          */
         SynthesizeFrame(cx, *fi, callee);
         int slots = FlushNativeStackFrame(cx, 1 /* callDepth */, (*callstack)->get_typemap(),
                                           stack, cx->fp, 0);
 #ifdef DEBUG
         JSStackFrame* fp = cx->fp;
         debug_only_printf(LC_TMTracer,
                           "synthesized deep frame for %s:%u@%u, slots=%d, fi=%p\n",
-                          fp->script->filename,
+                          fp->getScript()->filename,
                           js_FramePCToLineNumber(cx, fp),
                           FramePCOffset(cx, fp),
                           slots,
                           (void*)*callstack);
 #endif
         /*
          * Keep track of the additional frames we put on the interpreter stack
          * and the native stack slots we consumed.
@@ -6995,17 +6997,17 @@ LeaveTree(TraceMonitor *tm, TracerState&
 
         /* Reconstruct the frame. */
         calldepth_slots += SynthesizeFrame(cx, *callstack[n], callee);
         ++*state.inlineCallCountp;
 #ifdef DEBUG
         JSStackFrame* fp = cx->fp;
         debug_only_printf(LC_TMTracer,
                           "synthesized shallow frame for %s:%u@%u\n",
-                          fp->script->filename, js_FramePCToLineNumber(cx, fp),
+                          fp->getScript()->filename, js_FramePCToLineNumber(cx, fp),
                           FramePCOffset(cx, fp));
 #endif
     }
 
     /*
      * Adjust sp and pc relative to the tree we exited from (not the tree we
      * entered into).  These are our final values for sp and pc since
      * SynthesizeFrame has already taken care of all frames in between. But
@@ -7022,29 +7024,29 @@ LeaveTree(TraceMonitor *tm, TracerState&
      */
     cx->regs->pc = innermost->pc;
     if (innermost->imacpc)
         fp->setIMacroPC(innermost->imacpc);
     else
         fp->clearIMacroPC();
     cx->regs->sp = fp->base() + (innermost->sp_adj / sizeof(double)) - calldepth_slots;
     JS_ASSERT_IF(!fp->hasIMacroPC(),
-                 fp->slots() + fp->script->nfixed +
-                 js_ReconstructStackDepth(cx, fp->script, cx->regs->pc) == cx->regs->sp);
+                 fp->slots() + fp->getFixedCount() +
+                 js_ReconstructStackDepth(cx, fp->getScript(), cx->regs->pc) == cx->regs->sp);
 
 #ifdef EXECUTE_TREE_TIMER
     uint64 cycles = rdtsc() - state.startTime;
 #elif defined(JS_JIT_SPEW)
     uint64 cycles = 0;
 #endif
 
     debug_only_printf(LC_TMTracer,
                       "leaving trace at %s:%u@%u, op=%s, lr=%p, exitType=%s, sp=%lld, "
                       "calldepth=%d, cycles=%llu\n",
-                      fp->script->filename,
+                      fp->getScript()->filename,
                       js_FramePCToLineNumber(cx, fp),
                       FramePCOffset(cx, fp),
                       js_CodeName[fp->hasIMacroPC() ? *fp->getIMacroPC() : *cx->regs->pc],
                       (void*)lr,
                       getExitName(lr->exitType),
                       (long long int)(cx->regs->sp - fp->base()),
                       calldepth,
                       (unsigned long long int)cycles);
@@ -7397,19 +7399,19 @@ TraceRecorder::monitorRecording(JSOp op)
                                         val_ins->oprnd1(), val_ins->disp(),
                                         snapshot(BRANCH_EXIT));
         set(pendingUnboxSlot, unboxed_ins);
         pendingUnboxSlot = 0;
     }
 
     debug_only_stmt(
         if (LogController.lcbits & LC_TMRecorder) {
-            js_Disassemble1(cx, cx->fp->script, cx->regs->pc,
+            js_Disassemble1(cx, cx->fp->getScript(), cx->regs->pc,
                             cx->fp->hasIMacroPC()
-                                ? 0 : cx->regs->pc - cx->fp->script->code,
+                                ? 0 : cx->regs->pc - cx->fp->getScript()->code,
                             !cx->fp->hasIMacroPC(), stdout);
         }
     )
 
     /*
      * If op is not a break or a return from a loop, continue recording and
      * follow the trace. We check for imacro-calling bytecodes inside each
      * switch case to resolve the if (JSOP_IS_IMACOP(x)) conditions at compile
@@ -8054,40 +8056,40 @@ DeepBail(JSContext *cx)
      * |tm->storage| at a time.
      */
     state->deepBailSp = state->sp;
 }
 
 JS_REQUIRES_STACK Value&
 TraceRecorder::argval(unsigned n) const
 {
-    JS_ASSERT(n < cx->fp->fun->nargs);
+    JS_ASSERT(n < cx->fp->getArgumentCount());
     return cx->fp->argv[n];
 }
 
 JS_REQUIRES_STACK Value&
 TraceRecorder::varval(unsigned n) const
 {
-    JS_ASSERT(n < cx->fp->script->nslots);
+    JS_ASSERT(n < cx->fp->getSlotCount());
     return cx->fp->slots()[n];
 }
 
 JS_REQUIRES_STACK Value&
 TraceRecorder::stackval(int n) const
 {
     return cx->regs->sp[n];
 }
 
 JS_REQUIRES_STACK void
 TraceRecorder::updateAtoms()
 {
     atoms = FrameAtomBase(cx, cx->fp);
-    consts = cx->fp->hasIMacroPC() || cx->fp->script->constOffset == 0
+    consts = cx->fp->hasIMacroPC() || cx->fp->getScript()->constOffset == 0
            ? 0 
-           : cx->fp->script->consts()->vector;
+           : cx->fp->getScript()->consts()->vector;
 }
 
 JS_REQUIRES_STACK void
 TraceRecorder::updateAtoms(JSScript *script)
 {
     atoms = script->atomMap.vector;
     consts = script->constOffset == 0 ? 0 : script->consts()->vector;
 }
@@ -8239,25 +8241,25 @@ TraceRecorder::callProp(JSObject* obj, J
 
     uintN slot = uint16(sprop->shortid);
 
     vp = NULL;
     uintN upvar_slot = SPROP_INVALID_SLOT;
     JSStackFrame* cfp = (JSStackFrame*) obj->getPrivate();
     if (cfp) {
         if (sprop->getterOp() == js_GetCallArg) {
-            JS_ASSERT(slot < cfp->fun->nargs);
+            JS_ASSERT(slot < cfp->getArgumentCount());
             vp = &cfp->argv[slot];
             upvar_slot = slot;
             nr.v = *vp;
         } else if (sprop->getterOp() == js_GetCallVar ||
                    sprop->getterOp() == js_GetCallVarChecked) {
-            JS_ASSERT(slot < cfp->script->nslots);
+            JS_ASSERT(slot < cfp->getSlotCount());
             vp = &cfp->slots()[slot];
-            upvar_slot = cx->fp->fun->nargs + slot;
+            upvar_slot = cx->fp->getArgumentCount() + slot;
             nr.v = *vp;
         } else {
             RETURN_STOP("dynamic property of Call object");
         }
 
         // Now assert that our use of sprop->shortid was in fact kosher.
         JS_ASSERT(sprop->hasShortID());
 
@@ -9549,17 +9551,17 @@ TraceRecorder::guardPropertyCacheHit(LIn
     // Special case for the global object, which may be aliased to get a property value.
     // To catch cross-global property accesses we must check against globalObj identity.
     // But a JOF_NAME mode opcode needs no guard, as we ensure the global object's shape
     // never changes, and name ops can't reach across a global object ('with' aborts).
     if (aobj == globalObj) {
         if (entry->adding())
             RETURN_STOP("adding a property to the global object");
 
-        JSOp op = js_GetOpcode(cx, cx->fp->script, cx->regs->pc);
+        JSOp op = js_GetOpcode(cx, cx->fp->getScript(), cx->regs->pc);
         if (JOF_OPMODE(op) != JOF_NAME) {
             guard(true,
                   addName(lir->ins2(LIR_eqp, obj_ins, INS_CONSTOBJ(globalObj)), "guard_global"),
                   exit);
         }
     } else {
         CHECK_STATUS(guardShape(obj_ins, aobj, entry->kshape, "guard_kshape", exit));
     }
@@ -10272,41 +10274,43 @@ TraceRecorder::entryFrame() const
 }
 
 JS_REQUIRES_STACK void
 TraceRecorder::clearEntryFrameSlotsFromTracker(Tracker& which)
 {
     JSStackFrame *fp = entryFrame();
 
     // Clear only slots that are not also used by the next frame up.
-    clearFrameSlotsFromTracker(which, fp, fp->script->nfixed);
+    clearFrameSlotsFromTracker(which, fp, fp->getFixedCount());
 }
 
 JS_REQUIRES_STACK void
 TraceRecorder::clearCurrentFrameSlotsFromTracker(Tracker& which)
 {
     // Clear out all local slots.
-    clearFrameSlotsFromTracker(which, cx->fp, cx->fp->script->nslots);
+    clearFrameSlotsFromTracker(which, cx->fp, cx->fp->getSlotCount());
 }
 
 /*
  * If we have created an |arguments| object for the frame, we must copy the
  * argument values into the object as properties in case it is used after
  * this frame returns.
  */
 JS_REQUIRES_STACK void
 TraceRecorder::putActivationObjects()
 {
     bool have_args = cx->fp->hasArgsObj() && cx->fp->argc;
-    bool have_call = cx->fp->fun && JSFUN_HEAVYWEIGHT_TEST(cx->fp->fun->flags) && cx->fp->fun->countArgsAndVars();
+    bool have_call = cx->fp->hasFunction() &&
+        JSFUN_HEAVYWEIGHT_TEST(cx->fp->getFunction()->flags) &&
+        cx->fp->getFunction()->countArgsAndVars();
 
     if (!have_args && !have_call)
         return;
 
-    int nargs = have_args ? argSlots(cx->fp) : cx->fp->fun->nargs;
+    int nargs = have_args ? argSlots(cx->fp) : cx->fp->getArgumentCount();
 
     LIns* args_ins;
     if (nargs) {
         args_ins = lir->insAlloc(sizeof(Value) * nargs);
         for (int i = 0; i < nargs; ++i) {
             box_value_into(cx->fp->argv[i], get(&cx->fp->argv[i]), args_ins, i * sizeof(Value),
                            ACCSET_OTHER);
         }
@@ -10316,73 +10320,73 @@ TraceRecorder::putActivationObjects()
 
     if (have_args) {
         LIns* argsobj_ins = getFrameObjPtr(cx->fp->addressArgsObj());
         LIns* args[] = { args_ins, argsobj_ins, cx_ins };
         lir->insCall(&js_PutArguments_ci, args);
     }
 
     if (have_call) {
-        int nslots = cx->fp->fun->countVars();
+        int nslots = cx->fp->getFunction()->countVars();
         LIns* slots_ins;
         if (nslots) {
             slots_ins = lir->insAlloc(sizeof(Value) * nslots);
             for (int i = 0; i < nslots; ++i) {
                 box_value_into(cx->fp->slots()[i], get(&cx->fp->slots()[i]), slots_ins,
                                i * sizeof(Value), ACCSET_OTHER);
             }
         } else {
             slots_ins = INS_CONSTPTR(0);
         }
 
         LIns* scopeChain_ins = getFrameObjPtr(cx->fp->addressScopeChain());
         LIns* args[] = { slots_ins, INS_CONST(nslots), args_ins,
-                         INS_CONST(cx->fp->fun->nargs), scopeChain_ins, cx_ins };
+                         INS_CONST(cx->fp->getArgumentCount()), scopeChain_ins, cx_ins };
         lir->insCall(&js_PutCallObjectOnTrace_ci, args);
     }
 }
 
 static JS_REQUIRES_STACK inline bool
 IsTraceableRecursion(JSContext *cx)
 {
     JSStackFrame *fp = cx->fp;
     JSStackFrame *down = cx->fp->down;
     if (!down)
         return false;
-    if (down->script != fp->script)
+    if (down->maybeScript() != fp->maybeScript())
         return false;
     if (down->argc != fp->argc)
         return false;
-    if (fp->argc != fp->fun->nargs)
+    if (fp->argc != fp->getArgumentCount())
         return false;
     if (fp->hasIMacroPC() || down->hasIMacroPC())
         return false;
     if ((fp->flags & JSFRAME_CONSTRUCTING) || (down->flags & JSFRAME_CONSTRUCTING))
         return false;
     if (fp->hasBlockChain() || down->hasBlockChain())
         return false;
-    if (*fp->script->code != JSOP_TRACE)
+    if (*fp->getScript()->code != JSOP_TRACE)
         return false;
     return true;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
 {
     JSStackFrame* const fp = cx->fp;
 
     if (++callDepth >= MAX_CALLDEPTH)
         RETURN_STOP_A("exceeded maximum call depth");
 
     debug_only_printf(LC_TMTracer, "EnterFrame %s, callDepth=%d\n",
-                      js_AtomToPrintableString(cx, cx->fp->fun->atom),
+                      js_AtomToPrintableString(cx, cx->fp->getFunction()->atom),
                       callDepth);
     debug_only_stmt(
         if (LogController.lcbits & LC_TMRecorder) {
-            js_Disassemble(cx, cx->fp->script, JS_TRUE, stdout);
+            js_Disassemble(cx, cx->fp->getScript(), JS_TRUE, stdout);
             debug_only_print0(LC_TMTracer, "----\n");
         }
     )
     LIns* void_ins = INS_UNDEFINED();
 
     // Before we enter this frame, we need to clear out any dangling insns left
     // in the tracer. While we also clear when returning from a function, it is
     // possible to have the following sequence of stack usage:
@@ -10392,50 +10396,50 @@ TraceRecorder::record_EnterFrame(uintN& 
     //  [fp1]*****[fp2]          call
     //  [fp1]*****[fp2]***       push
     //
     // Duplicate native stack layout computation: see VisitFrameSlots header comment.
     // This doesn't do layout arithmetic, but it must initialize in the tracker all the
     // slots defined as imported by VisitFrameSlots.
 
     Value* vp = &fp->argv[fp->argc];
-    Value* vpstop = vp + ptrdiff_t(fp->fun->nargs) - ptrdiff_t(fp->argc);
+    Value* vpstop = vp + ptrdiff_t(fp->getArgumentCount()) - ptrdiff_t(fp->argc);
     for (; vp < vpstop; ++vp) {
         nativeFrameTracker.set(vp, NULL);
         set(vp, void_ins);
     }
 
     nativeFrameTracker.set(fp->addressArgsObj(), NULL);
     setFrameObjPtr(fp->addressArgsObj(), INS_NULL());
     nativeFrameTracker.set(fp->addressScopeChain(), NULL);
 
     vp = fp->slots();
-    vpstop = vp + fp->script->nfixed;
+    vpstop = vp + fp->getFixedCount();
     for (; vp < vpstop; ++vp) {
         nativeFrameTracker.set(vp, NULL);
         set(vp, void_ins);
     }
 
     vp = vpstop;
-    vpstop = vp + (fp->script->nslots - fp->script->nfixed);
+    vpstop = vp + (fp->getSlotCount() - fp->getFixedCount());
     for (; vp < vpstop; ++vp)
         nativeFrameTracker.set(vp, NULL);
 
     LIns* callee_ins = get(&cx->fp->argv[-2]);
     LIns* scopeChain_ins = stobj_get_parent(callee_ins);
 
-    if (cx->fp->fun && JSFUN_HEAVYWEIGHT_TEST(cx->fp->fun->flags)) {
+    if (cx->fp->hasFunction() && JSFUN_HEAVYWEIGHT_TEST(cx->fp->getFunction()->flags)) {
         // We need to make sure every part of the frame is known to the tracker
         // before taking a snapshot.
         setFrameObjPtr(fp->addressScopeChain(), INS_NULL());
 
-        if (js_IsNamedLambda(cx->fp->fun))
+        if (js_IsNamedLambda(cx->fp->getFunction()))
             RETURN_STOP_A("can't call named lambda heavyweight on trace");
 
-        LIns* fun_ins = INS_CONSTPTR(cx->fp->fun);
+        LIns* fun_ins = INS_CONSTPTR(cx->fp->getFunction());
 
         LIns* args[] = { scopeChain_ins, callee_ins, fun_ins, cx_ins };
         LIns* call_ins = lir->insCall(&js_CreateCallObjectOnTrace_ci, args);
         guard(false, lir->insEqP_0(call_ins), snapshot(OOM_EXIT));
 
         setFrameObjPtr(fp->addressScopeChain(), call_ins);
     } else {
         setFrameObjPtr(fp->addressScopeChain(), scopeChain_ins);
@@ -10444,28 +10448,28 @@ TraceRecorder::record_EnterFrame(uintN& 
 #if 0
     /*
      * Check for recursion. This is a special check for recursive cases that can be
      * a trace-tree, just like a loop. If recursion acts weird, for example
      * differing argc or existence of an imacpc, it's not something this code is
      * concerned about. That should pass through below to not regress pre-recursion
      * functionality.
      */
-    if (IsTraceableRecursion(cx) && tree->script == cx->fp->script) {
+    if (IsTraceableRecursion(cx) && tree->script == cx->fp->getScript()) {
         if (tree->recursion == Recursion_Disallowed)
             RETURN_STOP_A("recursion not allowed in this tree");
-        if (tree->script != cx->fp->script)
+        if (tree->script != cx->fp->getScript())
             RETURN_STOP_A("recursion does not match original tree");
         return InjectStatus(downRecursion());
     }
 #endif
 
     /* Try inlining one level in case this recursion doesn't go too deep. */
-    if (fp->script == fp->down->script &&
-        fp->down->down && fp->down->down->script == fp->script) {
+    if (fp->getScript() == fp->down->getScript() &&
+        fp->down->down && fp->down->down->getScript() == fp->getScript()) {
         RETURN_STOP_A("recursion started inlining");
     }
 
 #if 0
     TreeFragment* first = LookupLoop(&JS_TRACE_MONITOR(cx), cx->regs->pc, tree->globalObj,
                                      tree->globalShape, fp->argc);
     if (!first)
         return ARECORD_CONTINUE;
@@ -10508,24 +10512,24 @@ TraceRecorder::record_EnterFrame(uintN& 
 
     return ARECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_LeaveFrame()
 {
     debug_only_stmt(
-        if (cx->fp->fun)
+        if (cx->fp->hasFunction())
             debug_only_printf(LC_TMTracer,
                               "LeaveFrame (back to %s), callDepth=%d\n",
-                              js_AtomToPrintableString(cx, cx->fp->fun->atom),
+                              js_AtomToPrintableString(cx, cx->fp->getFunction()->atom),
                               callDepth);
         );
 
-    JS_ASSERT(js_CodeSpec[js_GetOpcode(cx, cx->fp->script,
+    JS_ASSERT(js_CodeSpec[js_GetOpcode(cx, cx->fp->getScript(),
               cx->regs->pc)].length == JSOP_CALL_LENGTH);
 
     if (callDepth-- <= 0)
         RETURN_STOP_A("returned out of a loop we started tracing");
 
     // LeaveFrame gets called after the interpreter popped the frame and
     // stored rval, so cx->fp not cx->fp->down, and -1 not 0.
     updateAtoms();
@@ -10544,17 +10548,17 @@ JS_REQUIRES_STACK AbortableRecordingStat
 TraceRecorder::record_JSOP_POPV()
 {
     Value& rval = stackval(-1);
 
     // Store it in cx->fp->rval. NB: Tricky dependencies. cx->fp is the right
     // frame because POPV appears only in global and eval code and we don't
     // trace JSOP_EVAL or leaving the frame where tracing started.
     LIns *fp_ins = lir->insLoad(LIR_ldp, cx_ins, offsetof(JSContext, fp), ACCSET_OTHER);
-    box_value_into(rval, get(&rval), fp_ins, offsetof(JSStackFrame, rval), ACCSET_OTHER);
+    box_value_into(rval, get(&rval), fp_ins, JSStackFrame::offsetReturnValue(), ACCSET_OTHER);
     return ARECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_ENTERWITH()
 {
     return ARECORD_STOP;
 }
@@ -10583,62 +10587,62 @@ JS_DEFINE_CALLINFO_3(static, BOOL, funct
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_RETURN()
 {
     /* A return from callDepth 0 terminates the current loop, except for recursion. */
     if (callDepth == 0) {
 #if 0
         if (IsTraceableRecursion(cx) && tree->recursion != Recursion_Disallowed &&
-            tree->script == cx->fp->script) {
+            tree->script == cx->fp->getScript()) {
             return InjectStatus(upRecursion());
         } else
 #endif
         {
             AUDIT(returnLoopExits);
             return endLoop();
         }
     }
 
     putActivationObjects();
 
 #ifdef MOZ_TRACE_JSCALLS
     if (cx->functionCallback) {
-        LIns* args[] = { INS_CONST(0), INS_CONSTPTR(cx->fp->fun), cx_ins };
+        LIns* args[] = { INS_CONST(0), INS_CONSTPTR(cx->fp->getFunction()), cx_ins };
         LIns* call_ins = lir->insCall(&functionProbe_ci, args);
         guard(false, lir->insEqI_0(call_ins), MISMATCH_EXIT);
     }
 #endif
 
     /* If we inlined this function call, make the return value available to the caller code. */
     Value& rval = stackval(-1);
     JSStackFrame *fp = cx->fp;
     if ((cx->fp->flags & JSFRAME_CONSTRUCTING) && rval.isPrimitive()) {
-        JS_ASSERT(fp->thisv == fp->argv[-1]);
+        JS_ASSERT(fp->getThisValue() == fp->argv[-1]);
         rval_ins = get(&fp->argv[-1]);
     } else {
         rval_ins = get(&rval);
     }
     debug_only_printf(LC_TMTracer,
                       "returning from %s\n",
-                      js_AtomToPrintableString(cx, cx->fp->fun->atom));
+                      js_AtomToPrintableString(cx, cx->fp->getFunction()->atom));
     clearCurrentFrameSlotsFromTracker(nativeFrameTracker);
 
     return ARECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_GOTO()
 {
     /*
      * If we hit a break or a continue to an outer loop, end the loop and
      * generate an always-taken loop exit guard.  For other downward gotos
      * (like if/else) continue recording.
      */
-    jssrcnote* sn = js_GetSrcNote(cx->fp->script, cx->regs->pc);
+    jssrcnote* sn = js_GetSrcNote(cx->fp->getScript(), cx->regs->pc);
 
     if (sn && (SN_TYPE(sn) == SRC_BREAK || SN_TYPE(sn) == SRC_CONT2LABEL)) {
         AUDIT(breakLoopExits);
         return endLoop();
     }
     return ARECORD_CONTINUE;
 }
 
@@ -13161,28 +13165,28 @@ TraceRecorder::upvar(JSScript* script, J
      * The upvar is not in the current trace, so get the upvar value exactly as
      * the interpreter does and unbox.
      */
     uint32 level = script->staticLevel - cookie.level();
     uint32 cookieSlot = cookie.slot();
     JSStackFrame* fp = cx->findFrameAtLevel(level);
     const CallInfo* ci;
     int32 slot;
-    if (!fp->fun || (fp->flags & JSFRAME_EVAL)) {
+    if (!fp->hasFunction() || (fp->flags & JSFRAME_EVAL)) {
         ci = &GetUpvarStackOnTrace_ci;
         slot = cookieSlot;
-    } else if (cookieSlot < fp->fun->nargs) {
+    } else if (cookieSlot < fp->getArgumentCount()) {
         ci = &GetUpvarArgOnTrace_ci;
         slot = cookieSlot;
     } else if (cookieSlot == UpvarCookie::CALLEE_SLOT) {
         ci = &GetUpvarArgOnTrace_ci;
         slot = -2;
     } else {
         ci = &GetUpvarVarOnTrace_ci;
-        slot = cookieSlot - fp->fun->nargs;
+        slot = cookieSlot - fp->getArgumentCount();
     }
 
     LIns* outp = lir->insAlloc(sizeof(double));
     LIns* args[] = {
         outp,
         INS_CONST(callDepth),
         INS_CONST(slot),
         INS_CONST(level),
@@ -13232,17 +13236,17 @@ TraceRecorder::stackLoad(LIns* base, Acc
         result = lir->ins1(LIR_i2d, result);
     return result;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_GETUPVAR()
 {
     uintN index = GET_UINT16(cx->regs->pc);
-    JSScript *script = cx->fp->script;
+    JSScript *script = cx->fp->getScript();
     JSUpvarArray* uva = script->upvars();
     JS_ASSERT(index < uva->length);
 
     Value v;
     LIns* upvar_ins = upvar(script, uva, index, v);
     if (!upvar_ins)
         return ARECORD_STOP;
     stack(0, upvar_ins);
@@ -14170,17 +14174,17 @@ TraceRecorder::record_JSOP_STRICTNE()
     strictEquality(false, false);
     return ARECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_OBJECT()
 {
     JSStackFrame* const fp = cx->fp;
-    JSScript* script = fp->script;
+    JSScript* script = fp->getScript();
     unsigned index = atoms - script->atomMap.vector + GET_INDEX(cx->regs->pc);
 
     JSObject* obj;
     obj = script->getObject(index);
     stack(0, INS_CONSTOBJ(obj));
     return ARECORD_CONTINUE;
 }
 
@@ -14759,29 +14763,29 @@ TraceRecorder::traverseScopeChain(JSObje
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_BINDNAME()
 {
     JSStackFrame* const fp = cx->fp;
     JSObject *obj;
 
-    if (!fp->fun) {
+    if (!fp->hasFunction()) {
         obj = fp->getScopeChain();
 
 #ifdef DEBUG
         JSStackFrame *fp2 = fp;
 #endif
 
         // In global code, fp->scopeChain can only contain blocks whose values
         // are still on the stack.  We never use BINDNAME to refer to these.
         while (obj->getClass() == &js_BlockClass) {
             // The block's values are still on the stack.
 #ifdef DEBUG
-            // NB: fp2 can't be a generator frame, because !fp->fun.
+            // NB: fp2 can't be a generator frame, because !fp->hasFunction.
             while (obj->getPrivate() != fp2) {
                 JS_ASSERT(fp2->flags & JSFRAME_SPECIAL);
                 fp2 = fp2->down;
                 if (!fp2)
                     JS_NOT_REACHED("bad stack frame");
             }
 #endif
             obj = obj->getParent();
@@ -14803,17 +14807,17 @@ TraceRecorder::record_JSOP_BINDNAME()
          */
         stack(0, INS_CONSTOBJ(obj));
         return ARECORD_CONTINUE;
     }
 
     // We can't trace BINDNAME in functions that contain direct calls to eval,
     // as they might add bindings which previously-traced references would have
     // to see.
-    if (JSFUN_HEAVYWEIGHT_TEST(fp->fun->flags))
+    if (JSFUN_HEAVYWEIGHT_TEST(fp->getFunction()->flags))
         RETURN_STOP_A("BINDNAME in heavyweight function.");
 
     // We don't have the scope chain on trace, so instead we get a start object
     // that is on the scope chain and doesn't skip the target object (the one
     // that contains the property).
     Value *callee = &cx->fp->argv[-2];
     obj = callee->toObject().getParent();
     if (obj == globalObj) {
@@ -15059,25 +15063,25 @@ TraceRecorder::record_JSOP_DEFVAR()
 {
     return ARECORD_STOP;
 }
 
 jsatomid
 TraceRecorder::getFullIndex(ptrdiff_t pcoff)
 {
     jsatomid index = GET_INDEX(cx->regs->pc + pcoff);
-    index += atoms - cx->fp->script->atomMap.vector;
+    index += atoms - cx->fp->getScript()->atomMap.vector;
     return index;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_LAMBDA()
 {
     JSFunction* fun;
-    fun = cx->fp->script->getFunction(getFullIndex());
+    fun = cx->fp->getScript()->getFunction(getFullIndex());
 
     /*
      * Emit code to clone a null closure parented by this recorder's global
      * object, in order to preserve function object evaluation rules observable
      * via identity and mutation. But don't clone if our result is consumed by
      * JSOP_SETMETHOD or JSOP_INITMETHOD, since we optimize away the clone for
      * these combinations and clone only if the "method value" escapes.
      *
@@ -15166,17 +15170,17 @@ TraceRecorder::record_JSOP_LAMBDA()
 
     return ARECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_LAMBDA_FC()
 {
     JSFunction* fun;
-    fun = cx->fp->script->getFunction(getFullIndex());
+    fun = cx->fp->getScript()->getFunction(getFullIndex());
 
     if (FUN_OBJECT(fun)->getParent() != globalObj)
         return ARECORD_STOP;
 
     LIns* args[] = {
         scopeChain(),
         INS_CONSTFUN(fun),
         cx_ins
@@ -15250,17 +15254,17 @@ TraceRecorder::record_JSOP_NOP()
 {
     return ARECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_ARGSUB()
 {
     JSStackFrame* const fp = cx->fp;
-    if (!(fp->fun->flags & JSFUN_HEAVYWEIGHT)) {
+    if (!(fp->getFunction()->flags & JSFUN_HEAVYWEIGHT)) {
         uintN slot = GET_ARGNO(cx->regs->pc);
         if (slot >= fp->argc)
             RETURN_STOP_A("can't trace out-of-range arguments");
         stack(0, get(&cx->fp->argv[slot]));
         return ARECORD_CONTINUE;
     }
     RETURN_STOP_A("can't trace JSOP_ARGSUB hard case");
 }
@@ -15274,17 +15278,17 @@ TraceRecorder::guardArgsLengthNotAssigne
     LIns *ovr_ins = lir->ins2(LIR_andi, len_ins, INS_CONST(2));
     guard(true, lir->insEqI_0(ovr_ins), snapshot(BRANCH_EXIT));
     return len_ins;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_ARGCNT()
 {
-    if (cx->fp->fun->flags & JSFUN_HEAVYWEIGHT)
+    if (cx->fp->getFunction()->flags & JSFUN_HEAVYWEIGHT)
         RETURN_STOP_A("can't trace heavyweight JSOP_ARGCNT");
 
     // argc is fixed on trace, so ideally we would simply generate LIR for
     // constant argc. But the user can mutate arguments.length in the
     // interpreter, so we have to check for that in the trace entry frame.
     // We also have to check that arguments.length has not been mutated
     // at record time, because if so we will generate incorrect constant
     // LIR, which will assert in alu().
@@ -15422,17 +15426,17 @@ TraceRecorder::record_JSOP_RETRVAL()
 {
     return ARECORD_STOP;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_REGEXP()
 {
     JSStackFrame* const fp = cx->fp;
-    JSScript* script = fp->script;
+    JSScript* script = fp->getScript();
     unsigned index = atoms - script->atomMap.vector + GET_INDEX(cx->regs->pc);
 
     LIns* proto_ins;
     CHECK_STATUS_A(getClassPrototype(JSProto_RegExp, proto_ins));
 
     LIns* args[] = {
         proto_ins,
         INS_CONSTOBJ(script->getRegExp(index)),
@@ -15707,52 +15711,52 @@ TraceRecorder::record_JSOP_CALLELEM()
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_STOP()
 {
 #if 0
     if (callDepth == 0 && IsTraceableRecursion(cx) &&
         tree->recursion != Recursion_Disallowed &&
-        tree->script == cx->fp->script) {
+        tree->script == cx->fp->getScript()) {
         return InjectStatus(upRecursion());
     }
 #endif
     JSStackFrame *fp = cx->fp;
 
     if (fp->hasIMacroPC()) {
         /*
          * End of imacro, so return true to the interpreter immediately. The
          * interpreter's JSOP_STOP case will return from the imacro, back to
          * the pc after the calling op, still in the same JSStackFrame.
          */
-        updateAtoms(fp->script);
+        updateAtoms(fp->getScript());
         return ARECORD_CONTINUE;
     }
 
     putActivationObjects();
 
 #ifdef MOZ_TRACE_JSCALLS
     if (cx->functionCallback) {
-        LIns* args[] = { INS_CONST(0), INS_CONSTPTR(cx->fp->fun), cx_ins };
+        LIns* args[] = { INS_CONST(0), INS_CONSTPTR(cx->fp->getFunction()), cx_ins };
         LIns* call_ins = lir->insCall(&functionProbe_ci, args);
         guard(false, lir->insEqI_0(call_ins), MISMATCH_EXIT);
     }
 #endif
 
     /*
      * We know falling off the end of a constructor returns the new object that
      * was passed in via fp->argv[-1], while falling off the end of a function
      * returns undefined.
      *
      * NB: we do not support script rval (eval, API users who want the result
      * of the last expression-statement, debugger API calls).
      */
     if (fp->flags & JSFRAME_CONSTRUCTING) {
-        JS_ASSERT(fp->thisv == fp->argv[-1]);
+        JS_ASSERT(fp->getThisValue() == fp->argv[-1]);
         rval_ins = get(&fp->argv[-1]);
     } else {
         rval_ins = INS_UNDEFINED();
     }
     clearCurrentFrameSlotsFromTracker(nativeFrameTracker);
     return ARECORD_CONTINUE;
 }
 
@@ -15782,17 +15786,17 @@ TraceRecorder::record_JSOP_TYPEOFEXPR()
 {
     return record_JSOP_TYPEOF();
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_ENTERBLOCK()
 {
     JSObject* obj;
-    obj = cx->fp->script->getObject(getFullIndex(0));
+    obj = cx->fp->getScript()->getObject(getFullIndex(0));
 
     LIns* void_ins = INS_UNDEFINED();
     for (int i = 0, n = OBJ_BLOCK_COUNT(cx, obj); i < n; i++)
         stack(i, void_ins);
     return ARECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
@@ -15815,17 +15819,17 @@ TraceRecorder::record_JSOP_YIELD()
 {
     return ARECORD_STOP;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_ARRAYPUSH()
 {
     uint32_t slot = GET_UINT16(cx->regs->pc);
-    JS_ASSERT(cx->fp->script->nfixed <= slot);
+    JS_ASSERT(cx->fp->getFixedCount() <= slot);
     JS_ASSERT(cx->fp->slots() + slot < cx->regs->sp - 1);
     Value &arrayval = cx->fp->slots()[slot];
     JS_ASSERT(arrayval.isObject());
     JS_ASSERT(arrayval.toObject().isDenseArray());
     LIns *array_ins = get(&arrayval);
     Value &elt = stackval(-1);
     LIns *elt_ins = box_value_for_native_call(elt, get(&elt));
 
@@ -15856,17 +15860,17 @@ TraceRecorder::record_JSOP_GETTHISPROP()
     LIns* this_ins;
 
     CHECK_STATUS_A(getThis(this_ins));
 
     /*
      * It's safe to just use cx->fp->thisv here because getThis() returns
      * ARECORD_STOP if thisv is not available.
      */
-    CHECK_STATUS_A(getProp(&cx->fp->thisv.toObject(), this_ins));
+    CHECK_STATUS_A(getProp(&cx->fp->getThisValue().toObject(), this_ins));
     return ARECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_GETARGPROP()
 {
     return getProp(argval(GET_ARGNO(cx->regs->pc)));
 }
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -1711,24 +1711,24 @@ ParseXMLSource(JSContext *cx, JSString *
     js_InflateStringToBuffer(cx, suffix, constrlen(suffix), chars + offset,
                              &dstlen);
     chars [offset + dstlen] = 0;
 
     LeaveTrace(cx);
     xml = NULL;
     FrameRegsIter i(cx);
     for (; !i.done() && !i.pc(); ++i)
-        JS_ASSERT(!i.fp()->script);
+        JS_ASSERT(!i.fp()->hasScript());
     filename = NULL;
     lineno = 1;
     if (!i.done()) {
         JSStackFrame *fp = i.fp();
         op = (JSOp) *i.pc();
         if (op == JSOP_TOXML || op == JSOP_TOXMLLIST) {
-            filename = fp->script->filename;
+            filename = fp->getScript()->filename;
             lineno = js_FramePCToLineNumber(cx, fp);
             for (endp = srcp + srclen; srcp < endp; srcp++) {
                 if (*srcp == '\n')
                     --lineno;
             }
         }
     }
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1446,17 +1446,17 @@ ValueToScript(JSContext *cx, jsval v)
     if (!JSVAL_IS_PRIMITIVE(v)) {
         JSObject *obj = JSVAL_TO_OBJECT(v);
         JSClass *clasp = JS_GET_CLASS(cx, obj);
 
         if (clasp == Jsvalify(&js_ScriptClass)) {
             script = (JSScript *) JS_GetPrivate(cx, obj);
         } else if (clasp == Jsvalify(&js_GeneratorClass)) {
             JSGenerator *gen = (JSGenerator *) JS_GetPrivate(cx, obj);
-            fun = gen->getFloatingFrame()->fun;
+            fun = gen->getFloatingFrame()->getFunction();
             script = FUN_SCRIPT(fun);
         }
     }
 
     if (!script) {
         fun = JS_ValueToFunction(cx, v);
         if (!fun)
             return NULL;
@@ -1487,17 +1487,17 @@ SetDebug(JSContext *cx, JSObject *obj, u
 static JSBool
 GetTrapArgs(JSContext *cx, uintN argc, jsval *argv, JSScript **scriptp,
             int32 *ip)
 {
     jsval v;
     uintN intarg;
     JSScript *script;
 
-    *scriptp = JS_GetScriptedCaller(cx, NULL)->script;
+    *scriptp = JS_GetScriptedCaller(cx, NULL)->getScript();
     *ip = 0;
     if (argc != 0) {
         v = argv[0];
         intarg = 0;
         if (!JSVAL_IS_PRIMITIVE(v) &&
             (JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == Jsvalify(&js_FunctionClass) ||
              JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == Jsvalify(&js_ScriptClass))) {
             script = ValueToScript(cx, v);
@@ -1517,17 +1517,18 @@ GetTrapArgs(JSContext *cx, uintN argc, j
 static JSTrapStatus
 TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
             jsval closure)
 {
     JSString *str = JSVAL_TO_STRING(closure);
     JSStackFrame *caller = JS_GetScriptedCaller(cx, NULL);
     if (!JS_EvaluateUCInStackFrame(cx, caller,
                                    JS_GetStringChars(str), JS_GetStringLength(str),
-                                   caller->script->filename, caller->script->lineno,
+                                   caller->getScript()->filename,
+                                   caller->getScript()->lineno,
                                    rval)) {
         return JSTRAP_ERROR;
     }
     if (!JSVAL_IS_VOID(*rval))
         return JSTRAP_RETURN;
     return JSTRAP_CONTINUE;
 }
 
@@ -1616,17 +1617,17 @@ LineToPC(JSContext *cx, JSObject *obj, u
     int32 i;
     uintN lineno;
     jsbytecode *pc;
 
     if (argc == 0) {
         JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_LINE2PC_USAGE);
         return JS_FALSE;
     }
-    script = JS_GetScriptedCaller(cx, NULL)->script;
+    script = JS_GetScriptedCaller(cx, NULL)->getScript();
     if (!GetTrapArgs(cx, argc, argv, &script, &i))
         return JS_FALSE;
     lineno = (i == 0) ? script->lineno : (uintN)i;
     pc = JS_LineNumberToPC(cx, script, lineno);
     if (!pc)
         return JS_FALSE;
     *rval = INT_TO_JSVAL(pc - script->code);
     return JS_TRUE;
@@ -3144,18 +3145,18 @@ EvalInContext(JSContext *cx, JSObject *o
         OBJ_TO_INNER_OBJECT(cx, sobj);
         if (!sobj)
             return false;
         if (!(sobj->getClass()->flags & JSCLASS_IS_GLOBAL)) {
             JS_ReportError(cx, "Invalid scope argument to evalcx");
             return false;
         }
         if (!JS_EvaluateUCScript(cx, sobj, src, srclen,
-                                 fp->script->filename,
-                                 JS_PCToLineNumber(cx, fp->script, fp->pc(cx)),
+                                 fp->getScript()->filename,
+                                 JS_PCToLineNumber(cx, fp->getScript(), fp->pc(cx)),
                                  rval)) {
             return false;
         }
     }
     return cx->compartment->wrap(cx, Valueify(rval));
 }
 
 static JSBool
@@ -3180,28 +3181,28 @@ EvalInFrame(JSContext *cx, uintN argc, j
 
     FrameRegsIter fi(cx);
     for (uint32 i = 0; i < upCount; ++i, ++fi) {
         if (!fi.fp()->down)
             break;
     }
 
     JSStackFrame *const fp = fi.fp();
-    if (!fp->script) {
+    if (!fp->hasScript()) {
         JS_ReportError(cx, "cannot eval in non-script frame");
         return JS_FALSE;
     }
 
     JSStackFrame *oldfp = NULL;
     if (saveCurrent)
         oldfp = JS_SaveFrameChain(cx);
 
     JSBool ok = JS_EvaluateUCInStackFrame(cx, fp, str->chars(), str->length(),
-                                          fp->script->filename,
-                                          JS_PCToLineNumber(cx, fp->script,
+                                          fp->getScript()->filename,
+                                          JS_PCToLineNumber(cx, fp->getScript(),
                                                             fi.pc()),
                                           vp);
 
     if (saveCurrent)
         JS_RestoreFrameChain(cx, oldfp);
 
     return ok;
 }
@@ -3913,19 +3914,19 @@ Snarf(JSContext *cx, JSObject *obj, uint
 
     str = JS_ValueToString(cx, argv[0]);
     if (!str)
         return JS_FALSE;
     filename = JS_GetStringBytes(str);
 
     /* Get the currently executing script's name. */
     fp = JS_GetScriptedCaller(cx, NULL);
-    JS_ASSERT(fp && fp->script->filename);
+    JS_ASSERT(fp && fp->getScript()->filename);
 #ifdef XP_UNIX
-    pathname = MakeAbsolutePathname(cx, fp->script->filename, filename);
+    pathname = MakeAbsolutePathname(cx, fp->getScript()->filename, filename);
     if (!pathname)
         return JS_FALSE;
 #else
     pathname = filename;
 #endif
 
     ok = JS_FALSE;
     len = 0;
--- a/js/src/xpconnect/src/XPCSystemOnlyWrapper.cpp
+++ b/js/src/xpconnect/src/XPCSystemOnlyWrapper.cpp
@@ -195,32 +195,32 @@ AllowedToAct(JSContext *cx, jsid id)
       // No code at all is running. So we must be arriving here as the result
       // of C++ code asking us to do something. Allow access.
       return JS_TRUE;
     }
 
     // Some code is running, we can't make the assumption, as above, but we
     // can't use a native frame, so clear fp.
     fp = nsnull;
-  } else if (!fp->script) {
+  } else if (!fp->hasScript()) {
     fp = nsnull;
   }
 
   PRBool privileged;
   if (NS_SUCCEEDED(ssm->IsSystemPrincipal(principal, &privileged)) &&
       privileged) {
     // Chrome things are allowed to touch us.
     return JS_TRUE;
   }
 
   // XXX HACK EWW! Allow chrome://global/ access to these things, even
   // if they've been cloned into less privileged contexts.
   const char *filename;
   if (fp &&
-      (filename = fp->script->filename) &&
+      (filename = fp->getScript()->filename) &&
       !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
     return JS_TRUE;
   }
 
   // Before we throw, check for UniversalXPConnect.
   nsresult rv = ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged);
   if (NS_SUCCEEDED(rv) && privileged) {
     return JS_TRUE;
@@ -241,17 +241,17 @@ AllowedToAct(JSContext *cx, jsid id)
   return JS_FALSE;
 }
 
 JSBool
 CheckFilename(JSContext *cx, jsid id, JSStackFrame *fp)
 {
   const char *filename;
   if (fp &&
-      (filename = fp->script->filename) &&
+      (filename = fp->getScript()->filename) &&
       !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
     return JS_TRUE;
   }
 
   if (JSID_IS_VOID(id)) {
     ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx);
   } else {
     jsval idval;
--- a/js/src/xpconnect/src/xpcconvert.cpp
+++ b/js/src/xpconnect/src/xpcconvert.cpp
@@ -1304,17 +1304,17 @@ XPCConvert::NativeInterface2JSObject(XPC
                 {
                     // Called from JS.  We're going to hand the resulting
                     // JSObject to said JS, so look for the script we want on
                     // the stack.
                     JSContext* cx = ccx;
                     JSStackFrame* fp = JS_GetScriptedCaller(cx, NULL);
                     if(fp)
                     {
-                        script = fp->script;
+                        script = fp->maybeScript();
                         callee = fp->callee();
                     }
                 }
                 else if(ccx.GetXPCContext()->CallerTypeIsNative())
                 {
                     callee = ccx.GetCallee();
                     if(callee && JS_ObjectIsFunction(ccx, callee))
                     {
--- a/js/src/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/src/xpconnect/wrappers/AccessCheck.cpp
@@ -202,32 +202,32 @@ AccessCheck::isSystemOnlyAccessPermitted
             // No code at all is running. So we must be arriving here as the result
             // of C++ code asking us to do something. Allow access.
             return true;
         }
 
         // Some code is running, we can't make the assumption, as above, but we
         // can't use a native frame, so clear fp.
         fp = NULL;
-    } else if (!fp->script) {
+    } else if (!fp->hasScript()) {
         fp = NULL;
     }
 
     PRBool privileged;
     if (NS_SUCCEEDED(ssm->IsSystemPrincipal(principal, &privileged)) &&
         privileged) {
         return true;
     }
 
     // Allow any code loaded from chrome://global/ to touch us, even if it was
     // cloned into a less privileged context.
     static const char prefix[] = "chrome://global/";
     const char *filename;
     if (fp &&
-       (filename = fp->script->filename) &&
+        (filename = fp->getScript()->filename) &&
         !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) {
         return true;
     }
 
     return NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) && privileged;
 }
 
 bool