• 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_DECLARABLE_H_
6 #define V8_TORQUE_DECLARABLE_H_
7 
8 #include <cassert>
9 #include <string>
10 
11 #include "src/base/functional.h"
12 #include "src/base/logging.h"
13 #include "src/torque/ast.h"
14 #include "src/torque/types.h"
15 #include "src/torque/utils.h"
16 
17 namespace v8 {
18 namespace internal {
19 namespace torque {
20 
21 class Scope;
22 class ScopeChain;
23 class Generic;
24 
25 class Declarable {
26  public:
~Declarable()27   virtual ~Declarable() {}
28   enum Kind {
29     kVariable,
30     kParameter,
31     kMacro,
32     kMacroList,
33     kBuiltin,
34     kRuntimeFunction,
35     kGeneric,
36     kGenericList,
37     kTypeAlias,
38     kLabel,
39     kExternConstant,
40     kModuleConstant
41   };
kind()42   Kind kind() const { return kind_; }
IsMacro()43   bool IsMacro() const { return kind() == kMacro; }
IsBuiltin()44   bool IsBuiltin() const { return kind() == kBuiltin; }
IsRuntimeFunction()45   bool IsRuntimeFunction() const { return kind() == kRuntimeFunction; }
IsGeneric()46   bool IsGeneric() const { return kind() == kGeneric; }
IsTypeAlias()47   bool IsTypeAlias() const { return kind() == kTypeAlias; }
IsParameter()48   bool IsParameter() const { return kind() == kParameter; }
IsLabel()49   bool IsLabel() const { return kind() == kLabel; }
IsVariable()50   bool IsVariable() const { return kind() == kVariable; }
IsMacroList()51   bool IsMacroList() const { return kind() == kMacroList; }
IsGenericList()52   bool IsGenericList() const { return kind() == kGenericList; }
IsExternConstant()53   bool IsExternConstant() const { return kind() == kExternConstant; }
IsModuleConstant()54   bool IsModuleConstant() const { return kind() == kModuleConstant; }
IsValue()55   bool IsValue() const {
56     return IsVariable() || IsExternConstant() || IsParameter() ||
57            IsModuleConstant();
58   }
type_name()59   virtual const char* type_name() const { return "<<unknown>>"; }
60 
61  protected:
Declarable(Kind kind)62   explicit Declarable(Kind kind) : kind_(kind) {}
63 
64  private:
65   const Kind kind_;
66 };
67 
68 #define DECLARE_DECLARABLE_BOILERPLATE(x, y)                  \
69   static x* cast(Declarable* declarable) {                    \
70     DCHECK(declarable->Is##x());                              \
71     return static_cast<x*>(declarable);                       \
72   }                                                           \
73   static const x* cast(const Declarable* declarable) {        \
74     DCHECK(declarable->Is##x());                              \
75     return static_cast<const x*>(declarable);                 \
76   }                                                           \
77   const char* type_name() const override { return #y; }       \
78   static x* DynamicCast(Declarable* declarable) {             \
79     if (!declarable) return nullptr;                          \
80     if (!declarable->Is##x()) return nullptr;                 \
81     return static_cast<x*>(declarable);                       \
82   }                                                           \
83   static const x* DynamicCast(const Declarable* declarable) { \
84     if (!declarable) return nullptr;                          \
85     if (!declarable->Is##x()) return nullptr;                 \
86     return static_cast<const x*>(declarable);                 \
87   }
88 
89 class Value : public Declarable {
90  public:
name()91   const std::string& name() const { return name_; }
IsConst()92   virtual bool IsConst() const { return true; }
93   virtual std::string value() const = 0;
RValue()94   virtual std::string RValue() const { return value(); }
95   DECLARE_DECLARABLE_BOILERPLATE(Value, value);
type()96   const Type* type() const { return type_; }
97 
98  protected:
Value(Kind kind,const Type * type,const std::string & name)99   Value(Kind kind, const Type* type, const std::string& name)
100       : Declarable(kind), type_(type), name_(name) {}
101 
102  private:
103   const Type* type_;
104   std::string name_;
105 };
106 
107 class Parameter : public Value {
108  public:
109   DECLARE_DECLARABLE_BOILERPLATE(Parameter, parameter);
value()110   std::string value() const override { return var_name_; }
111 
112  private:
113   friend class Declarations;
Parameter(const std::string & name,const Type * type,const std::string & var_name)114   Parameter(const std::string& name, const Type* type,
115             const std::string& var_name)
116       : Value(Declarable::kParameter, type, name), var_name_(var_name) {}
117 
118   std::string var_name_;
119 };
120 
121 class ModuleConstant : public Value {
122  public:
123   DECLARE_DECLARABLE_BOILERPLATE(ModuleConstant, constant);
value()124   std::string value() const override { UNREACHABLE(); }
RValue()125   std::string RValue() const override { return name() + "()"; }
126 
127  private:
128   friend class Declarations;
ModuleConstant(const std::string & name,const Type * type)129   explicit ModuleConstant(const std::string& name, const Type* type)
130       : Value(Declarable::kModuleConstant, type, name) {}
131 };
132 
133 class Variable : public Value {
134  public:
135   DECLARE_DECLARABLE_BOILERPLATE(Variable, variable);
IsConst()136   bool IsConst() const override { return const_; }
value()137   std::string value() const override { return value_; }
138   std::string RValue() const override;
Define()139   void Define() {
140     if (defined_ && IsConst()) {
141       ReportError("Cannot re-define a const-bound variable.");
142     }
143     defined_ = true;
144   }
IsDefined()145   bool IsDefined() const { return defined_; }
146 
147  private:
148   friend class Declarations;
Variable(const std::string & name,const std::string & value,const Type * type,bool is_const)149   Variable(const std::string& name, const std::string& value, const Type* type,
150            bool is_const)
151       : Value(Declarable::kVariable, type, name),
152         value_(value),
153         defined_(false),
154         const_(is_const) {
155     DCHECK_IMPLIES(type->IsConstexpr(), IsConst());
156   }
157 
158   std::string value_;
159   bool defined_;
160   bool const_;
161 };
162 
163 class Label : public Declarable {
164  public:
AddVariable(Variable * var)165   void AddVariable(Variable* var) { parameters_.push_back(var); }
name()166   std::string name() const { return name_; }
generated()167   std::string generated() const { return generated_; }
GetParameter(size_t i)168   Variable* GetParameter(size_t i) const { return parameters_[i]; }
GetParameterCount()169   size_t GetParameterCount() const { return parameters_.size(); }
GetParameters()170   const std::vector<Variable*>& GetParameters() const { return parameters_; }
171 
172   DECLARE_DECLARABLE_BOILERPLATE(Label, label);
MarkUsed()173   void MarkUsed() { used_ = true; }
IsUsed()174   bool IsUsed() const { return used_; }
175 
176  private:
177   friend class Declarations;
Label(const std::string & name)178   explicit Label(const std::string& name)
179       : Declarable(Declarable::kLabel),
180         name_(name),
181         generated_("label_" + name + "_" + std::to_string(next_id_++)),
182         used_(false) {}
183 
184   std::string name_;
185   std::string generated_;
186   std::vector<Variable*> parameters_;
187   static size_t next_id_;
188   bool used_;
189 };
190 
191 class ExternConstant : public Value {
192  public:
193   DECLARE_DECLARABLE_BOILERPLATE(ExternConstant, constant);
value()194   std::string value() const override { return value_; }
195 
196  private:
197   friend class Declarations;
ExternConstant(const std::string & name,const Type * type,const std::string & value)198   explicit ExternConstant(const std::string& name, const Type* type,
199                           const std::string& value)
200       : Value(Declarable::kExternConstant, type, name), value_(value) {}
201 
202   std::string value_;
203 };
204 
205 class Callable : public Declarable {
206  public:
cast(Declarable * declarable)207   static Callable* cast(Declarable* declarable) {
208     assert(declarable->IsMacro() || declarable->IsBuiltin() ||
209            declarable->IsRuntimeFunction());
210     return static_cast<Callable*>(declarable);
211   }
cast(const Declarable * declarable)212   static const Callable* cast(const Declarable* declarable) {
213     assert(declarable->IsMacro() || declarable->IsBuiltin() ||
214            declarable->IsRuntimeFunction());
215     return static_cast<const Callable*>(declarable);
216   }
name()217   const std::string& name() const { return name_; }
signature()218   const Signature& signature() const { return signature_; }
parameter_names()219   const NameVector& parameter_names() const {
220     return signature_.parameter_names;
221   }
HasReturnValue()222   bool HasReturnValue() const {
223     return !signature_.return_type->IsVoidOrNever();
224   }
IncrementReturns()225   void IncrementReturns() { ++returns_; }
HasReturns()226   bool HasReturns() const { return returns_; }
generic()227   base::Optional<Generic*> generic() const { return generic_; }
228 
229  protected:
Callable(Declarable::Kind kind,const std::string & name,const Signature & signature,base::Optional<Generic * > generic)230   Callable(Declarable::Kind kind, const std::string& name,
231            const Signature& signature, base::Optional<Generic*> generic)
232       : Declarable(kind),
233         name_(name),
234         signature_(signature),
235         returns_(0),
236         generic_(generic) {}
237 
238  private:
239   std::string name_;
240   Signature signature_;
241   size_t returns_;
242   base::Optional<Generic*> generic_;
243 };
244 
245 class Macro : public Callable {
246  public:
247   DECLARE_DECLARABLE_BOILERPLATE(Macro, macro);
248 
249  private:
250   friend class Declarations;
Macro(const std::string & name,const Signature & signature,base::Optional<Generic * > generic)251   Macro(const std::string& name, const Signature& signature,
252         base::Optional<Generic*> generic)
253       : Callable(Declarable::kMacro, name, signature, generic) {
254     if (signature.parameter_types.var_args) {
255       ReportError("Varargs are not supported for macros.");
256     }
257   }
258 };
259 
260 class MacroList : public Declarable {
261  public:
262   DECLARE_DECLARABLE_BOILERPLATE(MacroList, macro_list);
list()263   const std::vector<Macro*>& list() { return list_; }
AddMacro(Macro * macro)264   Macro* AddMacro(Macro* macro) {
265     list_.emplace_back(macro);
266     return macro;
267   }
268 
269  private:
270   friend class Declarations;
MacroList()271   MacroList() : Declarable(Declarable::kMacroList) {}
272 
273   std::vector<Macro*> list_;
274 };
275 
276 class Builtin : public Callable {
277  public:
278   enum Kind { kStub, kFixedArgsJavaScript, kVarArgsJavaScript };
279   DECLARE_DECLARABLE_BOILERPLATE(Builtin, builtin);
kind()280   Kind kind() const { return kind_; }
IsStub()281   bool IsStub() const { return kind_ == kStub; }
IsVarArgsJavaScript()282   bool IsVarArgsJavaScript() const { return kind_ == kVarArgsJavaScript; }
IsFixedArgsJavaScript()283   bool IsFixedArgsJavaScript() const { return kind_ == kFixedArgsJavaScript; }
IsExternal()284   bool IsExternal() const { return external_; }
285 
286  private:
287   friend class Declarations;
Builtin(const std::string & name,Builtin::Kind kind,bool external,const Signature & signature,base::Optional<Generic * > generic)288   Builtin(const std::string& name, Builtin::Kind kind, bool external,
289           const Signature& signature, base::Optional<Generic*> generic)
290       : Callable(Declarable::kBuiltin, name, signature, generic),
291         kind_(kind),
292         external_(external) {}
293 
294   Kind kind_;
295   bool external_;
296 };
297 
298 class RuntimeFunction : public Callable {
299  public:
300   DECLARE_DECLARABLE_BOILERPLATE(RuntimeFunction, runtime);
301 
302  private:
303   friend class Declarations;
RuntimeFunction(const std::string & name,const Signature & signature,base::Optional<Generic * > generic)304   RuntimeFunction(const std::string& name, const Signature& signature,
305                   base::Optional<Generic*> generic)
306       : Callable(Declarable::kRuntimeFunction, name, signature, generic) {}
307 };
308 
309 class Generic : public Declarable {
310  public:
311   DECLARE_DECLARABLE_BOILERPLATE(Generic, generic);
312 
declaration()313   GenericDeclaration* declaration() const { return declaration_; }
name()314   const std::string& name() const { return name_; }
module()315   Module* module() const { return module_; }
316 
317  private:
318   friend class Declarations;
Generic(const std::string & name,Module * module,GenericDeclaration * declaration)319   Generic(const std::string& name, Module* module,
320           GenericDeclaration* declaration)
321       : Declarable(Declarable::kGeneric),
322         name_(name),
323         module_(module),
324         declaration_(declaration) {}
325 
326   std::string name_;
327   Module* module_;
328   GenericDeclaration* declaration_;
329 };
330 
331 class GenericList : public Declarable {
332  public:
333   DECLARE_DECLARABLE_BOILERPLATE(GenericList, generic_list);
list()334   const std::vector<Generic*>& list() { return list_; }
AddGeneric(Generic * generic)335   Generic* AddGeneric(Generic* generic) {
336     list_.push_back(generic);
337     return generic;
338   }
339 
340  private:
341   friend class Declarations;
GenericList()342   GenericList() : Declarable(Declarable::kGenericList) {}
343 
344   std::vector<Generic*> list_;
345 };
346 
347 typedef std::pair<Generic*, TypeVector> SpecializationKey;
348 
349 class TypeAlias : public Declarable {
350  public:
351   DECLARE_DECLARABLE_BOILERPLATE(TypeAlias, type_alias);
352 
type()353   const Type* type() const { return type_; }
354 
355  private:
356   friend class Declarations;
TypeAlias(const Type * type)357   explicit TypeAlias(const Type* type)
358       : Declarable(Declarable::kTypeAlias), type_(type) {}
359 
360   const Type* type_;
361 };
362 
363 void PrintLabel(std::ostream& os, const Label& l, bool with_names);
364 
365 std::ostream& operator<<(std::ostream& os, const Callable& m);
366 std::ostream& operator<<(std::ostream& os, const Variable& v);
367 std::ostream& operator<<(std::ostream& os, const Builtin& b);
368 std::ostream& operator<<(std::ostream& os, const Label& l);
369 std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b);
370 std::ostream& operator<<(std::ostream& os, const Generic& g);
371 
372 #undef DECLARE_DECLARABLE_BOILERPLATE
373 
374 }  // namespace torque
375 }  // namespace internal
376 }  // namespace v8
377 
378 #endif  // V8_TORQUE_DECLARABLE_H_
379