Sat, 03 Jan 2015 20:18:00 +0100
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 ®s, 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 ®s)
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 */