1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/vm/Stack-inl.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,973 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef vm_Stack_inl_h 1.11 +#define vm_Stack_inl_h 1.12 + 1.13 +#include "vm/Stack.h" 1.14 + 1.15 +#include "mozilla/PodOperations.h" 1.16 + 1.17 +#include "jscntxt.h" 1.18 + 1.19 +#include "jit/BaselineFrame.h" 1.20 +#include "jit/RematerializedFrame.h" 1.21 +#include "vm/ScopeObject.h" 1.22 + 1.23 +#include "jsobjinlines.h" 1.24 + 1.25 +#include "jit/BaselineFrame-inl.h" 1.26 + 1.27 +namespace js { 1.28 + 1.29 +/* 1.30 + * We cache name lookup results only for the global object or for native 1.31 + * non-global objects without prototype or with prototype that never mutates, 1.32 + * see bug 462734 and bug 487039. 1.33 + */ 1.34 +static inline bool 1.35 +IsCacheableNonGlobalScope(JSObject *obj) 1.36 +{ 1.37 + bool cacheable = (obj->is<CallObject>() || obj->is<BlockObject>() || obj->is<DeclEnvObject>()); 1.38 + 1.39 + JS_ASSERT_IF(cacheable, !obj->getOps()->lookupProperty); 1.40 + return cacheable; 1.41 +} 1.42 + 1.43 +inline HandleObject 1.44 +InterpreterFrame::scopeChain() const 1.45 +{ 1.46 + JS_ASSERT_IF(!(flags_ & HAS_SCOPECHAIN), isFunctionFrame()); 1.47 + if (!(flags_ & HAS_SCOPECHAIN)) { 1.48 + scopeChain_ = callee().environment(); 1.49 + flags_ |= HAS_SCOPECHAIN; 1.50 + } 1.51 + return HandleObject::fromMarkedLocation(&scopeChain_); 1.52 +} 1.53 + 1.54 +inline GlobalObject & 1.55 +InterpreterFrame::global() const 1.56 +{ 1.57 + return scopeChain()->global(); 1.58 +} 1.59 + 1.60 +inline JSObject & 1.61 +InterpreterFrame::varObj() 1.62 +{ 1.63 + JSObject *obj = scopeChain(); 1.64 + while (!obj->isVarObj()) 1.65 + obj = obj->enclosingScope(); 1.66 + return *obj; 1.67 +} 1.68 + 1.69 +inline JSCompartment * 1.70 +InterpreterFrame::compartment() const 1.71 +{ 1.72 + JS_ASSERT(scopeChain()->compartment() == script()->compartment()); 1.73 + return scopeChain()->compartment(); 1.74 +} 1.75 + 1.76 +inline void 1.77 +InterpreterFrame::initCallFrame(JSContext *cx, InterpreterFrame *prev, jsbytecode *prevpc, 1.78 + Value *prevsp, JSFunction &callee, JSScript *script, Value *argv, 1.79 + uint32_t nactual, InterpreterFrame::Flags flagsArg) 1.80 +{ 1.81 + JS_ASSERT((flagsArg & ~CONSTRUCTING) == 0); 1.82 + JS_ASSERT(callee.nonLazyScript() == script); 1.83 + 1.84 + /* Initialize stack frame members. */ 1.85 + flags_ = FUNCTION | HAS_SCOPECHAIN | flagsArg; 1.86 + argv_ = argv; 1.87 + exec.fun = &callee; 1.88 + u.nactual = nactual; 1.89 + scopeChain_ = callee.environment(); 1.90 + prev_ = prev; 1.91 + prevpc_ = prevpc; 1.92 + prevsp_ = prevsp; 1.93 + JS_ASSERT(!hasHookData()); 1.94 + 1.95 + initVarsToUndefined(); 1.96 +} 1.97 + 1.98 +inline void 1.99 +InterpreterFrame::initVarsToUndefined() 1.100 +{ 1.101 + SetValueRangeToUndefined(slots(), script()->nfixed()); 1.102 +} 1.103 + 1.104 +inline Value & 1.105 +InterpreterFrame::unaliasedVar(uint32_t i, MaybeCheckAliasing checkAliasing) 1.106 +{ 1.107 + JS_ASSERT_IF(checkAliasing, !script()->varIsAliased(i)); 1.108 + JS_ASSERT(i < script()->nfixedvars()); 1.109 + return slots()[i]; 1.110 +} 1.111 + 1.112 +inline Value & 1.113 +InterpreterFrame::unaliasedLocal(uint32_t i, MaybeCheckAliasing checkAliasing) 1.114 +{ 1.115 + JS_ASSERT(i < script()->nfixed()); 1.116 +#ifdef DEBUG 1.117 + CheckLocalUnaliased(checkAliasing, script(), i); 1.118 +#endif 1.119 + return slots()[i]; 1.120 +} 1.121 + 1.122 +inline Value & 1.123 +InterpreterFrame::unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing) 1.124 +{ 1.125 + JS_ASSERT(i < numFormalArgs()); 1.126 + JS_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals()); 1.127 + JS_ASSERT_IF(checkAliasing, !script()->formalIsAliased(i)); 1.128 + return argv()[i]; 1.129 +} 1.130 + 1.131 +inline Value & 1.132 +InterpreterFrame::unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing) 1.133 +{ 1.134 + JS_ASSERT(i < numActualArgs()); 1.135 + JS_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals()); 1.136 + JS_ASSERT_IF(checkAliasing && i < numFormalArgs(), !script()->formalIsAliased(i)); 1.137 + return argv()[i]; 1.138 +} 1.139 + 1.140 +template <class Op> 1.141 +inline void 1.142 +InterpreterFrame::unaliasedForEachActual(Op op) 1.143 +{ 1.144 + // Don't assert !script()->funHasAnyAliasedFormal() since this function is 1.145 + // called from ArgumentsObject::createUnexpected() which can access aliased 1.146 + // slots. 1.147 + 1.148 + const Value *argsEnd = argv() + numActualArgs(); 1.149 + for (const Value *p = argv(); p < argsEnd; ++p) 1.150 + op(*p); 1.151 +} 1.152 + 1.153 +struct CopyTo 1.154 +{ 1.155 + Value *dst; 1.156 + CopyTo(Value *dst) : dst(dst) {} 1.157 + void operator()(const Value &src) { *dst++ = src; } 1.158 +}; 1.159 + 1.160 +struct CopyToHeap 1.161 +{ 1.162 + HeapValue *dst; 1.163 + CopyToHeap(HeapValue *dst) : dst(dst) {} 1.164 + void operator()(const Value &src) { dst->init(src); ++dst; } 1.165 +}; 1.166 + 1.167 +inline ArgumentsObject & 1.168 +InterpreterFrame::argsObj() const 1.169 +{ 1.170 + JS_ASSERT(script()->needsArgsObj()); 1.171 + JS_ASSERT(flags_ & HAS_ARGS_OBJ); 1.172 + return *argsObj_; 1.173 +} 1.174 + 1.175 +inline void 1.176 +InterpreterFrame::initArgsObj(ArgumentsObject &argsobj) 1.177 +{ 1.178 + JS_ASSERT(script()->needsArgsObj()); 1.179 + flags_ |= HAS_ARGS_OBJ; 1.180 + argsObj_ = &argsobj; 1.181 +} 1.182 + 1.183 +inline ScopeObject & 1.184 +InterpreterFrame::aliasedVarScope(ScopeCoordinate sc) const 1.185 +{ 1.186 + JSObject *scope = &scopeChain()->as<ScopeObject>(); 1.187 + for (unsigned i = sc.hops(); i; i--) 1.188 + scope = &scope->as<ScopeObject>().enclosingScope(); 1.189 + return scope->as<ScopeObject>(); 1.190 +} 1.191 + 1.192 +inline void 1.193 +InterpreterFrame::pushOnScopeChain(ScopeObject &scope) 1.194 +{ 1.195 + JS_ASSERT(*scopeChain() == scope.enclosingScope() || 1.196 + *scopeChain() == scope.as<CallObject>().enclosingScope().as<DeclEnvObject>().enclosingScope()); 1.197 + scopeChain_ = &scope; 1.198 + flags_ |= HAS_SCOPECHAIN; 1.199 +} 1.200 + 1.201 +inline void 1.202 +InterpreterFrame::popOffScopeChain() 1.203 +{ 1.204 + JS_ASSERT(flags_ & HAS_SCOPECHAIN); 1.205 + scopeChain_ = &scopeChain_->as<ScopeObject>().enclosingScope(); 1.206 +} 1.207 + 1.208 +bool 1.209 +InterpreterFrame::hasCallObj() const 1.210 +{ 1.211 + JS_ASSERT(isStrictEvalFrame() || fun()->isHeavyweight()); 1.212 + return flags_ & HAS_CALL_OBJ; 1.213 +} 1.214 + 1.215 +inline CallObject & 1.216 +InterpreterFrame::callObj() const 1.217 +{ 1.218 + JS_ASSERT(fun()->isHeavyweight()); 1.219 + 1.220 + JSObject *pobj = scopeChain(); 1.221 + while (MOZ_UNLIKELY(!pobj->is<CallObject>())) 1.222 + pobj = pobj->enclosingScope(); 1.223 + return pobj->as<CallObject>(); 1.224 +} 1.225 + 1.226 +/*****************************************************************************/ 1.227 + 1.228 +inline void 1.229 +InterpreterStack::purge(JSRuntime *rt) 1.230 +{ 1.231 + rt->freeLifoAlloc.transferUnusedFrom(&allocator_); 1.232 +} 1.233 + 1.234 +uint8_t * 1.235 +InterpreterStack::allocateFrame(JSContext *cx, size_t size) 1.236 +{ 1.237 + size_t maxFrames; 1.238 + if (cx->compartment()->principals == cx->runtime()->trustedPrincipals()) 1.239 + maxFrames = MAX_FRAMES_TRUSTED; 1.240 + else 1.241 + maxFrames = MAX_FRAMES; 1.242 + 1.243 + if (MOZ_UNLIKELY(frameCount_ >= maxFrames)) { 1.244 + js_ReportOverRecursed(cx); 1.245 + return nullptr; 1.246 + } 1.247 + 1.248 + uint8_t *buffer = reinterpret_cast<uint8_t *>(allocator_.alloc(size)); 1.249 + if (!buffer) 1.250 + return nullptr; 1.251 + 1.252 + frameCount_++; 1.253 + return buffer; 1.254 +} 1.255 + 1.256 +MOZ_ALWAYS_INLINE InterpreterFrame * 1.257 +InterpreterStack::getCallFrame(JSContext *cx, const CallArgs &args, HandleScript script, 1.258 + InterpreterFrame::Flags *flags, Value **pargv) 1.259 +{ 1.260 + JSFunction *fun = &args.callee().as<JSFunction>(); 1.261 + 1.262 + JS_ASSERT(fun->nonLazyScript() == script); 1.263 + unsigned nformal = fun->nargs(); 1.264 + unsigned nvals = script->nslots(); 1.265 + 1.266 + if (args.length() >= nformal) { 1.267 + *pargv = args.array(); 1.268 + uint8_t *buffer = allocateFrame(cx, sizeof(InterpreterFrame) + nvals * sizeof(Value)); 1.269 + return reinterpret_cast<InterpreterFrame *>(buffer); 1.270 + } 1.271 + 1.272 + // Pad any missing arguments with |undefined|. 1.273 + JS_ASSERT(args.length() < nformal); 1.274 + 1.275 + nvals += nformal + 2; // Include callee, |this|. 1.276 + uint8_t *buffer = allocateFrame(cx, sizeof(InterpreterFrame) + nvals * sizeof(Value)); 1.277 + if (!buffer) 1.278 + return nullptr; 1.279 + 1.280 + Value *argv = reinterpret_cast<Value *>(buffer); 1.281 + unsigned nmissing = nformal - args.length(); 1.282 + 1.283 + mozilla::PodCopy(argv, args.base(), 2 + args.length()); 1.284 + SetValueRangeToUndefined(argv + 2 + args.length(), nmissing); 1.285 + 1.286 + *pargv = argv + 2; 1.287 + return reinterpret_cast<InterpreterFrame *>(argv + 2 + nformal); 1.288 +} 1.289 + 1.290 +MOZ_ALWAYS_INLINE bool 1.291 +InterpreterStack::pushInlineFrame(JSContext *cx, InterpreterRegs ®s, const CallArgs &args, 1.292 + HandleScript script, InitialFrameFlags initial) 1.293 +{ 1.294 + RootedFunction callee(cx, &args.callee().as<JSFunction>()); 1.295 + JS_ASSERT(regs.sp == args.end()); 1.296 + JS_ASSERT(callee->nonLazyScript() == script); 1.297 + 1.298 + script->ensureNonLazyCanonicalFunction(cx); 1.299 + 1.300 + InterpreterFrame *prev = regs.fp(); 1.301 + jsbytecode *prevpc = regs.pc; 1.302 + Value *prevsp = regs.sp; 1.303 + JS_ASSERT(prev); 1.304 + 1.305 + LifoAlloc::Mark mark = allocator_.mark(); 1.306 + 1.307 + InterpreterFrame::Flags flags = ToFrameFlags(initial); 1.308 + Value *argv; 1.309 + InterpreterFrame *fp = getCallFrame(cx, args, script, &flags, &argv); 1.310 + if (!fp) 1.311 + return false; 1.312 + 1.313 + fp->mark_ = mark; 1.314 + 1.315 + /* Initialize frame, locals, regs. */ 1.316 + fp->initCallFrame(cx, prev, prevpc, prevsp, *callee, script, argv, args.length(), flags); 1.317 + 1.318 + regs.prepareToRun(*fp, script); 1.319 + return true; 1.320 +} 1.321 + 1.322 +MOZ_ALWAYS_INLINE void 1.323 +InterpreterStack::popInlineFrame(InterpreterRegs ®s) 1.324 +{ 1.325 + InterpreterFrame *fp = regs.fp(); 1.326 + regs.popInlineFrame(); 1.327 + regs.sp[-1] = fp->returnValue(); 1.328 + releaseFrame(fp); 1.329 + JS_ASSERT(regs.fp()); 1.330 +} 1.331 + 1.332 +template <class Op> 1.333 +inline void 1.334 +FrameIter::unaliasedForEachActual(JSContext *cx, Op op) 1.335 +{ 1.336 + switch (data_.state_) { 1.337 + case DONE: 1.338 + case ASMJS: 1.339 + break; 1.340 + case INTERP: 1.341 + interpFrame()->unaliasedForEachActual(op); 1.342 + return; 1.343 + case JIT: 1.344 +#ifdef JS_ION 1.345 + if (data_.jitFrames_.isIonJS()) { 1.346 + ionInlineFrames_.unaliasedForEachActual(cx, op, jit::ReadFrame_Actuals); 1.347 + } else { 1.348 + JS_ASSERT(data_.jitFrames_.isBaselineJS()); 1.349 + data_.jitFrames_.unaliasedForEachActual(op, jit::ReadFrame_Actuals); 1.350 + } 1.351 + return; 1.352 +#else 1.353 + break; 1.354 +#endif 1.355 + } 1.356 + MOZ_ASSUME_UNREACHABLE("Unexpected state"); 1.357 +} 1.358 + 1.359 +inline void * 1.360 +AbstractFramePtr::maybeHookData() const 1.361 +{ 1.362 + if (isInterpreterFrame()) 1.363 + return asInterpreterFrame()->maybeHookData(); 1.364 +#ifdef JS_ION 1.365 + return asBaselineFrame()->maybeHookData(); 1.366 +#else 1.367 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.368 +#endif 1.369 +} 1.370 + 1.371 +inline void 1.372 +AbstractFramePtr::setHookData(void *data) const 1.373 +{ 1.374 + if (isInterpreterFrame()) { 1.375 + asInterpreterFrame()->setHookData(data); 1.376 + return; 1.377 + } 1.378 +#ifdef JS_ION 1.379 + asBaselineFrame()->setHookData(data); 1.380 +#else 1.381 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.382 +#endif 1.383 +} 1.384 + 1.385 +inline HandleValue 1.386 +AbstractFramePtr::returnValue() const 1.387 +{ 1.388 + if (isInterpreterFrame()) 1.389 + return asInterpreterFrame()->returnValue(); 1.390 +#ifdef JS_ION 1.391 + return asBaselineFrame()->returnValue(); 1.392 +#else 1.393 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.394 +#endif 1.395 +} 1.396 + 1.397 +inline void 1.398 +AbstractFramePtr::setReturnValue(const Value &rval) const 1.399 +{ 1.400 + if (isInterpreterFrame()) { 1.401 + asInterpreterFrame()->setReturnValue(rval); 1.402 + return; 1.403 + } 1.404 +#ifdef JS_ION 1.405 + asBaselineFrame()->setReturnValue(rval); 1.406 +#else 1.407 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.408 +#endif 1.409 +} 1.410 + 1.411 +inline JSObject * 1.412 +AbstractFramePtr::scopeChain() const 1.413 +{ 1.414 + if (isInterpreterFrame()) 1.415 + return asInterpreterFrame()->scopeChain(); 1.416 +#ifdef JS_ION 1.417 + if (isBaselineFrame()) 1.418 + return asBaselineFrame()->scopeChain(); 1.419 + return asRematerializedFrame()->scopeChain(); 1.420 +#else 1.421 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.422 +#endif 1.423 +} 1.424 + 1.425 +inline void 1.426 +AbstractFramePtr::pushOnScopeChain(ScopeObject &scope) 1.427 +{ 1.428 + if (isInterpreterFrame()) { 1.429 + asInterpreterFrame()->pushOnScopeChain(scope); 1.430 + return; 1.431 + } 1.432 +#ifdef JS_ION 1.433 + asBaselineFrame()->pushOnScopeChain(scope); 1.434 +#else 1.435 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.436 +#endif 1.437 +} 1.438 + 1.439 +inline CallObject & 1.440 +AbstractFramePtr::callObj() const 1.441 +{ 1.442 + if (isInterpreterFrame()) 1.443 + return asInterpreterFrame()->callObj(); 1.444 +#ifdef JS_ION 1.445 + if (isBaselineFrame()) 1.446 + return asBaselineFrame()->callObj(); 1.447 + return asRematerializedFrame()->callObj(); 1.448 +#else 1.449 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.450 +#endif 1.451 +} 1.452 + 1.453 +inline bool 1.454 +AbstractFramePtr::initFunctionScopeObjects(JSContext *cx) 1.455 +{ 1.456 + if (isInterpreterFrame()) 1.457 + return asInterpreterFrame()->initFunctionScopeObjects(cx); 1.458 +#ifdef JS_ION 1.459 + return asBaselineFrame()->initFunctionScopeObjects(cx); 1.460 +#else 1.461 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.462 +#endif 1.463 +} 1.464 + 1.465 +inline JSCompartment * 1.466 +AbstractFramePtr::compartment() const 1.467 +{ 1.468 + return scopeChain()->compartment(); 1.469 +} 1.470 + 1.471 +inline unsigned 1.472 +AbstractFramePtr::numActualArgs() const 1.473 +{ 1.474 + if (isInterpreterFrame()) 1.475 + return asInterpreterFrame()->numActualArgs(); 1.476 +#ifdef JS_ION 1.477 + if (isBaselineFrame()) 1.478 + return asBaselineFrame()->numActualArgs(); 1.479 + return asRematerializedFrame()->numActualArgs(); 1.480 +#else 1.481 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.482 +#endif 1.483 +} 1.484 +inline unsigned 1.485 +AbstractFramePtr::numFormalArgs() const 1.486 +{ 1.487 + if (isInterpreterFrame()) 1.488 + return asInterpreterFrame()->numFormalArgs(); 1.489 +#ifdef JS_ION 1.490 + if (isBaselineFrame()) 1.491 + return asBaselineFrame()->numFormalArgs(); 1.492 + return asRematerializedFrame()->numActualArgs(); 1.493 +#else 1.494 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.495 +#endif 1.496 +} 1.497 + 1.498 +inline Value & 1.499 +AbstractFramePtr::unaliasedVar(uint32_t i, MaybeCheckAliasing checkAliasing) 1.500 +{ 1.501 + if (isInterpreterFrame()) 1.502 + return asInterpreterFrame()->unaliasedVar(i, checkAliasing); 1.503 +#ifdef JS_ION 1.504 + if (isBaselineFrame()) 1.505 + return asBaselineFrame()->unaliasedVar(i, checkAliasing); 1.506 + return asRematerializedFrame()->unaliasedVar(i, checkAliasing); 1.507 +#else 1.508 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.509 +#endif 1.510 +} 1.511 + 1.512 +inline Value & 1.513 +AbstractFramePtr::unaliasedLocal(uint32_t i, MaybeCheckAliasing checkAliasing) 1.514 +{ 1.515 + if (isInterpreterFrame()) 1.516 + return asInterpreterFrame()->unaliasedLocal(i, checkAliasing); 1.517 +#ifdef JS_ION 1.518 + if (isBaselineFrame()) 1.519 + return asBaselineFrame()->unaliasedLocal(i, checkAliasing); 1.520 + return asRematerializedFrame()->unaliasedLocal(i, checkAliasing); 1.521 +#else 1.522 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.523 +#endif 1.524 +} 1.525 + 1.526 +inline Value & 1.527 +AbstractFramePtr::unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing) 1.528 +{ 1.529 + if (isInterpreterFrame()) 1.530 + return asInterpreterFrame()->unaliasedFormal(i, checkAliasing); 1.531 +#ifdef JS_ION 1.532 + if (isBaselineFrame()) 1.533 + return asBaselineFrame()->unaliasedFormal(i, checkAliasing); 1.534 + return asRematerializedFrame()->unaliasedFormal(i, checkAliasing); 1.535 +#else 1.536 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.537 +#endif 1.538 +} 1.539 + 1.540 +inline Value & 1.541 +AbstractFramePtr::unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing) 1.542 +{ 1.543 + if (isInterpreterFrame()) 1.544 + return asInterpreterFrame()->unaliasedActual(i, checkAliasing); 1.545 +#ifdef JS_ION 1.546 + if (isBaselineFrame()) 1.547 + return asBaselineFrame()->unaliasedActual(i, checkAliasing); 1.548 + return asRematerializedFrame()->unaliasedActual(i, checkAliasing); 1.549 +#else 1.550 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.551 +#endif 1.552 +} 1.553 + 1.554 +inline bool 1.555 +AbstractFramePtr::hasCallObj() const 1.556 +{ 1.557 + if (isInterpreterFrame()) 1.558 + return asInterpreterFrame()->hasCallObj(); 1.559 +#ifdef JS_ION 1.560 + if (isBaselineFrame()) 1.561 + return asBaselineFrame()->hasCallObj(); 1.562 + return asRematerializedFrame()->hasCallObj(); 1.563 +#else 1.564 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.565 +#endif 1.566 +} 1.567 +inline bool 1.568 +AbstractFramePtr::useNewType() const 1.569 +{ 1.570 + if (isInterpreterFrame()) 1.571 + return asInterpreterFrame()->useNewType(); 1.572 + return false; 1.573 +} 1.574 +inline bool 1.575 +AbstractFramePtr::isGeneratorFrame() const 1.576 +{ 1.577 + if (isInterpreterFrame()) 1.578 + return asInterpreterFrame()->isGeneratorFrame(); 1.579 + return false; 1.580 +} 1.581 +inline bool 1.582 +AbstractFramePtr::isYielding() const 1.583 +{ 1.584 + if (isInterpreterFrame()) 1.585 + return asInterpreterFrame()->isYielding(); 1.586 + return false; 1.587 +} 1.588 +inline bool 1.589 +AbstractFramePtr::isFunctionFrame() const 1.590 +{ 1.591 + if (isInterpreterFrame()) 1.592 + return asInterpreterFrame()->isFunctionFrame(); 1.593 +#ifdef JS_ION 1.594 + if (isBaselineFrame()) 1.595 + return asBaselineFrame()->isFunctionFrame(); 1.596 + return asRematerializedFrame()->isFunctionFrame(); 1.597 +#else 1.598 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.599 +#endif 1.600 +} 1.601 +inline bool 1.602 +AbstractFramePtr::isGlobalFrame() const 1.603 +{ 1.604 + if (isInterpreterFrame()) 1.605 + return asInterpreterFrame()->isGlobalFrame(); 1.606 +#ifdef JS_ION 1.607 + if (isBaselineFrame()) 1.608 + return asBaselineFrame()->isGlobalFrame(); 1.609 + return asRematerializedFrame()->isGlobalFrame(); 1.610 +#else 1.611 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.612 +#endif 1.613 +} 1.614 +inline bool 1.615 +AbstractFramePtr::isEvalFrame() const 1.616 +{ 1.617 + if (isInterpreterFrame()) 1.618 + return asInterpreterFrame()->isEvalFrame(); 1.619 +#ifdef JS_ION 1.620 + if (isBaselineFrame()) 1.621 + return asBaselineFrame()->isEvalFrame(); 1.622 + MOZ_ASSERT(isRematerializedFrame()); 1.623 + return false; 1.624 +#else 1.625 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.626 +#endif 1.627 +} 1.628 +inline bool 1.629 +AbstractFramePtr::isFramePushedByExecute() const 1.630 +{ 1.631 + return isGlobalFrame() || isEvalFrame(); 1.632 +} 1.633 +inline bool 1.634 +AbstractFramePtr::isDebuggerFrame() const 1.635 +{ 1.636 + if (isInterpreterFrame()) 1.637 + return asInterpreterFrame()->isDebuggerFrame(); 1.638 +#ifdef JS_ION 1.639 + if (isBaselineFrame()) 1.640 + return asBaselineFrame()->isDebuggerFrame(); 1.641 + MOZ_ASSERT(isRematerializedFrame()); 1.642 + return false; 1.643 +#else 1.644 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.645 +#endif 1.646 +} 1.647 +inline bool 1.648 +AbstractFramePtr::hasArgs() const { 1.649 + return isNonEvalFunctionFrame(); 1.650 +} 1.651 +inline JSScript * 1.652 +AbstractFramePtr::script() const 1.653 +{ 1.654 + if (isInterpreterFrame()) 1.655 + return asInterpreterFrame()->script(); 1.656 +#ifdef JS_ION 1.657 + if (isBaselineFrame()) 1.658 + return asBaselineFrame()->script(); 1.659 + return asRematerializedFrame()->script(); 1.660 +#else 1.661 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.662 +#endif 1.663 +} 1.664 +inline JSFunction * 1.665 +AbstractFramePtr::fun() const 1.666 +{ 1.667 + if (isInterpreterFrame()) 1.668 + return asInterpreterFrame()->fun(); 1.669 +#ifdef JS_ION 1.670 + if (isBaselineFrame()) 1.671 + return asBaselineFrame()->fun(); 1.672 + return asRematerializedFrame()->fun(); 1.673 +#else 1.674 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.675 +#endif 1.676 +} 1.677 +inline JSFunction * 1.678 +AbstractFramePtr::maybeFun() const 1.679 +{ 1.680 + if (isInterpreterFrame()) 1.681 + return asInterpreterFrame()->maybeFun(); 1.682 +#ifdef JS_ION 1.683 + if (isBaselineFrame()) 1.684 + return asBaselineFrame()->maybeFun(); 1.685 + return asRematerializedFrame()->maybeFun(); 1.686 +#else 1.687 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.688 +#endif 1.689 +} 1.690 +inline JSFunction * 1.691 +AbstractFramePtr::callee() const 1.692 +{ 1.693 + if (isInterpreterFrame()) 1.694 + return &asInterpreterFrame()->callee(); 1.695 +#ifdef JS_ION 1.696 + if (isBaselineFrame()) 1.697 + return asBaselineFrame()->callee(); 1.698 + return asRematerializedFrame()->callee(); 1.699 +#else 1.700 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.701 +#endif 1.702 +} 1.703 +inline Value 1.704 +AbstractFramePtr::calleev() const 1.705 +{ 1.706 + if (isInterpreterFrame()) 1.707 + return asInterpreterFrame()->calleev(); 1.708 +#ifdef JS_ION 1.709 + if (isBaselineFrame()) 1.710 + return asBaselineFrame()->calleev(); 1.711 + return asRematerializedFrame()->calleev(); 1.712 +#else 1.713 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.714 +#endif 1.715 +} 1.716 +inline bool 1.717 +AbstractFramePtr::isNonEvalFunctionFrame() const 1.718 +{ 1.719 + if (isInterpreterFrame()) 1.720 + return asInterpreterFrame()->isNonEvalFunctionFrame(); 1.721 +#ifdef JS_ION 1.722 + if (isBaselineFrame()) 1.723 + return asBaselineFrame()->isNonEvalFunctionFrame(); 1.724 + return asRematerializedFrame()->isNonEvalFunctionFrame(); 1.725 +#else 1.726 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.727 +#endif 1.728 +} 1.729 +inline bool 1.730 +AbstractFramePtr::isNonStrictDirectEvalFrame() const 1.731 +{ 1.732 + if (isInterpreterFrame()) 1.733 + return asInterpreterFrame()->isNonStrictDirectEvalFrame(); 1.734 +#ifdef JS_ION 1.735 + if (isBaselineFrame()) 1.736 + return asBaselineFrame()->isNonStrictDirectEvalFrame(); 1.737 + MOZ_ASSERT(isRematerializedFrame()); 1.738 + return false; 1.739 +#else 1.740 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.741 +#endif 1.742 +} 1.743 +inline bool 1.744 +AbstractFramePtr::isStrictEvalFrame() const 1.745 +{ 1.746 + if (isInterpreterFrame()) 1.747 + return asInterpreterFrame()->isStrictEvalFrame(); 1.748 +#ifdef JS_ION 1.749 + if (isBaselineFrame()) 1.750 + return asBaselineFrame()->isStrictEvalFrame(); 1.751 + MOZ_ASSERT(isRematerializedFrame()); 1.752 + return false; 1.753 +#else 1.754 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.755 +#endif 1.756 +} 1.757 + 1.758 +inline Value * 1.759 +AbstractFramePtr::argv() const 1.760 +{ 1.761 + if (isInterpreterFrame()) 1.762 + return asInterpreterFrame()->argv(); 1.763 +#ifdef JS_ION 1.764 + if (isBaselineFrame()) 1.765 + return asBaselineFrame()->argv(); 1.766 + return asRematerializedFrame()->argv(); 1.767 +#else 1.768 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.769 +#endif 1.770 +} 1.771 + 1.772 +inline bool 1.773 +AbstractFramePtr::hasArgsObj() const 1.774 +{ 1.775 + if (isInterpreterFrame()) 1.776 + return asInterpreterFrame()->hasArgsObj(); 1.777 +#ifdef JS_ION 1.778 + if (isBaselineFrame()) 1.779 + return asBaselineFrame()->hasArgsObj(); 1.780 + return asRematerializedFrame()->hasArgsObj(); 1.781 +#else 1.782 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.783 +#endif 1.784 +} 1.785 +inline ArgumentsObject & 1.786 +AbstractFramePtr::argsObj() const 1.787 +{ 1.788 + if (isInterpreterFrame()) 1.789 + return asInterpreterFrame()->argsObj(); 1.790 +#ifdef JS_ION 1.791 + if (isBaselineFrame()) 1.792 + return asBaselineFrame()->argsObj(); 1.793 + return asRematerializedFrame()->argsObj(); 1.794 +#else 1.795 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.796 +#endif 1.797 +} 1.798 +inline void 1.799 +AbstractFramePtr::initArgsObj(ArgumentsObject &argsobj) const 1.800 +{ 1.801 + if (isInterpreterFrame()) { 1.802 + asInterpreterFrame()->initArgsObj(argsobj); 1.803 + return; 1.804 + } 1.805 +#ifdef JS_ION 1.806 + asBaselineFrame()->initArgsObj(argsobj); 1.807 +#else 1.808 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.809 +#endif 1.810 +} 1.811 +inline bool 1.812 +AbstractFramePtr::copyRawFrameSlots(AutoValueVector *vec) const 1.813 +{ 1.814 + if (isInterpreterFrame()) 1.815 + return asInterpreterFrame()->copyRawFrameSlots(vec); 1.816 +#ifdef JS_ION 1.817 + return asBaselineFrame()->copyRawFrameSlots(vec); 1.818 +#else 1.819 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.820 +#endif 1.821 +} 1.822 + 1.823 +inline bool 1.824 +AbstractFramePtr::prevUpToDate() const 1.825 +{ 1.826 + if (isInterpreterFrame()) 1.827 + return asInterpreterFrame()->prevUpToDate(); 1.828 +#ifdef JS_ION 1.829 + if (isBaselineFrame()) 1.830 + return asBaselineFrame()->prevUpToDate(); 1.831 + return asRematerializedFrame()->prevUpToDate(); 1.832 +#else 1.833 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.834 +#endif 1.835 +} 1.836 +inline void 1.837 +AbstractFramePtr::setPrevUpToDate() const 1.838 +{ 1.839 + if (isInterpreterFrame()) { 1.840 + asInterpreterFrame()->setPrevUpToDate(); 1.841 + return; 1.842 + } 1.843 +#ifdef JS_ION 1.844 + if (isBaselineFrame()) { 1.845 + asBaselineFrame()->setPrevUpToDate(); 1.846 + return; 1.847 + } 1.848 + asRematerializedFrame()->setPrevUpToDate(); 1.849 +#else 1.850 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.851 +#endif 1.852 +} 1.853 + 1.854 +inline Value & 1.855 +AbstractFramePtr::thisValue() const 1.856 +{ 1.857 + if (isInterpreterFrame()) 1.858 + return asInterpreterFrame()->thisValue(); 1.859 +#ifdef JS_ION 1.860 + if (isBaselineFrame()) 1.861 + return asBaselineFrame()->thisValue(); 1.862 + return asRematerializedFrame()->thisValue(); 1.863 +#else 1.864 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.865 +#endif 1.866 +} 1.867 + 1.868 +inline void 1.869 +AbstractFramePtr::popBlock(JSContext *cx) const 1.870 +{ 1.871 + if (isInterpreterFrame()) { 1.872 + asInterpreterFrame()->popBlock(cx); 1.873 + return; 1.874 + } 1.875 +#ifdef JS_ION 1.876 + asBaselineFrame()->popBlock(cx); 1.877 +#else 1.878 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.879 +#endif 1.880 +} 1.881 + 1.882 +inline void 1.883 +AbstractFramePtr::popWith(JSContext *cx) const 1.884 +{ 1.885 + if (isInterpreterFrame()) { 1.886 + asInterpreterFrame()->popWith(cx); 1.887 + return; 1.888 + } 1.889 +#ifdef JS_ION 1.890 + asBaselineFrame()->popWith(cx); 1.891 +#else 1.892 + MOZ_ASSUME_UNREACHABLE("Invalid frame"); 1.893 +#endif 1.894 +} 1.895 + 1.896 +Activation::Activation(JSContext *cx, Kind kind) 1.897 + : cx_(cx), 1.898 + compartment_(cx->compartment()), 1.899 + prev_(cx->mainThread().activation_), 1.900 + savedFrameChain_(0), 1.901 + hideScriptedCallerCount_(0), 1.902 + kind_(kind) 1.903 +{ 1.904 + cx->mainThread().activation_ = this; 1.905 +} 1.906 + 1.907 +Activation::~Activation() 1.908 +{ 1.909 + JS_ASSERT(cx_->mainThread().activation_ == this); 1.910 + JS_ASSERT(hideScriptedCallerCount_ == 0); 1.911 + cx_->mainThread().activation_ = prev_; 1.912 +} 1.913 + 1.914 +InterpreterActivation::InterpreterActivation(RunState &state, JSContext *cx, 1.915 + InterpreterFrame *entryFrame) 1.916 + : Activation(cx, Interpreter), 1.917 + state_(state), 1.918 + entryFrame_(entryFrame), 1.919 + opMask_(0) 1.920 +#ifdef DEBUG 1.921 + , oldFrameCount_(cx_->runtime()->interpreterStack().frameCount_) 1.922 +#endif 1.923 +{ 1.924 + if (!state.isGenerator()) { 1.925 + regs_.prepareToRun(*entryFrame, state.script()); 1.926 + JS_ASSERT(regs_.pc == state.script()->code()); 1.927 + } else { 1.928 + regs_ = state.asGenerator()->gen()->regs; 1.929 + } 1.930 + 1.931 + JS_ASSERT_IF(entryFrame_->isEvalFrame(), state_.script()->isActiveEval()); 1.932 +} 1.933 + 1.934 +InterpreterActivation::~InterpreterActivation() 1.935 +{ 1.936 + // Pop all inline frames. 1.937 + while (regs_.fp() != entryFrame_) 1.938 + popInlineFrame(regs_.fp()); 1.939 + 1.940 + JS_ASSERT(oldFrameCount_ == cx_->runtime()->interpreterStack().frameCount_); 1.941 + JS_ASSERT_IF(oldFrameCount_ == 0, cx_->runtime()->interpreterStack().allocator_.used() == 0); 1.942 + 1.943 + if (state_.isGenerator()) { 1.944 + JSGenerator *gen = state_.asGenerator()->gen(); 1.945 + gen->fp->unsetPushedSPSFrame(); 1.946 + gen->regs = regs_; 1.947 + return; 1.948 + } 1.949 + 1.950 + if (entryFrame_) 1.951 + cx_->runtime()->interpreterStack().releaseFrame(entryFrame_); 1.952 +} 1.953 + 1.954 +inline bool 1.955 +InterpreterActivation::pushInlineFrame(const CallArgs &args, HandleScript script, 1.956 + InitialFrameFlags initial) 1.957 +{ 1.958 + if (!cx_->runtime()->interpreterStack().pushInlineFrame(cx_, regs_, args, script, initial)) 1.959 + return false; 1.960 + JS_ASSERT(regs_.fp()->script()->compartment() == compartment_); 1.961 + return true; 1.962 +} 1.963 + 1.964 +inline void 1.965 +InterpreterActivation::popInlineFrame(InterpreterFrame *frame) 1.966 +{ 1.967 + (void)frame; // Quell compiler warning. 1.968 + JS_ASSERT(regs_.fp() == frame); 1.969 + JS_ASSERT(regs_.fp() != entryFrame_); 1.970 + 1.971 + cx_->runtime()->interpreterStack().popInlineFrame(regs_); 1.972 +} 1.973 + 1.974 +} /* namespace js */ 1.975 + 1.976 +#endif /* vm_Stack_inl_h */