tor-browser

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

LexicalScopeEmitter.h (2930B)


      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 frontend_LexicalScopeEmitter_h
      8 #define frontend_LexicalScopeEmitter_h
      9 
     10 #include "mozilla/Attributes.h"  // MOZ_STACK_CLASS
     11 #include "mozilla/Maybe.h"       // Maybe
     12 
     13 #include "frontend/EmitterScope.h"   // EmitterScope
     14 #include "frontend/TDZCheckCache.h"  // TDZCheckCache
     15 #include "vm/Scope.h"                // ScopeKind, LexicalScope
     16 
     17 namespace js {
     18 namespace frontend {
     19 
     20 struct BytecodeEmitter;
     21 
     22 // Class for emitting bytecode for lexical scope.
     23 //
     24 // In addition to emitting code for entering and leaving a scope, this RAII
     25 // guard affects the code emitted for `break` and other non-structured
     26 // control flow. See NonLocalExitControl::prepareForNonLocalJump().
     27 //
     28 // Usage: (check for the return value is omitted for simplicity)
     29 //
     30 //   `{ ... }` -- lexical scope with no bindings
     31 //     LexicalScopeEmitter lse(this);
     32 //     lse.emitEmptyScope();
     33 //     emit(scopeBody);
     34 //     lse.emitEnd();
     35 //
     36 //   `{ let a; body }`
     37 //     LexicalScopeEmitter lse(this);
     38 //     lse.emitScope(ScopeKind::Lexical, scopeBinding);
     39 //     emit(let_and_body);
     40 //     lse.emitEnd();
     41 //
     42 //   `catch (e) { body }`
     43 //     LexicalScopeEmitter lse(this);
     44 //     lse.emitScope(ScopeKind::SimpleCatch, scopeBinding);
     45 //     emit(body);
     46 //     lse.emitEnd();
     47 //
     48 //   `catch ([a, b]) { body }`
     49 //     LexicalScopeEmitter lse(this);
     50 //     lse.emitScope(ScopeKind::Catch, scopeBinding);
     51 //     emit(body);
     52 //     lse.emitEnd();
     53 class MOZ_STACK_CLASS LexicalScopeEmitter {
     54  BytecodeEmitter* bce_;
     55 
     56  mozilla::Maybe<TDZCheckCache> tdzCache_;
     57  mozilla::Maybe<EmitterScope> emitterScope_;
     58 
     59 #ifdef DEBUG
     60  // The state of this emitter.
     61  //
     62  // +-------+ emitScope  +-------+ emitEnd  +-----+
     63  // | Start |----------->| Scope |--------->| End |
     64  // +-------+            +-------+          +-----+
     65  enum class State {
     66    // The initial state.
     67    Start,
     68 
     69    // After calling emitScope/emitEmptyScope.
     70    Scope,
     71 
     72    // After calling emitEnd.
     73    End,
     74  };
     75  State state_ = State::Start;
     76 #endif
     77 
     78 public:
     79  explicit LexicalScopeEmitter(BytecodeEmitter* bce);
     80 
     81  // Returns the scope object for non-empty scope.
     82  const EmitterScope& emitterScope() const { return *emitterScope_; }
     83 
     84  [[nodiscard]] bool emitScope(ScopeKind kind,
     85                               LexicalScope::ParserData* bindings
     86 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
     87                               ,
     88                               BlockKind blockKind = BlockKind::Other
     89 #endif
     90  );
     91  [[nodiscard]] bool emitEmptyScope();
     92 
     93  [[nodiscard]] bool emitEnd();
     94 };
     95 
     96 } /* namespace frontend */
     97 } /* namespace js */
     98 
     99 #endif /* frontend_LexicalScopeEmitter_h */