• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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