js/src/vm/Stack-inl.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef vm_Stack_inl_h
     8 #define vm_Stack_inl_h
    10 #include "vm/Stack.h"
    12 #include "mozilla/PodOperations.h"
    14 #include "jscntxt.h"
    16 #include "jit/BaselineFrame.h"
    17 #include "jit/RematerializedFrame.h"
    18 #include "vm/ScopeObject.h"
    20 #include "jsobjinlines.h"
    22 #include "jit/BaselineFrame-inl.h"
    24 namespace js {
    26 /*
    27  * We cache name lookup results only for the global object or for native
    28  * non-global objects without prototype or with prototype that never mutates,
    29  * see bug 462734 and bug 487039.
    30  */
    31 static inline bool
    32 IsCacheableNonGlobalScope(JSObject *obj)
    33 {
    34     bool cacheable = (obj->is<CallObject>() || obj->is<BlockObject>() || obj->is<DeclEnvObject>());
    36     JS_ASSERT_IF(cacheable, !obj->getOps()->lookupProperty);
    37     return cacheable;
    38 }
    40 inline HandleObject
    41 InterpreterFrame::scopeChain() const
    42 {
    43     JS_ASSERT_IF(!(flags_ & HAS_SCOPECHAIN), isFunctionFrame());
    44     if (!(flags_ & HAS_SCOPECHAIN)) {
    45         scopeChain_ = callee().environment();
    46         flags_ |= HAS_SCOPECHAIN;
    47     }
    48     return HandleObject::fromMarkedLocation(&scopeChain_);
    49 }
    51 inline GlobalObject &
    52 InterpreterFrame::global() const
    53 {
    54     return scopeChain()->global();
    55 }
    57 inline JSObject &
    58 InterpreterFrame::varObj()
    59 {
    60     JSObject *obj = scopeChain();
    61     while (!obj->isVarObj())
    62         obj = obj->enclosingScope();
    63     return *obj;
    64 }
    66 inline JSCompartment *
    67 InterpreterFrame::compartment() const
    68 {
    69     JS_ASSERT(scopeChain()->compartment() == script()->compartment());
    70     return scopeChain()->compartment();
    71 }
    73 inline void
    74 InterpreterFrame::initCallFrame(JSContext *cx, InterpreterFrame *prev, jsbytecode *prevpc,
    75                                 Value *prevsp, JSFunction &callee, JSScript *script, Value *argv,
    76                                 uint32_t nactual, InterpreterFrame::Flags flagsArg)
    77 {
    78     JS_ASSERT((flagsArg & ~CONSTRUCTING) == 0);
    79     JS_ASSERT(callee.nonLazyScript() == script);
    81     /* Initialize stack frame members. */
    82     flags_ = FUNCTION | HAS_SCOPECHAIN | flagsArg;
    83     argv_ = argv;
    84     exec.fun = &callee;
    85     u.nactual = nactual;
    86     scopeChain_ = callee.environment();
    87     prev_ = prev;
    88     prevpc_ = prevpc;
    89     prevsp_ = prevsp;
    90     JS_ASSERT(!hasHookData());
    92     initVarsToUndefined();
    93 }
    95 inline void
    96 InterpreterFrame::initVarsToUndefined()
    97 {
    98     SetValueRangeToUndefined(slots(), script()->nfixed());
    99 }
   101 inline Value &
   102 InterpreterFrame::unaliasedVar(uint32_t i, MaybeCheckAliasing checkAliasing)
   103 {
   104     JS_ASSERT_IF(checkAliasing, !script()->varIsAliased(i));
   105     JS_ASSERT(i < script()->nfixedvars());
   106     return slots()[i];
   107 }
   109 inline Value &
   110 InterpreterFrame::unaliasedLocal(uint32_t i, MaybeCheckAliasing checkAliasing)
   111 {
   112     JS_ASSERT(i < script()->nfixed());
   113 #ifdef DEBUG
   114     CheckLocalUnaliased(checkAliasing, script(), i);
   115 #endif
   116     return slots()[i];
   117 }
   119 inline Value &
   120 InterpreterFrame::unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing)
   121 {
   122     JS_ASSERT(i < numFormalArgs());
   123     JS_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals());
   124     JS_ASSERT_IF(checkAliasing, !script()->formalIsAliased(i));
   125     return argv()[i];
   126 }
   128 inline Value &
   129 InterpreterFrame::unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing)
   130 {
   131     JS_ASSERT(i < numActualArgs());
   132     JS_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals());
   133     JS_ASSERT_IF(checkAliasing && i < numFormalArgs(), !script()->formalIsAliased(i));
   134     return argv()[i];
   135 }
   137 template <class Op>
   138 inline void
   139 InterpreterFrame::unaliasedForEachActual(Op op)
   140 {
   141     // Don't assert !script()->funHasAnyAliasedFormal() since this function is
   142     // called from ArgumentsObject::createUnexpected() which can access aliased
   143     // slots.
   145     const Value *argsEnd = argv() + numActualArgs();
   146     for (const Value *p = argv(); p < argsEnd; ++p)
   147         op(*p);
   148 }
   150 struct CopyTo
   151 {
   152     Value *dst;
   153     CopyTo(Value *dst) : dst(dst) {}
   154     void operator()(const Value &src) { *dst++ = src; }
   155 };
   157 struct CopyToHeap
   158 {
   159     HeapValue *dst;
   160     CopyToHeap(HeapValue *dst) : dst(dst) {}
   161     void operator()(const Value &src) { dst->init(src); ++dst; }
   162 };
   164 inline ArgumentsObject &
   165 InterpreterFrame::argsObj() const
   166 {
   167     JS_ASSERT(script()->needsArgsObj());
   168     JS_ASSERT(flags_ & HAS_ARGS_OBJ);
   169     return *argsObj_;
   170 }
   172 inline void
   173 InterpreterFrame::initArgsObj(ArgumentsObject &argsobj)
   174 {
   175     JS_ASSERT(script()->needsArgsObj());
   176     flags_ |= HAS_ARGS_OBJ;
   177     argsObj_ = &argsobj;
   178 }
   180 inline ScopeObject &
   181 InterpreterFrame::aliasedVarScope(ScopeCoordinate sc) const
   182 {
   183     JSObject *scope = &scopeChain()->as<ScopeObject>();
   184     for (unsigned i = sc.hops(); i; i--)
   185         scope = &scope->as<ScopeObject>().enclosingScope();
   186     return scope->as<ScopeObject>();
   187 }
   189 inline void
   190 InterpreterFrame::pushOnScopeChain(ScopeObject &scope)
   191 {
   192     JS_ASSERT(*scopeChain() == scope.enclosingScope() ||
   193               *scopeChain() == scope.as<CallObject>().enclosingScope().as<DeclEnvObject>().enclosingScope());
   194     scopeChain_ = &scope;
   195     flags_ |= HAS_SCOPECHAIN;
   196 }
   198 inline void
   199 InterpreterFrame::popOffScopeChain()
   200 {
   201     JS_ASSERT(flags_ & HAS_SCOPECHAIN);
   202     scopeChain_ = &scopeChain_->as<ScopeObject>().enclosingScope();
   203 }
   205 bool
   206 InterpreterFrame::hasCallObj() const
   207 {
   208     JS_ASSERT(isStrictEvalFrame() || fun()->isHeavyweight());
   209     return flags_ & HAS_CALL_OBJ;
   210 }
   212 inline CallObject &
   213 InterpreterFrame::callObj() const
   214 {
   215     JS_ASSERT(fun()->isHeavyweight());
   217     JSObject *pobj = scopeChain();
   218     while (MOZ_UNLIKELY(!pobj->is<CallObject>()))
   219         pobj = pobj->enclosingScope();
   220     return pobj->as<CallObject>();
   221 }
   223 /*****************************************************************************/
   225 inline void
   226 InterpreterStack::purge(JSRuntime *rt)
   227 {
   228     rt->freeLifoAlloc.transferUnusedFrom(&allocator_);
   229 }
   231 uint8_t *
   232 InterpreterStack::allocateFrame(JSContext *cx, size_t size)
   233 {
   234     size_t maxFrames;
   235     if (cx->compartment()->principals == cx->runtime()->trustedPrincipals())
   236         maxFrames = MAX_FRAMES_TRUSTED;
   237     else
   238         maxFrames = MAX_FRAMES;
   240     if (MOZ_UNLIKELY(frameCount_ >= maxFrames)) {
   241         js_ReportOverRecursed(cx);
   242         return nullptr;
   243     }
   245     uint8_t *buffer = reinterpret_cast<uint8_t *>(allocator_.alloc(size));
   246     if (!buffer)
   247         return nullptr;
   249     frameCount_++;
   250     return buffer;
   251 }
   253 MOZ_ALWAYS_INLINE InterpreterFrame *
   254 InterpreterStack::getCallFrame(JSContext *cx, const CallArgs &args, HandleScript script,
   255                                InterpreterFrame::Flags *flags, Value **pargv)
   256 {
   257     JSFunction *fun = &args.callee().as<JSFunction>();
   259     JS_ASSERT(fun->nonLazyScript() == script);
   260     unsigned nformal = fun->nargs();
   261     unsigned nvals = script->nslots();
   263     if (args.length() >= nformal) {
   264         *pargv = args.array();
   265         uint8_t *buffer = allocateFrame(cx, sizeof(InterpreterFrame) + nvals * sizeof(Value));
   266         return reinterpret_cast<InterpreterFrame *>(buffer);
   267     }
   269     // Pad any missing arguments with |undefined|.
   270     JS_ASSERT(args.length() < nformal);
   272     nvals += nformal + 2; // Include callee, |this|.
   273     uint8_t *buffer = allocateFrame(cx, sizeof(InterpreterFrame) + nvals * sizeof(Value));
   274     if (!buffer)
   275         return nullptr;
   277     Value *argv = reinterpret_cast<Value *>(buffer);
   278     unsigned nmissing = nformal - args.length();
   280     mozilla::PodCopy(argv, args.base(), 2 + args.length());
   281     SetValueRangeToUndefined(argv + 2 + args.length(), nmissing);
   283     *pargv = argv + 2;
   284     return reinterpret_cast<InterpreterFrame *>(argv + 2 + nformal);
   285 }
   287 MOZ_ALWAYS_INLINE bool
   288 InterpreterStack::pushInlineFrame(JSContext *cx, InterpreterRegs &regs, const CallArgs &args,
   289                                   HandleScript script, InitialFrameFlags initial)
   290 {
   291     RootedFunction callee(cx, &args.callee().as<JSFunction>());
   292     JS_ASSERT(regs.sp == args.end());
   293     JS_ASSERT(callee->nonLazyScript() == script);
   295     script->ensureNonLazyCanonicalFunction(cx);
   297     InterpreterFrame *prev = regs.fp();
   298     jsbytecode *prevpc = regs.pc;
   299     Value *prevsp = regs.sp;
   300     JS_ASSERT(prev);
   302     LifoAlloc::Mark mark = allocator_.mark();
   304     InterpreterFrame::Flags flags = ToFrameFlags(initial);
   305     Value *argv;
   306     InterpreterFrame *fp = getCallFrame(cx, args, script, &flags, &argv);
   307     if (!fp)
   308         return false;
   310     fp->mark_ = mark;
   312     /* Initialize frame, locals, regs. */
   313     fp->initCallFrame(cx, prev, prevpc, prevsp, *callee, script, argv, args.length(), flags);
   315     regs.prepareToRun(*fp, script);
   316     return true;
   317 }
   319 MOZ_ALWAYS_INLINE void
   320 InterpreterStack::popInlineFrame(InterpreterRegs &regs)
   321 {
   322     InterpreterFrame *fp = regs.fp();
   323     regs.popInlineFrame();
   324     regs.sp[-1] = fp->returnValue();
   325     releaseFrame(fp);
   326     JS_ASSERT(regs.fp());
   327 }
   329 template <class Op>
   330 inline void
   331 FrameIter::unaliasedForEachActual(JSContext *cx, Op op)
   332 {
   333     switch (data_.state_) {
   334       case DONE:
   335       case ASMJS:
   336         break;
   337       case INTERP:
   338         interpFrame()->unaliasedForEachActual(op);
   339         return;
   340       case JIT:
   341 #ifdef JS_ION
   342         if (data_.jitFrames_.isIonJS()) {
   343             ionInlineFrames_.unaliasedForEachActual(cx, op, jit::ReadFrame_Actuals);
   344         } else {
   345             JS_ASSERT(data_.jitFrames_.isBaselineJS());
   346             data_.jitFrames_.unaliasedForEachActual(op, jit::ReadFrame_Actuals);
   347         }
   348         return;
   349 #else
   350         break;
   351 #endif
   352     }
   353     MOZ_ASSUME_UNREACHABLE("Unexpected state");
   354 }
   356 inline void *
   357 AbstractFramePtr::maybeHookData() const
   358 {
   359     if (isInterpreterFrame())
   360         return asInterpreterFrame()->maybeHookData();
   361 #ifdef JS_ION
   362     return asBaselineFrame()->maybeHookData();
   363 #else
   364     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   365 #endif
   366 }
   368 inline void
   369 AbstractFramePtr::setHookData(void *data) const
   370 {
   371     if (isInterpreterFrame()) {
   372         asInterpreterFrame()->setHookData(data);
   373         return;
   374     }
   375 #ifdef JS_ION
   376     asBaselineFrame()->setHookData(data);
   377 #else
   378     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   379 #endif
   380 }
   382 inline HandleValue
   383 AbstractFramePtr::returnValue() const
   384 {
   385     if (isInterpreterFrame())
   386         return asInterpreterFrame()->returnValue();
   387 #ifdef JS_ION
   388     return asBaselineFrame()->returnValue();
   389 #else
   390     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   391 #endif
   392 }
   394 inline void
   395 AbstractFramePtr::setReturnValue(const Value &rval) const
   396 {
   397     if (isInterpreterFrame()) {
   398         asInterpreterFrame()->setReturnValue(rval);
   399         return;
   400     }
   401 #ifdef JS_ION
   402     asBaselineFrame()->setReturnValue(rval);
   403 #else
   404     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   405 #endif
   406 }
   408 inline JSObject *
   409 AbstractFramePtr::scopeChain() const
   410 {
   411     if (isInterpreterFrame())
   412         return asInterpreterFrame()->scopeChain();
   413 #ifdef JS_ION
   414     if (isBaselineFrame())
   415         return asBaselineFrame()->scopeChain();
   416     return asRematerializedFrame()->scopeChain();
   417 #else
   418     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   419 #endif
   420 }
   422 inline void
   423 AbstractFramePtr::pushOnScopeChain(ScopeObject &scope)
   424 {
   425     if (isInterpreterFrame()) {
   426         asInterpreterFrame()->pushOnScopeChain(scope);
   427         return;
   428     }
   429 #ifdef JS_ION
   430     asBaselineFrame()->pushOnScopeChain(scope);
   431 #else
   432     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   433 #endif
   434 }
   436 inline CallObject &
   437 AbstractFramePtr::callObj() const
   438 {
   439     if (isInterpreterFrame())
   440         return asInterpreterFrame()->callObj();
   441 #ifdef JS_ION
   442     if (isBaselineFrame())
   443         return asBaselineFrame()->callObj();
   444     return asRematerializedFrame()->callObj();
   445 #else
   446     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   447 #endif
   448 }
   450 inline bool
   451 AbstractFramePtr::initFunctionScopeObjects(JSContext *cx)
   452 {
   453     if (isInterpreterFrame())
   454         return asInterpreterFrame()->initFunctionScopeObjects(cx);
   455 #ifdef JS_ION
   456     return asBaselineFrame()->initFunctionScopeObjects(cx);
   457 #else
   458     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   459 #endif
   460 }
   462 inline JSCompartment *
   463 AbstractFramePtr::compartment() const
   464 {
   465     return scopeChain()->compartment();
   466 }
   468 inline unsigned
   469 AbstractFramePtr::numActualArgs() const
   470 {
   471     if (isInterpreterFrame())
   472         return asInterpreterFrame()->numActualArgs();
   473 #ifdef JS_ION
   474     if (isBaselineFrame())
   475         return asBaselineFrame()->numActualArgs();
   476     return asRematerializedFrame()->numActualArgs();
   477 #else
   478     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   479 #endif
   480 }
   481 inline unsigned
   482 AbstractFramePtr::numFormalArgs() const
   483 {
   484     if (isInterpreterFrame())
   485         return asInterpreterFrame()->numFormalArgs();
   486 #ifdef JS_ION
   487     if (isBaselineFrame())
   488         return asBaselineFrame()->numFormalArgs();
   489     return asRematerializedFrame()->numActualArgs();
   490 #else
   491     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   492 #endif
   493 }
   495 inline Value &
   496 AbstractFramePtr::unaliasedVar(uint32_t i, MaybeCheckAliasing checkAliasing)
   497 {
   498     if (isInterpreterFrame())
   499         return asInterpreterFrame()->unaliasedVar(i, checkAliasing);
   500 #ifdef JS_ION
   501     if (isBaselineFrame())
   502         return asBaselineFrame()->unaliasedVar(i, checkAliasing);
   503     return asRematerializedFrame()->unaliasedVar(i, checkAliasing);
   504 #else
   505     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   506 #endif
   507 }
   509 inline Value &
   510 AbstractFramePtr::unaliasedLocal(uint32_t i, MaybeCheckAliasing checkAliasing)
   511 {
   512     if (isInterpreterFrame())
   513         return asInterpreterFrame()->unaliasedLocal(i, checkAliasing);
   514 #ifdef JS_ION
   515     if (isBaselineFrame())
   516         return asBaselineFrame()->unaliasedLocal(i, checkAliasing);
   517     return asRematerializedFrame()->unaliasedLocal(i, checkAliasing);
   518 #else
   519     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   520 #endif
   521 }
   523 inline Value &
   524 AbstractFramePtr::unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing)
   525 {
   526     if (isInterpreterFrame())
   527         return asInterpreterFrame()->unaliasedFormal(i, checkAliasing);
   528 #ifdef JS_ION
   529     if (isBaselineFrame())
   530         return asBaselineFrame()->unaliasedFormal(i, checkAliasing);
   531     return asRematerializedFrame()->unaliasedFormal(i, checkAliasing);
   532 #else
   533     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   534 #endif
   535 }
   537 inline Value &
   538 AbstractFramePtr::unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing)
   539 {
   540     if (isInterpreterFrame())
   541         return asInterpreterFrame()->unaliasedActual(i, checkAliasing);
   542 #ifdef JS_ION
   543     if (isBaselineFrame())
   544         return asBaselineFrame()->unaliasedActual(i, checkAliasing);
   545     return asRematerializedFrame()->unaliasedActual(i, checkAliasing);
   546 #else
   547     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   548 #endif
   549 }
   551 inline bool
   552 AbstractFramePtr::hasCallObj() const
   553 {
   554     if (isInterpreterFrame())
   555         return asInterpreterFrame()->hasCallObj();
   556 #ifdef JS_ION
   557     if (isBaselineFrame())
   558         return asBaselineFrame()->hasCallObj();
   559     return asRematerializedFrame()->hasCallObj();
   560 #else
   561     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   562 #endif
   563 }
   564 inline bool
   565 AbstractFramePtr::useNewType() const
   566 {
   567     if (isInterpreterFrame())
   568         return asInterpreterFrame()->useNewType();
   569     return false;
   570 }
   571 inline bool
   572 AbstractFramePtr::isGeneratorFrame() const
   573 {
   574     if (isInterpreterFrame())
   575         return asInterpreterFrame()->isGeneratorFrame();
   576     return false;
   577 }
   578 inline bool
   579 AbstractFramePtr::isYielding() const
   580 {
   581     if (isInterpreterFrame())
   582         return asInterpreterFrame()->isYielding();
   583     return false;
   584 }
   585 inline bool
   586 AbstractFramePtr::isFunctionFrame() const
   587 {
   588     if (isInterpreterFrame())
   589         return asInterpreterFrame()->isFunctionFrame();
   590 #ifdef JS_ION
   591     if (isBaselineFrame())
   592         return asBaselineFrame()->isFunctionFrame();
   593     return asRematerializedFrame()->isFunctionFrame();
   594 #else
   595     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   596 #endif
   597 }
   598 inline bool
   599 AbstractFramePtr::isGlobalFrame() const
   600 {
   601     if (isInterpreterFrame())
   602         return asInterpreterFrame()->isGlobalFrame();
   603 #ifdef JS_ION
   604     if (isBaselineFrame())
   605         return asBaselineFrame()->isGlobalFrame();
   606     return asRematerializedFrame()->isGlobalFrame();
   607 #else
   608     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   609 #endif
   610 }
   611 inline bool
   612 AbstractFramePtr::isEvalFrame() const
   613 {
   614     if (isInterpreterFrame())
   615         return asInterpreterFrame()->isEvalFrame();
   616 #ifdef JS_ION
   617     if (isBaselineFrame())
   618         return asBaselineFrame()->isEvalFrame();
   619     MOZ_ASSERT(isRematerializedFrame());
   620     return false;
   621 #else
   622     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   623 #endif
   624 }
   625 inline bool
   626 AbstractFramePtr::isFramePushedByExecute() const
   627 {
   628     return isGlobalFrame() || isEvalFrame();
   629 }
   630 inline bool
   631 AbstractFramePtr::isDebuggerFrame() const
   632 {
   633     if (isInterpreterFrame())
   634         return asInterpreterFrame()->isDebuggerFrame();
   635 #ifdef JS_ION
   636     if (isBaselineFrame())
   637         return asBaselineFrame()->isDebuggerFrame();
   638     MOZ_ASSERT(isRematerializedFrame());
   639     return false;
   640 #else
   641     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   642 #endif
   643 }
   644 inline bool
   645 AbstractFramePtr::hasArgs() const {
   646     return isNonEvalFunctionFrame();
   647 }
   648 inline JSScript *
   649 AbstractFramePtr::script() const
   650 {
   651     if (isInterpreterFrame())
   652         return asInterpreterFrame()->script();
   653 #ifdef JS_ION
   654     if (isBaselineFrame())
   655         return asBaselineFrame()->script();
   656     return asRematerializedFrame()->script();
   657 #else
   658     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   659 #endif
   660 }
   661 inline JSFunction *
   662 AbstractFramePtr::fun() const
   663 {
   664     if (isInterpreterFrame())
   665         return asInterpreterFrame()->fun();
   666 #ifdef JS_ION
   667     if (isBaselineFrame())
   668         return asBaselineFrame()->fun();
   669     return asRematerializedFrame()->fun();
   670 #else
   671     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   672 #endif
   673 }
   674 inline JSFunction *
   675 AbstractFramePtr::maybeFun() const
   676 {
   677     if (isInterpreterFrame())
   678         return asInterpreterFrame()->maybeFun();
   679 #ifdef JS_ION
   680     if (isBaselineFrame())
   681         return asBaselineFrame()->maybeFun();
   682     return asRematerializedFrame()->maybeFun();
   683 #else
   684     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   685 #endif
   686 }
   687 inline JSFunction *
   688 AbstractFramePtr::callee() const
   689 {
   690     if (isInterpreterFrame())
   691         return &asInterpreterFrame()->callee();
   692 #ifdef JS_ION
   693     if (isBaselineFrame())
   694         return asBaselineFrame()->callee();
   695     return asRematerializedFrame()->callee();
   696 #else
   697     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   698 #endif
   699 }
   700 inline Value
   701 AbstractFramePtr::calleev() const
   702 {
   703     if (isInterpreterFrame())
   704         return asInterpreterFrame()->calleev();
   705 #ifdef JS_ION
   706     if (isBaselineFrame())
   707         return asBaselineFrame()->calleev();
   708     return asRematerializedFrame()->calleev();
   709 #else
   710     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   711 #endif
   712 }
   713 inline bool
   714 AbstractFramePtr::isNonEvalFunctionFrame() const
   715 {
   716     if (isInterpreterFrame())
   717         return asInterpreterFrame()->isNonEvalFunctionFrame();
   718 #ifdef JS_ION
   719     if (isBaselineFrame())
   720         return asBaselineFrame()->isNonEvalFunctionFrame();
   721     return asRematerializedFrame()->isNonEvalFunctionFrame();
   722 #else
   723     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   724 #endif
   725 }
   726 inline bool
   727 AbstractFramePtr::isNonStrictDirectEvalFrame() const
   728 {
   729     if (isInterpreterFrame())
   730         return asInterpreterFrame()->isNonStrictDirectEvalFrame();
   731 #ifdef JS_ION
   732     if (isBaselineFrame())
   733         return asBaselineFrame()->isNonStrictDirectEvalFrame();
   734     MOZ_ASSERT(isRematerializedFrame());
   735     return false;
   736 #else
   737     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   738 #endif
   739 }
   740 inline bool
   741 AbstractFramePtr::isStrictEvalFrame() const
   742 {
   743     if (isInterpreterFrame())
   744         return asInterpreterFrame()->isStrictEvalFrame();
   745 #ifdef JS_ION
   746     if (isBaselineFrame())
   747         return asBaselineFrame()->isStrictEvalFrame();
   748     MOZ_ASSERT(isRematerializedFrame());
   749     return false;
   750 #else
   751     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   752 #endif
   753 }
   755 inline Value *
   756 AbstractFramePtr::argv() const
   757 {
   758     if (isInterpreterFrame())
   759         return asInterpreterFrame()->argv();
   760 #ifdef JS_ION
   761     if (isBaselineFrame())
   762         return asBaselineFrame()->argv();
   763     return asRematerializedFrame()->argv();
   764 #else
   765     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   766 #endif
   767 }
   769 inline bool
   770 AbstractFramePtr::hasArgsObj() const
   771 {
   772     if (isInterpreterFrame())
   773         return asInterpreterFrame()->hasArgsObj();
   774 #ifdef JS_ION
   775     if (isBaselineFrame())
   776         return asBaselineFrame()->hasArgsObj();
   777     return asRematerializedFrame()->hasArgsObj();
   778 #else
   779     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   780 #endif
   781 }
   782 inline ArgumentsObject &
   783 AbstractFramePtr::argsObj() const
   784 {
   785     if (isInterpreterFrame())
   786         return asInterpreterFrame()->argsObj();
   787 #ifdef JS_ION
   788     if (isBaselineFrame())
   789         return asBaselineFrame()->argsObj();
   790     return asRematerializedFrame()->argsObj();
   791 #else
   792     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   793 #endif
   794 }
   795 inline void
   796 AbstractFramePtr::initArgsObj(ArgumentsObject &argsobj) const
   797 {
   798     if (isInterpreterFrame()) {
   799         asInterpreterFrame()->initArgsObj(argsobj);
   800         return;
   801     }
   802 #ifdef JS_ION
   803     asBaselineFrame()->initArgsObj(argsobj);
   804 #else
   805     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   806 #endif
   807 }
   808 inline bool
   809 AbstractFramePtr::copyRawFrameSlots(AutoValueVector *vec) const
   810 {
   811     if (isInterpreterFrame())
   812         return asInterpreterFrame()->copyRawFrameSlots(vec);
   813 #ifdef JS_ION
   814     return asBaselineFrame()->copyRawFrameSlots(vec);
   815 #else
   816     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   817 #endif
   818 }
   820 inline bool
   821 AbstractFramePtr::prevUpToDate() const
   822 {
   823     if (isInterpreterFrame())
   824         return asInterpreterFrame()->prevUpToDate();
   825 #ifdef JS_ION
   826     if (isBaselineFrame())
   827         return asBaselineFrame()->prevUpToDate();
   828     return asRematerializedFrame()->prevUpToDate();
   829 #else
   830     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   831 #endif
   832 }
   833 inline void
   834 AbstractFramePtr::setPrevUpToDate() const
   835 {
   836     if (isInterpreterFrame()) {
   837         asInterpreterFrame()->setPrevUpToDate();
   838         return;
   839     }
   840 #ifdef JS_ION
   841     if (isBaselineFrame()) {
   842         asBaselineFrame()->setPrevUpToDate();
   843         return;
   844     }
   845     asRematerializedFrame()->setPrevUpToDate();
   846 #else
   847     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   848 #endif
   849 }
   851 inline Value &
   852 AbstractFramePtr::thisValue() const
   853 {
   854     if (isInterpreterFrame())
   855         return asInterpreterFrame()->thisValue();
   856 #ifdef JS_ION
   857     if (isBaselineFrame())
   858         return asBaselineFrame()->thisValue();
   859     return asRematerializedFrame()->thisValue();
   860 #else
   861     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   862 #endif
   863 }
   865 inline void
   866 AbstractFramePtr::popBlock(JSContext *cx) const
   867 {
   868     if (isInterpreterFrame()) {
   869         asInterpreterFrame()->popBlock(cx);
   870         return;
   871     }
   872 #ifdef JS_ION
   873     asBaselineFrame()->popBlock(cx);
   874 #else
   875     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   876 #endif
   877 }
   879 inline void
   880 AbstractFramePtr::popWith(JSContext *cx) const
   881 {
   882     if (isInterpreterFrame()) {
   883         asInterpreterFrame()->popWith(cx);
   884         return;
   885     }
   886 #ifdef JS_ION
   887     asBaselineFrame()->popWith(cx);
   888 #else
   889     MOZ_ASSUME_UNREACHABLE("Invalid frame");
   890 #endif
   891 }
   893 Activation::Activation(JSContext *cx, Kind kind)
   894   : cx_(cx),
   895     compartment_(cx->compartment()),
   896     prev_(cx->mainThread().activation_),
   897     savedFrameChain_(0),
   898     hideScriptedCallerCount_(0),
   899     kind_(kind)
   900 {
   901     cx->mainThread().activation_ = this;
   902 }
   904 Activation::~Activation()
   905 {
   906     JS_ASSERT(cx_->mainThread().activation_ == this);
   907     JS_ASSERT(hideScriptedCallerCount_ == 0);
   908     cx_->mainThread().activation_ = prev_;
   909 }
   911 InterpreterActivation::InterpreterActivation(RunState &state, JSContext *cx,
   912                                              InterpreterFrame *entryFrame)
   913   : Activation(cx, Interpreter),
   914     state_(state),
   915     entryFrame_(entryFrame),
   916     opMask_(0)
   917 #ifdef DEBUG
   918   , oldFrameCount_(cx_->runtime()->interpreterStack().frameCount_)
   919 #endif
   920 {
   921     if (!state.isGenerator()) {
   922         regs_.prepareToRun(*entryFrame, state.script());
   923         JS_ASSERT(regs_.pc == state.script()->code());
   924     } else {
   925         regs_ = state.asGenerator()->gen()->regs;
   926     }
   928     JS_ASSERT_IF(entryFrame_->isEvalFrame(), state_.script()->isActiveEval());
   929 }
   931 InterpreterActivation::~InterpreterActivation()
   932 {
   933     // Pop all inline frames.
   934     while (regs_.fp() != entryFrame_)
   935         popInlineFrame(regs_.fp());
   937     JS_ASSERT(oldFrameCount_ == cx_->runtime()->interpreterStack().frameCount_);
   938     JS_ASSERT_IF(oldFrameCount_ == 0, cx_->runtime()->interpreterStack().allocator_.used() == 0);
   940     if (state_.isGenerator()) {
   941         JSGenerator *gen = state_.asGenerator()->gen();
   942         gen->fp->unsetPushedSPSFrame();
   943         gen->regs = regs_;
   944         return;
   945     }
   947     if (entryFrame_)
   948         cx_->runtime()->interpreterStack().releaseFrame(entryFrame_);
   949 }
   951 inline bool
   952 InterpreterActivation::pushInlineFrame(const CallArgs &args, HandleScript script,
   953                                        InitialFrameFlags initial)
   954 {
   955     if (!cx_->runtime()->interpreterStack().pushInlineFrame(cx_, regs_, args, script, initial))
   956         return false;
   957     JS_ASSERT(regs_.fp()->script()->compartment() == compartment_);
   958     return true;
   959 }
   961 inline void
   962 InterpreterActivation::popInlineFrame(InterpreterFrame *frame)
   963 {
   964     (void)frame; // Quell compiler warning.
   965     JS_ASSERT(regs_.fp() == frame);
   966     JS_ASSERT(regs_.fp() != entryFrame_);
   968     cx_->runtime()->interpreterStack().popInlineFrame(regs_);
   969 }
   971 } /* namespace js */
   973 #endif /* vm_Stack_inl_h */

mercurial