v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
declarations.cc
Go to the documentation of this file.
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
6
7#include <optional>
8
13
14namespace v8::internal::torque {
15namespace {
16
17template <class T>
18std::vector<T> EnsureNonempty(std::vector<T> list, const std::string& name,
19 const char* kind) {
20 if (list.empty()) {
21 ReportError("there is no ", kind, " named ", name);
22 }
23 return std::move(list);
24}
25
26template <class T, class Name>
27T EnsureUnique(const std::vector<T>& list, const Name& name, const char* kind) {
28 if (list.empty()) {
29 ReportError("there is no ", kind, " named ", name);
30 }
31 if (list.size() >= 2) {
32 ReportError("ambiguous reference to ", kind, " ", name);
33 }
34 return list.front();
35}
36
37template <class T>
38void CheckAlreadyDeclared(const std::string& name, const char* new_type) {
39 std::vector<T*> declarations =
41 if (!declarations.empty()) {
42 Scope* scope = CurrentScope::Get();
43 ReportError("cannot redeclare ", name, " (type ", *new_type, scope, ")");
44 }
45}
46
47} // namespace
48
49std::vector<Declarable*> Declarations::LookupGlobalScope(
50 const QualifiedName& name) {
51 std::vector<Declarable*> d =
53 if (d.empty()) {
54 std::stringstream s;
55 s << "cannot find \"" << name << "\" in global scope";
56 ReportError(s.str());
57 }
58 return d;
59}
60
63 EnsureUnique(FilterDeclarables<TypeAlias>(Lookup(name)), name, "type");
64 return declaration;
65}
66
68 return LookupTypeAlias(name)->type();
69}
70
72 const TypeAlias* alias = LookupTypeAlias(QualifiedName(name->value));
75 alias->GetDeclarationPosition());
76 }
77 return alias->type();
78}
79
80std::optional<const Type*> Declarations::TryLookupType(
81 const QualifiedName& name) {
82 auto decls = FilterDeclarables<TypeAlias>(TryLookup(name));
83 if (decls.empty()) return std::nullopt;
84 return EnsureUnique(std::move(decls), name, "type")->type();
85}
86
88 TypeAlias* declaration = EnsureUnique(
90 return declaration->type();
91}
92
94 const BuiltinPointerType* type) {
95 for (auto& declarable : GlobalContext::AllDeclarables()) {
96 if (Builtin* builtin = Builtin::DynamicCast(declarable.get())) {
97 if (!builtin->IsExternal() && builtin->kind() == Builtin::kStub &&
98 builtin->signature().return_type == type->return_type() &&
99 builtin->signature().parameter_types.types ==
100 type->parameter_types()) {
101 return builtin;
102 }
103 }
104 }
105 return nullptr;
106}
107
109 return EnsureUnique(FilterDeclarables<Value>(Lookup(name)), name, "value");
110}
111
112Macro* Declarations::TryLookupMacro(const std::string& name,
113 const TypeVector& types) {
114 std::vector<Macro*> macros = TryLookup<Macro>(QualifiedName(name));
115 for (auto& m : macros) {
116 auto signature_types = m->signature().GetExplicitTypes();
117 if (signature_types == types && !m->signature().parameter_types.var_args) {
118 return m;
119 }
120 }
121 return nullptr;
122}
123
124std::optional<Builtin*> Declarations::TryLookupBuiltin(
125 const QualifiedName& name) {
126 std::vector<Builtin*> builtins = TryLookup<Builtin>(name);
127 if (builtins.empty()) return std::nullopt;
128 return EnsureUnique(builtins, name.name, "builtin");
129}
130
131std::vector<GenericCallable*> Declarations::LookupGeneric(
132 const std::string& name) {
133 return EnsureNonempty(
135 "generic callable");
136}
137
139 return EnsureUnique(FilterDeclarables<GenericCallable>(Lookup(name)), name,
140 "generic callable");
141}
142
144 return EnsureUnique(FilterDeclarables<GenericType>(Lookup(name)), name,
145 "generic type");
146}
147
149 const std::string& name) {
150 return EnsureUnique(
152 name, "generic type");
153}
154
155std::optional<GenericType*> Declarations::TryLookupGenericType(
156 const QualifiedName& name) {
157 std::vector<GenericType*> results = TryLookup<GenericType>(name);
158 if (results.empty()) return std::nullopt;
159 return EnsureUnique(results, name.name, "generic type");
160}
161
162Namespace* Declarations::DeclareNamespace(const std::string& name) {
163 return Declare(name, std::make_unique<Namespace>(name));
164}
165
167 CheckAlreadyDeclared<TypeAlias>(name->value, "type");
168 return Declare(name->value, std::unique_ptr<TypeAlias>(
169 new TypeAlias(type, true, name->pos)));
170}
171
173 TypeDeclaration* type,
174 bool redeclaration) {
175 CheckAlreadyDeclared<TypeAlias>(name->value, "type");
176 std::unique_ptr<TypeAlias> alias_ptr(
177 new TypeAlias(type, redeclaration, name->pos));
178 return Declare(name->value, std::move(alias_ptr));
179}
180
182 std::string external_name, std::string readable_name, bool exported_to_csa,
183 Signature signature, std::optional<Statement*> body, bool is_user_defined) {
184 external_name = GlobalContext::MakeUniqueName(external_name);
185 return RegisterDeclarable(std::unique_ptr<TorqueMacro>(new TorqueMacro(
186 std::move(external_name), std::move(readable_name), std::move(signature),
187 body, is_user_defined, exported_to_csa)));
188}
189
191 std::string name, std::string external_assembler_name,
192 Signature signature) {
193 return RegisterDeclarable(std::unique_ptr<ExternMacro>(
194 new ExternMacro(std::move(name), std::move(external_assembler_name),
195 std::move(signature))));
196}
197
199 const std::string& name, bool accessible_from_csa,
200 std::optional<std::string> external_assembler_name,
201 const Signature& signature, std::optional<Statement*> body,
202 std::optional<std::string> op, bool is_user_defined) {
203 if (Macro* existing_macro =
204 TryLookupMacro(name, signature.GetExplicitTypes())) {
205 if (existing_macro->ParentScope() == CurrentScope::Get()) {
206 ReportError("cannot redeclare macro ", name,
207 " with identical explicit parameters");
208 }
209 }
210 Macro* macro;
211 if (external_assembler_name) {
212 macro =
213 CreateExternMacro(name, std::move(*external_assembler_name), signature);
214 } else {
215 macro = CreateTorqueMacro(name, name, accessible_from_csa, signature, body,
216 is_user_defined);
217 }
218
219 Declare(name, macro);
220 if (op) {
221 if (TryLookupMacro(*op, signature.GetExplicitTypes())) {
222 ReportError("cannot redeclare operator ", name,
223 " with identical explicit parameters");
224 }
225 DeclareOperator(*op, macro);
226 }
227 return macro;
228}
229
231 const std::string& name, Signature signature,
232 Statement* body) {
233 std::string generated_name = GlobalContext::MakeUniqueName(
234 "Method_" + container_type->SimpleName() + "_" + name);
235 Method* result = RegisterDeclarable(std::unique_ptr<Method>(new Method(
236 container_type, generated_name, name, std::move(signature), body)));
237 container_type->RegisterMethod(result);
238 return result;
239}
240
242 const Signature& signature) {
243 Intrinsic* result = RegisterDeclarable(std::unique_ptr<Intrinsic>(
244 new Intrinsic(std::move(name), std::move(signature))));
245 return result;
246}
247
249 const Signature& signature) {
250 Intrinsic* result = CreateIntrinsic(std::move(name), std::move(signature));
251 Declare(name, result);
252 return result;
253}
254
256 std::string external_name, std::string readable_name, Builtin::Kind kind,
257 Builtin::Flags flags, Signature signature,
258 std::optional<std::string> use_counter_name,
259 std::optional<Statement*> body) {
260 return RegisterDeclarable(std::unique_ptr<Builtin>(new Builtin(
261 std::move(external_name), std::move(readable_name), kind, flags,
262 std::move(signature), std::move(use_counter_name), body)));
263}
264
266 const std::string& name, const Signature& signature) {
267 CheckAlreadyDeclared<RuntimeFunction>(name, "runtime function");
268 return Declare(name, RegisterDeclarable(std::unique_ptr<RuntimeFunction>(
269 new RuntimeFunction(name, signature))));
270}
271
273 const Type* type,
274 std::string value) {
275 CheckAlreadyDeclared<Value>(name->value, "constant");
276 return Declare(name->value, std::unique_ptr<ExternConstant>(
277 new ExternConstant(name, type, value)));
278}
279
281 const Type* type,
282 Expression* body) {
283 CheckAlreadyDeclared<Value>(name->value, "constant");
284 std::string external_name = GlobalContext::MakeUniqueName(name->value);
285 std::unique_ptr<NamespaceConstant> namespaceConstant(
286 new NamespaceConstant(name, std::move(external_name), type, body));
287 NamespaceConstant* result = namespaceConstant.get();
288 Declare(name->value, std::move(namespaceConstant));
289 return result;
290}
291
293 const std::string& name, GenericCallableDeclaration* ast_node) {
294 return Declare(name, std::unique_ptr<GenericCallable>(
295 new GenericCallable(name, ast_node)));
296}
297
299 const std::string& name, GenericTypeDeclaration* ast_node) {
300 return Declare(name,
301 std::unique_ptr<GenericType>(new GenericType(name, ast_node)));
302}
303
305 const std::string& name, const TypeVector& specialized_types) {
306 std::string result = name;
307 for (auto type : specialized_types) {
308 result += "_" + type->SimpleName();
309 }
310 return result;
311}
312
313Macro* Declarations::DeclareOperator(const std::string& name, Macro* m) {
315 return m;
316}
317
318} // namespace v8::internal::torque
Builtins::Kind kind
Definition builtins.cc:40
void RegisterMethod(Method *method)
Definition types.h:570
static Value * LookupValue(const QualifiedName &name)
static std::optional< Builtin * > TryLookupBuiltin(const QualifiedName &name)
static Intrinsic * CreateIntrinsic(const std::string &name, const Signature &signature)
static TypeAlias * DeclareType(const Identifier *name, const Type *type)
static TorqueMacro * CreateTorqueMacro(std::string external_name, std::string readable_name, bool exported_to_csa, Signature signature, std::optional< Statement * > body, bool is_user_defined)
static Macro * TryLookupMacro(const std::string &name, const TypeVector &types)
static std::vector< Declarable * > LookupGlobalScope(const QualifiedName &name)
static T * Declare(const std::string &name, T *d)
static Macro * DeclareMacro(const std::string &name, bool accessible_from_csa, std::optional< std::string > external_assembler_name, const Signature &signature, std::optional< Statement * > body, std::optional< std::string > op={}, bool is_user_defined=true)
static std::vector< Declarable * > TryLookupShallow(const QualifiedName &name)
static ExternConstant * DeclareExternConstant(Identifier *name, const Type *type, std::string value)
static Builtin * CreateBuiltin(std::string external_name, std::string readable_name, Builtin::Kind kind, Builtin::Flags flags, Signature signature, std::optional< std::string > use_counter_name, std::optional< Statement * > body)
static Namespace * DeclareNamespace(const std::string &name)
static Method * CreateMethod(AggregateType *class_type, const std::string &name, Signature signature, Statement *body)
static std::vector< GenericCallable * > LookupGeneric(const std::string &name)
static RuntimeFunction * DeclareRuntimeFunction(const std::string &name, const Signature &signature)
static ExternMacro * CreateExternMacro(std::string name, std::string external_assembler_name, Signature signature)
static std::vector< Declarable * > TryLookup(const QualifiedName &name)
static GenericCallable * LookupUniqueGeneric(const QualifiedName &name)
static Intrinsic * DeclareIntrinsic(const std::string &name, const Signature &signature)
static GenericCallable * DeclareGenericCallable(const std::string &name, GenericCallableDeclaration *ast_node)
static const Type * LookupGlobalType(const QualifiedName &name)
static std::string GetGeneratedCallableName(const std::string &name, const TypeVector &specialized_types)
static const TypeAlias * LookupTypeAlias(const QualifiedName &name)
static Macro * DeclareOperator(const std::string &name, Macro *m)
static GenericType * LookupGlobalUniqueGenericType(const std::string &name)
static const Type * LookupType(const QualifiedName &name)
static NamespaceConstant * DeclareNamespaceConstant(Identifier *name, const Type *type, Expression *body)
static Builtin * FindSomeInternalBuiltinWithType(const BuiltinPointerType *type)
static TypeAlias * PredeclareTypeAlias(const Identifier *name, TypeDeclaration *type, bool redeclaration)
static GenericType * LookupUniqueGenericType(const QualifiedName &name)
static std::vector< Declarable * > Lookup(const QualifiedName &name)
static std::optional< GenericType * > TryLookupGenericType(const QualifiedName &name)
static GenericType * DeclareGenericType(const std::string &name, GenericTypeDeclaration *ast_node)
static std::optional< const Type * > TryLookupType(const QualifiedName &name)
static const std::vector< std::unique_ptr< Declarable > > & AllDeclarables()
static Namespace * GetDefaultNamespace()
static std::string MakeUniqueName(const std::string &base)
static V8_EXPORT_PRIVATE void AddDefinition(SourcePosition token, SourcePosition definition)
T * AddDeclarable(const std::string &name, T *declarable)
Definition declarable.h:196
std::vector< Declarable * > Lookup(const QualifiedName &name)
Definition declarable.cc:90
const Type * type() const
Definition declarable.h:673
SourcePosition GetDeclarationPosition() const
Definition declarable.h:679
virtual std::string SimpleName() const
Definition types.cc:57
ZoneVector< RpoNumber > & result
Builtin builtin
int s
Definition mul-fft.cc:297
int m
Definition mul-fft.cc:294
T * RegisterDeclarable(std::unique_ptr< T > d)
void ReportError(Args &&... args)
Definition utils.h:96
std::vector< T * > FilterDeclarables(const std::vector< Declarable * > list)
std::vector< const Type * > TypeVector
Definition types.h:85
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
Definition flags.cc:2086
Intrinsic
Definition v8-template.h:41
TypeVector GetExplicitTypes() const
Definition types.h:936
Symbol declaration