js/src/vm/Stack-inl.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial