TDZCheckCache.cpp (2000B)
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 #include "frontend/TDZCheckCache.h" 8 9 #include "frontend/BytecodeEmitter.h" 10 11 using namespace js; 12 using namespace js::frontend; 13 14 using mozilla::Maybe; 15 using mozilla::Nothing; 16 using mozilla::Some; 17 18 TDZCheckCache::TDZCheckCache(BytecodeEmitter* bce) 19 : Nestable<TDZCheckCache>(&bce->innermostTDZCheckCache), 20 cache_(bce->fc->nameCollectionPool()) {} 21 22 bool TDZCheckCache::ensureCache(BytecodeEmitter* bce) { 23 return cache_ || cache_.acquire(bce->fc); 24 } 25 26 Maybe<MaybeCheckTDZ> TDZCheckCache::needsTDZCheck(BytecodeEmitter* bce, 27 TaggedParserAtomIndex name) { 28 if (!ensureCache(bce)) { 29 return Nothing(); 30 } 31 32 CheckTDZMap::AddPtr p = cache_->lookupForAdd(name); 33 if (p) { 34 return Some(p->value().wrapped); 35 } 36 37 MaybeCheckTDZ rv = CheckTDZ; 38 for (TDZCheckCache* it = enclosing(); it; it = it->enclosing()) { 39 if (it->cache_) { 40 if (CheckTDZMap::Ptr p2 = it->cache_->lookup(name)) { 41 rv = p2->value(); 42 break; 43 } 44 } 45 } 46 47 if (!cache_->add(p, name, rv)) { 48 ReportOutOfMemory(bce->fc); 49 return Nothing(); 50 } 51 52 return Some(rv); 53 } 54 55 bool TDZCheckCache::noteTDZCheck(BytecodeEmitter* bce, 56 TaggedParserAtomIndex name, 57 MaybeCheckTDZ check) { 58 if (!ensureCache(bce)) { 59 return false; 60 } 61 62 CheckTDZMap::AddPtr p = cache_->lookupForAdd(name); 63 if (p) { 64 MOZ_ASSERT( 65 !check, 66 "TDZ only needs to be checked once per binding per basic block."); 67 p->value() = check; 68 } else { 69 if (!cache_->add(p, name, check)) { 70 ReportOutOfMemory(bce->fc); 71 return false; 72 } 73 } 74 75 return true; 76 }