1 // Copyright 2017 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_TORQUE_SCOPE_H_ 6 #define V8_TORQUE_SCOPE_H_ 7 8 #include <string> 9 10 #include "./antlr4-runtime.h" 11 #include "src/torque/ast.h" 12 #include "src/torque/types.h" 13 #include "src/torque/utils.h" 14 15 namespace v8 { 16 namespace internal { 17 namespace torque { 18 19 class ScopeChain; 20 21 class Scope { 22 public: 23 explicit Scope(ScopeChain& scope_chain); 24 Stream(std::ostream & stream)25 void Stream(std::ostream& stream) const { 26 stream << "scope " << std::to_string(scope_number_) << " {"; 27 for (auto& c : lookup_) { 28 stream << c.first << ","; 29 } 30 stream << "}"; 31 } 32 scope_number()33 int scope_number() const { return scope_number_; } 34 GetScopeChain()35 ScopeChain& GetScopeChain() const { return scope_chain_; } 36 37 void AddLiveVariables(std::set<const Variable*>& set); 38 39 void Print(); 40 41 class Activator; 42 43 private: 44 friend class ScopeChain; 45 46 void CheckAlreadyDeclared(SourcePosition pos, const std::string& name, 47 const char* new_type); 48 Declare(const std::string & name,Declarable * d)49 void Declare(const std::string& name, Declarable* d) { 50 DCHECK_EQ(lookup_.end(), lookup_.find(name)); 51 DCHECK(d != nullptr); 52 lookup_[name] = d; 53 } 54 Lookup(const std::string & name)55 Declarable* Lookup(const std::string& name) { 56 auto i = lookup_.find(name); 57 if (i == lookup_.end()) { 58 return nullptr; 59 } 60 return i->second; 61 } 62 63 ScopeChain& scope_chain_; 64 int scope_number_; 65 int private_label_number_; 66 std::map<std::string, Declarable*> lookup_; 67 }; 68 69 class Scope::Activator { 70 public: 71 explicit Activator(Scope* scope); 72 ~Activator(); 73 74 private: 75 Scope* scope_; 76 }; 77 78 class ScopeChain { 79 public: ScopeChain()80 ScopeChain() : next_scope_number_(0) {} 81 Scope* NewScope(); 82 TopScope()83 Scope* TopScope() const { return current_scopes_.back(); } PushScope(Scope * scope)84 void PushScope(Scope* scope) { current_scopes_.push_back(scope); } PopScope()85 void PopScope() { current_scopes_.pop_back(); } 86 GetLiveVariables()87 std::set<const Variable*> GetLiveVariables() { 88 std::set<const Variable*> result; 89 for (auto scope : current_scopes_) { 90 scope->AddLiveVariables(result); 91 } 92 return result; 93 } 94 Declare(const std::string & name,Declarable * d)95 void Declare(const std::string& name, Declarable* d) { 96 TopScope()->Declare(name, d); 97 } 98 Lookup(const std::string & name)99 Declarable* Lookup(const std::string& name) { 100 auto e = current_scopes_.rend(); 101 auto c = current_scopes_.rbegin(); 102 while (c != e) { 103 Declarable* result = (*c)->Lookup(name); 104 if (result != nullptr) return result; 105 ++c; 106 } 107 return nullptr; 108 } 109 ShallowLookup(const std::string & name)110 Declarable* ShallowLookup(const std::string& name) { 111 auto& e = current_scopes_.back(); 112 return e->Lookup(name); 113 } 114 LookupGlobalScope(const std::string & name)115 Declarable* LookupGlobalScope(const std::string& name) { 116 auto& e = current_scopes_.front(); 117 return e->Lookup(name); 118 } 119 Print()120 void Print() { 121 for (auto s : current_scopes_) { 122 s->Print(); 123 } 124 } 125 126 struct Snapshot { 127 ScopeChain* chain; 128 std::vector<Scope*> current_scopes; 129 }; 130 TaskSnapshot()131 Snapshot TaskSnapshot() { return {this, current_scopes_}; } 132 133 class ScopedSnapshotRestorer { 134 public: ScopedSnapshotRestorer(const Snapshot & snapshot)135 explicit ScopedSnapshotRestorer(const Snapshot& snapshot) 136 : chain_(snapshot.chain) { 137 saved_ = chain_->current_scopes_; 138 chain_->current_scopes_ = snapshot.current_scopes; 139 } ~ScopedSnapshotRestorer()140 ~ScopedSnapshotRestorer() { chain_->current_scopes_ = saved_; } 141 142 private: 143 ScopeChain* chain_; 144 std::vector<Scope*> saved_; 145 }; 146 147 private: 148 friend class Scope; 149 friend class ScopedSnapshotRestorer; 150 GetNextScopeNumber()151 int GetNextScopeNumber() { return next_scope_number_++; } 152 153 int next_scope_number_; 154 std::vector<std::unique_ptr<Scope>> scopes_; 155 std::vector<Scope*> current_scopes_; 156 }; 157 158 inline std::ostream& operator<<(std::ostream& os, const Scope& scope) { 159 scope.Stream(os); 160 return os; 161 } 162 163 } // namespace torque 164 } // namespace internal 165 } // namespace v8 166 167 #endif // V8_TORQUE_SCOPE_H_ 168