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