| // Copyright 2017 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_TORQUE_SCOPE_H_ |
| #define V8_TORQUE_SCOPE_H_ |
| |
| #include <map> |
| #include <string> |
| |
| #include "src/torque/ast.h" |
| #include "src/torque/types.h" |
| #include "src/torque/utils.h" |
| |
| namespace v8 { |
| namespace internal { |
| namespace torque { |
| |
| class ScopeChain; |
| class Variable; |
| class Declarable; |
| |
| class Scope { |
| public: |
| explicit Scope(ScopeChain& scope_chain); |
| |
| void Stream(std::ostream& stream) const { |
| stream << "scope " << std::to_string(scope_number_) << " {"; |
| for (auto& c : lookup_) { |
| stream << c.first << ","; |
| } |
| stream << "}"; |
| } |
| |
| int scope_number() const { return scope_number_; } |
| |
| ScopeChain& GetScopeChain() const { return scope_chain_; } |
| |
| void AddLiveVariables(std::set<const Variable*>& set); |
| |
| void Print(); |
| |
| class Activator; |
| |
| private: |
| friend class ScopeChain; |
| |
| void CheckAlreadyDeclared(SourcePosition pos, const std::string& name, |
| const char* new_type); |
| |
| void Declare(const std::string& name, Declarable* d) { |
| DCHECK_EQ(lookup_.end(), lookup_.find(name)); |
| DCHECK(d != nullptr); |
| lookup_[name] = d; |
| } |
| |
| Declarable* Lookup(const std::string& name) { |
| auto i = lookup_.find(name); |
| if (i == lookup_.end()) { |
| return nullptr; |
| } |
| return i->second; |
| } |
| |
| ScopeChain& scope_chain_; |
| int scope_number_; |
| int private_label_number_; |
| std::map<std::string, Declarable*> lookup_; |
| }; |
| |
| class Scope::Activator { |
| public: |
| explicit Activator(Scope* scope); |
| ~Activator(); |
| |
| private: |
| Scope* scope_; |
| }; |
| |
| class ScopeChain { |
| public: |
| ScopeChain() : next_scope_number_(0) {} |
| Scope* NewScope(); |
| |
| Scope* TopScope() const { return current_scopes_.back(); } |
| void PushScope(Scope* scope) { current_scopes_.push_back(scope); } |
| void PopScope() { current_scopes_.pop_back(); } |
| |
| std::set<const Variable*> GetLiveVariables() { |
| std::set<const Variable*> result; |
| for (auto scope : current_scopes_) { |
| scope->AddLiveVariables(result); |
| } |
| return result; |
| } |
| |
| void Declare(const std::string& name, Declarable* d) { |
| TopScope()->Declare(name, d); |
| } |
| |
| Declarable* Lookup(const std::string& name) { |
| auto e = current_scopes_.rend(); |
| auto c = current_scopes_.rbegin(); |
| while (c != e) { |
| Declarable* result = (*c)->Lookup(name); |
| if (result != nullptr) return result; |
| ++c; |
| } |
| return nullptr; |
| } |
| |
| Declarable* ShallowLookup(const std::string& name) { |
| auto& e = current_scopes_.back(); |
| return e->Lookup(name); |
| } |
| |
| Declarable* LookupGlobalScope(const std::string& name) { |
| auto& e = current_scopes_.front(); |
| return e->Lookup(name); |
| } |
| |
| void Print() { |
| for (auto s : current_scopes_) { |
| s->Print(); |
| } |
| } |
| |
| struct Snapshot { |
| ScopeChain* chain; |
| std::vector<Scope*> current_scopes; |
| }; |
| |
| Snapshot TaskSnapshot() { return {this, current_scopes_}; } |
| |
| class ScopedSnapshotRestorer { |
| public: |
| explicit ScopedSnapshotRestorer(const Snapshot& snapshot) |
| : chain_(snapshot.chain) { |
| saved_ = chain_->current_scopes_; |
| chain_->current_scopes_ = snapshot.current_scopes; |
| } |
| ~ScopedSnapshotRestorer() { chain_->current_scopes_ = saved_; } |
| |
| private: |
| ScopeChain* chain_; |
| std::vector<Scope*> saved_; |
| }; |
| |
| private: |
| friend class Scope; |
| friend class ScopedSnapshotRestorer; |
| |
| int GetNextScopeNumber() { return next_scope_number_++; } |
| |
| int next_scope_number_; |
| std::vector<std::unique_ptr<Scope>> scopes_; |
| std::vector<Scope*> current_scopes_; |
| }; |
| |
| inline std::ostream& operator<<(std::ostream& os, const Scope& scope) { |
| scope.Stream(os); |
| return os; |
| } |
| |
| } // namespace torque |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_TORQUE_SCOPE_H_ |