js/src/vm/Stack-inl.h

changeset 0
6474c204b198
     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 &regs, 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 &regs)
   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 */

mercurial