tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

BaselineFrame-inl.h (4616B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef jit_BaselineFrame_inl_h
      8 #define jit_BaselineFrame_inl_h
      9 
     10 #include "jit/BaselineFrame.h"
     11 
     12 #include "jit/TrialInlining.h"
     13 #include "jit/VMFunctions.h"
     14 #include "vm/JSContext.h"
     15 #include "vm/Realm.h"
     16 
     17 #include "vm/EnvironmentObject-inl.h"
     18 #include "vm/JSScript-inl.h"
     19 #include "vm/NativeObject-inl.h"  // js::NativeObject::initDenseElementsFromRange
     20 
     21 namespace js {
     22 namespace jit {
     23 
     24 template <typename SpecificEnvironment>
     25 inline void BaselineFrame::pushOnEnvironmentChain(SpecificEnvironment& env) {
     26  MOZ_ASSERT(*environmentChain() == env.enclosingEnvironment());
     27  envChain_ = &env;
     28  if (IsFrameInitialEnvironment(this, env)) {
     29    flags_ |= HAS_INITIAL_ENV;
     30  }
     31 }
     32 
     33 template <typename SpecificEnvironment>
     34 inline void BaselineFrame::popOffEnvironmentChain() {
     35  MOZ_ASSERT(envChain_->is<SpecificEnvironment>());
     36  envChain_ = &envChain_->as<SpecificEnvironment>().enclosingEnvironment();
     37 }
     38 
     39 inline void BaselineFrame::replaceInnermostEnvironment(EnvironmentObject& env) {
     40  MOZ_ASSERT(env.enclosingEnvironment() ==
     41             envChain_->as<EnvironmentObject>().enclosingEnvironment());
     42  envChain_ = &env;
     43 }
     44 
     45 inline bool BaselineFrame::saveGeneratorSlots(JSContext* cx, unsigned nslots,
     46                                              ArrayObject* dest) const {
     47  // By convention, generator slots are stored in interpreter order,
     48  // which is the reverse of BaselineFrame order.
     49 
     50  MOZ_ASSERT(nslots == numValueSlots(debugFrameSize()) - 1);
     51  const Value* end = reinterpret_cast<const Value*>(this);
     52  mozilla::Span<const Value> span{end - nslots, end};
     53  return dest->initDenseElementsFromRange(cx, span.rbegin(), span.rend());
     54 }
     55 
     56 inline bool BaselineFrame::pushLexicalEnvironment(JSContext* cx,
     57                                                  Handle<LexicalScope*> scope) {
     58  BlockLexicalEnvironmentObject* env =
     59      BlockLexicalEnvironmentObject::createForFrame(cx, scope, this);
     60  if (!env) {
     61    return false;
     62  }
     63  pushOnEnvironmentChain(*env);
     64 
     65  return true;
     66 }
     67 
     68 inline bool BaselineFrame::pushClassBodyEnvironment(
     69    JSContext* cx, Handle<ClassBodyScope*> scope) {
     70  ClassBodyLexicalEnvironmentObject* env =
     71      ClassBodyLexicalEnvironmentObject::createForFrame(cx, scope, this);
     72  if (!env) {
     73    return false;
     74  }
     75  pushOnEnvironmentChain(*env);
     76 
     77  return true;
     78 }
     79 
     80 template <bool IsDebuggee>
     81 inline bool BaselineFrame::freshenLexicalEnvironment(JSContext* cx,
     82                                                     const jsbytecode* pc) {
     83  Rooted<BlockLexicalEnvironmentObject*> current(
     84      cx, &envChain_->as<BlockLexicalEnvironmentObject>());
     85  BlockLexicalEnvironmentObject* clone =
     86      BlockLexicalEnvironmentObject::clone(cx, current);
     87  if (!clone) {
     88    return false;
     89  }
     90 
     91  if constexpr (IsDebuggee) {
     92    MOZ_ASSERT(pc);
     93    Rooted<BlockLexicalEnvironmentObject*> cloneRoot(cx, clone);
     94    MOZ_ALWAYS_TRUE(DebugLeaveLexicalEnv(cx, this, pc));
     95    clone = cloneRoot;
     96  }
     97 
     98  replaceInnermostEnvironment(*clone);
     99  return true;
    100 }
    101 
    102 template <bool IsDebuggee>
    103 inline bool BaselineFrame::recreateLexicalEnvironment(JSContext* cx,
    104                                                      const jsbytecode* pc) {
    105  Rooted<BlockLexicalEnvironmentObject*> current(
    106      cx, &envChain_->as<BlockLexicalEnvironmentObject>());
    107  BlockLexicalEnvironmentObject* clone =
    108      BlockLexicalEnvironmentObject::recreate(cx, current);
    109  if (!clone) {
    110    return false;
    111  }
    112 
    113  if constexpr (IsDebuggee) {
    114    MOZ_ASSERT(pc);
    115    Rooted<BlockLexicalEnvironmentObject*> cloneRoot(cx, clone);
    116    MOZ_ALWAYS_TRUE(DebugLeaveLexicalEnv(cx, this, pc));
    117    clone = cloneRoot;
    118  }
    119 
    120  replaceInnermostEnvironment(*clone);
    121  return true;
    122 }
    123 
    124 inline CallObject& BaselineFrame::callObj() const {
    125  MOZ_ASSERT(hasInitialEnvironment());
    126  MOZ_ASSERT(callee()->needsCallObject());
    127 
    128  JSObject* obj = environmentChain();
    129  while (!obj->is<CallObject>()) {
    130    obj = obj->enclosingEnvironment();
    131  }
    132  return obj->as<CallObject>();
    133 }
    134 
    135 inline JSScript* BaselineFrame::outerScript() const {
    136  if (!icScript()->isInlined()) {
    137    return script();
    138  }
    139  return icScript()->inliningRoot()->owningScript();
    140 }
    141 
    142 inline void BaselineFrame::unsetIsDebuggee() {
    143  MOZ_ASSERT(!script()->isDebuggee());
    144  flags_ &= ~DEBUGGEE;
    145 }
    146 
    147 }  // namespace jit
    148 }  // namespace js
    149 
    150 #endif /* jit_BaselineFrame_inl_h */