[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 id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone2.0b4pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
[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