TDZCheckCache.h (2298B)
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_TDZCheckCache_h 8 #define frontend_TDZCheckCache_h 9 10 #include "mozilla/Maybe.h" 11 12 #include "ds/Nestable.h" 13 #include "frontend/NameCollections.h" 14 15 namespace js { 16 namespace frontend { 17 18 struct BytecodeEmitter; 19 class TaggedParserAtomIndex; 20 21 enum MaybeCheckTDZ { CheckTDZ = true, DontCheckTDZ = false }; 22 23 using CheckTDZMap = RecyclableNameMap<MaybeCheckTDZ>; 24 25 // A cache that tracks Temporal Dead Zone (TDZ) checks, so that any use of a 26 // lexical variable that's dominated by an earlier use, or by evaluation of its 27 // declaration (which will initialize it, perhaps to |undefined|), doesn't have 28 // to redundantly check that the lexical variable has been initialized 29 // 30 // Each basic block should have a TDZCheckCache in scope. Some NestableControl 31 // subclasses contain a TDZCheckCache. 32 // 33 // When a scope containing lexical variables is entered, all such variables are 34 // marked as CheckTDZ. When a lexical variable is accessed, its entry is 35 // checked. If it's CheckTDZ, a JSOp::CheckLexical is emitted and then the 36 // entry is marked DontCheckTDZ. If it's DontCheckTDZ, no check is emitted 37 // because a prior check would have already failed. Finally, because 38 // evaluating a lexical variable declaration initializes it (after any 39 // initializer is evaluated), evaluating a lexical declaration marks its entry 40 // as DontCheckTDZ. 41 class MOZ_STACK_CLASS TDZCheckCache : public Nestable<TDZCheckCache> { 42 PooledMapPtr<CheckTDZMap> cache_; 43 44 [[nodiscard]] bool ensureCache(BytecodeEmitter* bce); 45 46 public: 47 explicit TDZCheckCache(BytecodeEmitter* bce); 48 49 mozilla::Maybe<MaybeCheckTDZ> needsTDZCheck(BytecodeEmitter* bce, 50 TaggedParserAtomIndex name); 51 [[nodiscard]] bool noteTDZCheck(BytecodeEmitter* bce, 52 TaggedParserAtomIndex name, 53 MaybeCheckTDZ check); 54 }; 55 56 } /* namespace frontend */ 57 } /* namespace js */ 58 59 #endif /* frontend_TDZCheckCache_h */