WhileEmitter.h (2855B)
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_WhileEmitter_h 8 #define frontend_WhileEmitter_h 9 10 #include "mozilla/Attributes.h" 11 #include "mozilla/Maybe.h" 12 13 #include <stdint.h> 14 15 #include "frontend/BytecodeControlStructures.h" 16 #include "frontend/TDZCheckCache.h" 17 18 namespace js { 19 namespace frontend { 20 21 struct BytecodeEmitter; 22 23 // Class for emitting bytecode for while loop. 24 // 25 // Usage: (check for the return value is omitted for simplicity) 26 // 27 // `while (cond) body` 28 // WhileEmitter wh(this); 29 // wh.emitCond(offset_of_while, 30 // offset_of_body, 31 // offset_of_end); 32 // emit(cond); 33 // wh.emitBody(); 34 // emit(body); 35 // wh.emitEnd(); 36 // 37 class MOZ_STACK_CLASS WhileEmitter { 38 #if defined(ENABLE_DECORATORS) || defined(ENABLE_EXPLICIT_RESOURCE_MANAGEMENT) 39 protected: 40 #endif 41 BytecodeEmitter* bce_; 42 43 mozilla::Maybe<LoopControl> loopInfo_; 44 45 // Cache for the loop body, which is enclosed by the cache in `loopInfo_`, 46 // which is effectively for the loop condition. 47 mozilla::Maybe<TDZCheckCache> tdzCacheForBody_; 48 49 #ifdef DEBUG 50 // The state of this emitter. 51 // 52 // +-------+ emitCond +------+ emitBody +------+ emitEnd +-----+ 53 // | Start |--------->| Cond |--------->| Body |--------->| End | 54 // +-------+ +------+ +------+ +-----+ 55 enum class State { 56 // The initial state. 57 Start, 58 59 // After calling emitCond. 60 Cond, 61 62 // After calling emitBody. 63 Body, 64 65 // After calling emitEnd. 66 End 67 }; 68 State state_ = State::Start; 69 #endif 70 71 public: 72 explicit WhileEmitter(BytecodeEmitter* bce); 73 74 // Parameters are the offset in the source code for each character below: 75 // 76 // while ( x < 20 ) { ... } 77 // ^ ^ ^ 78 // | | | 79 // | | endPos_ 80 // | | 81 // | condPos_ 82 // | 83 // whilePos_ 84 [[nodiscard]] bool emitCond(uint32_t whilePos, uint32_t condPos, 85 uint32_t endPos); 86 [[nodiscard]] bool emitBody(); 87 [[nodiscard]] bool emitEnd(); 88 }; 89 90 #if defined(ENABLE_DECORATORS) || defined(ENABLE_EXPLICIT_RESOURCE_MANAGEMENT) 91 // This version is for emitting the condition in synthesized code that 92 // does not have a corresponding location in the source code. 93 class MOZ_STACK_CLASS InternalWhileEmitter : public WhileEmitter { 94 public: 95 explicit InternalWhileEmitter(BytecodeEmitter* bce) : WhileEmitter(bce) {} 96 [[nodiscard]] bool emitCond(); 97 }; 98 #endif 99 100 } /* namespace frontend */ 101 } /* namespace js */ 102 103 #endif /* frontend_WhileEmitter_h */