• 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 #include "src/torque/declarations.h"
6 #include "src/torque/declarable.h"
7 #include "src/torque/type-oracle.h"
8 
9 namespace v8 {
10 namespace internal {
11 namespace torque {
12 
GetModuleScope(const Module * module)13 Scope* Declarations::GetModuleScope(const Module* module) {
14   auto i = module_scopes_.find(module);
15   if (i != module_scopes_.end()) return i->second;
16   Scope* result = chain_.NewScope();
17   module_scopes_[module] = result;
18   return result;
19 }
20 
GetNodeScope(const AstNode * node,bool reset_scope)21 Scope* Declarations::GetNodeScope(const AstNode* node, bool reset_scope) {
22   std::pair<const AstNode*, TypeVector> key(
23       node, current_generic_specialization_ == nullptr
24                 ? TypeVector()
25                 : current_generic_specialization_->second);
26   if (!reset_scope) {
27     auto i = scopes_.find(key);
28     if (i != scopes_.end()) return i->second;
29   }
30   Scope* result = chain_.NewScope();
31   scopes_[key] = result;
32   return result;
33 }
34 
GetGenericScope(Generic * generic,const TypeVector & types)35 Scope* Declarations::GetGenericScope(Generic* generic,
36                                      const TypeVector& types) {
37   std::pair<const AstNode*, TypeVector> key(generic->declaration()->callable,
38                                             types);
39   auto i = scopes_.find(key);
40   if (i != scopes_.end()) return i->second;
41   Scope* result = chain_.NewScope();
42   scopes_[key] = result;
43   return result;
44 }
45 
IsDeclaredInCurrentScope(const std::string & name)46 bool Declarations::IsDeclaredInCurrentScope(const std::string& name) {
47   return chain_.ShallowLookup(name) != nullptr;
48 }
49 
CheckAlreadyDeclared(const std::string & name,const char * new_type)50 void Declarations::CheckAlreadyDeclared(const std::string& name,
51                                         const char* new_type) {
52   if (IsDeclaredInCurrentScope(name)) {
53     std::stringstream s;
54     s << "cannot redeclare " << name << " (type " << new_type << ")";
55     ReportError(s.str());
56   }
57 }
58 
LookupType(const std::string & name)59 const Type* Declarations::LookupType(const std::string& name) {
60   Declarable* raw = Lookup(name);
61   if (raw->IsTypeAlias()) {
62     return TypeAlias::cast(raw)->type();
63   }
64   std::stringstream s;
65   s << "declaration \"" << name << "\" is not a Type";
66   ReportError(s.str());
67   return nullptr;
68 }
69 
LookupGlobalType(const std::string & name)70 const Type* Declarations::LookupGlobalType(const std::string& name) {
71   Declarable* raw = LookupGlobalScope(name);
72   if (!raw->IsTypeAlias()) {
73     std::stringstream s;
74     s << "declaration \"" << name << "\" is not a Type";
75     ReportError(s.str());
76   }
77   return TypeAlias::cast(raw)->type();
78 }
79 
GetType(TypeExpression * type_expression)80 const Type* Declarations::GetType(TypeExpression* type_expression) {
81   if (auto* basic = BasicTypeExpression::DynamicCast(type_expression)) {
82     std::string name =
83         (basic->is_constexpr ? CONSTEXPR_TYPE_PREFIX : "") + basic->name;
84     return LookupType(name);
85   } else if (auto* union_type = UnionTypeExpression::cast(type_expression)) {
86     return TypeOracle::GetUnionType(GetType(union_type->a),
87                                     GetType(union_type->b));
88   } else {
89     auto* function_type_exp = FunctionTypeExpression::cast(type_expression);
90     TypeVector argument_types;
91     for (TypeExpression* type_exp : function_type_exp->parameters) {
92       argument_types.push_back(GetType(type_exp));
93     }
94     return TypeOracle::GetFunctionPointerType(
95         argument_types, GetType(function_type_exp->return_type));
96   }
97 }
98 
FindSomeInternalBuiltinWithType(const FunctionPointerType * type)99 Builtin* Declarations::FindSomeInternalBuiltinWithType(
100     const FunctionPointerType* type) {
101   for (auto& declarable : declarables_) {
102     if (Builtin* builtin = Builtin::DynamicCast(declarable.get())) {
103       if (!builtin->IsExternal() && builtin->kind() == Builtin::kStub &&
104           builtin->signature().return_type == type->return_type() &&
105           builtin->signature().parameter_types.types ==
106               type->parameter_types()) {
107         return builtin;
108       }
109     }
110   }
111   return nullptr;
112 }
113 
LookupValue(const std::string & name)114 Value* Declarations::LookupValue(const std::string& name) {
115   Declarable* d = Lookup(name);
116   if (!d->IsValue()) {
117     std::stringstream s;
118     s << "declaration \"" << name << "\" is not a Value";
119     ReportError(s.str());
120   }
121   return Value::cast(d);
122 }
123 
LookupLabel(const std::string & name)124 Label* Declarations::LookupLabel(const std::string& name) {
125   Declarable* d = Lookup(name);
126   if (!d->IsLabel()) {
127     std::stringstream s;
128     s << "declaration \"" << name << "\" is not a Label";
129     ReportError(s.str());
130   }
131   return Label::cast(d);
132 }
133 
TryLookupMacro(const std::string & name,const TypeVector & types)134 Macro* Declarations::TryLookupMacro(const std::string& name,
135                                     const TypeVector& types) {
136   Declarable* declarable = TryLookup(name);
137   if (declarable != nullptr) {
138     if (declarable->IsMacroList()) {
139       for (auto& m : MacroList::cast(declarable)->list()) {
140         if (m->signature().parameter_types.types == types &&
141             !m->signature().parameter_types.var_args) {
142           return m;
143         }
144       }
145     }
146   }
147   return nullptr;
148 }
149 
LookupMacro(const std::string & name,const TypeVector & types)150 Macro* Declarations::LookupMacro(const std::string& name,
151                                  const TypeVector& types) {
152   Macro* result = TryLookupMacro(name, types);
153   if (result != nullptr) return result;
154   std::stringstream stream;
155   stream << "macro " << name << " with parameter types " << types
156          << " is not defined";
157   ReportError(stream.str());
158   return nullptr;
159 }
160 
LookupBuiltin(const std::string & name)161 Builtin* Declarations::LookupBuiltin(const std::string& name) {
162   Declarable* declarable = Lookup(name);
163   if (declarable != nullptr) {
164     if (declarable->IsBuiltin()) {
165       return Builtin::cast(declarable);
166     }
167     ReportError(name + " is not a builtin");
168   }
169   ReportError(std::string("builtin ") + name + " is not defined");
170   return nullptr;
171 }
172 
LookupGeneric(const std::string & name)173 GenericList* Declarations::LookupGeneric(const std::string& name) {
174   Declarable* declarable_list = Lookup(name);
175   if (declarable_list != nullptr) {
176     if (declarable_list->IsGenericList()) {
177       return GenericList::cast(declarable_list);
178     }
179     ReportError(name + " is not a generic");
180   }
181   ReportError(std::string("generic ") + name + " is not defined");
182   return nullptr;
183 }
184 
LookupModuleConstant(const std::string & name)185 ModuleConstant* Declarations::LookupModuleConstant(const std::string& name) {
186   Declarable* declarable = Lookup(name);
187   if (declarable != nullptr) {
188     if (declarable->IsModuleConstant()) {
189       return ModuleConstant::cast(declarable);
190     }
191     ReportError(name + " is not a constant");
192   }
193   ReportError(std::string("constant \"") + name + "\" is not defined");
194   return nullptr;
195 }
196 
DeclareAbstractType(const std::string & name,const std::string & generated,base::Optional<const AbstractType * > non_constexpr_version,const base::Optional<std::string> & parent)197 const AbstractType* Declarations::DeclareAbstractType(
198     const std::string& name, const std::string& generated,
199     base::Optional<const AbstractType*> non_constexpr_version,
200     const base::Optional<std::string>& parent) {
201   CheckAlreadyDeclared(name, "type");
202   const Type* parent_type = nullptr;
203   if (parent) {
204     Declarable* maybe_parent_type = Lookup(*parent);
205     if (maybe_parent_type == nullptr) {
206       std::stringstream s;
207       s << "cannot find parent type \"" << *parent << "\"";
208       ReportError(s.str());
209     }
210     if (!maybe_parent_type->IsTypeAlias()) {
211       std::stringstream s;
212       s << "parent \"" << *parent << "\" of type \"" << name << "\""
213         << " is not a type";
214       ReportError(s.str());
215     }
216     parent_type = TypeAlias::cast(maybe_parent_type)->type();
217   }
218   const AbstractType* type = TypeOracle::GetAbstractType(
219       parent_type, name, generated, non_constexpr_version);
220   DeclareType(name, type);
221   return type;
222 }
223 
DeclareType(const std::string & name,const Type * type)224 void Declarations::DeclareType(const std::string& name, const Type* type) {
225   CheckAlreadyDeclared(name, "type");
226   TypeAlias* result = new TypeAlias(type);
227   Declare(name, std::unique_ptr<TypeAlias>(result));
228 }
229 
DeclareStruct(Module * module,const std::string & name,const std::vector<NameAndType> & fields)230 void Declarations::DeclareStruct(Module* module, const std::string& name,
231                                  const std::vector<NameAndType>& fields) {
232   const StructType* new_type = TypeOracle::GetStructType(module, name, fields);
233   DeclareType(name, new_type);
234 }
235 
DeclareLabel(const std::string & name)236 Label* Declarations::DeclareLabel(const std::string& name) {
237   CheckAlreadyDeclared(name, "label");
238   Label* result = new Label(name);
239   Declare(name, std::unique_ptr<Declarable>(result));
240   return result;
241 }
242 
GetMacroListForName(const std::string & name,const Signature & signature)243 MacroList* Declarations::GetMacroListForName(const std::string& name,
244                                              const Signature& signature) {
245   auto previous = chain_.Lookup(name);
246   MacroList* macro_list = nullptr;
247   if (previous == nullptr) {
248     macro_list = new MacroList();
249     Declare(name, std::unique_ptr<Declarable>(macro_list));
250   } else if (!previous->IsMacroList()) {
251     std::stringstream s;
252     s << "cannot redeclare non-macro " << name << " as a macro";
253     ReportError(s.str());
254   } else {
255     macro_list = MacroList::cast(previous);
256   }
257   for (auto& macro : macro_list->list()) {
258     if (signature.parameter_types.types ==
259             macro->signature().parameter_types.types &&
260         signature.parameter_types.var_args ==
261             macro->signature().parameter_types.var_args) {
262       std::stringstream s;
263       s << "cannot redeclare " << name
264         << " as a macro with identical parameter list "
265         << signature.parameter_types;
266       ReportError(s.str());
267     }
268   }
269   return macro_list;
270 }
271 
DeclareMacro(const std::string & name,const Signature & signature,base::Optional<std::string> op)272 Macro* Declarations::DeclareMacro(const std::string& name,
273                                   const Signature& signature,
274                                   base::Optional<std::string> op) {
275   Macro* macro = RegisterDeclarable(
276       std::unique_ptr<Macro>(new Macro(name, signature, GetCurrentGeneric())));
277   GetMacroListForName(name, signature)->AddMacro(macro);
278   if (op) GetMacroListForName(*op, signature)->AddMacro(macro);
279   return macro;
280 }
281 
DeclareBuiltin(const std::string & name,Builtin::Kind kind,bool external,const Signature & signature)282 Builtin* Declarations::DeclareBuiltin(const std::string& name,
283                                       Builtin::Kind kind, bool external,
284                                       const Signature& signature) {
285   CheckAlreadyDeclared(name, "builtin");
286   Builtin* result =
287       new Builtin(name, kind, external, signature, GetCurrentGeneric());
288   Declare(name, std::unique_ptr<Declarable>(result));
289   return result;
290 }
291 
DeclareRuntimeFunction(const std::string & name,const Signature & signature)292 RuntimeFunction* Declarations::DeclareRuntimeFunction(
293     const std::string& name, const Signature& signature) {
294   CheckAlreadyDeclared(name, "runtime function");
295   RuntimeFunction* result =
296       new RuntimeFunction(name, signature, GetCurrentGeneric());
297   Declare(name, std::unique_ptr<Declarable>(result));
298   return result;
299 }
300 
DeclareVariable(const std::string & var,const Type * type,bool is_const)301 Variable* Declarations::DeclareVariable(const std::string& var,
302                                         const Type* type, bool is_const) {
303   std::string name(var + "_" +
304                    std::to_string(GetNextUniqueDeclarationNumber()));
305   std::replace(name.begin(), name.end(), '.', '_');
306   CheckAlreadyDeclared(var, "variable");
307   Variable* result = new Variable(var, name, type, is_const);
308   Declare(var, std::unique_ptr<Declarable>(result));
309   return result;
310 }
311 
DeclareParameter(const std::string & name,const std::string & var_name,const Type * type)312 Parameter* Declarations::DeclareParameter(const std::string& name,
313                                           const std::string& var_name,
314                                           const Type* type) {
315   CheckAlreadyDeclared(name, "parameter");
316   Parameter* result = new Parameter(name, type, var_name);
317   Declare(name, std::unique_ptr<Declarable>(result));
318   return result;
319 }
320 
DeclarePrivateLabel(const std::string & raw_name)321 Label* Declarations::DeclarePrivateLabel(const std::string& raw_name) {
322   std::string name =
323       raw_name + "_" + std::to_string(GetNextUniqueDeclarationNumber());
324   CheckAlreadyDeclared(name, "label");
325   Label* result = new Label(name);
326   Declare(name, std::unique_ptr<Declarable>(result));
327   return result;
328 }
329 
DeclareExternConstant(const std::string & name,const Type * type,const std::string & value)330 void Declarations::DeclareExternConstant(const std::string& name,
331                                          const Type* type,
332                                          const std::string& value) {
333   CheckAlreadyDeclared(name, "constant, parameter or arguments");
334   ExternConstant* result = new ExternConstant(name, type, value);
335   Declare(name, std::unique_ptr<Declarable>(result));
336 }
337 
DeclareModuleConstant(const std::string & name,const Type * type)338 ModuleConstant* Declarations::DeclareModuleConstant(const std::string& name,
339                                                     const Type* type) {
340   CheckAlreadyDeclared(name, "module constant");
341   ModuleConstant* result = new ModuleConstant(name, type);
342   Declare(name, std::unique_ptr<Declarable>(result));
343   return result;
344 }
345 
DeclareGeneric(const std::string & name,Module * module,GenericDeclaration * generic)346 Generic* Declarations::DeclareGeneric(const std::string& name, Module* module,
347                                       GenericDeclaration* generic) {
348   auto previous = chain_.Lookup(name);
349   GenericList* generic_list = nullptr;
350   if (previous == nullptr) {
351     generic_list = new GenericList();
352     Declare(name, std::unique_ptr<Declarable>(generic_list));
353   } else if (!previous->IsGenericList()) {
354     std::stringstream s;
355     s << "cannot redeclare non-generic " << name << " as a generic";
356     ReportError(s.str());
357   } else {
358     generic_list = GenericList::cast(previous);
359   }
360   Generic* result = RegisterDeclarable(
361       std::unique_ptr<Generic>(new Generic(name, module, generic)));
362   generic_list->AddGeneric(result);
363   generic_declaration_scopes_[result] = GetScopeChainSnapshot();
364   return result;
365 }
366 
GetCurrentSpecializationTypeNamesVector()367 TypeVector Declarations::GetCurrentSpecializationTypeNamesVector() {
368   TypeVector result;
369   if (current_generic_specialization_ != nullptr) {
370     result = current_generic_specialization_->second;
371   }
372   return result;
373 }
374 
GetCurrentGeneric()375 base::Optional<Generic*> Declarations::GetCurrentGeneric() {
376   if (current_generic_specialization_ != nullptr) {
377     return current_generic_specialization_->first;
378   }
379   return base::nullopt;
380 }
381 
GetGeneratedCallableName(const std::string & name,const TypeVector & specialized_types)382 std::string GetGeneratedCallableName(const std::string& name,
383                                      const TypeVector& specialized_types) {
384   std::string result = name;
385   for (auto type : specialized_types) {
386     std::string type_string = type->MangledName();
387     result += std::to_string(type_string.size()) + type_string;
388   }
389   return result;
390 }
391 
392 }  // namespace torque
393 }  // namespace internal
394 }  // namespace v8
395