// 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 <string> #include "./antlr4-runtime.h" #include "src/torque/ast.h" #include "src/torque/types.h" #include "src/torque/utils.h" namespace v8 { namespace internal { namespace torque { class ScopeChain; 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_