summaryrefslogtreecommitdiff
path: root/deps/v8/src/torque
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/torque')
-rw-r--r--deps/v8/src/torque/ast.h203
-rw-r--r--deps/v8/src/torque/class-debug-reader-generator.cc222
-rw-r--r--deps/v8/src/torque/constants.h5
-rw-r--r--deps/v8/src/torque/contextual.h32
-rw-r--r--deps/v8/src/torque/csa-generator.cc23
-rw-r--r--deps/v8/src/torque/declarable.cc72
-rw-r--r--deps/v8/src/torque/declarable.h69
-rw-r--r--deps/v8/src/torque/declaration-visitor.cc166
-rw-r--r--deps/v8/src/torque/declaration-visitor.h40
-rw-r--r--deps/v8/src/torque/declarations.cc61
-rw-r--r--deps/v8/src/torque/declarations.h23
-rw-r--r--deps/v8/src/torque/earley-parser.h4
-rw-r--r--deps/v8/src/torque/global-context.cc7
-rw-r--r--deps/v8/src/torque/global-context.h13
-rw-r--r--deps/v8/src/torque/implementation-visitor.cc663
-rw-r--r--deps/v8/src/torque/implementation-visitor.h82
-rw-r--r--deps/v8/src/torque/instructions.cc15
-rw-r--r--deps/v8/src/torque/instructions.h7
-rw-r--r--deps/v8/src/torque/torque-compiler.cc2
-rw-r--r--deps/v8/src/torque/torque-compiler.h6
-rw-r--r--deps/v8/src/torque/torque-parser.cc259
-rw-r--r--deps/v8/src/torque/torque.cc25
-rw-r--r--deps/v8/src/torque/type-inference.cc121
-rw-r--r--deps/v8/src/torque/type-inference.h84
-rw-r--r--deps/v8/src/torque/type-oracle.cc23
-rw-r--r--deps/v8/src/torque/type-oracle.h36
-rw-r--r--deps/v8/src/torque/type-visitor.cc164
-rw-r--r--deps/v8/src/torque/type-visitor.h12
-rw-r--r--deps/v8/src/torque/types.cc90
-rw-r--r--deps/v8/src/torque/types.h99
-rw-r--r--deps/v8/src/torque/utils.cc42
-rw-r--r--deps/v8/src/torque/utils.h50
32 files changed, 1656 insertions, 1064 deletions
diff --git a/deps/v8/src/torque/ast.h b/deps/v8/src/torque/ast.h
index 23de121065..5ce25cf13a 100644
--- a/deps/v8/src/torque/ast.h
+++ b/deps/v8/src/torque/ast.h
@@ -46,8 +46,7 @@ namespace torque {
#define AST_TYPE_EXPRESSION_NODE_KIND_LIST(V) \
V(BasicTypeExpression) \
V(FunctionTypeExpression) \
- V(UnionTypeExpression) \
- V(ReferenceTypeExpression)
+ V(UnionTypeExpression)
#define AST_STATEMENT_NODE_KIND_LIST(V) \
V(BlockStatement) \
@@ -72,20 +71,17 @@ namespace torque {
#define AST_DECLARATION_NODE_KIND_LIST(V) \
AST_TYPE_DECLARATION_NODE_KIND_LIST(V) \
- V(StandardDeclaration) \
V(GenericDeclaration) \
V(SpecializationDeclaration) \
V(ExternConstDeclaration) \
V(NamespaceDeclaration) \
V(ConstDeclaration) \
- V(CppIncludeDeclaration)
-
-#define AST_CALLABLE_NODE_KIND_LIST(V) \
- V(TorqueMacroDeclaration) \
- V(TorqueBuiltinDeclaration) \
- V(ExternalMacroDeclaration) \
- V(ExternalBuiltinDeclaration) \
- V(ExternalRuntimeDeclaration) \
+ V(CppIncludeDeclaration) \
+ V(TorqueMacroDeclaration) \
+ V(TorqueBuiltinDeclaration) \
+ V(ExternalMacroDeclaration) \
+ V(ExternalBuiltinDeclaration) \
+ V(ExternalRuntimeDeclaration) \
V(IntrinsicDeclaration)
#define AST_NODE_KIND_LIST(V) \
@@ -93,7 +89,6 @@ namespace torque {
AST_TYPE_EXPRESSION_NODE_KIND_LIST(V) \
AST_STATEMENT_NODE_KIND_LIST(V) \
AST_DECLARATION_NODE_KIND_LIST(V) \
- AST_CALLABLE_NODE_KIND_LIST(V) \
V(Identifier) \
V(LabelBlock)
@@ -118,16 +113,16 @@ struct AstNodeClassCheck {
};
// Boilerplate for most derived classes.
-#define DEFINE_AST_NODE_LEAF_BOILERPLATE(T) \
- static const Kind kKind = Kind::k##T; \
- static T* cast(AstNode* node) { \
- if (node->kind != kKind) return nullptr; \
- return static_cast<T*>(node); \
- } \
- static T* DynamicCast(AstNode* node) { \
- if (!node) return nullptr; \
- if (!AstNodeClassCheck::IsInstanceOf<T>(node)) return nullptr; \
- return static_cast<T*>(node); \
+#define DEFINE_AST_NODE_LEAF_BOILERPLATE(T) \
+ static const Kind kKind = Kind::k##T; \
+ static T* cast(AstNode* node) { \
+ DCHECK_EQ(node->kind, kKind); \
+ return static_cast<T*>(node); \
+ } \
+ static T* DynamicCast(AstNode* node) { \
+ if (!node) return nullptr; \
+ if (node->kind != kKind) return nullptr; \
+ return static_cast<T*>(node); \
}
// Boilerplate for classes with subclasses.
@@ -221,6 +216,10 @@ struct Identifier : AstNode {
std::string value;
};
+inline std::ostream& operator<<(std::ostream& os, Identifier* id) {
+ return os << id->value;
+}
+
struct IdentifierPtrValueEq {
bool operator()(const Identifier* a, const Identifier* b) {
return a->value < b->value;
@@ -252,11 +251,11 @@ struct IdentifierExpression : LocationExpression {
struct IntrinsicCallExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(IntrinsicCallExpression)
- IntrinsicCallExpression(SourcePosition pos, std::string name,
+ IntrinsicCallExpression(SourcePosition pos, Identifier* name,
std::vector<TypeExpression*> generic_arguments,
std::vector<Expression*> arguments)
: Expression(kKind, pos),
- name(std::move(name)),
+ name(name),
generic_arguments(std::move(generic_arguments)),
arguments(std::move(arguments)) {}
@@ -267,7 +266,7 @@ struct IntrinsicCallExpression : Expression {
callback(this);
}
- std::string name;
+ Identifier* name;
std::vector<TypeExpression*> generic_arguments;
std::vector<Expression*> arguments;
};
@@ -619,13 +618,6 @@ struct UnionTypeExpression : TypeExpression {
TypeExpression* b;
};
-struct ReferenceTypeExpression : TypeExpression {
- DEFINE_AST_NODE_LEAF_BOILERPLATE(ReferenceTypeExpression)
- ReferenceTypeExpression(SourcePosition pos, TypeExpression* referenced_type)
- : TypeExpression(kKind, pos), referenced_type(referenced_type) {}
- TypeExpression* referenced_type;
-};
-
struct ExpressionStatement : Statement {
DEFINE_AST_NODE_LEAF_BOILERPLATE(ExpressionStatement)
ExpressionStatement(SourcePosition pos, Expression* expression)
@@ -849,10 +841,15 @@ struct ConditionalAnnotation {
ConditionalAnnotationType type;
};
+struct Annotation {
+ Identifier* name;
+ base::Optional<std::string> param;
+};
+
struct ClassFieldExpression {
NameAndTypeExpression name_and_type;
base::Optional<std::string> index;
- base::Optional<ConditionalAnnotation> conditional;
+ std::vector<ConditionalAnnotation> conditions;
bool weak;
bool const_qualified;
bool generate_verify;
@@ -865,34 +862,33 @@ struct LabelAndTypes {
using LabelAndTypesVector = std::vector<LabelAndTypes>;
-struct CallableNodeSignature {
+struct CallableDeclaration : Declaration {
+ CallableDeclaration(AstNode::Kind kind, SourcePosition pos,
+ bool transitioning, Identifier* name,
+ ParameterList parameters, TypeExpression* return_type,
+ LabelAndTypesVector labels)
+ : Declaration(kind, pos),
+ transitioning(transitioning),
+ name(name),
+ parameters(std::move(parameters)),
+ return_type(return_type),
+ labels(std::move(labels)) {}
+ DEFINE_AST_NODE_INNER_BOILERPLATE(CallableDeclaration)
+ bool transitioning;
+ Identifier* name;
ParameterList parameters;
TypeExpression* return_type;
LabelAndTypesVector labels;
};
-struct CallableNode : AstNode {
- CallableNode(AstNode::Kind kind, SourcePosition pos, bool transitioning,
- std::string name, ParameterList parameters,
- TypeExpression* return_type, const LabelAndTypesVector& labels)
- : AstNode(kind, pos),
- transitioning(transitioning),
- name(std::move(name)),
- signature(new CallableNodeSignature{parameters, return_type, labels}) {}
- DEFINE_AST_NODE_INNER_BOILERPLATE(CallableNode)
- bool transitioning;
- std::string name;
- std::unique_ptr<CallableNodeSignature> signature;
-};
-
-struct MacroDeclaration : CallableNode {
+struct MacroDeclaration : CallableDeclaration {
DEFINE_AST_NODE_INNER_BOILERPLATE(MacroDeclaration)
MacroDeclaration(AstNode::Kind kind, SourcePosition pos, bool transitioning,
- std::string name, base::Optional<std::string> op,
+ Identifier* name, base::Optional<std::string> op,
ParameterList parameters, TypeExpression* return_type,
const LabelAndTypesVector& labels)
- : CallableNode(kind, pos, transitioning, std::move(name),
- std::move(parameters), return_type, labels),
+ : CallableDeclaration(kind, pos, transitioning, name,
+ std::move(parameters), return_type, labels),
op(std::move(op)) {
if (parameters.implicit_kind == ImplicitKind::kJSImplicit) {
Error("Cannot use \"js-implicit\" with macros, use \"implicit\" instead.")
@@ -906,23 +902,22 @@ struct ExternalMacroDeclaration : MacroDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(ExternalMacroDeclaration)
ExternalMacroDeclaration(SourcePosition pos, bool transitioning,
std::string external_assembler_name,
- std::string name, base::Optional<std::string> op,
+ Identifier* name, base::Optional<std::string> op,
ParameterList parameters,
TypeExpression* return_type,
const LabelAndTypesVector& labels)
- : MacroDeclaration(kKind, pos, transitioning, std::move(name),
- std::move(op), std::move(parameters), return_type,
- labels),
+ : MacroDeclaration(kKind, pos, transitioning, name, std::move(op),
+ std::move(parameters), return_type, labels),
external_assembler_name(std::move(external_assembler_name)) {}
std::string external_assembler_name;
};
-struct IntrinsicDeclaration : CallableNode {
+struct IntrinsicDeclaration : CallableDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(IntrinsicDeclaration)
- IntrinsicDeclaration(SourcePosition pos, std::string name,
+ IntrinsicDeclaration(SourcePosition pos, Identifier* name,
ParameterList parameters, TypeExpression* return_type)
- : CallableNode(kKind, pos, false, std::move(name), std::move(parameters),
- return_type, {}) {
+ : CallableDeclaration(kKind, pos, false, name, std::move(parameters),
+ return_type, {}) {
if (parameters.implicit_kind != ImplicitKind::kNoImplicit) {
Error("Intinsics cannot have implicit parameters.");
}
@@ -932,24 +927,26 @@ struct IntrinsicDeclaration : CallableNode {
struct TorqueMacroDeclaration : MacroDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(TorqueMacroDeclaration)
TorqueMacroDeclaration(SourcePosition pos, bool transitioning,
- std::string name, base::Optional<std::string> op,
+ Identifier* name, base::Optional<std::string> op,
ParameterList parameters, TypeExpression* return_type,
- const LabelAndTypesVector& labels, bool export_to_csa)
- : MacroDeclaration(kKind, pos, transitioning, std::move(name),
- std::move(op), std::move(parameters), return_type,
- labels),
- export_to_csa(export_to_csa) {}
+ const LabelAndTypesVector& labels, bool export_to_csa,
+ base::Optional<Statement*> body)
+ : MacroDeclaration(kKind, pos, transitioning, name, std::move(op),
+ std::move(parameters), return_type, labels),
+ export_to_csa(export_to_csa),
+ body(body) {}
bool export_to_csa;
+ base::Optional<Statement*> body;
};
-struct BuiltinDeclaration : CallableNode {
+struct BuiltinDeclaration : CallableDeclaration {
DEFINE_AST_NODE_INNER_BOILERPLATE(BuiltinDeclaration)
BuiltinDeclaration(AstNode::Kind kind, SourcePosition pos,
bool javascript_linkage, bool transitioning,
- std::string name, ParameterList parameters,
+ Identifier* name, ParameterList parameters,
TypeExpression* return_type)
- : CallableNode(kind, pos, transitioning, std::move(name),
- std::move(parameters), return_type, {}),
+ : CallableDeclaration(kind, pos, transitioning, name,
+ std::move(parameters), return_type, {}),
javascript_linkage(javascript_linkage) {
if (parameters.implicit_kind == ImplicitKind::kJSImplicit &&
!javascript_linkage) {
@@ -971,32 +968,33 @@ struct BuiltinDeclaration : CallableNode {
struct ExternalBuiltinDeclaration : BuiltinDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(ExternalBuiltinDeclaration)
ExternalBuiltinDeclaration(SourcePosition pos, bool transitioning,
- bool javascript_linkage, std::string name,
+ bool javascript_linkage, Identifier* name,
ParameterList parameters,
TypeExpression* return_type)
- : BuiltinDeclaration(kKind, pos, javascript_linkage, transitioning,
- std::move(name), std::move(parameters),
- return_type) {}
+ : BuiltinDeclaration(kKind, pos, javascript_linkage, transitioning, name,
+ std::move(parameters), return_type) {}
};
struct TorqueBuiltinDeclaration : BuiltinDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(TorqueBuiltinDeclaration)
TorqueBuiltinDeclaration(SourcePosition pos, bool transitioning,
- bool javascript_linkage, std::string name,
+ bool javascript_linkage, Identifier* name,
ParameterList parameters,
- TypeExpression* return_type)
- : BuiltinDeclaration(kKind, pos, javascript_linkage, transitioning,
- std::move(name), std::move(parameters),
- return_type) {}
+ TypeExpression* return_type,
+ base::Optional<Statement*> body)
+ : BuiltinDeclaration(kKind, pos, javascript_linkage, transitioning, name,
+ std::move(parameters), return_type),
+ body(body) {}
+ base::Optional<Statement*> body;
};
-struct ExternalRuntimeDeclaration : CallableNode {
+struct ExternalRuntimeDeclaration : CallableDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(ExternalRuntimeDeclaration)
ExternalRuntimeDeclaration(SourcePosition pos, bool transitioning,
- std::string name, ParameterList parameters,
+ Identifier* name, ParameterList parameters,
TypeExpression* return_type)
- : CallableNode(kKind, pos, transitioning, name, parameters, return_type,
- {}) {}
+ : CallableDeclaration(kKind, pos, transitioning, name, parameters,
+ return_type, {}) {}
};
struct ConstDeclaration : Declaration {
@@ -1012,47 +1010,32 @@ struct ConstDeclaration : Declaration {
Expression* expression;
};
-struct StandardDeclaration : Declaration {
- DEFINE_AST_NODE_LEAF_BOILERPLATE(StandardDeclaration)
- StandardDeclaration(SourcePosition pos, CallableNode* callable,
- base::Optional<Statement*> body)
- : Declaration(kKind, pos), callable(callable), body(body) {}
- CallableNode* callable;
- base::Optional<Statement*> body;
-};
-
struct GenericDeclaration : Declaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(GenericDeclaration)
- GenericDeclaration(SourcePosition pos, CallableNode* callable,
+ GenericDeclaration(SourcePosition pos,
std::vector<Identifier*> generic_parameters,
- base::Optional<Statement*> body = base::nullopt)
+ CallableDeclaration* declaration)
: Declaration(kKind, pos),
- callable(callable),
generic_parameters(std::move(generic_parameters)),
- body(body) {}
- CallableNode* callable;
+ declaration(declaration) {}
std::vector<Identifier*> generic_parameters;
- base::Optional<Statement*> body;
+ CallableDeclaration* declaration;
};
-struct SpecializationDeclaration : Declaration {
+struct SpecializationDeclaration : CallableDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(SpecializationDeclaration)
- SpecializationDeclaration(SourcePosition pos, Identifier* name,
+ SpecializationDeclaration(SourcePosition pos, bool transitioning,
+ Identifier* name,
std::vector<TypeExpression*> generic_parameters,
ParameterList parameters,
TypeExpression* return_type,
- LabelAndTypesVector labels, Statement* b)
- : Declaration(kKind, pos),
- name(name),
- external(false),
+ LabelAndTypesVector labels, Statement* body)
+ : CallableDeclaration(kKind, pos, transitioning, name,
+ std::move(parameters), return_type,
+ std::move(labels)),
generic_parameters(std::move(generic_parameters)),
- signature(new CallableNodeSignature{std::move(parameters), return_type,
- std::move(labels)}),
- body(b) {}
- Identifier* name;
- bool external;
+ body(body) {}
std::vector<TypeExpression*> generic_parameters;
- std::unique_ptr<CallableNodeSignature> signature;
Statement* body;
};
diff --git a/deps/v8/src/torque/class-debug-reader-generator.cc b/deps/v8/src/torque/class-debug-reader-generator.cc
new file mode 100644
index 0000000000..6abdffcc91
--- /dev/null
+++ b/deps/v8/src/torque/class-debug-reader-generator.cc
@@ -0,0 +1,222 @@
+// Copyright 2019 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/flags/flags.h"
+#include "src/torque/implementation-visitor.h"
+#include "src/torque/type-oracle.h"
+
+namespace v8 {
+namespace internal {
+namespace torque {
+
+namespace {
+void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents,
+ std::ostream& cc_contents, std::ostream& visitor,
+ std::unordered_set<const ClassType*>* done) {
+ // Make sure each class only gets generated once.
+ if (!type.IsExtern() || !done->insert(&type).second) return;
+ const ClassType* super_type = type.GetSuperClass();
+
+ // We must emit the classes in dependency order. If the super class hasn't
+ // been emitted yet, go handle it first.
+ if (super_type != nullptr) {
+ GenerateClassDebugReader(*super_type, h_contents, cc_contents, visitor,
+ done);
+ }
+
+ const std::string name = type.name();
+ const std::string super_name =
+ super_type == nullptr ? "Object" : super_type->name();
+ h_contents << "\nclass Tq" << name << " : public Tq" << super_name << " {\n";
+ h_contents << " public:\n";
+ h_contents << " inline Tq" << name << "(uintptr_t address) : Tq"
+ << super_name << "(address) {}\n";
+ h_contents << " std::vector<std::unique_ptr<ObjectProperty>> "
+ "GetProperties(d::MemoryAccessor accessor) const override;\n";
+ h_contents << " const char* GetName() const override;\n";
+ h_contents << " void Visit(TqObjectVisitor* visitor) const override;\n";
+
+ cc_contents << "\nconst char* Tq" << name << "::GetName() const {\n";
+ cc_contents << " return \"v8::internal::" << name << "\";\n";
+ cc_contents << "}\n";
+
+ cc_contents << "\nvoid Tq" << name
+ << "::Visit(TqObjectVisitor* visitor) const {\n";
+ cc_contents << " visitor->Visit" << name << "(this);\n";
+ cc_contents << "}\n";
+
+ visitor << " virtual void Visit" << name << "(const Tq" << name
+ << "* object) {\n";
+ visitor << " Visit" << super_name << "(object);\n";
+ visitor << " }\n";
+
+ std::stringstream get_props_impl;
+
+ for (const Field& field : type.fields()) {
+ const Type* field_type = field.name_and_type.type;
+ if (field_type == TypeOracle::GetVoidType()) continue;
+ const std::string& field_name = field.name_and_type.name;
+ bool is_field_tagged = field_type->IsSubtypeOf(TypeOracle::GetTaggedType());
+ base::Optional<const ClassType*> field_class_type =
+ field_type->ClassSupertype();
+ size_t field_size = 0;
+ std::string field_size_string;
+ std::tie(field_size, field_size_string) = field.GetFieldSizeInformation();
+
+ std::string field_value_type;
+ std::string field_value_type_compressed;
+ std::string field_cc_type;
+ std::string field_cc_type_compressed;
+ if (is_field_tagged) {
+ field_value_type = "uintptr_t";
+ field_value_type_compressed = "i::Tagged_t";
+ field_cc_type = "v8::internal::" + (field_class_type.has_value()
+ ? (*field_class_type)->name()
+ : "Object");
+ field_cc_type_compressed =
+ COMPRESS_POINTERS_BOOL ? "v8::internal::TaggedValue" : field_cc_type;
+ } else {
+ const Type* constexpr_version = field_type->ConstexprVersion();
+ if (constexpr_version == nullptr) {
+ Error("Type '", field_type->ToString(),
+ "' requires a constexpr representation");
+ continue;
+ }
+ field_cc_type = constexpr_version->GetGeneratedTypeName();
+ field_cc_type_compressed = field_cc_type;
+ // Note that we need constexpr names to resolve correctly in the global
+ // namespace, because we're passing them as strings to a debugging
+ // extension. We can verify this during build of the debug helper, because
+ // we use this type for a local variable below, and generate this code in
+ // a disjoint namespace. However, we can't emit a useful error at this
+ // point. Instead we'll emit a comment that might be helpful.
+ field_value_type =
+ field_cc_type +
+ " /*Failing? Ensure constexpr type name is fully qualified and "
+ "necessary #includes are in debug-helper-internal.h*/";
+ field_value_type_compressed = field_value_type;
+ }
+
+ const std::string field_getter =
+ "Get" + CamelifyString(field_name) + "Value";
+ const std::string address_getter =
+ "Get" + CamelifyString(field_name) + "Address";
+
+ std::string indexed_field_info;
+ std::string index_param;
+ std::string index_offset;
+ if (field.index) {
+ const Type* index_type = (*field.index)->name_and_type.type;
+ std::string index_type_name;
+ std::string index_value;
+ if (index_type == TypeOracle::GetSmiType()) {
+ index_type_name = "uintptr_t";
+ index_value =
+ "i::PlatformSmiTagging::SmiToInt(indexed_field_count.value)";
+ } else if (!index_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
+ const Type* constexpr_index = index_type->ConstexprVersion();
+ if (constexpr_index == nullptr) {
+ Error("Type '", index_type->ToString(),
+ "' requires a constexpr representation");
+ continue;
+ }
+ index_type_name = constexpr_index->GetGeneratedTypeName();
+ index_value = "indexed_field_count.value";
+ } else {
+ Error("Unsupported index type: ", index_type);
+ continue;
+ }
+ get_props_impl << " Value<" << index_type_name
+ << "> indexed_field_count = Get"
+ << CamelifyString((*field.index)->name_and_type.name)
+ << "Value(accessor);\n";
+ indexed_field_info =
+ ", " + index_value + ", GetArrayKind(indexed_field_count.validity)";
+ index_param = ", size_t offset";
+ index_offset = " + offset * sizeof(value)";
+ }
+ get_props_impl
+ << " result.push_back(v8::base::make_unique<ObjectProperty>(\""
+ << field_name << "\", \"" << field_cc_type_compressed << "\", \""
+ << field_cc_type << "\", " << address_getter << "()"
+ << indexed_field_info << "));\n";
+
+ h_contents << " uintptr_t " << address_getter << "() const;\n";
+ h_contents << " Value<" << field_value_type << "> " << field_getter
+ << "(d::MemoryAccessor accessor " << index_param << ") const;\n";
+ cc_contents << "\nuintptr_t Tq" << name << "::" << address_getter
+ << "() const {\n";
+ cc_contents << " return address_ - i::kHeapObjectTag + " << field.offset
+ << ";\n";
+ cc_contents << "}\n";
+ cc_contents << "\nValue<" << field_value_type << "> Tq" << name
+ << "::" << field_getter << "(d::MemoryAccessor accessor"
+ << index_param << ") const {\n";
+ cc_contents << " " << field_value_type_compressed << " value{};\n";
+ cc_contents << " d::MemoryAccessResult validity = accessor("
+ << address_getter << "()" << index_offset
+ << ", reinterpret_cast<uint8_t*>(&value), sizeof(value));\n";
+ cc_contents << " return {validity, "
+ << (is_field_tagged ? "Decompress(value, address_)" : "value")
+ << "};\n";
+ cc_contents << "}\n";
+ }
+
+ h_contents << "};\n";
+
+ cc_contents << "\nstd::vector<std::unique_ptr<ObjectProperty>> Tq" << name
+ << "::GetProperties(d::MemoryAccessor accessor) const {\n";
+ cc_contents << " std::vector<std::unique_ptr<ObjectProperty>> result = Tq"
+ << super_name << "::GetProperties(accessor);\n";
+ cc_contents << get_props_impl.str();
+ cc_contents << " return result;\n";
+ cc_contents << "}\n";
+}
+} // namespace
+
+void ImplementationVisitor::GenerateClassDebugReaders(
+ const std::string& output_directory) {
+ const std::string file_name = "class-debug-readers-tq";
+ std::stringstream h_contents;
+ std::stringstream cc_contents;
+ h_contents << "// Provides the ability to read object properties in\n";
+ h_contents << "// postmortem or remote scenarios, where the debuggee's\n";
+ h_contents << "// memory is not part of the current process's address\n";
+ h_contents << "// space and must be read using a callback function.\n\n";
+ {
+ IncludeGuardScope include_guard(h_contents, file_name + ".h");
+
+ h_contents << "#include <cstdint>\n";
+ h_contents << "#include <vector>\n";
+ h_contents
+ << "\n#include \"tools/debug_helper/debug-helper-internal.h\"\n\n";
+
+ cc_contents << "#include \"torque-generated/" << file_name << ".h\"\n";
+ cc_contents << "#include \"include/v8-internal.h\"\n\n";
+ cc_contents << "namespace i = v8::internal;\n\n";
+
+ NamespaceScope h_namespaces(h_contents, {"v8_debug_helper_internal"});
+ NamespaceScope cc_namespaces(cc_contents, {"v8_debug_helper_internal"});
+
+ std::stringstream visitor;
+ visitor << "\nclass TqObjectVisitor {\n";
+ visitor << " public:\n";
+ visitor << " virtual void VisitObject(const TqObject* object) {}\n";
+
+ std::unordered_set<const ClassType*> done;
+ for (const TypeAlias* alias : GlobalContext::GetClasses()) {
+ const ClassType* type = ClassType::DynamicCast(alias->type());
+ GenerateClassDebugReader(*type, h_contents, cc_contents, visitor, &done);
+ }
+
+ visitor << "};\n";
+ h_contents << visitor.str();
+ }
+ WriteFile(output_directory + "/" + file_name + ".h", h_contents.str());
+ WriteFile(output_directory + "/" + file_name + ".cc", cc_contents.str());
+}
+
+} // namespace torque
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/torque/constants.h b/deps/v8/src/torque/constants.h
index 4ad3a6ec3c..efbbf9588e 100644
--- a/deps/v8/src/torque/constants.h
+++ b/deps/v8/src/torque/constants.h
@@ -28,6 +28,7 @@ static const char* const JS_FUNCTION_TYPE_STRING = "JSFunction";
static const char* const MAP_TYPE_STRING = "Map";
static const char* const OBJECT_TYPE_STRING = "Object";
static const char* const HEAP_OBJECT_TYPE_STRING = "HeapObject";
+static const char* const JSANY_TYPE_STRING = "JSAny";
static const char* const JSOBJECT_TYPE_STRING = "JSObject";
static const char* const SMI_TYPE_STRING = "Smi";
static const char* const TAGGED_TYPE_STRING = "Tagged";
@@ -49,6 +50,10 @@ static const char* const FLOAT64_TYPE_STRING = "float64";
static const char* const CONST_INT31_TYPE_STRING = "constexpr int31";
static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64";
+static const char* const TORQUE_INTERNAL_NAMESPACE_STRING = "torque_internal";
+static const char* const REFERENCE_TYPE_STRING = "Reference";
+static const char* const SLICE_TYPE_STRING = "Slice";
+static const char* const STRUCT_NAMESPACE_STRING = "_struct";
inline bool IsConstexprName(const std::string& name) {
return name.substr(0, std::strlen(CONSTEXPR_TYPE_PREFIX)) ==
diff --git a/deps/v8/src/torque/contextual.h b/deps/v8/src/torque/contextual.h
index 92d2bdf3d7..d7764bfa68 100644
--- a/deps/v8/src/torque/contextual.h
+++ b/deps/v8/src/torque/contextual.h
@@ -15,7 +15,7 @@ namespace internal {
namespace torque {
template <class Variable>
-V8_EXPORT_PRIVATE typename Variable::VariableType*& ContextualVariableTop();
+V8_EXPORT_PRIVATE typename Variable::Scope*& ContextualVariableTop();
// {ContextualVariable} provides a clean alternative to a global variable.
// The contextual variable is mutable, and supports managing the value of
@@ -30,8 +30,6 @@ V8_EXPORT_PRIVATE typename Variable::VariableType*& ContextualVariableTop();
template <class Derived, class VarType>
class ContextualVariable {
public:
- using VariableType = VarType;
-
// A {Scope} contains a new object of type {VarType} and gives
// ContextualVariable::Get() access to it. Upon destruction, the contextual
// variable is restored to the state before the {Scope} was created. Scopes
@@ -41,18 +39,20 @@ class ContextualVariable {
public:
template <class... Args>
explicit Scope(Args&&... args)
- : current_(std::forward<Args>(args)...), previous_(Top()) {
- Top() = &current_;
+ : value_(std::forward<Args>(args)...), previous_(Top()) {
+ Top() = this;
}
~Scope() {
// Ensure stack discipline.
- DCHECK_EQ(&current_, Top());
+ DCHECK_EQ(this, Top());
Top() = previous_;
}
+ VarType& Value() { return value_; }
+
private:
- VarType current_;
- VarType* previous_;
+ VarType value_;
+ Scope* previous_;
static_assert(std::is_base_of<ContextualVariable, Derived>::value,
"Curiously Recurring Template Pattern");
@@ -65,13 +65,13 @@ class ContextualVariable {
// for this contextual variable.
static VarType& Get() {
DCHECK_NOT_NULL(Top());
- return *Top();
+ return Top()->Value();
}
private:
template <class T>
- friend typename T::VariableType*& ContextualVariableTop();
- static VarType*& Top() { return ContextualVariableTop<Derived>(); }
+ friend typename T::Scope*& ContextualVariableTop();
+ static Scope*& Top() { return ContextualVariableTop<Derived>(); }
static bool HasScope() { return Top() != nullptr; }
friend class MessageBuilder;
@@ -82,11 +82,11 @@ class ContextualVariable {
struct VarName \
: v8::internal::torque::ContextualVariable<VarName, __VA_ARGS__> {}
-#define DEFINE_CONTEXTUAL_VARIABLE(VarName) \
- template <> \
- V8_EXPORT_PRIVATE VarName::VariableType*& ContextualVariableTop<VarName>() { \
- static thread_local VarName::VariableType* top = nullptr; \
- return top; \
+#define DEFINE_CONTEXTUAL_VARIABLE(VarName) \
+ template <> \
+ V8_EXPORT_PRIVATE VarName::Scope*& ContextualVariableTop<VarName>() { \
+ static thread_local VarName::Scope* top = nullptr; \
+ return top; \
}
// By inheriting from {ContextualClass} a class can become a contextual variable
diff --git a/deps/v8/src/torque/csa-generator.cc b/deps/v8/src/torque/csa-generator.cc
index cd7ff22c48..0c49033955 100644
--- a/deps/v8/src/torque/csa-generator.cc
+++ b/deps/v8/src/torque/csa-generator.cc
@@ -56,14 +56,10 @@ Stack<std::string> CSAGenerator::EmitBlock(const Block* block) {
}
void CSAGenerator::EmitSourcePosition(SourcePosition pos, bool always_emit) {
- std::string file = SourceFileMap::AbsolutePath(pos.source);
+ const std::string& file = SourceFileMap::AbsolutePath(pos.source);
if (always_emit || !previous_position_.CompareStartIgnoreColumn(pos)) {
// Lines in Torque SourcePositions are zero-based, while the
// CodeStubAssembler and downwind systems are one-based.
- for (auto& c : file) {
- if (c == '\\')
- c = '/';
- }
out_ << " ca_.SetSourcePosition(\"" << file << "\", "
<< (pos.start.line + 1) << ");\n";
previous_position_ = pos;
@@ -309,8 +305,7 @@ void CSAGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction,
std::string catch_name =
PreCallableExceptionPreparation(instruction.catch_block);
out_ << " ";
- bool needs_flattening =
- return_type->IsStructType() || return_type->IsReferenceType();
+ bool needs_flattening = return_type->IsStructType();
if (needs_flattening) {
out_ << "std::tie(";
PrintCommaSeparatedList(out_, results);
@@ -713,8 +708,13 @@ void CSAGenerator::EmitInstruction(const UnsafeCastInstruction& instruction,
void CSAGenerator::EmitInstruction(
const CreateFieldReferenceInstruction& instruction,
Stack<std::string>* stack) {
- const Field& field =
- instruction.class_type->LookupField(instruction.field_name);
+ base::Optional<const ClassType*> class_type =
+ instruction.type->ClassSupertype();
+ if (!class_type.has_value()) {
+ ReportError("Cannot create field reference of type ", instruction.type,
+ " which does not inherit from a class type");
+ }
+ const Field& field = class_type.value()->LookupField(instruction.field_name);
std::string offset_name = FreshNodeName();
stack->Push(offset_name);
@@ -770,11 +770,6 @@ void CSAGenerator::EmitCSAValue(VisitResult result,
out);
}
out << "}";
- } else if (result.type()->IsReferenceType()) {
- DCHECK_EQ(2, result.stack_range().Size());
- size_t offset = result.stack_range().begin().offset;
- out << "CodeStubAssembler::Reference{" << values.Peek(BottomOffset{offset})
- << ", " << values.Peek(BottomOffset{offset + 1}) << "}";
} else {
DCHECK_EQ(1, result.stack_range().Size());
out << "compiler::TNode<" << result.type()->GetGeneratedTNodeTypeName()
diff --git a/deps/v8/src/torque/declarable.cc b/deps/v8/src/torque/declarable.cc
index 1fd07d5b0d..5bcaff016d 100644
--- a/deps/v8/src/torque/declarable.cc
+++ b/deps/v8/src/torque/declarable.cc
@@ -7,6 +7,7 @@
#include "src/torque/declarable.h"
#include "src/torque/global-context.h"
+#include "src/torque/type-inference.h"
#include "src/torque/type-visitor.h"
namespace v8 {
@@ -58,67 +59,38 @@ std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) {
std::ostream& operator<<(std::ostream& os, const Generic& g) {
os << "generic " << g.name() << "<";
PrintCommaSeparatedList(
- os, g.declaration()->generic_parameters,
+ os, g.generic_parameters(),
[](const Identifier* identifier) { return identifier->value; });
os << ">";
return os;
}
-namespace {
-base::Optional<const Type*> InferTypeArgument(const std::string& to_infer,
- TypeExpression* parameter,
- const Type* argument) {
- BasicTypeExpression* basic = BasicTypeExpression::DynamicCast(parameter);
- if (basic && basic->namespace_qualification.empty() && !basic->is_constexpr &&
- basic->name == to_infer) {
- return argument;
- }
- auto* ref = ReferenceTypeExpression::DynamicCast(parameter);
- if (ref && argument->IsReferenceType()) {
- return InferTypeArgument(to_infer, ref->referenced_type,
- ReferenceType::cast(argument)->referenced_type());
- }
- return base::nullopt;
-}
-
-base::Optional<const Type*> InferTypeArgument(
- const std::string& to_infer, const std::vector<TypeExpression*>& parameters,
+TypeArgumentInference Generic::InferSpecializationTypes(
+ const TypeVector& explicit_specialization_types,
const TypeVector& arguments) {
- for (size_t i = 0; i < arguments.size() && i < parameters.size(); ++i) {
- if (base::Optional<const Type*> inferred =
- InferTypeArgument(to_infer, parameters[i], arguments[i])) {
- return *inferred;
- }
- }
- return base::nullopt;
+ size_t implicit_count = declaration()->parameters.implicit_count;
+ const std::vector<TypeExpression*>& parameters =
+ declaration()->parameters.types;
+ std::vector<TypeExpression*> explicit_parameters(
+ parameters.begin() + implicit_count, parameters.end());
+
+ CurrentScope::Scope generic_scope(ParentScope());
+ TypeArgumentInference inference(generic_parameters(),
+ explicit_specialization_types,
+ explicit_parameters, arguments);
+ return inference;
}
-} // namespace
-
-base::Optional<TypeVector> Generic::InferSpecializationTypes(
- const TypeVector& explicit_specialization_types,
- const TypeVector& arguments) {
- TypeVector result = explicit_specialization_types;
- size_t type_parameter_count = declaration()->generic_parameters.size();
- if (explicit_specialization_types.size() > type_parameter_count) {
+base::Optional<Statement*> Generic::CallableBody() {
+ if (auto* decl = TorqueMacroDeclaration::DynamicCast(declaration())) {
+ return decl->body;
+ } else if (auto* decl =
+ TorqueBuiltinDeclaration::DynamicCast(declaration())) {
+ return decl->body;
+ } else {
return base::nullopt;
}
- for (size_t i = explicit_specialization_types.size();
- i < type_parameter_count; ++i) {
- const std::string type_name = declaration()->generic_parameters[i]->value;
- size_t implicit_count =
- declaration()->callable->signature->parameters.implicit_count;
- const std::vector<TypeExpression*>& parameters =
- declaration()->callable->signature->parameters.types;
- std::vector<TypeExpression*> explicit_parameters(
- parameters.begin() + implicit_count, parameters.end());
- base::Optional<const Type*> inferred =
- InferTypeArgument(type_name, explicit_parameters, arguments);
- if (!inferred) return base::nullopt;
- result.push_back(*inferred);
- }
- return result;
}
bool Namespace::IsDefaultNamespace() const {
diff --git a/deps/v8/src/torque/declarable.h b/deps/v8/src/torque/declarable.h
index cf6fd2554b..502180953d 100644
--- a/deps/v8/src/torque/declarable.h
+++ b/deps/v8/src/torque/declarable.h
@@ -21,6 +21,7 @@ namespace torque {
class Scope;
class Namespace;
+class TypeArgumentInference;
DECLARE_CONTEXTUAL_VARIABLE(CurrentScope, Scope*);
@@ -261,6 +262,7 @@ class Callable : public Scope {
const std::string& ExternalName() const { return external_name_; }
const std::string& ReadableName() const { return readable_name_; }
const Signature& signature() const { return signature_; }
+ bool IsTransitioning() const { return signature().transitioning; }
const NameVector& parameter_names() const {
return signature_.parameter_names;
}
@@ -269,7 +271,6 @@ class Callable : public Scope {
}
void IncrementReturns() { ++returns_; }
bool HasReturns() const { return returns_; }
- bool IsTransitioning() const { return transitioning_; }
base::Optional<Statement*> body() const { return body_; }
bool IsExternal() const { return !body_.has_value(); }
virtual bool ShouldBeInlined() const { return false; }
@@ -277,14 +278,13 @@ class Callable : public Scope {
protected:
Callable(Declarable::Kind kind, std::string external_name,
- std::string readable_name, Signature signature, bool transitioning,
+ std::string readable_name, Signature signature,
base::Optional<Statement*> body)
: Scope(kind),
external_name_(std::move(external_name)),
readable_name_(std::move(readable_name)),
signature_(std::move(signature)),
- transitioning_(transitioning),
returns_(0),
body_(body) {
DCHECK(!body || *body);
@@ -294,7 +294,6 @@ class Callable : public Scope {
std::string external_name_;
std::string readable_name_;
Signature signature_;
- bool transitioning_;
size_t returns_;
base::Optional<Statement*> body_;
};
@@ -320,9 +319,9 @@ class Macro : public Callable {
protected:
Macro(Declarable::Kind kind, std::string external_name,
std::string readable_name, const Signature& signature,
- bool transitioning, base::Optional<Statement*> body)
+ base::Optional<Statement*> body)
: Callable(kind, std::move(external_name), std::move(readable_name),
- signature, transitioning, body),
+ signature, body),
used_(false) {
if (signature.parameter_types.var_args) {
ReportError("Varargs are not supported for macros.");
@@ -344,9 +343,9 @@ class ExternMacro : public Macro {
private:
friend class Declarations;
ExternMacro(const std::string& name, std::string external_assembler_name,
- Signature signature, bool transitioning)
+ Signature signature)
: Macro(Declarable::kExternMacro, name, name, std::move(signature),
- transitioning, base::nullopt),
+ base::nullopt),
external_assembler_name_(std::move(external_assembler_name)) {}
std::string external_assembler_name_;
@@ -360,10 +359,10 @@ class TorqueMacro : public Macro {
protected:
TorqueMacro(Declarable::Kind kind, std::string external_name,
std::string readable_name, const Signature& signature,
- bool transitioning, base::Optional<Statement*> body,
- bool is_user_defined, bool exported_to_csa)
+ base::Optional<Statement*> body, bool is_user_defined,
+ bool exported_to_csa)
: Macro(kind, std::move(external_name), std::move(readable_name),
- signature, transitioning, body),
+ signature, body),
exported_to_csa_(exported_to_csa) {
SetIsUserDefined(is_user_defined);
}
@@ -371,12 +370,11 @@ class TorqueMacro : public Macro {
private:
friend class Declarations;
TorqueMacro(std::string external_name, std::string readable_name,
- const Signature& signature, bool transitioning,
- base::Optional<Statement*> body, bool is_user_defined,
- bool exported_to_csa)
+ const Signature& signature, base::Optional<Statement*> body,
+ bool is_user_defined, bool exported_to_csa)
: TorqueMacro(Declarable::kTorqueMacro, std::move(external_name),
- std::move(readable_name), signature, transitioning, body,
- is_user_defined, exported_to_csa) {}
+ std::move(readable_name), signature, body, is_user_defined,
+ exported_to_csa) {}
bool exported_to_csa_ = false;
};
@@ -395,11 +393,9 @@ class Method : public TorqueMacro {
private:
friend class Declarations;
Method(AggregateType* aggregate_type, std::string external_name,
- std::string readable_name, const Signature& signature,
- bool transitioning, Statement* body)
+ std::string readable_name, const Signature& signature, Statement* body)
: TorqueMacro(Declarable::kMethod, std::move(external_name),
- std::move(readable_name), signature, transitioning, body,
- true, false),
+ std::move(readable_name), signature, body, true, false),
aggregate_type_(aggregate_type) {}
AggregateType* aggregate_type_;
};
@@ -416,10 +412,10 @@ class Builtin : public Callable {
private:
friend class Declarations;
Builtin(std::string external_name, std::string readable_name,
- Builtin::Kind kind, const Signature& signature, bool transitioning,
+ Builtin::Kind kind, const Signature& signature,
base::Optional<Statement*> body)
: Callable(Declarable::kBuiltin, std::move(external_name),
- std::move(readable_name), signature, transitioning, body),
+ std::move(readable_name), signature, body),
kind_(kind) {}
Kind kind_;
@@ -431,10 +427,9 @@ class RuntimeFunction : public Callable {
private:
friend class Declarations;
- RuntimeFunction(const std::string& name, const Signature& signature,
- bool transitioning)
+ RuntimeFunction(const std::string& name, const Signature& signature)
: Callable(Declarable::kRuntimeFunction, name, name, signature,
- transitioning, base::nullopt) {}
+ base::nullopt) {}
};
class Intrinsic : public Callable {
@@ -444,8 +439,7 @@ class Intrinsic : public Callable {
private:
friend class Declarations;
Intrinsic(std::string name, const Signature& signature)
- : Callable(Declarable::kIntrinsic, name, name, signature, false,
- base::nullopt) {
+ : Callable(Declarable::kIntrinsic, name, name, signature, base::nullopt) {
if (signature.parameter_types.var_args) {
ReportError("Varargs are not supported for intrinsics.");
}
@@ -483,33 +477,32 @@ class Generic : public Declarable {
DECLARE_DECLARABLE_BOILERPLATE(Generic, generic)
const std::string& name() const { return name_; }
- GenericDeclaration* declaration() const { return declaration_; }
+ CallableDeclaration* declaration() const {
+ return generic_declaration_->declaration;
+ }
const std::vector<Identifier*> generic_parameters() const {
- return declaration()->generic_parameters;
+ return generic_declaration_->generic_parameters;
}
SpecializationMap<Callable>& specializations() { return specializations_; }
- base::Optional<TypeVector> InferSpecializationTypes(
+ base::Optional<Statement*> CallableBody();
+
+ TypeArgumentInference InferSpecializationTypes(
const TypeVector& explicit_specialization_types,
const TypeVector& arguments);
private:
friend class Declarations;
- Generic(const std::string& name, GenericDeclaration* declaration)
+ Generic(const std::string& name, GenericDeclaration* generic_declaration)
: Declarable(Declarable::kGeneric),
name_(name),
- declaration_(declaration) {}
+ generic_declaration_(generic_declaration) {}
std::string name_;
- GenericDeclaration* declaration_;
+ GenericDeclaration* generic_declaration_;
SpecializationMap<Callable> specializations_;
};
-struct SpecializationKey {
- Generic* generic;
- TypeVector specialized_types;
-};
-
class GenericStructType : public Declarable {
public:
DECLARE_DECLARABLE_BOILERPLATE(GenericStructType, generic_type)
diff --git a/deps/v8/src/torque/declaration-visitor.cc b/deps/v8/src/torque/declaration-visitor.cc
index e0e996f33b..f762337463 100644
--- a/deps/v8/src/torque/declaration-visitor.cc
+++ b/deps/v8/src/torque/declaration-visitor.cc
@@ -53,26 +53,13 @@ void DeclarationVisitor::Visit(Declaration* decl) {
}
}
-void DeclarationVisitor::Visit(CallableNode* decl, const Signature& signature,
- base::Optional<Statement*> body) {
- switch (decl->kind) {
-#define ENUM_ITEM(name) \
- case AstNode::Kind::k##name: \
- return Visit(name::cast(decl), signature, body);
- AST_CALLABLE_NODE_KIND_LIST(ENUM_ITEM)
-#undef ENUM_ITEM
- default:
- UNIMPLEMENTED();
- }
-}
-
Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl,
std::string external_name,
std::string readable_name,
Signature signature,
base::Optional<Statement*> body) {
const bool javascript = decl->javascript_linkage;
- const bool varargs = decl->signature->parameters.has_varargs;
+ const bool varargs = decl->parameters.has_varargs;
Builtin::Kind kind = !javascript ? Builtin::kStub
: varargs ? Builtin::kVarArgsJavaScript
: Builtin::kFixedArgsJavaScript;
@@ -82,6 +69,21 @@ Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl,
" to be a JavaScript builtin");
}
+ if (javascript) {
+ if (!signature.return_type->IsSubtypeOf(TypeOracle::GetJSAnyType())) {
+ Error("Return type of JavaScript-linkage builtins has to be JSAny.")
+ .Position(decl->return_type->pos);
+ }
+ for (size_t i = signature.implicit_count;
+ i < signature.parameter_types.types.size(); ++i) {
+ const Type* parameter_type = signature.parameter_types.types[i];
+ if (parameter_type != TypeOracle::GetJSAnyType()) {
+ Error("Parameters of JavaScript-linkage builtins have to be JSAny.")
+ .Position(decl->parameters.types[i]->pos);
+ }
+ }
+ }
+
for (size_t i = 0; i < signature.types().size(); ++i) {
if (const StructType* type =
StructType::DynamicCast(signature.types()[i])) {
@@ -111,14 +113,20 @@ Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl,
struct_type->name());
}
- return Declarations::CreateBuiltin(
- std::move(external_name), std::move(readable_name), kind,
- std::move(signature), decl->transitioning, body);
+ return Declarations::CreateBuiltin(std::move(external_name),
+ std::move(readable_name), kind,
+ std::move(signature), body);
+}
+
+void DeclarationVisitor::Visit(ExternalBuiltinDeclaration* decl) {
+ Declarations::Declare(
+ decl->name->value,
+ CreateBuiltin(decl, decl->name->value, decl->name->value,
+ TypeVisitor::MakeSignature(decl), base::nullopt));
}
-void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl,
- const Signature& signature,
- base::Optional<Statement*> body) {
+void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl) {
+ Signature signature = TypeVisitor::MakeSignature(decl);
if (signature.parameter_types.types.size() == 0 ||
!(signature.parameter_types.types[0] == TypeOracle::GetContextType())) {
ReportError(
@@ -142,39 +150,34 @@ void DeclarationVisitor::Visit(ExternalRuntimeDeclaration* decl,
}
}
- Declarations::DeclareRuntimeFunction(decl->name, signature,
- decl->transitioning);
+ Declarations::DeclareRuntimeFunction(decl->name->value, signature);
}
-void DeclarationVisitor::Visit(ExternalMacroDeclaration* decl,
- const Signature& signature,
- base::Optional<Statement*> body) {
- Declarations::DeclareMacro(decl->name, true, decl->external_assembler_name,
- signature, decl->transitioning, body, decl->op);
+void DeclarationVisitor::Visit(ExternalMacroDeclaration* decl) {
+ Declarations::DeclareMacro(
+ decl->name->value, true, decl->external_assembler_name,
+ TypeVisitor::MakeSignature(decl), base::nullopt, decl->op);
}
-void DeclarationVisitor::Visit(TorqueBuiltinDeclaration* decl,
- const Signature& signature,
- base::Optional<Statement*> body) {
+void DeclarationVisitor::Visit(TorqueBuiltinDeclaration* decl) {
Declarations::Declare(
- decl->name, CreateBuiltin(decl, decl->name, decl->name, signature, body));
+ decl->name->value,
+ CreateBuiltin(decl, decl->name->value, decl->name->value,
+ TypeVisitor::MakeSignature(decl), decl->body));
}
-void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl,
- const Signature& signature,
- base::Optional<Statement*> body) {
+void DeclarationVisitor::Visit(TorqueMacroDeclaration* decl) {
Macro* macro = Declarations::DeclareMacro(
- decl->name, decl->export_to_csa, base::nullopt, signature,
- decl->transitioning, body, decl->op);
+ decl->name->value, decl->export_to_csa, base::nullopt,
+ TypeVisitor::MakeSignature(decl), decl->body, decl->op);
// TODO(szuend): Set identifier_position to decl->name->pos once all callable
// names are changed from std::string to Identifier*.
macro->SetPosition(decl->pos);
}
-void DeclarationVisitor::Visit(IntrinsicDeclaration* decl,
- const Signature& signature,
- base::Optional<Statement*> body) {
- Declarations::DeclareIntrinsic(decl->name, signature);
+void DeclarationVisitor::Visit(IntrinsicDeclaration* decl) {
+ Declarations::DeclareIntrinsic(decl->name->value,
+ TypeVisitor::MakeSignature(decl));
}
void DeclarationVisitor::Visit(ConstDeclaration* decl) {
@@ -182,30 +185,16 @@ void DeclarationVisitor::Visit(ConstDeclaration* decl) {
decl->name, TypeVisitor::ComputeType(decl->type), decl->expression);
}
-void DeclarationVisitor::Visit(StandardDeclaration* decl) {
- Signature signature =
- TypeVisitor::MakeSignature(decl->callable->signature.get());
- Visit(decl->callable, signature, decl->body);
-}
-
void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
- if ((decl->body != nullptr) == decl->external) {
- std::stringstream stream;
- stream << "specialization of " << decl->name
- << " must either be marked 'extern' or have a body";
- ReportError(stream.str());
- }
-
std::vector<Generic*> generic_list =
Declarations::LookupGeneric(decl->name->value);
// Find the matching generic specialization based on the concrete parameter
// list.
Generic* matching_generic = nullptr;
- Signature signature_with_types =
- TypeVisitor::MakeSignature(decl->signature.get());
+ Signature signature_with_types = TypeVisitor::MakeSignature(decl);
for (Generic* generic : generic_list) {
Signature generic_signature_with_types =
- MakeSpecializedSignature(SpecializationKey{
+ MakeSpecializedSignature(SpecializationKey<Generic>{
generic, TypeVisitor::ComputeTypeVector(decl->generic_parameters)});
if (signature_with_types.HasSameTypesAs(generic_signature_with_types,
ParameterMode::kIgnoreImplicit)) {
@@ -233,7 +222,7 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
stream << "\ncandidates are:";
for (Generic* generic : generic_list) {
stream << "\n "
- << MakeSpecializedSignature(SpecializationKey{
+ << MakeSpecializedSignature(SpecializationKey<Generic>{
generic,
TypeVisitor::ComputeTypeVector(decl->generic_parameters)});
}
@@ -245,10 +234,12 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) {
matching_generic->IdentifierPosition());
}
- Specialize(SpecializationKey{matching_generic, TypeVisitor::ComputeTypeVector(
- decl->generic_parameters)},
- matching_generic->declaration()->callable, decl->signature.get(),
- decl->body, decl->pos);
+ CallableDeclaration* generic_declaration = matching_generic->declaration();
+
+ Specialize(SpecializationKey<Generic>{matching_generic,
+ TypeVisitor::ComputeTypeVector(
+ decl->generic_parameters)},
+ generic_declaration, decl, decl->body, decl->pos);
}
void DeclarationVisitor::Visit(ExternConstDeclaration* decl) {
@@ -267,10 +258,11 @@ void DeclarationVisitor::Visit(CppIncludeDeclaration* decl) {
GlobalContext::AddCppInclude(decl->include_path);
}
-void DeclarationVisitor::DeclareSpecializedTypes(const SpecializationKey& key) {
+void DeclarationVisitor::DeclareSpecializedTypes(
+ const SpecializationKey<Generic>& key) {
size_t i = 0;
const std::size_t generic_parameter_count =
- key.generic->declaration()->generic_parameters.size();
+ key.generic->generic_parameters().size();
if (generic_parameter_count != key.specialized_types.size()) {
std::stringstream stream;
stream << "Wrong generic argument count for specialization of \""
@@ -280,37 +272,35 @@ void DeclarationVisitor::DeclareSpecializedTypes(const SpecializationKey& key) {
}
for (auto type : key.specialized_types) {
- Identifier* generic_type_name =
- key.generic->declaration()->generic_parameters[i++];
+ Identifier* generic_type_name = key.generic->generic_parameters()[i++];
TypeAlias* alias = Declarations::DeclareType(generic_type_name, type);
alias->SetIsUserDefined(false);
}
}
Signature DeclarationVisitor::MakeSpecializedSignature(
- const SpecializationKey& key) {
+ const SpecializationKey<Generic>& key) {
CurrentScope::Scope generic_scope(key.generic->ParentScope());
// Create a temporary fake-namespace just to temporarily declare the
// specialization aliases for the generic types to create a signature.
Namespace tmp_namespace("_tmp");
CurrentScope::Scope tmp_namespace_scope(&tmp_namespace);
DeclareSpecializedTypes(key);
- return TypeVisitor::MakeSignature(
- key.generic->declaration()->callable->signature.get());
+ return TypeVisitor::MakeSignature(key.generic->declaration());
}
-Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) {
- if (!key.generic->declaration()->body &&
- IntrinsicDeclaration::DynamicCast(key.generic->declaration()->callable) ==
- nullptr) {
+Callable* DeclarationVisitor::SpecializeImplicit(
+ const SpecializationKey<Generic>& key) {
+ base::Optional<Statement*> body = key.generic->CallableBody();
+ if (!body && IntrinsicDeclaration::DynamicCast(key.generic->declaration()) ==
+ nullptr) {
ReportError("missing specialization of ", key.generic->name(),
" with types <", key.specialized_types, "> declared at ",
key.generic->Position());
}
CurrentScope::Scope generic_scope(key.generic->ParentScope());
- Callable* result = Specialize(key, key.generic->declaration()->callable,
- base::nullopt, key.generic->declaration()->body,
- CurrentSourcePosition::Get());
+ Callable* result = Specialize(key, key.generic->declaration(), base::nullopt,
+ body, CurrentSourcePosition::Get());
result->SetIsUserDefined(false);
CurrentScope::Scope callable_scope(result);
DeclareSpecializedTypes(key);
@@ -318,12 +308,11 @@ Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) {
}
Callable* DeclarationVisitor::Specialize(
- const SpecializationKey& key, CallableNode* declaration,
- base::Optional<const CallableNodeSignature*> signature,
+ const SpecializationKey<Generic>& key, CallableDeclaration* declaration,
+ base::Optional<const SpecializationDeclaration*> explicit_specialization,
base::Optional<Statement*> body, SourcePosition position) {
CurrentSourcePosition::Scope pos_scope(position);
- size_t generic_parameter_count =
- key.generic->declaration()->generic_parameters.size();
+ size_t generic_parameter_count = key.generic->generic_parameters().size();
if (generic_parameter_count != key.specialized_types.size()) {
std::stringstream stream;
stream << "number of template parameters ("
@@ -338,13 +327,15 @@ Callable* DeclarationVisitor::Specialize(
" with types <", key.specialized_types, ">");
}
- Signature type_signature = signature ? TypeVisitor::MakeSignature(*signature)
- : MakeSpecializedSignature(key);
+ Signature type_signature =
+ explicit_specialization
+ ? TypeVisitor::MakeSignature(*explicit_specialization)
+ : MakeSpecializedSignature(key);
std::string generated_name = Declarations::GetGeneratedCallableName(
- declaration->name, key.specialized_types);
+ declaration->name->value, key.specialized_types);
std::stringstream readable_name;
- readable_name << declaration->name << "<";
+ readable_name << declaration->name->value << "<";
bool first = true;
for (const Type* t : key.specialized_types) {
if (!first) readable_name << ", ";
@@ -354,11 +345,12 @@ Callable* DeclarationVisitor::Specialize(
readable_name << ">";
Callable* callable;
if (MacroDeclaration::DynamicCast(declaration) != nullptr) {
- callable = Declarations::CreateTorqueMacro(
- generated_name, readable_name.str(), false, type_signature,
- declaration->transitioning, *body, true);
+ callable =
+ Declarations::CreateTorqueMacro(generated_name, readable_name.str(),
+ false, type_signature, *body, true);
} else if (IntrinsicDeclaration::DynamicCast(declaration) != nullptr) {
- callable = Declarations::CreateIntrinsic(declaration->name, type_signature);
+ callable =
+ Declarations::CreateIntrinsic(declaration->name->value, type_signature);
} else {
BuiltinDeclaration* builtin = BuiltinDeclaration::cast(declaration);
callable = CreateBuiltin(builtin, generated_name, readable_name.str(),
diff --git a/deps/v8/src/torque/declaration-visitor.h b/deps/v8/src/torque/declaration-visitor.h
index dbd28f4b87..3a5201e24a 100644
--- a/deps/v8/src/torque/declaration-visitor.h
+++ b/deps/v8/src/torque/declaration-visitor.h
@@ -45,7 +45,7 @@ class PredeclarationVisitor {
}
}
static void Predeclare(GenericDeclaration* decl) {
- Declarations::DeclareGeneric(decl->callable->name, decl);
+ Declarations::DeclareGeneric(decl->declaration->name->value, decl);
}
};
@@ -76,30 +76,15 @@ class DeclarationVisitor {
std::string external_name,
std::string readable_name, Signature signature,
base::Optional<Statement*> body);
- static void Visit(ExternalBuiltinDeclaration* decl,
- const Signature& signature,
- base::Optional<Statement*> body) {
- Declarations::Declare(
- decl->name,
- CreateBuiltin(decl, decl->name, decl->name, signature, base::nullopt));
- }
-
- static void Visit(ExternalRuntimeDeclaration* decl, const Signature& sig,
- base::Optional<Statement*> body);
- static void Visit(ExternalMacroDeclaration* decl, const Signature& sig,
- base::Optional<Statement*> body);
- static void Visit(TorqueBuiltinDeclaration* decl, const Signature& signature,
- base::Optional<Statement*> body);
- static void Visit(TorqueMacroDeclaration* decl, const Signature& signature,
- base::Optional<Statement*> body);
- static void Visit(IntrinsicDeclaration* decl, const Signature& signature,
- base::Optional<Statement*> body);
- static void Visit(CallableNode* decl, const Signature& signature,
- base::Optional<Statement*> body);
+ static void Visit(ExternalBuiltinDeclaration* decl);
+ static void Visit(ExternalRuntimeDeclaration* decl);
+ static void Visit(ExternalMacroDeclaration* decl);
+ static void Visit(TorqueBuiltinDeclaration* decl);
+ static void Visit(TorqueMacroDeclaration* decl);
+ static void Visit(IntrinsicDeclaration* decl);
static void Visit(ConstDeclaration* decl);
- static void Visit(StandardDeclaration* decl);
static void Visit(GenericDeclaration* decl) {
// The PredeclarationVisitor already handled this case.
}
@@ -107,15 +92,16 @@ class DeclarationVisitor {
static void Visit(ExternConstDeclaration* decl);
static void Visit(CppIncludeDeclaration* decl);
- static Signature MakeSpecializedSignature(const SpecializationKey& key);
- static Callable* SpecializeImplicit(const SpecializationKey& key);
+ static Signature MakeSpecializedSignature(
+ const SpecializationKey<Generic>& key);
+ static Callable* SpecializeImplicit(const SpecializationKey<Generic>& key);
static Callable* Specialize(
- const SpecializationKey& key, CallableNode* declaration,
- base::Optional<const CallableNodeSignature*> signature,
+ const SpecializationKey<Generic>& key, CallableDeclaration* declaration,
+ base::Optional<const SpecializationDeclaration*> explicit_specialization,
base::Optional<Statement*> body, SourcePosition position);
private:
- static void DeclareSpecializedTypes(const SpecializationKey& key);
+ static void DeclareSpecializedTypes(const SpecializationKey<Generic>& key);
};
} // namespace torque
diff --git a/deps/v8/src/torque/declarations.cc b/deps/v8/src/torque/declarations.cc
index 73d46d6998..ed4ad23044 100644
--- a/deps/v8/src/torque/declarations.cc
+++ b/deps/v8/src/torque/declarations.cc
@@ -11,9 +11,6 @@
namespace v8 {
namespace internal {
namespace torque {
-
-DEFINE_CONTEXTUAL_VARIABLE(GlobalContext)
-
namespace {
template <class T>
@@ -139,6 +136,13 @@ GenericStructType* Declarations::LookupUniqueGenericStructType(
"generic struct");
}
+base::Optional<GenericStructType*> Declarations::TryLookupGenericStructType(
+ const QualifiedName& name) {
+ std::vector<GenericStructType*> results = TryLookup<GenericStructType>(name);
+ if (results.empty()) return base::nullopt;
+ return EnsureUnique(results, name.name, "generic struct");
+}
+
Namespace* Declarations::DeclareNamespace(const std::string& name) {
return Declare(name, std::unique_ptr<Namespace>(new Namespace(name)));
}
@@ -158,43 +162,44 @@ const TypeAlias* Declarations::PredeclareTypeAlias(const Identifier* name,
return Declare(name->value, std::move(alias_ptr));
}
-TorqueMacro* Declarations::CreateTorqueMacro(
- std::string external_name, std::string readable_name, bool exported_to_csa,
- Signature signature, bool transitioning, base::Optional<Statement*> body,
- bool is_user_defined) {
+TorqueMacro* Declarations::CreateTorqueMacro(std::string external_name,
+ std::string readable_name,
+ bool exported_to_csa,
+ Signature signature,
+ base::Optional<Statement*> body,
+ bool is_user_defined) {
// TODO(tebbi): Switch to more predictable names to improve incremental
// compilation.
external_name += "_" + std::to_string(GlobalContext::FreshId());
return RegisterDeclarable(std::unique_ptr<TorqueMacro>(new TorqueMacro(
std::move(external_name), std::move(readable_name), std::move(signature),
- transitioning, body, is_user_defined, exported_to_csa)));
+ body, is_user_defined, exported_to_csa)));
}
ExternMacro* Declarations::CreateExternMacro(
- std::string name, std::string external_assembler_name, Signature signature,
- bool transitioning) {
+ std::string name, std::string external_assembler_name,
+ Signature signature) {
return RegisterDeclarable(std::unique_ptr<ExternMacro>(
new ExternMacro(std::move(name), std::move(external_assembler_name),
- std::move(signature), transitioning)));
+ std::move(signature))));
}
Macro* Declarations::DeclareMacro(
const std::string& name, bool accessible_from_csa,
base::Optional<std::string> external_assembler_name,
- const Signature& signature, bool transitioning,
- base::Optional<Statement*> body, base::Optional<std::string> op,
- bool is_user_defined) {
+ const Signature& signature, base::Optional<Statement*> body,
+ base::Optional<std::string> op, bool is_user_defined) {
if (TryLookupMacro(name, signature.GetExplicitTypes())) {
ReportError("cannot redeclare macro ", name,
" with identical explicit parameters");
}
Macro* macro;
if (external_assembler_name) {
- macro = CreateExternMacro(name, std::move(*external_assembler_name),
- signature, transitioning);
+ macro =
+ CreateExternMacro(name, std::move(*external_assembler_name), signature);
} else {
- macro = CreateTorqueMacro(name, name, accessible_from_csa, signature,
- transitioning, body, is_user_defined);
+ macro = CreateTorqueMacro(name, name, accessible_from_csa, signature, body,
+ is_user_defined);
}
Declare(name, macro);
if (op) {
@@ -209,11 +214,11 @@ Macro* Declarations::DeclareMacro(
Method* Declarations::CreateMethod(AggregateType* container_type,
const std::string& name, Signature signature,
- bool transitioning, Statement* body) {
+ Statement* body) {
std::string generated_name{container_type->GetGeneratedMethodName(name)};
Method* result = RegisterDeclarable(std::unique_ptr<Method>(
new Method(container_type, container_type->GetGeneratedMethodName(name),
- name, std::move(signature), transitioning, body)));
+ name, std::move(signature), body)));
container_type->RegisterMethod(result);
return result;
}
@@ -235,29 +240,27 @@ Intrinsic* Declarations::DeclareIntrinsic(const std::string& name,
Builtin* Declarations::CreateBuiltin(std::string external_name,
std::string readable_name,
Builtin::Kind kind, Signature signature,
- bool transitioning,
+
base::Optional<Statement*> body) {
return RegisterDeclarable(std::unique_ptr<Builtin>(
new Builtin(std::move(external_name), std::move(readable_name), kind,
- std::move(signature), transitioning, body)));
+ std::move(signature), body)));
}
Builtin* Declarations::DeclareBuiltin(const std::string& name,
Builtin::Kind kind,
const Signature& signature,
- bool transitioning,
+
base::Optional<Statement*> body) {
CheckAlreadyDeclared<Builtin>(name, "builtin");
- return Declare(
- name, CreateBuiltin(name, name, kind, signature, transitioning, body));
+ return Declare(name, CreateBuiltin(name, name, kind, signature, body));
}
RuntimeFunction* Declarations::DeclareRuntimeFunction(
- const std::string& name, const Signature& signature, bool transitioning) {
+ const std::string& name, const Signature& signature) {
CheckAlreadyDeclared<RuntimeFunction>(name, "runtime function");
- return Declare(name,
- RegisterDeclarable(std::unique_ptr<RuntimeFunction>(
- new RuntimeFunction(name, signature, transitioning))));
+ return Declare(name, RegisterDeclarable(std::unique_ptr<RuntimeFunction>(
+ new RuntimeFunction(name, signature))));
}
void Declarations::DeclareExternConstant(Identifier* name, const Type* type,
diff --git a/deps/v8/src/torque/declarations.h b/deps/v8/src/torque/declarations.h
index 00e0facefe..240680fa1e 100644
--- a/deps/v8/src/torque/declarations.h
+++ b/deps/v8/src/torque/declarations.h
@@ -15,8 +15,6 @@ namespace internal {
namespace torque {
static constexpr const char* const kFromConstexprMacroName = "FromConstexpr";
-static constexpr const char* kTrueLabelName = "__True";
-static constexpr const char* kFalseLabelName = "__False";
static constexpr const char* kMacroEndLabelName = "__macro_end";
static constexpr const char* kBreakLabelName = "__break";
static constexpr const char* kContinueLabelName = "__continue";
@@ -78,6 +76,8 @@ class Declarations {
static GenericStructType* LookupUniqueGenericStructType(
const QualifiedName& name);
+ static base::Optional<GenericStructType*> TryLookupGenericStructType(
+ const QualifiedName& name);
static Namespace* DeclareNamespace(const std::string& name);
static TypeAlias* DeclareType(const Identifier* name, const Type* type);
@@ -88,23 +88,21 @@ class Declarations {
static TorqueMacro* CreateTorqueMacro(std::string external_name,
std::string readable_name,
bool exported_to_csa,
- Signature signature, bool transitioning,
+ Signature signature,
base::Optional<Statement*> body,
bool is_user_defined);
static ExternMacro* CreateExternMacro(std::string name,
std::string external_assembler_name,
- Signature signature,
- bool transitioning);
+ Signature signature);
static Macro* DeclareMacro(
const std::string& name, bool accessible_from_csa,
base::Optional<std::string> external_assembler_name,
- const Signature& signature, bool transitioning,
- base::Optional<Statement*> body, base::Optional<std::string> op = {},
- bool is_user_defined = true);
+ const Signature& signature, base::Optional<Statement*> body,
+ base::Optional<std::string> op = {}, bool is_user_defined = true);
static Method* CreateMethod(AggregateType* class_type,
const std::string& name, Signature signature,
- bool transitioning, Statement* body);
+ Statement* body);
static Intrinsic* CreateIntrinsic(const std::string& name,
const Signature& signature);
@@ -114,15 +112,14 @@ class Declarations {
static Builtin* CreateBuiltin(std::string external_name,
std::string readable_name, Builtin::Kind kind,
- Signature signature, bool transitioning,
+ Signature signature,
base::Optional<Statement*> body);
static Builtin* DeclareBuiltin(const std::string& name, Builtin::Kind kind,
- const Signature& signature, bool transitioning,
+ const Signature& signature,
base::Optional<Statement*> body);
static RuntimeFunction* DeclareRuntimeFunction(const std::string& name,
- const Signature& signature,
- bool transitioning);
+ const Signature& signature);
static void DeclareExternConstant(Identifier* name, const Type* type,
std::string value);
diff --git a/deps/v8/src/torque/earley-parser.h b/deps/v8/src/torque/earley-parser.h
index d3d0c89c42..9f7ba6a7ae 100644
--- a/deps/v8/src/torque/earley-parser.h
+++ b/deps/v8/src/torque/earley-parser.h
@@ -56,8 +56,8 @@ enum class ParseResultHolderBase::TypeId {
kImplicitParameters,
kOptionalImplicitParameters,
kNameAndExpression,
- kConditionalAnnotation,
- kOptionalConditionalAnnotation,
+ kAnnotation,
+ kVectorOfAnnotation,
kClassFieldExpression,
kStructFieldExpression,
kStdVectorOfNameAndTypeExpression,
diff --git a/deps/v8/src/torque/global-context.cc b/deps/v8/src/torque/global-context.cc
index f258f18474..13503038c5 100644
--- a/deps/v8/src/torque/global-context.cc
+++ b/deps/v8/src/torque/global-context.cc
@@ -8,6 +8,9 @@ namespace v8 {
namespace internal {
namespace torque {
+DEFINE_CONTEXTUAL_VARIABLE(GlobalContext)
+DEFINE_CONTEXTUAL_VARIABLE(TargetArchitecture)
+
GlobalContext::GlobalContext(Ast ast)
: collect_language_server_data_(false),
force_assert_statements_(false),
@@ -19,6 +22,10 @@ GlobalContext::GlobalContext(Ast ast)
RegisterDeclarable(base::make_unique<Namespace>(kBaseNamespaceName));
}
+TargetArchitecture::TargetArchitecture(bool force_32bit)
+ : tagged_size_(force_32bit ? sizeof(int32_t) : kTaggedSize),
+ raw_ptr_size_(force_32bit ? sizeof(int32_t) : kSystemPointerSize) {}
+
} // namespace torque
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/torque/global-context.h b/deps/v8/src/torque/global-context.h
index e103a22575..e1106adbd1 100644
--- a/deps/v8/src/torque/global-context.h
+++ b/deps/v8/src/torque/global-context.h
@@ -7,6 +7,7 @@
#include <map>
+#include "src/common/globals.h"
#include "src/torque/ast.h"
#include "src/torque/contextual.h"
#include "src/torque/declarable.h"
@@ -91,6 +92,18 @@ T* RegisterDeclarable(std::unique_ptr<T> d) {
return GlobalContext::Get().RegisterDeclarable(std::move(d));
}
+class TargetArchitecture : public ContextualClass<TargetArchitecture> {
+ public:
+ explicit TargetArchitecture(bool force_32bit);
+
+ static int TaggedSize() { return Get().tagged_size_; }
+ static int RawPtrSize() { return Get().raw_ptr_size_; }
+
+ private:
+ const int tagged_size_;
+ const int raw_ptr_size_;
+};
+
} // namespace torque
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/torque/implementation-visitor.cc b/deps/v8/src/torque/implementation-visitor.cc
index a0aeeee81b..8f36afd020 100644
--- a/deps/v8/src/torque/implementation-visitor.cc
+++ b/deps/v8/src/torque/implementation-visitor.cc
@@ -10,6 +10,7 @@
#include "src/torque/implementation-visitor.h"
#include "src/torque/parameter-difference.h"
#include "src/torque/server-data.h"
+#include "src/torque/type-inference.h"
#include "src/torque/type-visitor.h"
namespace v8 {
@@ -107,7 +108,8 @@ void ImplementationVisitor::EndCSAFiles() {
}
void ImplementationVisitor::Visit(NamespaceConstant* decl) {
- Signature signature{{}, base::nullopt, {{}, false}, 0, decl->type(), {}};
+ Signature signature{{}, base::nullopt, {{}, false}, 0, decl->type(),
+ {}, false};
BindingsManagersScope bindings_managers_scope;
@@ -466,13 +468,13 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
: "UncheckedCast<Object>(Parameter(Descriptor::kReceiver))")
<< ";\n";
source_out() << "USE(" << generated_name << ");\n";
- expected_type = TypeOracle::GetObjectType();
+ expected_type = TypeOracle::GetJSAnyType();
} else if (param_name == "newTarget") {
source_out() << " TNode<Object> " << generated_name
<< " = UncheckedCast<Object>(Parameter("
<< "Descriptor::kJSNewTarget));\n";
source_out() << "USE(" << generated_name << ");\n";
- expected_type = TypeOracle::GetObjectType();
+ expected_type = TypeOracle::GetJSAnyType();
} else if (param_name == "target") {
source_out() << " TNode<JSFunction> " << generated_name
<< " = UncheckedCast<JSFunction>(Parameter("
@@ -646,24 +648,8 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
}
VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
- VisitResult left_result;
- {
- Block* false_block = assembler().NewBlock(assembler().CurrentStack());
- Binding<LocalLabel> false_binding{&LabelBindingsManager::Get(),
- kFalseLabelName, LocalLabel{false_block}};
- left_result = Visit(expr->left);
- if (left_result.type()->IsBool()) {
- Block* true_block = LookupSimpleLabel(kTrueLabelName);
- assembler().Branch(true_block, false_block);
- assembler().Bind(false_block);
- } else if (left_result.type()->IsNever()) {
- assembler().Bind(false_block);
- } else if (!left_result.type()->IsConstexprBool()) {
- ReportError(
- "expected type bool, constexpr bool, or never on left-hand side of "
- "operator ||");
- }
- }
+ StackScope outer_scope(this);
+ VisitResult left_result = Visit(expr->left);
if (left_result.type()->IsConstexprBool()) {
VisitResult right_result = Visit(expr->right);
@@ -677,38 +663,34 @@ VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
" || " + right_result.constexpr_value() + ")");
}
- VisitResult right_result = Visit(expr->right);
- if (right_result.type()->IsBool()) {
- Block* true_block = LookupSimpleLabel(kTrueLabelName);
- Block* false_block = LookupSimpleLabel(kFalseLabelName);
- assembler().Branch(true_block, false_block);
- return VisitResult::NeverResult();
- } else if (!right_result.type()->IsNever()) {
- ReportError(
- "expected type bool or never on right-hand side of operator ||");
+ Block* true_block = assembler().NewBlock();
+ Block* false_block = assembler().NewBlock();
+ Block* done_block = assembler().NewBlock();
+
+ left_result = GenerateImplicitConvert(TypeOracle::GetBoolType(), left_result);
+ GenerateBranch(left_result, true_block, false_block);
+
+ assembler().Bind(true_block);
+ VisitResult true_result = GenerateBoolConstant(true);
+ assembler().Goto(done_block);
+
+ assembler().Bind(false_block);
+ VisitResult false_result;
+ {
+ StackScope false_block_scope(this);
+ false_result = false_block_scope.Yield(
+ GenerateImplicitConvert(TypeOracle::GetBoolType(), Visit(expr->right)));
}
- return right_result;
+ assembler().Goto(done_block);
+
+ assembler().Bind(done_block);
+ DCHECK_EQ(true_result, false_result);
+ return outer_scope.Yield(true_result);
}
VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
- VisitResult left_result;
- {
- Block* true_block = assembler().NewBlock(assembler().CurrentStack());
- Binding<LocalLabel> false_binding{&LabelBindingsManager::Get(),
- kTrueLabelName, LocalLabel{true_block}};
- left_result = Visit(expr->left);
- if (left_result.type()->IsBool()) {
- Block* false_block = LookupSimpleLabel(kFalseLabelName);
- assembler().Branch(true_block, false_block);
- assembler().Bind(true_block);
- } else if (left_result.type()->IsNever()) {
- assembler().Bind(true_block);
- } else if (!left_result.type()->IsConstexprBool()) {
- ReportError(
- "expected type bool, constexpr bool, or never on left-hand side of "
- "operator &&");
- }
- }
+ StackScope outer_scope(this);
+ VisitResult left_result = Visit(expr->left);
if (left_result.type()->IsConstexprBool()) {
VisitResult right_result = Visit(expr->right);
@@ -722,17 +704,29 @@ VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
" && " + right_result.constexpr_value() + ")");
}
- VisitResult right_result = Visit(expr->right);
- if (right_result.type()->IsBool()) {
- Block* true_block = LookupSimpleLabel(kTrueLabelName);
- Block* false_block = LookupSimpleLabel(kFalseLabelName);
- assembler().Branch(true_block, false_block);
- return VisitResult::NeverResult();
- } else if (!right_result.type()->IsNever()) {
- ReportError(
- "expected type bool or never on right-hand side of operator &&");
+ Block* true_block = assembler().NewBlock();
+ Block* false_block = assembler().NewBlock();
+ Block* done_block = assembler().NewBlock();
+
+ left_result = GenerateImplicitConvert(TypeOracle::GetBoolType(), left_result);
+ GenerateBranch(left_result, true_block, false_block);
+
+ assembler().Bind(true_block);
+ VisitResult true_result;
+ {
+ StackScope true_block_scope(this);
+ true_result = true_block_scope.Yield(
+ GenerateImplicitConvert(TypeOracle::GetBoolType(), Visit(expr->right)));
}
- return right_result;
+ assembler().Goto(done_block);
+
+ assembler().Bind(false_block);
+ VisitResult false_result = GenerateBoolConstant(false);
+ assembler().Goto(done_block);
+
+ assembler().Bind(done_block);
+ DCHECK_EQ(true_result, false_result);
+ return outer_scope.Yield(true_result);
}
VisitResult ImplementationVisitor::Visit(IncrementDecrementExpression* expr) {
@@ -1110,29 +1104,6 @@ const Type* ImplementationVisitor::Visit(ReturnStatement* stmt) {
return TypeOracle::GetNeverType();
}
-VisitResult ImplementationVisitor::TemporaryUninitializedStruct(
- const StructType* struct_type, const std::string& reason) {
- StackRange range = assembler().TopRange(0);
- for (const Field& f : struct_type->fields()) {
- if (const StructType* struct_type =
- StructType::DynamicCast(f.name_and_type.type)) {
- range.Extend(
- TemporaryUninitializedStruct(struct_type, reason).stack_range());
- } else {
- std::string descriptor = "uninitialized field '" + f.name_and_type.name +
- "' declared at " + PositionAsString(f.pos) +
- " (" + reason + ")";
- TypeVector lowered_types = LowerType(f.name_and_type.type);
- for (const Type* type : lowered_types) {
- assembler().Emit(PushUninitializedInstruction{
- TypeOracle::GetTopType(descriptor, type)});
- }
- range.Extend(assembler().TopRange(lowered_types.size()));
- }
- }
- return VisitResult(struct_type, range);
-}
-
VisitResult ImplementationVisitor::Visit(TryLabelExpression* expr) {
size_t parameter_count = expr->label_block->parameters.names.size();
std::vector<VisitResult> parameters;
@@ -1211,15 +1182,38 @@ VisitResult ImplementationVisitor::Visit(StatementExpression* expr) {
return VisitResult{Visit(expr->statement), assembler().TopRange(0)};
}
+void ImplementationVisitor::CheckInitializersWellformed(
+ const std::string& aggregate_name,
+ const std::vector<Field>& aggregate_fields,
+ const std::vector<NameAndExpression>& initializers,
+ bool ignore_first_field) {
+ size_t fields_offset = ignore_first_field ? 1 : 0;
+ size_t fields_size = aggregate_fields.size() - fields_offset;
+ for (size_t i = 0; i < std::min(fields_size, initializers.size()); i++) {
+ const std::string& field_name =
+ aggregate_fields[i + fields_offset].name_and_type.name;
+ Identifier* found_name = initializers[i].name;
+ if (field_name != found_name->value) {
+ Error("Expected field name \"", field_name, "\" instead of \"",
+ found_name->value, "\"")
+ .Position(found_name->pos)
+ .Throw();
+ }
+ }
+ if (fields_size != initializers.size()) {
+ ReportError("expected ", fields_size, " initializers for ", aggregate_name,
+ " found ", initializers.size());
+ }
+}
+
InitializerResults ImplementationVisitor::VisitInitializerResults(
- const AggregateType* current_aggregate,
+ const ClassType* class_type,
const std::vector<NameAndExpression>& initializers) {
InitializerResults result;
for (const NameAndExpression& initializer : initializers) {
result.names.push_back(initializer.name);
Expression* e = initializer.expression;
- const Field& field =
- current_aggregate->LookupField(initializer.name->value);
+ const Field& field = class_type->LookupField(initializer.name->value);
auto field_index = field.index;
if (SpreadExpression* s = SpreadExpression::DynamicCast(e)) {
if (!field_index) {
@@ -1238,54 +1232,30 @@ InitializerResults ImplementationVisitor::VisitInitializerResults(
return result;
}
-size_t ImplementationVisitor::InitializeAggregateHelper(
- const AggregateType* aggregate_type, VisitResult allocate_result,
+void ImplementationVisitor::InitializeClass(
+ const ClassType* class_type, VisitResult allocate_result,
const InitializerResults& initializer_results) {
- const ClassType* current_class = ClassType::DynamicCast(aggregate_type);
- size_t current = 0;
- if (current_class) {
- const ClassType* super = current_class->GetSuperClass();
- if (super) {
- current = InitializeAggregateHelper(super, allocate_result,
- initializer_results);
- }
+ if (const ClassType* super = class_type->GetSuperClass()) {
+ InitializeClass(super, allocate_result, initializer_results);
}
- for (Field f : aggregate_type->fields()) {
- if (current == initializer_results.field_value_map.size()) {
- ReportError("insufficient number of initializers for ",
- aggregate_type->name());
- }
+ for (Field f : class_type->fields()) {
VisitResult current_value =
initializer_results.field_value_map.at(f.name_and_type.name);
- Identifier* fieldname = initializer_results.names[current];
- if (fieldname->value != f.name_and_type.name) {
- CurrentSourcePosition::Scope scope(fieldname->pos);
- ReportError("Expected fieldname \"", f.name_and_type.name,
- "\" instead of \"", fieldname->value, "\"");
- }
- if (aggregate_type->IsClassType()) {
- if (f.index) {
- InitializeFieldFromSpread(allocate_result, f, initializer_results);
- } else {
- allocate_result.SetType(aggregate_type);
- GenerateCopy(allocate_result);
- assembler().Emit(CreateFieldReferenceInstruction{
- ClassType::cast(aggregate_type), f.name_and_type.name});
- VisitResult heap_reference(
- TypeOracle::GetReferenceType(f.name_and_type.type),
- assembler().TopRange(2));
- GenerateAssignToLocation(
- LocationReference::HeapReference(heap_reference), current_value);
- }
+ if (f.index) {
+ InitializeFieldFromSpread(allocate_result, f, initializer_results);
} else {
- LocationReference struct_field_ref = LocationReference::VariableAccess(
- ProjectStructField(allocate_result, f.name_and_type.name));
- GenerateAssignToLocation(struct_field_ref, current_value);
+ allocate_result.SetType(class_type);
+ GenerateCopy(allocate_result);
+ assembler().Emit(CreateFieldReferenceInstruction{
+ ClassType::cast(class_type), f.name_and_type.name});
+ VisitResult heap_reference(
+ TypeOracle::GetReferenceType(f.name_and_type.type),
+ assembler().TopRange(2));
+ GenerateAssignToLocation(LocationReference::HeapReference(heap_reference),
+ current_value);
}
- ++current;
}
- return current;
}
void ImplementationVisitor::InitializeFieldFromSpread(
@@ -1304,17 +1274,6 @@ void ImplementationVisitor::InitializeFieldFromSpread(
{field.aggregate, index.type, iterator.type()});
}
-void ImplementationVisitor::InitializeAggregate(
- const AggregateType* aggregate_type, VisitResult allocate_result,
- const InitializerResults& initializer_results) {
- size_t consumed_initializers = InitializeAggregateHelper(
- aggregate_type, allocate_result, initializer_results);
- if (consumed_initializers != initializer_results.field_value_map.size()) {
- ReportError("more initializers than fields present in ",
- aggregate_type->name());
- }
-}
-
VisitResult ImplementationVisitor::AddVariableObjectSize(
VisitResult object_size, const ClassType* current_class,
const InitializerResults& initializer_results) {
@@ -1397,6 +1356,11 @@ VisitResult ImplementationVisitor::Visit(NewExpression* expr) {
initializer_results.field_value_map[map_field.name_and_type.name] =
object_map;
}
+
+ CheckInitializersWellformed(class_type->name(),
+ class_type->ComputeAllFields(),
+ expr->initializers, !class_type->IsExtern());
+
Arguments size_arguments;
size_arguments.parameters.push_back(object_map);
VisitResult object_size = GenerateCall("%GetAllocationBaseSize",
@@ -1411,7 +1375,7 @@ VisitResult ImplementationVisitor::Visit(NewExpression* expr) {
GenerateCall("%Allocate", allocate_arguments, {class_type}, false);
DCHECK(allocate_result.IsOnStack());
- InitializeAggregate(class_type, allocate_result, initializer_results);
+ InitializeClass(class_type, allocate_result, initializer_results);
return stack_scope.Yield(allocate_result);
}
@@ -1582,7 +1546,9 @@ namespace {
void FailCallableLookup(const std::string& reason, const QualifiedName& name,
const TypeVector& parameter_types,
const std::vector<Binding<LocalLabel>*>& labels,
- const std::vector<Signature>& candidates) {
+ const std::vector<Signature>& candidates,
+ const std::vector<std::tuple<Generic*, const char*>>
+ inapplicable_generics) {
std::stringstream stream;
stream << "\n" << reason << ": \n " << name << "(" << parameter_types << ")";
if (labels.size() != 0) {
@@ -1596,10 +1562,20 @@ void FailCallableLookup(const std::string& reason, const QualifiedName& name,
stream << "\n " << name;
PrintSignature(stream, signature, false);
}
+ if (inapplicable_generics.size() != 0) {
+ stream << "\nfailed to instantiate all of these generic declarations:";
+ for (auto& failure : inapplicable_generics) {
+ Generic* generic;
+ const char* reason;
+ std::tie(generic, reason) = failure;
+ stream << "\n " << generic->name() << " defined at "
+ << generic->Position() << ":\n " << reason << "\n";
+ }
+ }
ReportError(stream.str());
}
-Callable* GetOrCreateSpecialization(const SpecializationKey& key) {
+Callable* GetOrCreateSpecialization(const SpecializationKey<Generic>& key) {
if (base::Optional<Callable*> specialization =
key.generic->specializations().Get(key.specialized_types)) {
return *specialization;
@@ -1655,16 +1631,20 @@ Callable* ImplementationVisitor::LookupCallable(
std::vector<Declarable*> overloads;
std::vector<Signature> overload_signatures;
+ std::vector<std::tuple<Generic*, const char*>> inapplicable_generics;
for (auto* declarable : declaration_container) {
if (Generic* generic = Generic::DynamicCast(declarable)) {
- base::Optional<TypeVector> inferred_specialization_types =
- generic->InferSpecializationTypes(specialization_types,
- parameter_types);
- if (!inferred_specialization_types) continue;
+ TypeArgumentInference inference = generic->InferSpecializationTypes(
+ specialization_types, parameter_types);
+ if (inference.HasFailed()) {
+ inapplicable_generics.push_back(
+ std::make_tuple(generic, inference.GetFailureReason()));
+ continue;
+ }
overloads.push_back(generic);
overload_signatures.push_back(
DeclarationVisitor::MakeSpecializedSignature(
- SpecializationKey{generic, *inferred_specialization_types}));
+ SpecializationKey<Generic>{generic, inference.GetResult()}));
} else if (Callable* callable = Callable::DynamicCast(declarable)) {
overloads.push_back(callable);
overload_signatures.push_back(callable->signature());
@@ -1674,16 +1654,12 @@ Callable* ImplementationVisitor::LookupCallable(
std::vector<size_t> candidates;
for (size_t i = 0; i < overloads.size(); ++i) {
const Signature& signature = overload_signatures[i];
- bool try_bool_context = labels.size() == 0 &&
- signature.return_type == TypeOracle::GetNeverType();
- if (IsCompatibleSignature(signature, parameter_types, labels.size()) ||
- (try_bool_context &&
- IsCompatibleSignature(signature, parameter_types, 2))) {
+ if (IsCompatibleSignature(signature, parameter_types, labels.size())) {
candidates.push_back(i);
}
}
- if (overloads.empty()) {
+ if (overloads.empty() && inapplicable_generics.empty()) {
if (silence_errors) return nullptr;
std::stringstream stream;
stream << "no matching declaration found for " << name;
@@ -1691,7 +1667,8 @@ Callable* ImplementationVisitor::LookupCallable(
} else if (candidates.empty()) {
if (silence_errors) return nullptr;
FailCallableLookup("cannot find suitable callable with name", name,
- parameter_types, labels, overload_signatures);
+ parameter_types, labels, overload_signatures,
+ inapplicable_generics);
}
auto is_better_candidate = [&](size_t a, size_t b) {
@@ -1712,14 +1689,15 @@ Callable* ImplementationVisitor::LookupCallable(
candidate_signatures.push_back(overload_signatures[i]);
}
FailCallableLookup("ambiguous callable ", name, parameter_types, labels,
- candidate_signatures);
+ candidate_signatures, inapplicable_generics);
}
}
if (Generic* generic = Generic::DynamicCast(overloads[best])) {
+ TypeArgumentInference inference = generic->InferSpecializationTypes(
+ specialization_types, parameter_types);
result = GetOrCreateSpecialization(
- SpecializationKey{generic, *generic->InferSpecializationTypes(
- specialization_types, parameter_types)});
+ SpecializationKey<Generic>{generic, inference.GetResult()});
} else {
result = Callable::cast(overloads[best]);
}
@@ -1749,14 +1727,13 @@ Callable* ImplementationVisitor::LookupCallable(
}
Method* ImplementationVisitor::LookupMethod(
- const std::string& name, LocationReference this_reference,
+ const std::string& name, const AggregateType* receiver_type,
const Arguments& arguments, const TypeVector& specialization_types) {
TypeVector types(arguments.parameters.ComputeTypeVector());
- types.insert(types.begin(), this_reference.ReferencedType());
- return Method::cast(LookupCallable(
- {{}, name},
- AggregateType::cast(this_reference.ReferencedType())->Methods(name),
- types, arguments.labels, specialization_types));
+ types.insert(types.begin(), receiver_type);
+ return Method::cast(LookupCallable({{}, name}, receiver_type->Methods(name),
+ types, arguments.labels,
+ specialization_types));
}
const Type* ImplementationVisitor::GetCommonType(const Type* left,
@@ -1783,24 +1760,36 @@ VisitResult ImplementationVisitor::GenerateCopy(const VisitResult& to_copy) {
VisitResult ImplementationVisitor::Visit(StructExpression* expr) {
StackScope stack_scope(this);
- const Type* raw_type = TypeVisitor::ComputeType(expr->type);
- if (!raw_type->IsStructType()) {
- ReportError(*raw_type, " is not a struct but used like one");
- }
- const StructType* struct_type = StructType::cast(raw_type);
+ auto& initializers = expr->initializers;
+ std::vector<VisitResult> values;
+ std::vector<const Type*> term_argument_types;
+ values.reserve(initializers.size());
+ term_argument_types.reserve(initializers.size());
- InitializerResults initialization_results =
- ImplementationVisitor::VisitInitializerResults(struct_type,
- expr->initializers);
+ // Compute values and types of all initializer arguments
+ for (const NameAndExpression& initializer : initializers) {
+ VisitResult value = Visit(initializer.expression);
+ values.push_back(value);
+ term_argument_types.push_back(value.type());
+ }
- // Push uninitialized 'this'
- VisitResult result = TemporaryUninitializedStruct(
- struct_type, "it's not initialized in the struct " + struct_type->name());
+ // Compute and check struct type from given struct name and argument types
+ const StructType* struct_type = TypeVisitor::ComputeTypeForStructExpression(
+ expr->type, term_argument_types);
+ CheckInitializersWellformed(struct_type->name(), struct_type->fields(),
+ initializers);
- InitializeAggregate(struct_type, result, initialization_results);
+ // Implicitly convert values and thereby build the struct on the stack
+ StackRange struct_range = assembler().TopRange(0);
+ auto& fields = struct_type->fields();
+ for (size_t i = 0; i < values.size(); i++) {
+ values[i] =
+ GenerateImplicitConvert(fields[i].name_and_type.type, values[i]);
+ struct_range.Extend(values[i].stack_range());
+ }
- return stack_scope.Yield(result);
+ return stack_scope.Yield(VisitResult(struct_type, struct_range));
}
LocationReference ImplementationVisitor::GetLocationReference(
@@ -1865,7 +1854,33 @@ LocationReference ImplementationVisitor::GetLocationReference(
LanguageServerData::AddDefinition(expr->field->pos, field.pos);
}
if (field.index) {
- return LocationReference::IndexedFieldAccess(object_result, fieldname);
+ assembler().Emit(
+ CreateFieldReferenceInstruction{object_result.type(), fieldname});
+ // Fetch the length from the object
+ {
+ StackScope length_scope(this);
+ // Get a reference to the length
+ const Field* index_field = field.index.value();
+ GenerateCopy(object_result);
+ assembler().Emit(CreateFieldReferenceInstruction{
+ object_result.type(), index_field->name_and_type.name});
+ VisitResult length_reference(
+ TypeOracle::GetReferenceType(index_field->name_and_type.type),
+ assembler().TopRange(2));
+
+ // Load the length from the reference and convert it to intptr
+ VisitResult length = GenerateFetchFromLocation(
+ LocationReference::HeapReference(length_reference));
+ VisitResult converted_length =
+ GenerateCall("Convert", {{length}, {}},
+ {TypeOracle::GetIntPtrType(), length.type()}, false);
+ DCHECK_EQ(converted_length.stack_range().Size(), 1);
+ length_scope.Yield(converted_length);
+ }
+ const Type* slice_type =
+ TypeOracle::GetSliceType(field.name_and_type.type);
+ return LocationReference::HeapSlice(
+ VisitResult(slice_type, assembler().TopRange(3)));
} else {
assembler().Emit(
CreateFieldReferenceInstruction{*class_type, fieldname});
@@ -1883,8 +1898,13 @@ LocationReference ImplementationVisitor::GetLocationReference(
ElementAccessExpression* expr) {
LocationReference reference = GetLocationReference(expr->array);
VisitResult index = Visit(expr->index);
- if (reference.IsIndexedFieldAccess()) {
- return LocationReference::IndexedFieldIndexedAccess(reference, index);
+ if (reference.IsHeapSlice()) {
+ Arguments arguments{{index}, {}};
+ const AggregateType* slice_type =
+ AggregateType::cast(reference.heap_slice().type());
+ Method* method = LookupMethod("AtIndex", slice_type, arguments, {});
+ return LocationReference::HeapReference(
+ GenerateCall(method, reference, arguments, {}, false));
} else {
return LocationReference::ArrayAccess(GenerateFetchFromLocation(reference),
index);
@@ -1927,8 +1947,9 @@ LocationReference ImplementationVisitor::GetLocationReference(
}
if (expr->generic_arguments.size() != 0) {
Generic* generic = Declarations::LookupUniqueGeneric(name);
- Callable* specialization = GetOrCreateSpecialization(SpecializationKey{
- generic, TypeVisitor::ComputeTypeVector(expr->generic_arguments)});
+ Callable* specialization =
+ GetOrCreateSpecialization(SpecializationKey<Generic>{
+ generic, TypeVisitor::ComputeTypeVector(expr->generic_arguments)});
if (Builtin* builtin = Builtin::DynamicCast(specialization)) {
DCHECK(!builtin->IsExternal());
return LocationReference::Temporary(GetBuiltinCode(builtin),
@@ -1963,8 +1984,8 @@ LocationReference ImplementationVisitor::GetLocationReference(
LocationReference ImplementationVisitor::GetLocationReference(
DereferenceExpression* expr) {
VisitResult ref = Visit(expr->reference);
- const ReferenceType* type = ReferenceType::DynamicCast(ref.type());
- if (!type) {
+ if (!StructType::MatchUnaryGeneric(ref.type(),
+ TypeOracle::GetReferenceGeneric())) {
ReportError("Operator * expects a reference but found a value of type ",
*ref.type());
}
@@ -1983,7 +2004,7 @@ VisitResult ImplementationVisitor::GenerateFetchFromLocation(
DCHECK_EQ(1, LoweredSlotCount(reference.ReferencedType()));
return VisitResult(reference.ReferencedType(), assembler().TopRange(1));
} else {
- if (reference.IsIndexedFieldAccess()) {
+ if (reference.IsHeapSlice()) {
ReportError(
"fetching a value directly from an indexed field isn't allowed");
}
@@ -2011,12 +2032,19 @@ void ImplementationVisitor::GenerateAssignToLocation(
if (reference.binding()) {
(*reference.binding())->SetWritten();
}
- } else if (reference.IsIndexedFieldAccess()) {
+ } else if (reference.IsHeapSlice()) {
ReportError("assigning a value directly to an indexed field isn't allowed");
} else if (reference.IsHeapReference()) {
const Type* referenced_type = reference.ReferencedType();
GenerateCopy(reference.heap_reference());
- GenerateImplicitConvert(referenced_type, assignment_value);
+ VisitResult converted_assignment_value =
+ GenerateImplicitConvert(referenced_type, assignment_value);
+ if (referenced_type == TypeOracle::GetFloat64Type()) {
+ VisitResult silenced_float_value =
+ GenerateCall("Float64SilenceNaN", {{assignment_value}, {}});
+ assembler().Poke(converted_assignment_value.stack_range(),
+ silenced_float_value.stack_range(), referenced_type);
+ }
assembler().Emit(StoreReferenceInstruction{referenced_type});
} else {
DCHECK(reference.IsTemporary());
@@ -2097,27 +2125,20 @@ VisitResult ImplementationVisitor::GenerateCall(
Callable* callable, base::Optional<LocationReference> this_reference,
Arguments arguments, const TypeVector& specialization_types,
bool is_tailcall) {
- // Operators used in a branching context can also be function calls that never
- // return but have a True and False label
- if (arguments.labels.size() == 0 &&
- callable->signature().labels.size() == 2) {
- base::Optional<Binding<LocalLabel>*> true_label =
- TryLookupLabel(kTrueLabelName);
- base::Optional<Binding<LocalLabel>*> false_label =
- TryLookupLabel(kFalseLabelName);
- if (!true_label || !false_label) {
- ReportError(
- callable->ReadableName(),
- " does not return a value, but has to be called in a branching "
- "context (e.g., conditional or if-condition). You can fix this by "
- "adding \"? true : false\".");
+ const Type* return_type = callable->signature().return_type;
+
+ if (is_tailcall) {
+ if (Builtin* builtin = Builtin::DynamicCast(CurrentCallable::Get())) {
+ const Type* outer_return_type = builtin->signature().return_type;
+ if (!return_type->IsSubtypeOf(outer_return_type)) {
+ Error("Cannot tailcall, type of result is ", *return_type,
+ " but should be a subtype of ", *outer_return_type, ".");
+ }
+ } else {
+ Error("Tail calls are only allowed from builtins");
}
- arguments.labels.push_back(*true_label);
- arguments.labels.push_back(*false_label);
}
- const Type* return_type = callable->signature().return_type;
-
std::vector<VisitResult> converted_arguments;
StackRange argument_range = assembler().TopRange(0);
std::vector<std::string> constexpr_arguments;
@@ -2142,8 +2163,8 @@ VisitResult ImplementationVisitor::GenerateCall(
if (this_reference) {
DCHECK(callable->IsMethod());
Method* method = Method::cast(callable);
- // By now, the this reference should either be a variable or
- // a temporary, in both cases the fetch of the VisitResult should succeed.
+ // By now, the this reference should either be a variable, a temporary or
+ // a Slice. In either case the fetch of the VisitResult should succeed.
VisitResult this_value = this_reference->GetVisitResult();
if (method->ShouldBeInlined()) {
if (!this_value.type()->IsSubtypeOf(method->aggregate_type())) {
@@ -2280,9 +2301,10 @@ VisitResult ImplementationVisitor::GenerateCall(
size_t j = 0;
for (auto t : callable->signature().labels[i].types) {
const Type* parameter_type = label->parameter_types[j];
- if (parameter_type != t) {
- ReportError("mismatch of label parameters (expected ", *t, " got ",
- parameter_type, " for parameter ", i + 1, ")");
+ if (!t->IsSubtypeOf(parameter_type)) {
+ ReportError("mismatch of label parameters (label expects ",
+ *parameter_type, " but macro produces ", *t,
+ " for parameter ", i + 1, ")");
}
j++;
}
@@ -2360,6 +2382,7 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr,
if (auto* loc_expr = LocationExpression::DynamicCast(expr->arguments[0])) {
LocationReference ref = GetLocationReference(loc_expr);
if (ref.IsHeapReference()) return scope.Yield(ref.heap_reference());
+ if (ref.IsHeapSlice()) return scope.Yield(ref.heap_slice());
}
ReportError("Unable to create a heap reference.");
}
@@ -2413,7 +2436,7 @@ VisitResult ImplementationVisitor::Visit(CallMethodExpression* expr) {
DCHECK_EQ(expr->method->namespace_qualification.size(), 0);
QualifiedName qualified_name = QualifiedName(method_name);
Callable* callable = nullptr;
- callable = LookupMethod(method_name, target, arguments, {});
+ callable = LookupMethod(method_name, target_type, arguments, {});
if (GlobalContext::collect_language_server_data()) {
LanguageServerData::AddDefinition(expr->method->name->pos,
callable->IdentifierPosition());
@@ -2429,7 +2452,7 @@ VisitResult ImplementationVisitor::Visit(IntrinsicCallExpression* expr) {
for (Expression* arg : expr->arguments)
arguments.parameters.push_back(Visit(arg));
return scope.Yield(
- GenerateCall(expr->name, arguments, specialization_types, false));
+ GenerateCall(expr->name->value, arguments, specialization_types, false));
}
void ImplementationVisitor::GenerateBranch(const VisitResult& condition,
@@ -2440,32 +2463,20 @@ void ImplementationVisitor::GenerateBranch(const VisitResult& condition,
assembler().Branch(true_block, false_block);
}
-void ImplementationVisitor::GenerateExpressionBranch(
- VisitResultGenerator generator, Block* true_block, Block* false_block) {
- // Conditional expressions can either explicitly return a bit
- // type, or they can be backed by macros that don't return but
- // take a true and false label. By declaring the labels before
- // visiting the conditional expression, those label-based
- // macro conditionals will be able to find them through normal
- // label lookups.
- Binding<LocalLabel> true_binding{&LabelBindingsManager::Get(), kTrueLabelName,
- LocalLabel{true_block}};
- Binding<LocalLabel> false_binding{&LabelBindingsManager::Get(),
- kFalseLabelName, LocalLabel{false_block}};
- StackScope stack_scope(this);
- VisitResult expression_result = generator();
- if (!expression_result.type()->IsNever()) {
- expression_result = stack_scope.Yield(
- GenerateImplicitConvert(TypeOracle::GetBoolType(), expression_result));
- GenerateBranch(expression_result, true_block, false_block);
- }
+VisitResult ImplementationVisitor::GenerateBoolConstant(bool constant) {
+ return GenerateImplicitConvert(TypeOracle::GetBoolType(),
+ VisitResult(TypeOracle::GetConstexprBoolType(),
+ constant ? "true" : "false"));
}
void ImplementationVisitor::GenerateExpressionBranch(Expression* expression,
Block* true_block,
Block* false_block) {
- GenerateExpressionBranch([&]() { return this->Visit(expression); },
- true_block, false_block);
+ StackScope stack_scope(this);
+ VisitResult expression_result = this->Visit(expression);
+ expression_result = stack_scope.Yield(
+ GenerateImplicitConvert(TypeOracle::GetBoolType(), expression_result));
+ GenerateBranch(expression_result, true_block, false_block);
}
VisitResult ImplementationVisitor::GenerateImplicitConvert(
@@ -2530,10 +2541,6 @@ StackRange ImplementationVisitor::LowerParameter(
range.Extend(parameter_range);
}
return range;
- } else if (type->IsReferenceType()) {
- lowered_parameters->Push(parameter_name + ".object");
- lowered_parameters->Push(parameter_name + ".offset");
- return lowered_parameters->TopRange(2);
} else {
lowered_parameters->Push(parameter_name);
return lowered_parameters->TopRange(1);
@@ -2663,70 +2670,6 @@ void ImplementationVisitor::Visit(Declarable* declarable) {
}
}
-namespace {
-class IfDefScope {
- public:
- IfDefScope(std::ostream& os, std::string d) : os_(os), d_(std::move(d)) {
- os_ << "#ifdef " << d_ << "\n";
- }
- ~IfDefScope() { os_ << "#endif // " << d_ << "\n"; }
-
- private:
- std::ostream& os_;
- std::string d_;
-};
-
-class NamespaceScope {
- public:
- NamespaceScope(std::ostream& os,
- std::initializer_list<std::string> namespaces)
- : os_(os), d_(std::move(namespaces)) {
- for (const std::string& s : d_) {
- os_ << "namespace " << s << " {\n";
- }
- }
- ~NamespaceScope() {
- for (auto i = d_.rbegin(); i != d_.rend(); ++i) {
- os_ << "} // namespace " << *i << "\n";
- }
- }
-
- private:
- std::ostream& os_;
- std::vector<std::string> d_;
-};
-
-class IncludeGuardScope {
- public:
- IncludeGuardScope(std::ostream& os, std::string file_name)
- : os_(os),
- d_("V8_GEN_TORQUE_GENERATED_" + CapifyStringWithUnderscores(file_name) +
- "_") {
- os_ << "#ifndef " << d_ << "\n";
- os_ << "#define " << d_ << "\n\n";
- }
- ~IncludeGuardScope() { os_ << "#endif // " << d_ << "\n"; }
-
- private:
- std::ostream& os_;
- std::string d_;
-};
-
-class IncludeObjectMacrosScope {
- public:
- explicit IncludeObjectMacrosScope(std::ostream& os) : os_(os) {
- os_ << "\n// Has to be the last include (doesn't have include guards):\n"
- "#include \"src/objects/object-macros.h\"\n";
- }
- ~IncludeObjectMacrosScope() {
- os_ << "\n#include \"src/objects/object-macros-undef.h\"\n";
- }
-
- private:
- std::ostream& os_;
-};
-} // namespace
-
void ImplementationVisitor::GenerateBuiltinDefinitions(
const std::string& output_directory) {
std::stringstream new_contents_stream;
@@ -2741,7 +2684,7 @@ void ImplementationVisitor::GenerateBuiltinDefinitions(
for (auto& declarable : GlobalContext::AllDeclarables()) {
Builtin* builtin = Builtin::DynamicCast(declarable.get());
if (!builtin || builtin->IsExternal()) continue;
- int firstParameterIndex = 1;
+ size_t firstParameterIndex = 1;
bool declareParameters = true;
if (builtin->IsStub()) {
new_contents_stream << "TFS(" << builtin->ExternalName();
@@ -2752,24 +2695,22 @@ void ImplementationVisitor::GenerateBuiltinDefinitions(
<< ", SharedFunctionInfo::kDontAdaptArgumentsSentinel";
declareParameters = false;
} else {
- assert(builtin->IsFixedArgsJavaScript());
+ DCHECK(builtin->IsFixedArgsJavaScript());
// FixedArg javascript builtins need to offer the parameter
// count.
- int size = static_cast<int>(builtin->parameter_names().size());
- assert(size >= 1);
- new_contents_stream << ", " << (std::max(size - 2, 0));
+ int parameter_count =
+ static_cast<int>(builtin->signature().ExplicitCount());
+ new_contents_stream << ", " << parameter_count;
// And the receiver is explicitly declared.
new_contents_stream << ", kReceiver";
- firstParameterIndex = 2;
+ firstParameterIndex = builtin->signature().implicit_count;
}
}
if (declareParameters) {
- int index = 0;
- for (const auto& parameter : builtin->parameter_names()) {
- if (index >= firstParameterIndex) {
- new_contents_stream << ", k" << CamelifyString(parameter->value);
- }
- index++;
+ for (size_t i = firstParameterIndex;
+ i < builtin->parameter_names().size(); ++i) {
+ Identifier* parameter = builtin->parameter_names()[i];
+ new_contents_stream << ", k" << CamelifyString(parameter->value);
}
}
new_contents_stream << ") \\\n";
@@ -2834,15 +2775,31 @@ class FieldOffsetsGenerator {
public:
explicit FieldOffsetsGenerator(const ClassType* type) : type_(type) {}
- virtual void WriteField(const Field& f) = 0;
+ virtual void WriteField(const Field& f, const std::string& size_string) = 0;
virtual void WriteMarker(const std::string& marker) = 0;
+ virtual void BeginPrivateOffsets() = 0;
virtual ~FieldOffsetsGenerator() { CHECK(is_finished_); }
void RecordOffsetFor(const Field& f) {
CHECK(!is_finished_);
UpdateSection(f);
- WriteField(f);
+ // We don't know statically how much space an indexed field takes, so report
+ // it as zero.
+ std::string size_string = "0";
+ if (!f.index.has_value()) {
+ size_t field_size;
+ std::tie(field_size, size_string) = f.GetFieldSizeInformation();
+ }
+ WriteField(f, size_string);
+
+ // Offsets for anything after an indexed field are likely to cause
+ // confusion, because the indexed field itself takes up a variable amount of
+ // space. We could not emit them at all, but that might allow an inherited
+ // kSize to be accessible (and wrong), so we emit them as private.
+ if (f.index.has_value()) {
+ BeginPrivateOffsets();
+ }
}
void Finish() {
@@ -2923,17 +2880,16 @@ class MacroFieldOffsetsGenerator : public FieldOffsetsGenerator {
out_ << "TORQUE_GENERATED_" << CapifyStringWithUnderscores(type_->name())
<< "_FIELDS(V) \\\n";
}
- virtual void WriteField(const Field& f) {
- size_t field_size;
- std::string size_string;
- std::string machine_type;
- std::tie(field_size, size_string) = f.GetFieldSizeInformation();
+ void WriteField(const Field& f, const std::string& size_string) override {
out_ << "V(k" << CamelifyString(f.name_and_type.name) << "Offset, "
<< size_string << ") \\\n";
}
- virtual void WriteMarker(const std::string& marker) {
+ void WriteMarker(const std::string& marker) override {
out_ << "V(" << marker << ", 0) \\\n";
}
+ void BeginPrivateOffsets() override {
+ // Can't do anything meaningful here in the macro generator.
+ }
private:
std::ostream& out_;
@@ -3025,13 +2981,15 @@ void ImplementationVisitor::GenerateClassFieldOffsets(
// TODO(danno): Remove this once all classes use ClassFieldOffsetGenerator
// to generate field offsets without the use of macros.
- MacroFieldOffsetsGenerator g(header, type);
- for (auto f : type->fields()) {
- CurrentSourcePosition::Scope scope(f.pos);
- g.RecordOffsetFor(f);
+ if (!type->GenerateCppClassDefinitions()) {
+ MacroFieldOffsetsGenerator g(header, type);
+ for (auto f : type->fields()) {
+ CurrentSourcePosition::Scope scope(f.pos);
+ g.RecordOffsetFor(f);
+ }
+ g.Finish();
+ header << "\n";
}
- g.Finish();
- header << "\n";
}
}
const std::string output_header_path = output_directory + "/" + file_name;
@@ -3046,11 +3004,7 @@ class ClassFieldOffsetGenerator : public FieldOffsetsGenerator {
: FieldOffsetsGenerator(type),
hdr_(header),
previous_field_end_("P::kHeaderSize") {}
- virtual void WriteField(const Field& f) {
- size_t field_size;
- std::string size_string;
- std::string machine_type;
- std::tie(field_size, size_string) = f.GetFieldSizeInformation();
+ void WriteField(const Field& f, const std::string& size_string) override {
std::string field = "k" + CamelifyString(f.name_and_type.name) + "Offset";
std::string field_end = field + "End";
hdr_ << " static constexpr int " << field << " = " << previous_field_end_
@@ -3059,10 +3013,15 @@ class ClassFieldOffsetGenerator : public FieldOffsetsGenerator {
<< size_string << " - 1;\n";
previous_field_end_ = field_end + " + 1";
}
- virtual void WriteMarker(const std::string& marker) {
+ void WriteMarker(const std::string& marker) override {
hdr_ << " static constexpr int " << marker << " = " << previous_field_end_
<< ";\n";
}
+ void BeginPrivateOffsets() override {
+ // The following section must re-establish public mode (currently done by
+ // GenerateClassConstructors).
+ hdr_ << " private:\n";
+ }
private:
std::ostream& hdr_;
@@ -3109,8 +3068,6 @@ class CppClassGenerator {
};
void CppClassGenerator::GenerateClass() {
- hdr_ << "class " << name_ << ";\n\n";
-
hdr_ << template_decl() << "\n";
hdr_ << "class " << gen_name_ << " : public P {\n";
hdr_ << " static_assert(std::is_same<" << name_ << ", D>::value,\n"
@@ -3118,7 +3075,7 @@ void CppClassGenerator::GenerateClass() {
hdr_ << " static_assert(std::is_same<" << super_->name() << ", P>::value,\n"
<< " \"Pass in " << super_->name()
<< " as second template parameter for " << gen_name_ << ".\");\n";
- hdr_ << "public: \n";
+ hdr_ << " public: \n";
hdr_ << " using Super = P;\n";
for (const Field& f : type_->fields()) {
GenerateFieldAccessor(f);
@@ -3170,7 +3127,7 @@ void CppClassGenerator::GenerateClassCasts() {
}
void CppClassGenerator::GenerateClassConstructors() {
- hdr_ << "public:\n";
+ hdr_ << " public:\n";
hdr_ << " template <class DAlias = D>\n";
hdr_ << " constexpr " << gen_name_ << "() : P() {\n";
hdr_ << " static_assert(std::is_base_of<" << gen_name_ << ", \n";
@@ -3282,9 +3239,9 @@ void CppClassGenerator::GenerateFieldAccessorForObject(const Field& f) {
DCHECK(field_type->IsSubtypeOf(TypeOracle::GetObjectType()));
const std::string& name = f.name_and_type.name;
const std::string offset = "k" + CamelifyString(name) + "Offset";
- const ClassType* class_type = ClassType::DynamicCast(field_type);
+ base::Optional<const ClassType*> class_type = field_type->ClassSupertype();
- std::string type = class_type ? class_type->name() : "Object";
+ std::string type = class_type ? (*class_type)->name() : "Object";
// Generate declarations in header.
if (!class_type && field_type != TypeOracle::GetObjectType()) {
@@ -3356,20 +3313,42 @@ void ImplementationVisitor::GenerateClassDefinitions(
IncludeGuardScope inline_header_guard(inline_header, basename + "-inl.h");
inline_header << "#include \"torque-generated/class-definitions-tq.h\"\n\n";
- inline_header << "#include \"src/objects/objects-inl.h\"\n\n";
+ inline_header << "#include \"src/objects/js-promise.h\"\n";
+ inline_header << "#include \"src/objects/module.h\"\n";
+ inline_header << "#include \"src/objects/objects-inl.h\"\n";
+ inline_header << "#include \"src/objects/script.h\"\n\n";
IncludeObjectMacrosScope inline_header_macros(inline_header);
NamespaceScope inline_header_namespaces(inline_header, {"v8", "internal"});
implementation
<< "#include \"torque-generated/class-definitions-tq.h\"\n\n";
implementation << "#include \"torque-generated/class-verifiers-tq.h\"\n\n";
- implementation << "#include \"src/objects/struct-inl.h\"\n\n";
+ implementation << "#include \"src/objects/arguments-inl.h\"\n";
+ implementation << "#include \"src/objects/js-collection-inl.h\"\n";
+ implementation << "#include \"src/objects/embedder-data-array-inl.h\"\n";
+ implementation << "#include \"src/objects/js-generator-inl.h\"\n";
+ implementation << "#include \"src/objects/js-regexp-inl.h\"\n";
+ implementation
+ << "#include \"src/objects/js-regexp-string-iterator-inl.h\"\n";
+ implementation << "#include \"src/objects/literal-objects-inl.h\"\n";
+ implementation << "#include \"src/objects/microtask-inl.h\"\n";
+ implementation << "#include \"src/objects/module-inl.h\"\n";
+ implementation << "#include \"src/objects/promise-inl.h\"\n";
+ implementation << "#include \"src/objects/stack-frame-info-inl.h\"\n";
+ implementation << "#include \"src/objects/struct-inl.h\"\n";
+ implementation << "#include \"src/objects/template-objects-inl.h\"\n\n";
implementation
<< "#include "
"\"torque-generated/internal-class-definitions-tq-inl.h\"\n\n";
NamespaceScope implementation_namespaces(implementation,
{"v8", "internal"});
+ // Generate forward declarations for every class.
+ for (const TypeAlias* alias : GlobalContext::GetClasses()) {
+ const ClassType* type = ClassType::DynamicCast(alias->type());
+ header << "class " << type->name() << ";\n";
+ }
+
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
const ClassType* type = ClassType::DynamicCast(alias->type());
if (type->GenerateCppClassDefinitions()) {
@@ -3724,6 +3703,16 @@ void ReportAllUnusedMacros() {
if (macro->IsTorqueMacro() && TorqueMacro::cast(macro)->IsExportedToCSA()) {
continue;
}
+ // TODO(gsps): Mark methods of generic structs used if they are used in any
+ // instantiation
+ if (Method* method = Method::DynamicCast(macro)) {
+ if (StructType* struct_type =
+ StructType::DynamicCast(method->aggregate_type())) {
+ if (struct_type->GetSpecializedFrom().has_value()) {
+ continue;
+ }
+ }
+ }
std::vector<std::string> ignored_prefixes = {"Convert<", "Cast<",
"FromConstexpr<"};
diff --git a/deps/v8/src/torque/implementation-visitor.h b/deps/v8/src/torque/implementation-visitor.h
index a572ebb936..eb1a6c4452 100644
--- a/deps/v8/src/torque/implementation-visitor.h
+++ b/deps/v8/src/torque/implementation-visitor.h
@@ -12,6 +12,7 @@
#include "src/torque/cfg.h"
#include "src/torque/declarations.h"
#include "src/torque/global-context.h"
+#include "src/torque/type-oracle.h"
#include "src/torque/types.h"
#include "src/torque/utils.h"
@@ -52,10 +53,20 @@ class LocationReference {
// pointer.
static LocationReference HeapReference(VisitResult heap_reference) {
LocationReference result;
- DCHECK(heap_reference.type()->IsReferenceType());
+ DCHECK(StructType::MatchUnaryGeneric(heap_reference.type(),
+ TypeOracle::GetReferenceGeneric()));
result.heap_reference_ = std::move(heap_reference);
return result;
}
+ // A reference to an array on the heap. That is, a tagged value, an offset to
+ // encode an inner pointer, and the number of elements.
+ static LocationReference HeapSlice(VisitResult heap_slice) {
+ LocationReference result;
+ DCHECK(StructType::MatchUnaryGeneric(heap_slice.type(),
+ TypeOracle::GetSliceGeneric()));
+ result.heap_slice_ = std::move(heap_slice);
+ return result;
+ }
static LocationReference ArrayAccess(VisitResult base, VisitResult offset) {
LocationReference result;
result.eval_function_ = std::string{"[]"};
@@ -69,26 +80,6 @@ class LocationReference {
result.eval_function_ = "." + fieldname;
result.assign_function_ = "." + fieldname + "=";
result.call_arguments_ = {object};
- result.index_field_ = base::nullopt;
- return result;
- }
- static LocationReference IndexedFieldIndexedAccess(
- const LocationReference& indexed_field, VisitResult index) {
- LocationReference result;
- DCHECK(indexed_field.IsIndexedFieldAccess());
- std::string fieldname = *indexed_field.index_field_;
- result.eval_function_ = "." + fieldname + "[]";
- result.assign_function_ = "." + fieldname + "[]=";
- result.call_arguments_ = indexed_field.call_arguments_;
- result.call_arguments_.push_back(index);
- result.index_field_ = fieldname;
- return result;
- }
- static LocationReference IndexedFieldAccess(VisitResult object,
- std::string fieldname) {
- LocationReference result;
- result.call_arguments_ = {object};
- result.index_field_ = fieldname;
return result;
}
@@ -109,16 +100,26 @@ class LocationReference {
DCHECK(IsHeapReference());
return *heap_reference_;
}
+ bool IsHeapSlice() const { return heap_slice_.has_value(); }
+ const VisitResult& heap_slice() const {
+ DCHECK(IsHeapSlice());
+ return *heap_slice_;
+ }
const Type* ReferencedType() const {
if (IsHeapReference()) {
- return ReferenceType::cast(heap_reference().type())->referenced_type();
+ return *StructType::MatchUnaryGeneric(heap_reference().type(),
+ TypeOracle::GetReferenceGeneric());
+ } else if (IsHeapSlice()) {
+ return *StructType::MatchUnaryGeneric(heap_slice().type(),
+ TypeOracle::GetSliceGeneric());
}
return GetVisitResult().type();
}
const VisitResult& GetVisitResult() const {
if (IsVariableAccess()) return variable();
+ if (IsHeapSlice()) return heap_slice();
DCHECK(IsTemporary());
return temporary();
}
@@ -129,13 +130,6 @@ class LocationReference {
return *temporary_description_;
}
- bool IsArrayField() const { return index_field_.has_value(); }
- bool IsIndexedFieldAccess() const {
- return IsArrayField() && !IsCallAccess();
- }
- bool IsIndexedFieldIndexedAccess() const {
- return IsArrayField() && IsCallAccess();
- }
bool IsCallAccess() const {
bool is_call_access = eval_function_.has_value();
DCHECK_EQ(is_call_access, assign_function_.has_value());
@@ -163,10 +157,10 @@ class LocationReference {
base::Optional<VisitResult> temporary_;
base::Optional<std::string> temporary_description_;
base::Optional<VisitResult> heap_reference_;
+ base::Optional<VisitResult> heap_slice_;
base::Optional<std::string> eval_function_;
base::Optional<std::string> assign_function_;
VisitResultVector call_arguments_;
- base::Optional<std::string> index_field_;
base::Optional<Binding<LocalValue>*> binding_;
LocationReference() = default;
@@ -354,6 +348,7 @@ class ImplementationVisitor {
void GenerateClassDefinitions(const std::string& output_directory);
void GenerateInstanceTypes(const std::string& output_directory);
void GenerateClassVerifiers(const std::string& output_directory);
+ void GenerateClassDebugReaders(const std::string& output_directory);
void GenerateExportedMacrosAssembler(const std::string& output_directory);
void GenerateCSATypes(const std::string& output_directory);
void GenerateCppForInternalClasses(const std::string& output_directory);
@@ -361,27 +356,26 @@ class ImplementationVisitor {
VisitResult Visit(Expression* expr);
const Type* Visit(Statement* stmt);
+ void CheckInitializersWellformed(
+ const std::string& aggregate_name,
+ const std::vector<Field>& aggregate_fields,
+ const std::vector<NameAndExpression>& initializers,
+ bool ignore_first_field = false);
+
InitializerResults VisitInitializerResults(
- const AggregateType* aggregate,
+ const ClassType* class_type,
const std::vector<NameAndExpression>& expressions);
void InitializeFieldFromSpread(VisitResult object, const Field& field,
const InitializerResults& initializer_results);
- size_t InitializeAggregateHelper(
- const AggregateType* aggregate_type, VisitResult allocate_result,
- const InitializerResults& initializer_results);
-
VisitResult AddVariableObjectSize(
VisitResult object_size, const ClassType* current_class,
const InitializerResults& initializer_results);
- void InitializeAggregate(const AggregateType* aggregate_type,
- VisitResult allocate_result,
- const InitializerResults& initializer_results);
+ void InitializeClass(const ClassType* class_type, VisitResult allocate_result,
+ const InitializerResults& initializer_results);
- VisitResult TemporaryUninitializedStruct(const StructType* struct_type,
- const std::string& reason);
VisitResult Visit(StructExpression* decl);
LocationReference GetLocationReference(Expression* location);
@@ -570,7 +564,8 @@ class ImplementationVisitor {
const Arguments& arguments,
const TypeVector& specialization_types);
- Method* LookupMethod(const std::string& name, LocationReference target,
+ Method* LookupMethod(const std::string& name,
+ const AggregateType* receiver_type,
const Arguments& arguments,
const TypeVector& specialization_types);
@@ -608,9 +603,8 @@ class ImplementationVisitor {
void GenerateBranch(const VisitResult& condition, Block* true_block,
Block* false_block);
- using VisitResultGenerator = std::function<VisitResult()>;
- void GenerateExpressionBranch(VisitResultGenerator, Block* true_block,
- Block* false_block);
+ VisitResult GenerateBoolConstant(bool constant);
+
void GenerateExpressionBranch(Expression* expression, Block* true_block,
Block* false_block);
diff --git a/deps/v8/src/torque/instructions.cc b/deps/v8/src/torque/instructions.cc
index 36a22ee8fa..5bc2149f41 100644
--- a/deps/v8/src/torque/instructions.cc
+++ b/deps/v8/src/torque/instructions.cc
@@ -133,7 +133,7 @@ void CallCsaMacroInstruction::TypeInstruction(Stack<const Type*>* stack,
if (catch_block) {
Stack<const Type*> catch_stack = *stack;
- catch_stack.Push(TypeOracle::GetObjectType());
+ catch_stack.Push(TypeOracle::GetJSAnyType());
(*catch_block)->SetInputTypes(catch_stack);
}
@@ -170,7 +170,7 @@ void CallCsaMacroAndBranchInstruction::TypeInstruction(
if (catch_block) {
Stack<const Type*> catch_stack = *stack;
- catch_stack.Push(TypeOracle::GetObjectType());
+ catch_stack.Push(TypeOracle::GetJSAnyType());
(*catch_block)->SetInputTypes(catch_stack);
}
@@ -201,7 +201,7 @@ void CallBuiltinInstruction::TypeInstruction(Stack<const Type*>* stack,
if (catch_block) {
Stack<const Type*> catch_stack = *stack;
- catch_stack.Push(TypeOracle::GetObjectType());
+ catch_stack.Push(TypeOracle::GetJSAnyType());
(*catch_block)->SetInputTypes(catch_stack);
}
@@ -236,7 +236,7 @@ void CallRuntimeInstruction::TypeInstruction(Stack<const Type*>* stack,
if (catch_block) {
Stack<const Type*> catch_stack = *stack;
- catch_stack.Push(TypeOracle::GetObjectType());
+ catch_stack.Push(TypeOracle::GetJSAnyType());
(*catch_block)->SetInputTypes(catch_stack);
}
@@ -292,15 +292,14 @@ void UnsafeCastInstruction::TypeInstruction(Stack<const Type*>* stack,
void CreateFieldReferenceInstruction::TypeInstruction(
Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
- ExpectSubtype(stack->Pop(), class_type);
- stack->Push(TypeOracle::GetHeapObjectType());
+ ExpectSubtype(stack->Top(), type);
stack->Push(TypeOracle::GetIntPtrType());
}
void LoadReferenceInstruction::TypeInstruction(Stack<const Type*>* stack,
ControlFlowGraph* cfg) const {
ExpectType(TypeOracle::GetIntPtrType(), stack->Pop());
- ExpectType(TypeOracle::GetHeapObjectType(), stack->Pop());
+ ExpectSubtype(stack->Pop(), TypeOracle::GetHeapObjectType());
DCHECK_EQ(std::vector<const Type*>{type}, LowerType(type));
stack->Push(type);
}
@@ -309,7 +308,7 @@ void StoreReferenceInstruction::TypeInstruction(Stack<const Type*>* stack,
ControlFlowGraph* cfg) const {
ExpectSubtype(stack->Pop(), type);
ExpectType(TypeOracle::GetIntPtrType(), stack->Pop());
- ExpectType(TypeOracle::GetHeapObjectType(), stack->Pop());
+ ExpectSubtype(stack->Pop(), TypeOracle::GetHeapObjectType());
}
bool CallRuntimeInstruction::IsBlockTerminator() const {
diff --git a/deps/v8/src/torque/instructions.h b/deps/v8/src/torque/instructions.h
index 3136b58321..fe3b26b86f 100644
--- a/deps/v8/src/torque/instructions.h
+++ b/deps/v8/src/torque/instructions.h
@@ -206,10 +206,9 @@ struct NamespaceConstantInstruction : InstructionBase {
struct CreateFieldReferenceInstruction : InstructionBase {
TORQUE_INSTRUCTION_BOILERPLATE()
- CreateFieldReferenceInstruction(const ClassType* class_type,
- std::string field_name)
- : class_type(class_type), field_name(std::move(field_name)) {}
- const ClassType* class_type;
+ CreateFieldReferenceInstruction(const Type* type, std::string field_name)
+ : type(type), field_name(std::move(field_name)) {}
+ const Type* type;
std::string field_name;
};
diff --git a/deps/v8/src/torque/torque-compiler.cc b/deps/v8/src/torque/torque-compiler.cc
index a3da95c747..3968b001fb 100644
--- a/deps/v8/src/torque/torque-compiler.cc
+++ b/deps/v8/src/torque/torque-compiler.cc
@@ -53,6 +53,7 @@ void CompileCurrentAst(TorqueCompilerOptions options) {
if (options.force_assert_statements) {
GlobalContext::SetForceAssertStatements();
}
+ TargetArchitecture::Scope target_architecture(options.force_32bit_output);
TypeOracle::Scope type_oracle;
// Two-step process of predeclaration + resolution allows to resolve type
@@ -83,6 +84,7 @@ void CompileCurrentAst(TorqueCompilerOptions options) {
implementation_visitor.GeneratePrintDefinitions(output_directory);
implementation_visitor.GenerateClassDefinitions(output_directory);
implementation_visitor.GenerateClassVerifiers(output_directory);
+ implementation_visitor.GenerateClassDebugReaders(output_directory);
implementation_visitor.GenerateExportedMacrosAssembler(output_directory);
implementation_visitor.GenerateCSATypes(output_directory);
implementation_visitor.GenerateInstanceTypes(output_directory);
diff --git a/deps/v8/src/torque/torque-compiler.h b/deps/v8/src/torque/torque-compiler.h
index 32680986fd..df81d60d3e 100644
--- a/deps/v8/src/torque/torque-compiler.h
+++ b/deps/v8/src/torque/torque-compiler.h
@@ -24,6 +24,12 @@ struct TorqueCompilerOptions {
// language server support for statements inside asserts, this flag
// can force generate them.
bool force_assert_statements = false;
+
+ // Forge (Google3) can only run 64-bit executables. As Torque runs as part
+ // of the build process, we need a "cross-compile" mode when we target 32-bit
+ // architectures. Note that this does not needed in Chromium/V8 land, since we
+ // always build with the same bit width as the target architecture.
+ bool force_32bit_output = false;
};
struct TorqueCompilerResult {
diff --git a/deps/v8/src/torque/torque-parser.cc b/deps/v8/src/torque/torque-parser.cc
index 0a371b79f9..d9973dde3c 100644
--- a/deps/v8/src/torque/torque-parser.cc
+++ b/deps/v8/src/torque/torque-parser.cc
@@ -108,13 +108,12 @@ V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<NameAndExpression>::id =
ParseResultTypeId::kNameAndExpression;
template <>
-V8_EXPORT_PRIVATE const ParseResultTypeId
- ParseResultHolder<ConditionalAnnotation>::id =
- ParseResultTypeId::kConditionalAnnotation;
+V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Annotation>::id =
+ ParseResultTypeId::kAnnotation;
template <>
V8_EXPORT_PRIVATE const ParseResultTypeId
- ParseResultHolder<base::Optional<ConditionalAnnotation>>::id =
- ParseResultTypeId::kOptionalConditionalAnnotation;
+ ParseResultHolder<std::vector<Annotation>>::id =
+ ParseResultTypeId::kVectorOfAnnotation;
template <>
V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<ClassFieldExpression>::id =
@@ -360,7 +359,7 @@ base::Optional<ParseResult> MakeBinaryOperator(
base::Optional<ParseResult> MakeIntrinsicCallExpression(
ParseResultIterator* child_results) {
- auto callee = child_results->NextAs<std::string>();
+ auto callee = child_results->NextAs<Identifier*>();
auto generic_arguments =
child_results->NextAs<std::vector<TypeExpression*>>();
auto args = child_results->NextAs<std::vector<Expression*>>();
@@ -472,29 +471,27 @@ base::Optional<ParseResult> MakeExternalMacro(
auto operator_name = child_results->NextAs<base::Optional<std::string>>();
auto external_assembler_name =
child_results->NextAs<base::Optional<std::string>>();
- auto name = child_results->NextAs<std::string>();
+ auto name = child_results->NextAs<Identifier*>();
auto generic_parameters = child_results->NextAs<GenericParameters>();
LintGenericParameters(generic_parameters);
auto args = child_results->NextAs<ParameterList>();
auto return_type = child_results->NextAs<TypeExpression*>();
auto labels = child_results->NextAs<LabelAndTypesVector>();
- MacroDeclaration* macro = MakeNode<ExternalMacroDeclaration>(
+
+ Declaration* result = MakeNode<ExternalMacroDeclaration>(
transitioning,
external_assembler_name ? *external_assembler_name : "CodeStubAssembler",
name, operator_name, args, return_type, labels);
- Declaration* result;
- if (generic_parameters.empty()) {
- result = MakeNode<StandardDeclaration>(macro, base::nullopt);
- } else {
- result = MakeNode<GenericDeclaration>(macro, generic_parameters);
+ if (!generic_parameters.empty()) {
+ Error("External builtins cannot be generic.");
}
return ParseResult{result};
}
base::Optional<ParseResult> MakeIntrinsicDeclaration(
ParseResultIterator* child_results) {
- auto name = child_results->NextAs<std::string>();
+ auto name = child_results->NextAs<Identifier*>();
auto generic_parameters = child_results->NextAs<GenericParameters>();
LintGenericParameters(generic_parameters);
@@ -502,19 +499,17 @@ base::Optional<ParseResult> MakeIntrinsicDeclaration(
auto return_type = child_results->NextAs<TypeExpression*>();
auto body = child_results->NextAs<base::Optional<Statement*>>();
LabelAndTypesVector labels;
- CallableNode* callable = nullptr;
+ CallableDeclaration* declaration;
if (body) {
- callable = MakeNode<TorqueMacroDeclaration>(
+ declaration = MakeNode<TorqueMacroDeclaration>(
false, name, base::Optional<std::string>{}, args, return_type, labels,
- false);
+ false, body);
} else {
- callable = MakeNode<IntrinsicDeclaration>(name, args, return_type);
+ declaration = MakeNode<IntrinsicDeclaration>(name, args, return_type);
}
- Declaration* result;
- if (generic_parameters.empty()) {
- result = MakeNode<StandardDeclaration>(callable, body);
- } else {
- result = MakeNode<GenericDeclaration>(callable, generic_parameters, body);
+ Declaration* result = declaration;
+ if (!generic_parameters.empty()) {
+ result = MakeNode<GenericDeclaration>(generic_parameters, declaration);
}
return ParseResult{result};
}
@@ -524,8 +519,8 @@ base::Optional<ParseResult> MakeTorqueMacroDeclaration(
auto export_to_csa = child_results->NextAs<bool>();
auto transitioning = child_results->NextAs<bool>();
auto operator_name = child_results->NextAs<base::Optional<std::string>>();
- auto name = child_results->NextAs<std::string>();
- if (!IsUpperCamelCase(name)) {
+ auto name = child_results->NextAs<Identifier*>();
+ if (!IsUpperCamelCase(name->value)) {
NamingConventionError("Macro", name, "UpperCamelCase");
}
@@ -536,16 +531,15 @@ base::Optional<ParseResult> MakeTorqueMacroDeclaration(
auto return_type = child_results->NextAs<TypeExpression*>();
auto labels = child_results->NextAs<LabelAndTypesVector>();
auto body = child_results->NextAs<base::Optional<Statement*>>();
- MacroDeclaration* macro =
- MakeNode<TorqueMacroDeclaration>(transitioning, name, operator_name, args,
- return_type, labels, export_to_csa);
- Declaration* result;
+ CallableDeclaration* declaration = MakeNode<TorqueMacroDeclaration>(
+ transitioning, name, operator_name, args, return_type, labels,
+ export_to_csa, body);
+ Declaration* result = declaration;
if (generic_parameters.empty()) {
if (!body) ReportError("A non-generic declaration needs a body.");
- result = MakeNode<StandardDeclaration>(macro, *body);
} else {
if (export_to_csa) ReportError("Cannot export generics to CSA.");
- result = MakeNode<GenericDeclaration>(macro, generic_parameters, body);
+ result = MakeNode<GenericDeclaration>(generic_parameters, declaration);
}
return ParseResult{result};
}
@@ -554,8 +548,8 @@ base::Optional<ParseResult> MakeTorqueBuiltinDeclaration(
ParseResultIterator* child_results) {
auto transitioning = child_results->NextAs<bool>();
auto javascript_linkage = child_results->NextAs<bool>();
- auto name = child_results->NextAs<std::string>();
- if (!IsUpperCamelCase(name)) {
+ auto name = child_results->NextAs<Identifier*>();
+ if (!IsUpperCamelCase(name->value)) {
NamingConventionError("Builtin", name, "UpperCamelCase");
}
@@ -565,14 +559,13 @@ base::Optional<ParseResult> MakeTorqueBuiltinDeclaration(
auto args = child_results->NextAs<ParameterList>();
auto return_type = child_results->NextAs<TypeExpression*>();
auto body = child_results->NextAs<base::Optional<Statement*>>();
- BuiltinDeclaration* builtin = MakeNode<TorqueBuiltinDeclaration>(
- transitioning, javascript_linkage, name, args, return_type);
- Declaration* result;
+ CallableDeclaration* declaration = MakeNode<TorqueBuiltinDeclaration>(
+ transitioning, javascript_linkage, name, args, return_type, body);
+ Declaration* result = declaration;
if (generic_parameters.empty()) {
if (!body) ReportError("A non-generic declaration needs a body.");
- result = MakeNode<StandardDeclaration>(builtin, *body);
} else {
- result = MakeNode<GenericDeclaration>(builtin, generic_parameters, body);
+ result = MakeNode<GenericDeclaration>(generic_parameters, declaration);
}
return ParseResult{result};
}
@@ -649,8 +642,8 @@ base::Optional<ParseResult> MakeMethodDeclaration(
ParseResultIterator* child_results) {
auto transitioning = child_results->NextAs<bool>();
auto operator_name = child_results->NextAs<base::Optional<std::string>>();
- auto name = child_results->NextAs<std::string>();
- if (!IsUpperCamelCase(name)) {
+ auto name = child_results->NextAs<Identifier*>();
+ if (!IsUpperCamelCase(name->value)) {
NamingConventionError("Method", name, "UpperCamelCase");
}
@@ -658,39 +651,66 @@ base::Optional<ParseResult> MakeMethodDeclaration(
auto return_type = child_results->NextAs<TypeExpression*>();
auto labels = child_results->NextAs<LabelAndTypesVector>();
auto body = child_results->NextAs<Statement*>();
- MacroDeclaration* macro = MakeNode<TorqueMacroDeclaration>(
- transitioning, name, operator_name, args, return_type, labels, false);
- Declaration* result = MakeNode<StandardDeclaration>(macro, body);
+ Declaration* result =
+ MakeNode<TorqueMacroDeclaration>(transitioning, name, operator_name, args,
+ return_type, labels, false, body);
return ParseResult{result};
}
class AnnotationSet {
public:
AnnotationSet(ParseResultIterator* iter,
- const std::set<std::string>& allowed) {
- auto list = iter->NextAs<std::vector<Identifier*>>();
- for (const Identifier* i : list) {
- if (allowed.find(i->value) == allowed.end()) {
- Lint("Annotation ", i->value, " is not allowed here").Position(i->pos);
- }
- if (!set_.insert(i->value).second) {
- Lint("Duplicate annotation ", i->value).Position(i->pos);
+ const std::set<std::string>& allowed_without_param,
+ const std::set<std::string>& allowed_with_param) {
+ auto list = iter->NextAs<std::vector<Annotation>>();
+ for (const Annotation& a : list) {
+ if (a.param.has_value()) {
+ if (allowed_with_param.find(a.name->value) ==
+ allowed_with_param.end()) {
+ const char* error_message =
+ allowed_without_param.find(a.name->value) ==
+ allowed_without_param.end()
+ ? " is not allowed here"
+ : " cannot have parameter here";
+ Lint("Annotation ", a.name->value, error_message)
+ .Position(a.name->pos);
+ }
+ map_[a.name->value].push_back(*a.param);
+ } else {
+ if (allowed_without_param.find(a.name->value) ==
+ allowed_without_param.end()) {
+ const char* error_message =
+ allowed_with_param.find(a.name->value) == allowed_with_param.end()
+ ? " is not allowed here"
+ : " requires a parameter here";
+ Lint("Annotation ", a.name->value, error_message)
+ .Position(a.name->pos);
+ }
+ if (!set_.insert(a.name->value).second) {
+ Lint("Duplicate annotation ", a.name->value).Position(a.name->pos);
+ }
}
}
}
bool Contains(const std::string& s) { return set_.find(s) != set_.end(); }
+ const std::vector<std::string>& GetParams(const std::string& s) {
+ return map_[s];
+ }
private:
std::set<std::string> set_;
+ std::map<std::string, std::vector<std::string>> map_;
};
base::Optional<ParseResult> MakeClassDeclaration(
ParseResultIterator* child_results) {
AnnotationSet annotations(
- child_results, {"@generatePrint", "@noVerifier", "@abstract",
- "@dirtyInstantiatedAbstractClass",
- "@hasSameInstanceTypeAsParent", "@generateCppClass"});
+ child_results,
+ {"@generatePrint", "@noVerifier", "@abstract",
+ "@dirtyInstantiatedAbstractClass", "@hasSameInstanceTypeAsParent",
+ "@generateCppClass"},
+ {});
ClassFlags flags = ClassFlag::kNone;
bool generate_print = annotations.Contains("@generatePrint");
if (generate_print) flags |= ClassFlag::kGeneratePrint;
@@ -726,15 +746,18 @@ base::Optional<ParseResult> MakeClassDeclaration(
// Filter to only include fields that should be present based on decoration.
std::vector<ClassFieldExpression> fields;
- std::copy_if(fields_raw.begin(), fields_raw.end(), std::back_inserter(fields),
- [](const ClassFieldExpression& exp) {
- if (!exp.conditional.has_value()) return true;
- const ConditionalAnnotation& conditional = *exp.conditional;
- return conditional.type == ConditionalAnnotationType::kPositive
- ? BuildFlags::GetFlag(conditional.condition, "@if")
- : !BuildFlags::GetFlag(conditional.condition,
- "@ifnot");
- });
+ std::copy_if(
+ fields_raw.begin(), fields_raw.end(), std::back_inserter(fields),
+ [](const ClassFieldExpression& exp) {
+ for (const ConditionalAnnotation& condition : exp.conditions) {
+ if (condition.type == ConditionalAnnotationType::kPositive
+ ? !BuildFlags::GetFlag(condition.condition, "@if")
+ : BuildFlags::GetFlag(condition.condition, "@ifnot")) {
+ return false;
+ }
+ }
+ return true;
+ });
Declaration* result = MakeNode<ClassDeclaration>(
name, flags, std::move(extends), std::move(generates), std::move(methods),
@@ -756,6 +779,7 @@ base::Optional<ParseResult> MakeNamespaceDeclaration(
base::Optional<ParseResult> MakeSpecializationDeclaration(
ParseResultIterator* child_results) {
+ auto transitioning = child_results->NextAs<bool>();
auto name = child_results->NextAs<Identifier*>();
auto generic_parameters =
child_results->NextAs<std::vector<TypeExpression*>>();
@@ -765,8 +789,8 @@ base::Optional<ParseResult> MakeSpecializationDeclaration(
auto body = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(body);
Declaration* result = MakeNode<SpecializationDeclaration>(
- std::move(name), std::move(generic_parameters), std::move(parameters),
- return_type, std::move(labels), body);
+ transitioning, std::move(name), std::move(generic_parameters),
+ std::move(parameters), return_type, std::move(labels), body);
return ParseResult{result};
}
@@ -817,19 +841,16 @@ base::Optional<ParseResult> MakeExternalBuiltin(
ParseResultIterator* child_results) {
auto transitioning = child_results->NextAs<bool>();
auto js_linkage = child_results->NextAs<bool>();
- auto name = child_results->NextAs<std::string>();
+ auto name = child_results->NextAs<Identifier*>();
auto generic_parameters = child_results->NextAs<GenericParameters>();
LintGenericParameters(generic_parameters);
auto args = child_results->NextAs<ParameterList>();
auto return_type = child_results->NextAs<TypeExpression*>();
- BuiltinDeclaration* builtin = MakeNode<ExternalBuiltinDeclaration>(
+ Declaration* result = MakeNode<ExternalBuiltinDeclaration>(
transitioning, js_linkage, name, args, return_type);
- Declaration* result;
- if (generic_parameters.empty()) {
- result = MakeNode<StandardDeclaration>(builtin, base::nullopt);
- } else {
- result = MakeNode<GenericDeclaration>(builtin, generic_parameters);
+ if (!generic_parameters.empty()) {
+ Error("External builtins cannot be generic.");
}
return ParseResult{result};
}
@@ -837,12 +858,11 @@ base::Optional<ParseResult> MakeExternalBuiltin(
base::Optional<ParseResult> MakeExternalRuntime(
ParseResultIterator* child_results) {
auto transitioning = child_results->NextAs<bool>();
- auto name = child_results->NextAs<std::string>();
+ auto name = child_results->NextAs<Identifier*>();
auto args = child_results->NextAs<ParameterList>();
auto return_type = child_results->NextAs<TypeExpression*>();
- ExternalRuntimeDeclaration* runtime = MakeNode<ExternalRuntimeDeclaration>(
+ Declaration* result = MakeNode<ExternalRuntimeDeclaration>(
transitioning, name, args, return_type);
- Declaration* result = MakeNode<StandardDeclaration>(runtime, base::nullopt);
return ParseResult{result};
}
@@ -879,7 +899,11 @@ base::Optional<ParseResult> MakeFunctionTypeExpression(
base::Optional<ParseResult> MakeReferenceTypeExpression(
ParseResultIterator* child_results) {
auto referenced_type = child_results->NextAs<TypeExpression*>();
- TypeExpression* result = MakeNode<ReferenceTypeExpression>(referenced_type);
+ std::vector<std::string> namespace_qualification{
+ TORQUE_INTERNAL_NAMESPACE_STRING};
+ std::vector<TypeExpression*> generic_arguments{referenced_type};
+ TypeExpression* result = MakeNode<BasicTypeExpression>(
+ namespace_qualification, REFERENCE_TYPE_STRING, generic_arguments);
return ParseResult{result};
}
@@ -1141,7 +1165,7 @@ base::Optional<ParseResult> MakeCatchBlock(ParseResultIterator* child_results) {
ParameterList parameters;
parameters.names.push_back(MakeNode<Identifier>(variable));
parameters.types.push_back(MakeNode<BasicTypeExpression>(
- std::vector<std::string>{}, "Object", std::vector<TypeExpression*>{}));
+ std::vector<std::string>{}, "JSAny", std::vector<TypeExpression*>{}));
parameters.has_varargs = false;
LabelBlock* result = MakeNode<LabelBlock>(
MakeNode<Identifier>(kCatchLabelName), std::move(parameters), body);
@@ -1327,22 +1351,22 @@ base::Optional<ParseResult> MakeNameAndExpressionFromExpression(
ReportError("Constructor parameters need to be named.");
}
-base::Optional<ParseResult> MakeConditionalAnnotation(
- ParseResultIterator* child_results) {
- auto type_str = child_results->NextAs<Identifier*>()->value;
- DCHECK(type_str == "@if" || type_str == "@ifnot");
- ConditionalAnnotationType type = type_str == "@if"
- ? ConditionalAnnotationType::kPositive
- : ConditionalAnnotationType::kNegative;
- auto condition = child_results->NextAs<std::string>();
- return ParseResult{ConditionalAnnotation{condition, type}};
+base::Optional<ParseResult> MakeAnnotation(ParseResultIterator* child_results) {
+ return ParseResult{
+ Annotation{child_results->NextAs<Identifier*>(),
+ child_results->NextAs<base::Optional<std::string>>()}};
}
base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
- auto conditional =
- child_results->NextAs<base::Optional<ConditionalAnnotation>>();
- AnnotationSet annotations(child_results, {"@noVerifier"});
+ AnnotationSet annotations(child_results, {"@noVerifier"}, {"@if", "@ifnot"});
bool generate_verify = !annotations.Contains("@noVerifier");
+ std::vector<ConditionalAnnotation> conditions;
+ for (const std::string& condition : annotations.GetParams("@if")) {
+ conditions.push_back({condition, ConditionalAnnotationType::kPositive});
+ }
+ for (const std::string& condition : annotations.GetParams("@ifnot")) {
+ conditions.push_back({condition, ConditionalAnnotationType::kNegative});
+ }
auto weak = child_results->NextAs<bool>();
auto const_qualified = child_results->NextAs<bool>();
auto name = child_results->NextAs<Identifier*>();
@@ -1350,7 +1374,7 @@ base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
auto type = child_results->NextAs<TypeExpression*>();
return ParseResult{ClassFieldExpression{{name, type},
index,
- conditional,
+ std::move(conditions),
weak,
const_qualified,
generate_verify}};
@@ -1479,15 +1503,12 @@ struct TorqueGrammar : Grammar {
Symbol name = {Rule({&identifier}, MakeIdentifier)};
// Result: Identifier*
- Symbol annotation = {
+ Symbol annotationName = {
Rule({Pattern(MatchAnnotation)}, MakeIdentifierFromMatchedInput)};
- // Result: std::vector<Identifier*>
- Symbol* annotations = List<Identifier*>(&annotation);
-
// Result: std::string
Symbol intrinsicName = {
- Rule({Pattern(MatchIntrinsicName)}, YieldMatchedInput)};
+ Rule({Pattern(MatchIntrinsicName)}, MakeIdentifierFromMatchedInput)};
// Result: std::string
Symbol stringLiteral = {
@@ -1501,6 +1522,22 @@ struct TorqueGrammar : Grammar {
Rule({Pattern(MatchDecimalLiteral)}, YieldMatchedInput),
Rule({Pattern(MatchHexLiteral)}, YieldMatchedInput)};
+ // Result: std::string
+ Symbol annotationParameter = {Rule({&identifier}), Rule({&decimalLiteral}),
+ Rule({&externalString})};
+
+ // Result: std::string
+ Symbol annotationParameters = {
+ Rule({Token("("), &annotationParameter, Token(")")})};
+
+ // Result: Annotation
+ Symbol annotation = {
+ Rule({&annotationName, Optional<std::string>(&annotationParameters)},
+ MakeAnnotation)};
+
+ // Result: std::vector<Annotation>
+ Symbol* annotations = List<Annotation>(&annotation);
+
// Result: TypeList
Symbol* typeList = List<TypeExpression*>(&type, Token(","));
@@ -1578,14 +1615,8 @@ struct TorqueGrammar : Grammar {
Symbol* optionalArraySpecifier =
Optional<std::string>(Sequence({Token("["), &identifier, Token("]")}));
- // Result: ConditionalAnnotation
- Symbol conditionalAnnotation = {
- Rule({OneOf({"@if", "@ifnot"}), Token("("), &identifier, Token(")")},
- MakeConditionalAnnotation)};
-
Symbol classField = {
- Rule({Optional<ConditionalAnnotation>(&conditionalAnnotation),
- annotations, CheckIf(Token("weak")), CheckIf(Token("const")), &name,
+ Rule({annotations, CheckIf(Token("weak")), CheckIf(Token("const")), &name,
optionalArraySpecifier, Token(":"), &type, Token(";")},
MakeClassField)};
@@ -1857,8 +1888,8 @@ struct TorqueGrammar : Grammar {
Symbol method = {Rule(
{CheckIf(Token("transitioning")),
Optional<std::string>(Sequence({Token("operator"), &externalString})),
- &identifier, &parameterListNoVararg, &optionalReturnType,
- optionalLabelList, &block},
+ &name, &parameterListNoVararg, &optionalReturnType, optionalLabelList,
+ &block},
MakeMethodDeclaration)};
// Result: std::vector<Declaration*>
@@ -1900,34 +1931,34 @@ struct TorqueGrammar : Grammar {
Optional<std::string>(
Sequence({Token("operator"), &externalString})),
Token("macro"),
- Optional<std::string>(Sequence({&identifier, Token("::")})),
- &identifier, TryOrDefault<GenericParameters>(&genericParameters),
+ Optional<std::string>(Sequence({&identifier, Token("::")})), &name,
+ TryOrDefault<GenericParameters>(&genericParameters),
&typeListMaybeVarArgs, &optionalReturnType, optionalLabelList,
Token(";")},
AsSingletonVector<Declaration*, MakeExternalMacro>()),
Rule({Token("extern"), CheckIf(Token("transitioning")),
- CheckIf(Token("javascript")), Token("builtin"), &identifier,
+ CheckIf(Token("javascript")), Token("builtin"), &name,
TryOrDefault<GenericParameters>(&genericParameters),
&typeListMaybeVarArgs, &optionalReturnType, Token(";")},
AsSingletonVector<Declaration*, MakeExternalBuiltin>()),
- Rule(
- {Token("extern"), CheckIf(Token("transitioning")), Token("runtime"),
- &identifier, &typeListMaybeVarArgs, &optionalReturnType, Token(";")},
- AsSingletonVector<Declaration*, MakeExternalRuntime>()),
+ Rule({Token("extern"), CheckIf(Token("transitioning")), Token("runtime"),
+ &name, &typeListMaybeVarArgs, &optionalReturnType, Token(";")},
+ AsSingletonVector<Declaration*, MakeExternalRuntime>()),
Rule({CheckIf(Token("@export")), CheckIf(Token("transitioning")),
Optional<std::string>(
Sequence({Token("operator"), &externalString})),
- Token("macro"), &identifier,
+ Token("macro"), &name,
TryOrDefault<GenericParameters>(&genericParameters),
&parameterListNoVararg, &optionalReturnType, optionalLabelList,
&optionalBody},
AsSingletonVector<Declaration*, MakeTorqueMacroDeclaration>()),
Rule({CheckIf(Token("transitioning")), CheckIf(Token("javascript")),
- Token("builtin"), &identifier,
+ Token("builtin"), &name,
TryOrDefault<GenericParameters>(&genericParameters),
&parameterListAllowVararg, &optionalReturnType, &optionalBody},
AsSingletonVector<Declaration*, MakeTorqueBuiltinDeclaration>()),
- Rule({&name, &genericSpecializationTypeList, &parameterListAllowVararg,
+ Rule({CheckIf(Token("transitioning")), &name,
+ &genericSpecializationTypeList, &parameterListAllowVararg,
&optionalReturnType, optionalLabelList, &block},
AsSingletonVector<Declaration*, MakeSpecializationDeclaration>()),
Rule({Token("#include"), &externalString},
diff --git a/deps/v8/src/torque/torque.cc b/deps/v8/src/torque/torque.cc
index e759ce613c..ad7551f8aa 100644
--- a/deps/v8/src/torque/torque.cc
+++ b/deps/v8/src/torque/torque.cc
@@ -19,19 +19,24 @@ std::string ErrorPrefixFor(TorqueMessage::Kind kind) {
}
int WrappedMain(int argc, const char** argv) {
- std::string output_directory;
- std::string v8_root;
+ TorqueCompilerOptions options;
+ options.collect_language_server_data = false;
+ options.force_assert_statements = false;
+
std::vector<std::string> files;
for (int i = 1; i < argc; ++i) {
// Check for options
- if (std::string(argv[i]) == "-o") {
- output_directory = argv[++i];
- } else if (std::string(argv[i]) == "-v8-root") {
- v8_root = std::string(argv[++i]);
+ const std::string argument(argv[i]);
+ if (argument == "-o") {
+ options.output_directory = argv[++i];
+ } else if (argument == "-v8-root") {
+ options.v8_root = std::string(argv[++i]);
+ } else if (argument == "-m32") {
+ options.force_32bit_output = true;
} else {
// Otherwise it's a .tq file. Remember it for compilation.
- files.emplace_back(argv[i]);
+ files.emplace_back(std::move(argument));
if (!StringEndsWith(files.back(), ".tq")) {
std::cerr << "Unexpected command-line argument \"" << files.back()
<< "\", expected a .tq file.\n";
@@ -40,12 +45,6 @@ int WrappedMain(int argc, const char** argv) {
}
}
- TorqueCompilerOptions options;
- options.output_directory = std::move(output_directory);
- options.v8_root = std::move(v8_root);
- options.collect_language_server_data = false;
- options.force_assert_statements = false;
-
TorqueCompilerResult result = CompileTorque(files, options);
// PositionAsString requires the SourceFileMap to be set to
diff --git a/deps/v8/src/torque/type-inference.cc b/deps/v8/src/torque/type-inference.cc
new file mode 100644
index 0000000000..abd875f4f6
--- /dev/null
+++ b/deps/v8/src/torque/type-inference.cc
@@ -0,0 +1,121 @@
+// Copyright 2019 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/torque/type-inference.h"
+
+namespace v8 {
+namespace internal {
+namespace torque {
+
+TypeArgumentInference::TypeArgumentInference(
+ const NameVector& type_parameters,
+ const TypeVector& explicit_type_arguments,
+ const std::vector<TypeExpression*>& term_parameters,
+ const TypeVector& term_argument_types)
+ : num_explicit_(explicit_type_arguments.size()),
+ type_parameter_from_name_(type_parameters.size()),
+ inferred_(type_parameters.size()) {
+ if (num_explicit_ > type_parameters.size()) {
+ Fail("more explicit type arguments than expected");
+ return;
+ }
+ if (term_parameters.size() != term_argument_types.size()) {
+ Fail("number of term parameters does not match number of term arguments!");
+ return;
+ }
+
+ for (size_t i = 0; i < type_parameters.size(); i++) {
+ type_parameter_from_name_[type_parameters[i]->value] = i;
+ }
+ for (size_t i = 0; i < num_explicit_; i++) {
+ inferred_[i] = {explicit_type_arguments[i]};
+ }
+
+ for (size_t i = 0; i < term_parameters.size(); i++) {
+ Match(term_parameters[i], term_argument_types[i]);
+ if (HasFailed()) return;
+ }
+
+ for (size_t i = 0; i < type_parameters.size(); i++) {
+ if (!inferred_[i]) {
+ Fail("failed to infer arguments for all type parameters");
+ return;
+ }
+ }
+}
+
+TypeVector TypeArgumentInference::GetResult() const {
+ CHECK(!HasFailed());
+ TypeVector result(inferred_.size());
+ std::transform(
+ inferred_.begin(), inferred_.end(), result.begin(),
+ [](base::Optional<const Type*> maybe_type) { return *maybe_type; });
+ return result;
+}
+
+void TypeArgumentInference::Match(TypeExpression* parameter,
+ const Type* argument_type) {
+ if (BasicTypeExpression* basic =
+ BasicTypeExpression::DynamicCast(parameter)) {
+ // If the parameter is referring to one of the type parameters, substitute
+ if (basic->namespace_qualification.empty() && !basic->is_constexpr) {
+ auto result = type_parameter_from_name_.find(basic->name);
+ if (result != type_parameter_from_name_.end()) {
+ size_t type_parameter_index = result->second;
+ if (type_parameter_index < num_explicit_) {
+ return;
+ }
+ base::Optional<const Type*>& maybe_inferred =
+ inferred_[type_parameter_index];
+ if (maybe_inferred && *maybe_inferred != argument_type) {
+ Fail("found conflicting types for generic parameter");
+ } else {
+ inferred_[type_parameter_index] = {argument_type};
+ }
+ return;
+ }
+ }
+ // Try to recurse in case of generic types
+ if (!basic->generic_arguments.empty()) {
+ auto* argument_struct_type = StructType::DynamicCast(argument_type);
+ if (argument_struct_type) {
+ MatchGeneric(basic, argument_struct_type);
+ }
+ }
+ // NOTE: We could also check whether ground parameter types match the
+ // argument types, but we are only interested in inferring type arguments
+ // here
+ } else {
+ // TODO(gsps): Perform inference on function and union types
+ }
+}
+
+void TypeArgumentInference::MatchGeneric(BasicTypeExpression* parameter,
+ const StructType* argument_type) {
+ QualifiedName qualified_name{parameter->namespace_qualification,
+ parameter->name};
+ GenericStructType* generic_struct =
+ Declarations::LookupUniqueGenericStructType(qualified_name);
+ auto& specialized_from = argument_type->GetSpecializedFrom();
+ if (!specialized_from || specialized_from->generic != generic_struct) {
+ return Fail("found conflicting generic type constructors");
+ }
+ auto& parameters = parameter->generic_arguments;
+ auto& argument_types = specialized_from->specialized_types;
+ if (parameters.size() != argument_types.size()) {
+ Error(
+ "cannot infer types from generic-struct-typed parameter with "
+ "incompatible number of arguments")
+ .Position(parameter->pos)
+ .Throw();
+ }
+ for (size_t i = 0; i < parameters.size(); i++) {
+ Match(parameters[i], argument_types[i]);
+ if (HasFailed()) return;
+ }
+}
+
+} // namespace torque
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/torque/type-inference.h b/deps/v8/src/torque/type-inference.h
new file mode 100644
index 0000000000..671d68cce5
--- /dev/null
+++ b/deps/v8/src/torque/type-inference.h
@@ -0,0 +1,84 @@
+// Copyright 2019 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_TORQUE_TYPE_INFERENCE_H_
+#define V8_TORQUE_TYPE_INFERENCE_H_
+
+#include <string>
+#include <unordered_map>
+
+#include "src/base/optional.h"
+#include "src/torque/ast.h"
+#include "src/torque/declarations.h"
+#include "src/torque/types.h"
+
+namespace v8 {
+namespace internal {
+namespace torque {
+
+// Type argument inference computes a potential instantiation of a generic
+// callable given some concrete argument types. As an example, consider the
+// generic macro
+//
+// macro Pick<T: type>(x: T, y: T): T
+//
+// along with a given call site, such as
+//
+// Pick(1, 2);
+//
+// The inference proceeds by matching the term argument types (`constexpr
+// int31`, in case of `1` and `2`) against the formal parameter types (`T` in
+// both cases). During this matching we discover that `T` must equal `constexpr
+// int31`.
+//
+// The inference will not perform any comprehensive type checking of its own,
+// but *does* fail if type parameters cannot be soundly instantiated given the
+// call site. For instance, for the following call site
+//
+// const aSmi: Smi = ...;
+// Pick(1, aSmi); // inference fails
+//
+// inference would fail, since `constexpr int31` is distinct from `Smi`. To
+// allow for implicit conversions to be tried in a separate step after type
+// argument inference, a number of type arguments may be given explicitly:
+//
+// Pick<Smi>(1, aSmi); // inference succeeds (doing nothing)
+//
+// In the above case the inference simply ignores inconsistent constraints on
+// `T`. Similarly, we ignore all constraints arising from formal parameters
+// that are function- or union-typed.
+//
+// Finally, note that term parameters are passed as type expressions, since
+// we have no way of expressing a reference to type parameter as a Type. These
+// type expressions are resolved during matching, so TypeArgumentInference
+// should be instantiated in the appropriate scope.
+class TypeArgumentInference {
+ public:
+ TypeArgumentInference(const NameVector& type_parameters,
+ const TypeVector& explicit_type_arguments,
+ const std::vector<TypeExpression*>& term_parameters,
+ const TypeVector& term_argument_types);
+
+ bool HasFailed() const { return failure_reason_.has_value(); }
+ const char* GetFailureReason() { return *failure_reason_; }
+ TypeVector GetResult() const;
+
+ private:
+ void Fail(const char* reason) { failure_reason_ = {reason}; }
+
+ void Match(TypeExpression* parameter, const Type* argument_type);
+ void MatchGeneric(BasicTypeExpression* parameter,
+ const StructType* argument_type);
+
+ size_t num_explicit_;
+ std::unordered_map<std::string, size_t> type_parameter_from_name_;
+ std::vector<base::Optional<const Type*>> inferred_;
+ base::Optional<const char*> failure_reason_;
+};
+
+} // namespace torque
+} // namespace internal
+} // namespace v8
+
+#endif // V8_TORQUE_TYPE_INFERENCE_H_
diff --git a/deps/v8/src/torque/type-oracle.cc b/deps/v8/src/torque/type-oracle.cc
index 47331543fc..c7e11c2165 100644
--- a/deps/v8/src/torque/type-oracle.cc
+++ b/deps/v8/src/torque/type-oracle.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "src/torque/type-oracle.h"
+#include "src/torque/type-visitor.h"
namespace v8 {
namespace internal {
@@ -23,6 +24,28 @@ void TypeOracle::FinalizeAggregateTypes() {
}
}
+// static
+const StructType* TypeOracle::GetGenericStructTypeInstance(
+ GenericStructType* generic_struct, TypeVector arg_types) {
+ auto& params = generic_struct->generic_parameters();
+ auto& specializations = generic_struct->specializations();
+
+ if (params.size() != arg_types.size()) {
+ ReportError("Generic struct takes ", params.size(), " parameters, but ",
+ arg_types.size(), " were given");
+ }
+
+ if (auto specialization = specializations.Get(arg_types)) {
+ return *specialization;
+ } else {
+ CurrentScope::Scope generic_scope(generic_struct->ParentScope());
+ auto struct_type = TypeVisitor::ComputeType(generic_struct->declaration(),
+ {{generic_struct, arg_types}});
+ specializations.Add(arg_types, struct_type);
+ return struct_type;
+ }
+}
+
} // namespace torque
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/torque/type-oracle.h b/deps/v8/src/torque/type-oracle.h
index 405cb41e75..643c78c030 100644
--- a/deps/v8/src/torque/type-oracle.h
+++ b/deps/v8/src/torque/type-oracle.h
@@ -30,9 +30,13 @@ class TypeOracle : public ContextualClass<TypeOracle> {
return result;
}
- static StructType* GetStructType(const std::string& name) {
- StructType* result = new StructType(CurrentNamespace(), name);
+ static StructType* GetStructType(
+ const StructDeclaration* decl,
+ StructType::MaybeSpecializationKey specialized_from) {
+ Namespace* nspace = new Namespace(STRUCT_NAMESPACE_STRING);
+ StructType* result = new StructType(nspace, decl, specialized_from);
Get().aggregate_types_.push_back(std::unique_ptr<StructType>(result));
+ Get().struct_namespaces_.push_back(std::unique_ptr<Namespace>(nspace));
return result;
}
@@ -60,8 +64,26 @@ class TypeOracle : public ContextualClass<TypeOracle> {
return result;
}
- static const ReferenceType* GetReferenceType(const Type* referenced_type) {
- return Get().reference_types_.Add(ReferenceType(referenced_type));
+ static const StructType* GetGenericStructTypeInstance(
+ GenericStructType* generic_struct, TypeVector arg_types);
+
+ static GenericStructType* GetReferenceGeneric() {
+ return Declarations::LookupUniqueGenericStructType(QualifiedName(
+ {TORQUE_INTERNAL_NAMESPACE_STRING}, REFERENCE_TYPE_STRING));
+ }
+
+ static GenericStructType* GetSliceGeneric() {
+ return Declarations::LookupUniqueGenericStructType(
+ QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING}, SLICE_TYPE_STRING));
+ }
+
+ static const StructType* GetReferenceType(const Type* referenced_type) {
+ return GetGenericStructTypeInstance(GetReferenceGeneric(),
+ {referenced_type});
+ }
+
+ static const StructType* GetSliceType(const Type* referenced_type) {
+ return GetGenericStructTypeInstance(GetSliceGeneric(), {referenced_type});
}
static const std::vector<const BuiltinPointerType*>&
@@ -131,6 +153,10 @@ class TypeOracle : public ContextualClass<TypeOracle> {
return Get().GetBuiltinType(HEAP_OBJECT_TYPE_STRING);
}
+ static const Type* GetJSAnyType() {
+ return Get().GetBuiltinType(JSANY_TYPE_STRING);
+ }
+
static const Type* GetJSObjectType() {
return Get().GetBuiltinType(JSOBJECT_TYPE_STRING);
}
@@ -245,10 +271,10 @@ class TypeOracle : public ContextualClass<TypeOracle> {
Deduplicator<BuiltinPointerType> function_pointer_types_;
std::vector<const BuiltinPointerType*> all_builtin_pointer_types_;
Deduplicator<UnionType> union_types_;
- Deduplicator<ReferenceType> reference_types_;
std::vector<std::unique_ptr<Type>> nominal_types_;
std::vector<std::unique_ptr<AggregateType>> aggregate_types_;
std::vector<std::unique_ptr<Type>> top_types_;
+ std::vector<std::unique_ptr<Namespace>> struct_namespaces_;
};
} // namespace torque
diff --git a/deps/v8/src/torque/type-visitor.cc b/deps/v8/src/torque/type-visitor.cc
index 37be0df006..9b5c96ee40 100644
--- a/deps/v8/src/torque/type-visitor.cc
+++ b/deps/v8/src/torque/type-visitor.cc
@@ -8,6 +8,7 @@
#include "src/torque/declarable.h"
#include "src/torque/global-context.h"
#include "src/torque/server-data.h"
+#include "src/torque/type-inference.h"
#include "src/torque/type-oracle.h"
namespace v8 {
@@ -91,49 +92,47 @@ void DeclareMethods(AggregateType* container_type,
const std::vector<Declaration*>& methods) {
for (auto declaration : methods) {
CurrentSourcePosition::Scope pos_scope(declaration->pos);
- StandardDeclaration* standard_declaration =
- StandardDeclaration::DynamicCast(declaration);
- DCHECK(standard_declaration);
TorqueMacroDeclaration* method =
- TorqueMacroDeclaration::DynamicCast(standard_declaration->callable);
- Signature signature = TypeVisitor::MakeSignature(method->signature.get());
+ TorqueMacroDeclaration::DynamicCast(declaration);
+ Signature signature = TypeVisitor::MakeSignature(method);
signature.parameter_names.insert(
signature.parameter_names.begin() + signature.implicit_count,
MakeNode<Identifier>(kThisParameterName));
- Statement* body = *(standard_declaration->body);
- std::string method_name(method->name);
+ Statement* body = *(method->body);
+ const std::string& method_name(method->name->value);
signature.parameter_types.types.insert(
signature.parameter_types.types.begin() + signature.implicit_count,
container_type);
- Declarations::CreateMethod(container_type, method_name, signature, false,
- body);
+ Declarations::CreateMethod(container_type, method_name, signature, body);
}
}
-namespace {
-std::string ComputeStructName(StructDeclaration* decl) {
- TypeVector args;
- if (decl->IsGeneric()) {
- args.resize(decl->generic_parameters.size());
- std::transform(
- decl->generic_parameters.begin(), decl->generic_parameters.end(),
- args.begin(), [](Identifier* parameter) {
- return Declarations::LookupTypeAlias(QualifiedName(parameter->value))
- ->type();
- });
+const StructType* TypeVisitor::ComputeType(
+ StructDeclaration* decl,
+ StructType::MaybeSpecializationKey specialized_from) {
+ StructType* struct_type = TypeOracle::GetStructType(decl, specialized_from);
+ CurrentScope::Scope struct_namespace_scope(struct_type->nspace());
+ CurrentSourcePosition::Scope position_activator(decl->pos);
+
+ if (specialized_from) {
+ auto& params = specialized_from->generic->generic_parameters();
+ auto arg_types_iterator = specialized_from->specialized_types.begin();
+ for (auto param : params) {
+ TypeAlias* alias = Declarations::DeclareType(param, *arg_types_iterator);
+ alias->SetIsUserDefined(false);
+ arg_types_iterator++;
+ }
}
- return StructType::ComputeName(decl->name->value, args);
-}
-} // namespace
-const StructType* TypeVisitor::ComputeType(StructDeclaration* decl) {
- CurrentSourcePosition::Scope position_activator(decl->pos);
- StructType* struct_type = TypeOracle::GetStructType(ComputeStructName(decl));
size_t offset = 0;
for (auto& field : decl->fields) {
CurrentSourcePosition::Scope position_activator(
field.name_and_type.type->pos);
const Type* field_type = TypeVisitor::ComputeType(field.name_and_type.type);
+ if (field_type->IsConstexpr()) {
+ ReportError("struct field \"", field.name_and_type.name->value,
+ "\" carries constexpr type \"", *field_type, "\"");
+ }
struct_type->RegisterField({field.name_and_type.name->pos,
struct_type,
base::nullopt,
@@ -144,7 +143,6 @@ const StructType* TypeVisitor::ComputeType(StructDeclaration* decl) {
false});
offset += LoweredSlotCount(field_type);
}
- DeclareMethods(struct_type, decl->methods);
return struct_type;
}
@@ -214,34 +212,8 @@ const Type* TypeVisitor::ComputeType(TypeExpression* type_expression) {
} else {
auto* generic_struct =
Declarations::LookupUniqueGenericStructType(qualified_name);
- auto& params = generic_struct->generic_parameters();
- auto& specializations = generic_struct->specializations();
- if (params.size() != args.size()) {
- ReportError("Generic struct takes ", params.size(),
- " parameters, but only ", args.size(), " were given");
- }
-
- std::vector<const Type*> arg_types = ComputeTypeVector(args);
- if (auto specialization = specializations.Get(arg_types)) {
- type = *specialization;
- } else {
- CurrentScope::Scope generic_scope(generic_struct->ParentScope());
- // Create a temporary fake-namespace just to temporarily declare the
- // specialization aliases for the generic types to create a signature.
- Namespace tmp_namespace("_tmp");
- CurrentScope::Scope tmp_namespace_scope(&tmp_namespace);
- auto arg_types_iterator = arg_types.begin();
- for (auto param : params) {
- TypeAlias* alias =
- Declarations::DeclareType(param, *arg_types_iterator);
- alias->SetIsUserDefined(false);
- arg_types_iterator++;
- }
-
- auto struct_type = ComputeType(generic_struct->declaration());
- specializations.Add(arg_types, struct_type);
- type = struct_type;
- }
+ type = TypeOracle::GetGenericStructTypeInstance(generic_struct,
+ ComputeTypeVector(args));
pos = generic_struct->declaration()->name->pos;
}
@@ -254,10 +226,6 @@ const Type* TypeVisitor::ComputeType(TypeExpression* type_expression) {
UnionTypeExpression::DynamicCast(type_expression)) {
return TypeOracle::GetUnionType(ComputeType(union_type->a),
ComputeType(union_type->b));
- } else if (auto* reference_type =
- ReferenceTypeExpression::DynamicCast(type_expression)) {
- return TypeOracle::GetReferenceType(
- ComputeType(reference_type->referenced_type));
} else {
auto* function_type_exp = FunctionTypeExpression::cast(type_expression);
TypeVector argument_types;
@@ -269,22 +237,23 @@ const Type* TypeVisitor::ComputeType(TypeExpression* type_expression) {
}
}
-Signature TypeVisitor::MakeSignature(const CallableNodeSignature* signature) {
+Signature TypeVisitor::MakeSignature(const CallableDeclaration* declaration) {
LabelDeclarationVector definition_vector;
- for (const auto& label : signature->labels) {
+ for (const auto& label : declaration->labels) {
LabelDeclaration def = {label.name, ComputeTypeVector(label.types)};
definition_vector.push_back(def);
}
base::Optional<std::string> arguments_variable;
- if (signature->parameters.has_varargs)
- arguments_variable = signature->parameters.arguments_variable;
- Signature result{signature->parameters.names,
+ if (declaration->parameters.has_varargs)
+ arguments_variable = declaration->parameters.arguments_variable;
+ Signature result{declaration->parameters.names,
arguments_variable,
- {ComputeTypeVector(signature->parameters.types),
- signature->parameters.has_varargs},
- signature->parameters.implicit_count,
- ComputeType(signature->return_type),
- definition_vector};
+ {ComputeTypeVector(declaration->parameters.types),
+ declaration->parameters.has_varargs},
+ declaration->parameters.implicit_count,
+ ComputeType(declaration->return_type),
+ definition_vector,
+ declaration->transitioning};
return result;
}
@@ -345,7 +314,8 @@ void TypeVisitor::VisitClassFieldsAndMethods(
std::string machine_type;
std::tie(field_size, size_string) = field.GetFieldSizeInformation();
// Our allocations don't support alignments beyond kTaggedSize.
- size_t alignment = std::min(size_t{kTaggedSize}, field_size);
+ size_t alignment = std::min(
+ static_cast<size_t>(TargetArchitecture::TaggedSize()), field_size);
if (alignment > 0 && class_offset % alignment != 0) {
ReportError("field ", field_expression.name_and_type.name,
" at offset ", class_offset, " is not ", alignment,
@@ -359,6 +329,60 @@ void TypeVisitor::VisitClassFieldsAndMethods(
DeclareMethods(class_type, class_declaration->methods);
}
+void TypeVisitor::VisitStructMethods(
+ StructType* struct_type, const StructDeclaration* struct_declaration) {
+ DeclareMethods(struct_type, struct_declaration->methods);
+}
+
+const StructType* TypeVisitor::ComputeTypeForStructExpression(
+ TypeExpression* type_expression,
+ const std::vector<const Type*>& term_argument_types) {
+ auto* basic = BasicTypeExpression::DynamicCast(type_expression);
+ if (!basic) {
+ ReportError("expected basic type expression referring to struct");
+ }
+
+ QualifiedName qualified_name{basic->namespace_qualification, basic->name};
+ base::Optional<GenericStructType*> maybe_generic_struct =
+ Declarations::TryLookupGenericStructType(qualified_name);
+
+ // Compute types of non-generic structs as usual
+ if (!maybe_generic_struct) {
+ const Type* type = ComputeType(type_expression);
+ const StructType* struct_type = StructType::DynamicCast(type);
+ if (!struct_type) {
+ ReportError(*type, " is not a struct, but used like one");
+ }
+ return struct_type;
+ }
+
+ auto generic_struct = *maybe_generic_struct;
+ auto explicit_type_arguments = ComputeTypeVector(basic->generic_arguments);
+
+ std::vector<TypeExpression*> term_parameters;
+ auto& fields = generic_struct->declaration()->fields;
+ term_parameters.reserve(fields.size());
+ for (auto& field : fields) {
+ term_parameters.push_back(field.name_and_type.type);
+ }
+
+ CurrentScope::Scope generic_scope(generic_struct->ParentScope());
+ TypeArgumentInference inference(
+ generic_struct->declaration()->generic_parameters,
+ explicit_type_arguments, term_parameters, term_argument_types);
+
+ if (inference.HasFailed()) {
+ ReportError("failed to infer type arguments for struct ", basic->name,
+ " initialization: ", inference.GetFailureReason());
+ }
+ if (GlobalContext::collect_language_server_data()) {
+ LanguageServerData::AddDefinition(type_expression->pos,
+ generic_struct->declaration()->name->pos);
+ }
+ return TypeOracle::GetGenericStructTypeInstance(generic_struct,
+ inference.GetResult());
+}
+
} // namespace torque
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/torque/type-visitor.h b/deps/v8/src/torque/type-visitor.h
index 93de02b860..cafd752cbf 100644
--- a/deps/v8/src/torque/type-visitor.h
+++ b/deps/v8/src/torque/type-visitor.h
@@ -27,14 +27,22 @@ class TypeVisitor {
static const Type* ComputeType(TypeExpression* type_expression);
static void VisitClassFieldsAndMethods(
ClassType* class_type, const ClassDeclaration* class_declaration);
- static Signature MakeSignature(const CallableNodeSignature* signature);
+ static void VisitStructMethods(StructType* struct_type,
+ const StructDeclaration* struct_declaration);
+ static Signature MakeSignature(const CallableDeclaration* declaration);
+ static const StructType* ComputeTypeForStructExpression(
+ TypeExpression* type_expression,
+ const std::vector<const Type*>& term_argument_types);
private:
friend class TypeAlias;
+ friend class TypeOracle;
static const Type* ComputeType(TypeDeclaration* decl);
static const AbstractType* ComputeType(AbstractTypeDeclaration* decl);
static const Type* ComputeType(TypeAliasDeclaration* decl);
- static const StructType* ComputeType(StructDeclaration* decl);
+ static const StructType* ComputeType(
+ StructDeclaration* decl,
+ StructType::MaybeSpecializationKey specialized_from = base::nullopt);
static const ClassType* ComputeType(ClassDeclaration* decl);
};
diff --git a/deps/v8/src/torque/types.cc b/deps/v8/src/torque/types.cc
index 37a328b1dc..fe792401f6 100644
--- a/deps/v8/src/torque/types.cc
+++ b/deps/v8/src/torque/types.cc
@@ -4,9 +4,9 @@
#include <iostream>
-#include "src/common/globals.h"
#include "src/torque/ast.h"
#include "src/torque/declarable.h"
+#include "src/torque/global-context.h"
#include "src/torque/type-oracle.h"
#include "src/torque/type-visitor.h"
#include "src/torque/types.h"
@@ -263,7 +263,7 @@ const Field& AggregateType::LookupFieldInternal(const std::string& name) const {
return parent_class->LookupField(name);
}
}
- ReportError("no field ", name, " found");
+ ReportError("no field ", name, " found in ", this->ToString());
}
const Field& AggregateType::LookupField(const std::string& name) const {
@@ -276,13 +276,14 @@ std::string StructType::GetGeneratedTypeNameImpl() const {
}
// static
-std::string StructType::ComputeName(const std::string& basename,
- const std::vector<const Type*>& args) {
- if (args.size() == 0) return basename;
+std::string StructType::ComputeName(
+ const std::string& basename,
+ StructType::MaybeSpecializationKey specialized_from) {
+ if (!specialized_from) return basename;
std::stringstream s;
s << basename << "<";
bool first = true;
- for (auto t : args) {
+ for (auto t : specialized_from->specialized_types) {
if (!first) {
s << ", ";
}
@@ -293,6 +294,43 @@ std::string StructType::ComputeName(const std::string& basename,
return s.str();
}
+std::string StructType::MangledName() const {
+ std::stringstream result;
+ // TODO(gsps): Add 'ST' as a prefix once we can control the generated type
+ // name from Torque code
+ result << decl_->name->value;
+ if (specialized_from_) {
+ for (const Type* t : specialized_from_->specialized_types) {
+ std::string arg_type_string = t->MangledName();
+ result << arg_type_string.size() << arg_type_string;
+ }
+ }
+ return result.str();
+}
+
+// static
+base::Optional<const Type*> StructType::MatchUnaryGeneric(
+ const Type* type, GenericStructType* generic) {
+ if (auto* struct_type = StructType::DynamicCast(type)) {
+ return MatchUnaryGeneric(struct_type, generic);
+ }
+ return base::nullopt;
+}
+
+// static
+base::Optional<const Type*> StructType::MatchUnaryGeneric(
+ const StructType* type, GenericStructType* generic) {
+ DCHECK_EQ(generic->generic_parameters().size(), 1);
+ if (!type->specialized_from_) {
+ return base::nullopt;
+ }
+ auto& key = type->specialized_from_.value();
+ if (key.generic != generic || key.specialized_types.size() != 1) {
+ return base::nullopt;
+ }
+ return {key.specialized_types[0]};
+}
+
std::vector<Method*> AggregateType::Methods(const std::string& name) const {
if (!is_finalized_) Finalize();
std::vector<Method*> result;
@@ -307,6 +345,17 @@ std::string StructType::ToExplicitString() const {
return result.str();
}
+void StructType::Finalize() const {
+ if (is_finalized_) return;
+ {
+ CurrentScope::Scope scope_activator(nspace());
+ CurrentSourcePosition::Scope position_activator(decl_->pos);
+ TypeVisitor::VisitStructMethods(const_cast<StructType*>(this), decl_);
+ }
+ is_finalized_ = true;
+ CheckForDuplicateFields();
+}
+
constexpr ClassFlags ClassType::kInternalFlags;
ClassType::ClassType(const Type* parent, Namespace* nspace,
@@ -380,6 +429,17 @@ void ClassType::Finalize() const {
CheckForDuplicateFields();
}
+std::vector<Field> ClassType::ComputeAllFields() const {
+ std::vector<Field> all_fields;
+ const ClassType* super_class = this->GetSuperClass();
+ if (super_class) {
+ all_fields = super_class->ComputeAllFields();
+ }
+ const std::vector<Field>& fields = this->fields();
+ all_fields.insert(all_fields.end(), fields.begin(), fields.end());
+ return all_fields;
+}
+
void ClassType::GenerateAccessors() {
// For each field, construct AST snippets that implement a CSA accessor
// function and define a corresponding '.field' operator. The
@@ -404,8 +464,7 @@ void ClassType::GenerateAccessors() {
MakeNode<ReturnStatement>(MakeNode<FieldAccessExpression>(
parameter, MakeNode<Identifier>(field.name_and_type.name)));
Declarations::DeclareMacro(load_macro_name, true, base::nullopt,
- load_signature, false, load_body, base::nullopt,
- false);
+ load_signature, load_body, base::nullopt);
// Store accessor
IdentifierExpression* value = MakeNode<IdentifierExpression>(
@@ -425,8 +484,8 @@ void ClassType::GenerateAccessors() {
parameter, MakeNode<Identifier>(field.name_and_type.name)),
value));
Declarations::DeclareMacro(store_macro_name, true, base::nullopt,
- store_signature, false, store_body,
- base::nullopt, false);
+ store_signature, store_body, base::nullopt,
+ false);
}
}
@@ -560,9 +619,6 @@ void AppendLoweredTypes(const Type* type, std::vector<const Type*>* result) {
for (const Field& field : s->fields()) {
AppendLoweredTypes(field.name_and_type.type, result);
}
- } else if (type->IsReferenceType()) {
- result->push_back(TypeOracle::GetHeapObjectType());
- result->push_back(TypeOracle::GetIntPtrType());
} else {
result->push_back(type);
}
@@ -606,10 +662,10 @@ std::tuple<size_t, std::string> Field::GetFieldSizeInformation() const {
const Type* field_type = this->name_and_type.type;
size_t field_size = 0;
if (field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
- field_size = kTaggedSize;
+ field_size = TargetArchitecture::TaggedSize();
size_string = "kTaggedSize";
} else if (field_type->IsSubtypeOf(TypeOracle::GetRawPtrType())) {
- field_size = kSystemPointerSize;
+ field_size = TargetArchitecture::RawPtrSize();
size_string = "kSystemPointerSize";
} else if (field_type->IsSubtypeOf(TypeOracle::GetVoidType())) {
field_size = 0;
@@ -636,10 +692,10 @@ std::tuple<size_t, std::string> Field::GetFieldSizeInformation() const {
field_size = kDoubleSize;
size_string = "kDoubleSize";
} else if (field_type->IsSubtypeOf(TypeOracle::GetIntPtrType())) {
- field_size = kIntptrSize;
+ field_size = TargetArchitecture::RawPtrSize();
size_string = "kIntptrSize";
} else if (field_type->IsSubtypeOf(TypeOracle::GetUIntPtrType())) {
- field_size = kIntptrSize;
+ field_size = TargetArchitecture::RawPtrSize();
size_string = "kIntptrSize";
} else {
ReportError("fields of type ", *field_type, " are not (yet) supported");
diff --git a/deps/v8/src/torque/types.h b/deps/v8/src/torque/types.h
index f6180c4250..d2198d50c3 100644
--- a/deps/v8/src/torque/types.h
+++ b/deps/v8/src/torque/types.h
@@ -25,6 +25,7 @@ class AggregateType;
struct Identifier;
class Macro;
class Method;
+class GenericStructType;
class StructType;
class ClassType;
class Value;
@@ -36,7 +37,6 @@ class TypeBase {
kTopType,
kAbstractType,
kBuiltinPointerType,
- kReferenceType,
kUnionType,
kStructType,
kClassType
@@ -47,7 +47,6 @@ class TypeBase {
bool IsBuiltinPointerType() const {
return kind() == Kind::kBuiltinPointerType;
}
- bool IsReferenceType() const { return kind() == Kind::kReferenceType; }
bool IsUnionType() const { return kind() == Kind::kUnionType; }
bool IsStructType() const { return kind() == Kind::kStructType; }
bool IsClassType() const { return kind() == Kind::kClassType; }
@@ -143,6 +142,12 @@ struct NameAndType {
std::ostream& operator<<(std::ostream& os, const NameAndType& name_and_type);
+template <typename T>
+struct SpecializationKey {
+ T* generic;
+ TypeVector specialized_types;
+};
+
struct Field {
// TODO(danno): This likely should be refactored, the handling of the types
// using the universal grab-bag utility with std::tie, as well as the
@@ -298,43 +303,6 @@ class V8_EXPORT_PRIVATE BuiltinPointerType final : public Type {
const size_t function_pointer_type_id_;
};
-class ReferenceType final : public Type {
- public:
- DECLARE_TYPE_BOILERPLATE(ReferenceType)
- std::string MangledName() const override {
- return "RT" + referenced_type_->MangledName();
- }
- std::string ToExplicitString() const override {
- std::string s = referenced_type_->ToString();
- if (s.find(' ') != std::string::npos) {
- s = "(" + s + ")";
- }
- return "&" + s;
- }
- std::string GetGeneratedTypeNameImpl() const override {
- return "CodeStubAssembler::Reference";
- }
- std::string GetGeneratedTNodeTypeNameImpl() const override { UNREACHABLE(); }
-
- const Type* referenced_type() const { return referenced_type_; }
-
- friend size_t hash_value(const ReferenceType& p) {
- return base::hash_combine(static_cast<size_t>(Kind::kReferenceType),
- p.referenced_type_);
- }
- bool operator==(const ReferenceType& other) const {
- return referenced_type_ == other.referenced_type_;
- }
-
- private:
- friend class TypeOracle;
- explicit ReferenceType(const Type* referenced_type)
- : Type(Kind::kReferenceType, nullptr),
- referenced_type_(referenced_type) {}
-
- const Type* const referenced_type_;
-};
-
bool operator<(const Type& a, const Type& b);
struct TypeLess {
bool operator()(const Type* const a, const Type* const b) const {
@@ -500,32 +468,38 @@ class AggregateType : public Type {
class StructType final : public AggregateType {
public:
DECLARE_TYPE_BOILERPLATE(StructType)
+
+ using MaybeSpecializationKey =
+ base::Optional<SpecializationKey<GenericStructType>>;
+
std::string ToExplicitString() const override;
std::string GetGeneratedTypeNameImpl() const override;
- std::string MangledName() const override {
- // TODO(gsps): Generate more readable mangled names
- std::string str(name());
- std::replace(str.begin(), str.end(), ',', '_');
- std::replace(str.begin(), str.end(), ' ', '_');
- std::replace(str.begin(), str.end(), '<', '_');
- std::replace(str.begin(), str.end(), '>', '_');
- return str;
+ std::string MangledName() const override;
+ const MaybeSpecializationKey& GetSpecializedFrom() const {
+ return specialized_from_;
}
- static std::string ComputeName(const std::string& basename,
- const std::vector<const Type*>& args);
+ static base::Optional<const Type*> MatchUnaryGeneric(
+ const Type* type, GenericStructType* generic);
+ static base::Optional<const Type*> MatchUnaryGeneric(
+ const StructType* type, GenericStructType* generic);
private:
friend class TypeOracle;
- StructType(Namespace* nspace, const std::string& name)
- : AggregateType(Kind::kStructType, nullptr, nspace, name) {}
+ StructType(Namespace* nspace, const StructDeclaration* decl,
+ MaybeSpecializationKey specialized_from = base::nullopt)
+ : AggregateType(Kind::kStructType, nullptr, nspace,
+ ComputeName(decl->name->value, specialized_from)),
+ decl_(decl),
+ specialized_from_(specialized_from) {}
- void Finalize() const override {
- is_finalized_ = true;
- CheckForDuplicateFields();
- }
+ void Finalize() const override;
+
+ static std::string ComputeName(const std::string& basename,
+ MaybeSpecializationKey specialized_from);
- const std::string& GetStructName() const { return name(); }
+ const StructDeclaration* decl_;
+ MaybeSpecializationKey specialized_from_;
};
class TypeAlias;
@@ -573,6 +547,8 @@ class ClassType final : public AggregateType {
}
void Finalize() const override;
+ std::vector<Field> ComputeAllFields() const;
+
private:
friend class TypeOracle;
friend class TypeVisitor;
@@ -668,22 +644,25 @@ using NameVector = std::vector<Identifier*>;
struct Signature {
Signature(NameVector n, base::Optional<std::string> arguments_variable,
- ParameterTypes p, size_t i, const Type* r, LabelDeclarationVector l)
+ ParameterTypes p, size_t i, const Type* r, LabelDeclarationVector l,
+ bool transitioning)
: parameter_names(std::move(n)),
arguments_variable(arguments_variable),
parameter_types(std::move(p)),
implicit_count(i),
return_type(r),
- labels(std::move(l)) {}
- Signature() : implicit_count(0), return_type(nullptr) {}
+ labels(std::move(l)),
+ transitioning(transitioning) {}
+ Signature() = default;
const TypeVector& types() const { return parameter_types.types; }
NameVector parameter_names;
base::Optional<std::string> arguments_variable;
ParameterTypes parameter_types;
- size_t implicit_count;
+ size_t implicit_count = 0;
size_t ExplicitCount() const { return types().size() - implicit_count; }
const Type* return_type;
LabelDeclarationVector labels;
+ bool transitioning = false;
bool HasSameTypesAs(
const Signature& other,
ParameterMode mode = ParameterMode::kProcessImplicit) const;
diff --git a/deps/v8/src/torque/utils.cc b/deps/v8/src/torque/utils.cc
index 244d1587db..38862b31b0 100644
--- a/deps/v8/src/torque/utils.cc
+++ b/deps/v8/src/torque/utils.cc
@@ -168,9 +168,9 @@ bool IsKeywordLikeName(const std::string& s) {
// naming convention and are those exempt from the normal type convention.
bool IsMachineType(const std::string& s) {
static const char* const machine_types[]{
- "void", "never", "int8", "uint8", "int16", "uint16",
- "int31", "uint31", "int32", "uint32", "int64", "intptr",
- "uintptr", "float32", "float64", "bool", "string", "bint"};
+ "void", "never", "int8", "uint8", "int16", "uint16", "int31",
+ "uint31", "int32", "uint32", "int64", "intptr", "uintptr", "float32",
+ "float64", "bool", "string", "bint", "char8", "char16"};
return std::find(std::begin(machine_types), std::end(machine_types), s) !=
std::end(machine_types);
@@ -292,6 +292,42 @@ void ReplaceFileContentsIfDifferent(const std::string& file_path,
}
}
+IfDefScope::IfDefScope(std::ostream& os, std::string d)
+ : os_(os), d_(std::move(d)) {
+ os_ << "#ifdef " << d_ << "\n";
+}
+IfDefScope::~IfDefScope() { os_ << "#endif // " << d_ << "\n"; }
+
+NamespaceScope::NamespaceScope(std::ostream& os,
+ std::initializer_list<std::string> namespaces)
+ : os_(os), d_(std::move(namespaces)) {
+ for (const std::string& s : d_) {
+ os_ << "namespace " << s << " {\n";
+ }
+}
+NamespaceScope::~NamespaceScope() {
+ for (auto i = d_.rbegin(); i != d_.rend(); ++i) {
+ os_ << "} // namespace " << *i << "\n";
+ }
+}
+
+IncludeGuardScope::IncludeGuardScope(std::ostream& os, std::string file_name)
+ : os_(os),
+ d_("V8_GEN_TORQUE_GENERATED_" + CapifyStringWithUnderscores(file_name) +
+ "_") {
+ os_ << "#ifndef " << d_ << "\n";
+ os_ << "#define " << d_ << "\n\n";
+}
+IncludeGuardScope::~IncludeGuardScope() { os_ << "#endif // " << d_ << "\n"; }
+
+IncludeObjectMacrosScope::IncludeObjectMacrosScope(std::ostream& os) : os_(os) {
+ os_ << "\n// Has to be the last include (doesn't have include guards):\n"
+ "#include \"src/objects/object-macros.h\"\n";
+}
+IncludeObjectMacrosScope::~IncludeObjectMacrosScope() {
+ os_ << "\n#include \"src/objects/object-macros-undef.h\"\n";
+}
+
} // namespace torque
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/torque/utils.h b/deps/v8/src/torque/utils.h
index fb4ad59f99..5f44dedea9 100644
--- a/deps/v8/src/torque/utils.h
+++ b/deps/v8/src/torque/utils.h
@@ -292,7 +292,7 @@ T* CheckNotNull(T* x) {
}
template <class T>
-inline std::ostream& operator<<(std::ostream& os, Stack<T>& t) {
+inline std::ostream& operator<<(std::ostream& os, const Stack<T>& t) {
os << "Stack{";
PrintCommaSeparatedList(os, t);
os << "}";
@@ -356,6 +356,54 @@ inline bool StringEndsWith(const std::string& s, const std::string& suffix) {
return s.substr(s.size() - suffix.size()) == suffix;
}
+class IfDefScope {
+ public:
+ IfDefScope(std::ostream& os, std::string d);
+ ~IfDefScope();
+
+ private:
+ IfDefScope(const IfDefScope&) = delete;
+ IfDefScope& operator=(const IfDefScope&) = delete;
+ std::ostream& os_;
+ std::string d_;
+};
+
+class NamespaceScope {
+ public:
+ NamespaceScope(std::ostream& os,
+ std::initializer_list<std::string> namespaces);
+ ~NamespaceScope();
+
+ private:
+ NamespaceScope(const NamespaceScope&) = delete;
+ NamespaceScope& operator=(const NamespaceScope&) = delete;
+ std::ostream& os_;
+ std::vector<std::string> d_;
+};
+
+class IncludeGuardScope {
+ public:
+ IncludeGuardScope(std::ostream& os, std::string file_name);
+ ~IncludeGuardScope();
+
+ private:
+ IncludeGuardScope(const IncludeGuardScope&) = delete;
+ IncludeGuardScope& operator=(const IncludeGuardScope&) = delete;
+ std::ostream& os_;
+ std::string d_;
+};
+
+class IncludeObjectMacrosScope {
+ public:
+ explicit IncludeObjectMacrosScope(std::ostream& os);
+ ~IncludeObjectMacrosScope();
+
+ private:
+ IncludeObjectMacrosScope(const IncludeObjectMacrosScope&) = delete;
+ IncludeObjectMacrosScope& operator=(const IncludeObjectMacrosScope&) = delete;
+ std::ostream& os_;
+};
+
} // namespace torque
} // namespace internal
} // namespace v8