tor-browser

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

ForOfEmitter.h (3879B)


      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_ForOfEmitter_h
      8 #define frontend_ForOfEmitter_h
      9 
     10 #include "mozilla/Attributes.h"  // MOZ_STACK_CLASS
     11 #include "mozilla/Maybe.h"       // mozilla::Maybe
     12 
     13 #include <stdint.h>  // int32_t
     14 
     15 #include "frontend/ForOfLoopControl.h"  // ForOfLoopControl
     16 #include "frontend/IteratorKind.h"      // IteratorKind
     17 #include "frontend/SelfHostedIter.h"    // SelfHostedIter
     18 #include "frontend/TDZCheckCache.h"     // TDZCheckCache
     19 
     20 namespace js {
     21 namespace frontend {
     22 
     23 struct BytecodeEmitter;
     24 class EmitterScope;
     25 
     26 // Class for emitting bytecode for for-of loop.
     27 //
     28 // Usage: (check for the return value is omitted for simplicity)
     29 //
     30 //   `for (init of iterated) body`
     31 //     // headLexicalEmitterScope: lexical scope for init
     32 //     ForOfEmitter forOf(this, headLexicalEmitterScope);
     33 //     forOf.emitIterated();
     34 //     emit(iterated);
     35 //     forOf.emitInitialize(offset_of_for);
     36 //     emit(init);
     37 //     forOf.emitBody();
     38 //     emit(body);
     39 //     forOf.emitEnd(offset_of_iterated);
     40 //
     41 class MOZ_STACK_CLASS ForOfEmitter {
     42  BytecodeEmitter* bce_;
     43 
     44 #ifdef DEBUG
     45  // The stack depth before emitting IteratorNext code inside loop.
     46  int32_t loopDepth_ = 0;
     47 #endif
     48 
     49  SelfHostedIter selfHostedIter_;
     50  IteratorKind iterKind_;
     51 
     52  mozilla::Maybe<ForOfLoopControl> loopInfo_;
     53 
     54  // The lexical scope to be freshened for each iteration.
     55  // See the comment in `emitBody` for more details.
     56  const EmitterScope* headLexicalEmitterScope_;
     57 
     58  // Cache for the iterated value.
     59  // (The cache for the iteration body is inside `loopInfo_`)
     60  mozilla::Maybe<TDZCheckCache> tdzCacheForIteratedValue_;
     61 
     62 #ifdef DEBUG
     63  // The state of this emitter.
     64  //
     65  // +-------+ emitIterated +----------+ emitInitialize +------------+
     66  // | Start |------------->| Iterated |--------------->| Initialize |-+
     67  // +-------+              +----------+                +------------+ |
     68  //                                                                   |
     69  //                                +----------------------------------+
     70  //                                |
     71  //                                | emitBody +------+ emitEnd  +-----+
     72  //                                +----------| Body |--------->| End |
     73  //                                           +------+          +-----+
     74  enum class State {
     75    // The initial state.
     76    Start,
     77 
     78    // After calling emitIterated.
     79    Iterated,
     80 
     81    // After calling emitInitialize.
     82    Initialize,
     83 
     84    // After calling emitBody.
     85    Body,
     86 
     87    // After calling emitEnd.
     88    End
     89  };
     90  State state_ = State::Start;
     91 #endif
     92 
     93 public:
     94 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
     95  enum class HeadUsingDeclarationKind { None, Sync, Async };
     96 
     97 private:
     98  HeadUsingDeclarationKind usingDeclarationInHead_ =
     99      HeadUsingDeclarationKind::None;
    100 
    101 public:
    102 #endif
    103 
    104  ForOfEmitter(BytecodeEmitter* bce,
    105               const EmitterScope* headLexicalEmitterScope,
    106               SelfHostedIter selfHostedIter, IteratorKind iterKind
    107 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
    108               ,
    109               HeadUsingDeclarationKind usingDeclarationInHead
    110 #endif
    111  );
    112 
    113  // The offset in the source code for each character below:
    114  //
    115  //   for ( var x of obj ) { ... }
    116  //   ^              ^
    117  //   |              |
    118  //   |              iteratedPos
    119  //   |
    120  //   forPos
    121  [[nodiscard]] bool emitIterated();
    122  [[nodiscard]] bool emitInitialize(uint32_t forPos);
    123  [[nodiscard]] bool emitBody();
    124  [[nodiscard]] bool emitEnd(uint32_t iteratedPos);
    125 };
    126 
    127 } /* namespace frontend */
    128 } /* namespace js */
    129 
    130 #endif /* frontend_ForOfEmitter_h */