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