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