diff --git a/BUILD.gn b/BUILD.gn index a10aa15f50..548774b6e2 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -984,6 +984,7 @@ torque_files = [ "src/builtins/string-slice.tq", "src/builtins/string-startswith.tq", "src/builtins/string-substring.tq", + "src/builtins/torque-internal.tq", "src/builtins/typed-array-createtypedarray.tq", "src/builtins/typed-array-every.tq", "src/builtins/typed-array-filter.tq", diff --git a/src/builtins/torque-internal.tq b/src/builtins/torque-internal.tq new file mode 100644 index 0000000000..99cc52f19f --- /dev/null +++ b/src/builtins/torque-internal.tq @@ -0,0 +1,12 @@ +// 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. + +namespace torque_internal { + + struct Reference { + const object: HeapObject; + const offset: intptr; + } + +} // namespace torque_internal diff --git a/src/codegen/code-stub-assembler.h b/src/codegen/code-stub-assembler.h index 06d8d33d51..2588136d86 100644 --- a/src/codegen/code-stub-assembler.h +++ b/src/codegen/code-stub-assembler.h @@ -847,6 +847,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // Reference is the CSA-equivalent of a Torque reference value, // representing an inner pointer into a HeapObject. + // TODO(gsps): Remove in favor of flattened {Load,Store}Reference interface struct Reference { TNode object; TNode offset; diff --git a/src/torque/ast.h b/src/torque/ast.h index 23de121065..58613545c3 100644 --- a/src/torque/ast.h +++ b/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) \ @@ -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) diff --git a/src/torque/constants.h b/src/torque/constants.h index 4ad3a6ec3c..948e74bc1a 100644 --- a/src/torque/constants.h +++ b/src/torque/constants.h @@ -49,6 +49,8 @@ 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"; inline bool IsConstexprName(const std::string& name) { return name.substr(0, std::strlen(CONSTEXPR_TYPE_PREFIX)) == diff --git a/src/torque/csa-generator.cc b/src/torque/csa-generator.cc index 6a798a2707..9d2155d820 100644 --- a/src/torque/csa-generator.cc +++ b/src/torque/csa-generator.cc @@ -305,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); @@ -766,11 +765,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/src/torque/declarable.cc b/src/torque/declarable.cc index 1fd07d5b0d..2ea6b6d65c 100644 --- a/src/torque/declarable.cc +++ b/src/torque/declarable.cc @@ -74,11 +74,7 @@ base::Optional InferTypeArgument(const std::string& to_infer, 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()); - } + // TODO(gsps): Perform type inference for generic types return base::nullopt; } diff --git a/src/torque/declarable.h b/src/torque/declarable.h index cf6fd2554b..dc515b50c9 100644 --- a/src/torque/declarable.h +++ b/src/torque/declarable.h @@ -505,11 +505,6 @@ class Generic : public Declarable { SpecializationMap specializations_; }; -struct SpecializationKey { - Generic* generic; - TypeVector specialized_types; -}; - class GenericStructType : public Declarable { public: DECLARE_DECLARABLE_BOILERPLATE(GenericStructType, generic_type) diff --git a/src/torque/declaration-visitor.cc b/src/torque/declaration-visitor.cc index e0e996f33b..81e49b2f36 100644 --- a/src/torque/declaration-visitor.cc +++ b/src/torque/declaration-visitor.cc @@ -205,7 +205,7 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { TypeVisitor::MakeSignature(decl->signature.get()); for (Generic* generic : generic_list) { Signature generic_signature_with_types = - MakeSpecializedSignature(SpecializationKey{ + MakeSpecializedSignature(SpecializationKey{ generic, TypeVisitor::ComputeTypeVector(decl->generic_parameters)}); if (signature_with_types.HasSameTypesAs(generic_signature_with_types, ParameterMode::kIgnoreImplicit)) { @@ -233,7 +233,7 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { stream << "\ncandidates are:"; for (Generic* generic : generic_list) { stream << "\n " - << MakeSpecializedSignature(SpecializationKey{ + << MakeSpecializedSignature(SpecializationKey{ generic, TypeVisitor::ComputeTypeVector(decl->generic_parameters)}); } @@ -245,8 +245,9 @@ void DeclarationVisitor::Visit(SpecializationDeclaration* decl) { matching_generic->IdentifierPosition()); } - Specialize(SpecializationKey{matching_generic, TypeVisitor::ComputeTypeVector( - decl->generic_parameters)}, + Specialize(SpecializationKey{matching_generic, + TypeVisitor::ComputeTypeVector( + decl->generic_parameters)}, matching_generic->declaration()->callable, decl->signature.get(), decl->body, decl->pos); } @@ -267,7 +268,8 @@ void DeclarationVisitor::Visit(CppIncludeDeclaration* decl) { GlobalContext::AddCppInclude(decl->include_path); } -void DeclarationVisitor::DeclareSpecializedTypes(const SpecializationKey& key) { +void DeclarationVisitor::DeclareSpecializedTypes( + const SpecializationKey& key) { size_t i = 0; const std::size_t generic_parameter_count = key.generic->declaration()->generic_parameters.size(); @@ -288,7 +290,7 @@ void DeclarationVisitor::DeclareSpecializedTypes(const SpecializationKey& key) { } Signature DeclarationVisitor::MakeSpecializedSignature( - const SpecializationKey& key) { + const SpecializationKey& 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. @@ -299,7 +301,8 @@ Signature DeclarationVisitor::MakeSpecializedSignature( key.generic->declaration()->callable->signature.get()); } -Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) { +Callable* DeclarationVisitor::SpecializeImplicit( + const SpecializationKey& key) { if (!key.generic->declaration()->body && IntrinsicDeclaration::DynamicCast(key.generic->declaration()->callable) == nullptr) { @@ -318,7 +321,7 @@ Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) { } Callable* DeclarationVisitor::Specialize( - const SpecializationKey& key, CallableNode* declaration, + const SpecializationKey& key, CallableNode* declaration, base::Optional signature, base::Optional body, SourcePosition position) { CurrentSourcePosition::Scope pos_scope(position); diff --git a/src/torque/declaration-visitor.h b/src/torque/declaration-visitor.h index dbd28f4b87..d789330520 100644 --- a/src/torque/declaration-visitor.h +++ b/src/torque/declaration-visitor.h @@ -107,15 +107,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& key); + static Callable* SpecializeImplicit(const SpecializationKey& key); static Callable* Specialize( - const SpecializationKey& key, CallableNode* declaration, + const SpecializationKey& key, CallableNode* declaration, base::Optional signature, base::Optional body, SourcePosition position); private: - static void DeclareSpecializedTypes(const SpecializationKey& key); + static void DeclareSpecializedTypes(const SpecializationKey& key); }; } // namespace torque diff --git a/src/torque/implementation-visitor.cc b/src/torque/implementation-visitor.cc index 6a46bf9640..3a7105d744 100644 --- a/src/torque/implementation-visitor.cc +++ b/src/torque/implementation-visitor.cc @@ -1599,7 +1599,7 @@ void FailCallableLookup(const std::string& reason, const QualifiedName& name, ReportError(stream.str()); } -Callable* GetOrCreateSpecialization(const SpecializationKey& key) { +Callable* GetOrCreateSpecialization(const SpecializationKey& key) { if (base::Optional specialization = key.generic->specializations().Get(key.specialized_types)) { return *specialization; @@ -1664,7 +1664,8 @@ Callable* ImplementationVisitor::LookupCallable( overloads.push_back(generic); overload_signatures.push_back( DeclarationVisitor::MakeSpecializedSignature( - SpecializationKey{generic, *inferred_specialization_types})); + SpecializationKey{generic, + *inferred_specialization_types})); } else if (Callable* callable = Callable::DynamicCast(declarable)) { overloads.push_back(callable); overload_signatures.push_back(callable->signature()); @@ -1717,9 +1718,9 @@ Callable* ImplementationVisitor::LookupCallable( } if (Generic* generic = Generic::DynamicCast(overloads[best])) { - result = GetOrCreateSpecialization( - SpecializationKey{generic, *generic->InferSpecializationTypes( - specialization_types, parameter_types)}); + result = GetOrCreateSpecialization(SpecializationKey{ + generic, *generic->InferSpecializationTypes(specialization_types, + parameter_types)}); } else { result = Callable::cast(overloads[best]); } @@ -1927,8 +1928,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, TypeVisitor::ComputeTypeVector(expr->generic_arguments)}); if (Builtin* builtin = Builtin::DynamicCast(specialization)) { DCHECK(!builtin->IsExternal()); return LocationReference::Temporary(GetBuiltinCode(builtin), @@ -1963,8 +1965,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()); } @@ -2542,10 +2544,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); diff --git a/src/torque/implementation-visitor.h b/src/torque/implementation-visitor.h index a572ebb936..2acea86f17 100644 --- a/src/torque/implementation-visitor.h +++ b/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,7 +53,8 @@ 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; } @@ -112,7 +114,8 @@ class LocationReference { const Type* ReferencedType() const { if (IsHeapReference()) { - return ReferenceType::cast(heap_reference().type())->referenced_type(); + return *StructType::MatchUnaryGeneric(heap_reference().type(), + TypeOracle::GetReferenceGeneric()); } return GetVisitResult().type(); } diff --git a/src/torque/instructions.cc b/src/torque/instructions.cc index 36a22ee8fa..e4d03c6db8 100644 --- a/src/torque/instructions.cc +++ b/src/torque/instructions.cc @@ -297,6 +297,7 @@ void CreateFieldReferenceInstruction::TypeInstruction( stack->Push(TypeOracle::GetIntPtrType()); } +// TODO(gsps): Remove in favor of a method on Reference void LoadReferenceInstruction::TypeInstruction(Stack* stack, ControlFlowGraph* cfg) const { ExpectType(TypeOracle::GetIntPtrType(), stack->Pop()); @@ -305,6 +306,7 @@ void LoadReferenceInstruction::TypeInstruction(Stack* stack, stack->Push(type); } +// TODO(gsps): Remove in favor of a method on Reference void StoreReferenceInstruction::TypeInstruction(Stack* stack, ControlFlowGraph* cfg) const { ExpectSubtype(stack->Pop(), type); diff --git a/src/torque/torque-parser.cc b/src/torque/torque-parser.cc index 0a371b79f9..ce86ff5cb3 100644 --- a/src/torque/torque-parser.cc +++ b/src/torque/torque-parser.cc @@ -879,7 +879,11 @@ base::Optional MakeFunctionTypeExpression( base::Optional MakeReferenceTypeExpression( ParseResultIterator* child_results) { auto referenced_type = child_results->NextAs(); - TypeExpression* result = MakeNode(referenced_type); + std::vector namespace_qualification{ + TORQUE_INTERNAL_NAMESPACE_STRING}; + std::vector generic_arguments{referenced_type}; + TypeExpression* result = MakeNode( + namespace_qualification, REFERENCE_TYPE_STRING, generic_arguments); return ParseResult{result}; } diff --git a/src/torque/type-oracle.cc b/src/torque/type-oracle.cc index 47331543fc..ec2324ff40 100644 --- a/src/torque/type-oracle.cc +++ b/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,39 @@ 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()); + // 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 = 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/src/torque/type-oracle.h b/src/torque/type-oracle.h index 405cb41e75..a319a7e75e 100644 --- a/src/torque/type-oracle.h +++ b/src/torque/type-oracle.h @@ -30,8 +30,11 @@ class TypeOracle : public ContextualClass { return result; } - static StructType* GetStructType(const std::string& name) { - StructType* result = new StructType(CurrentNamespace(), name); + static StructType* GetStructType( + const std::string& basename, + StructType::MaybeSpecializationKey specialized_from) { + StructType* result = + new StructType(CurrentNamespace(), basename, specialized_from); Get().aggregate_types_.push_back(std::unique_ptr(result)); return result; } @@ -60,8 +63,17 @@ class TypeOracle : public ContextualClass { 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 const StructType* GetReferenceType(const Type* referenced_type) { + return GetGenericStructTypeInstance(GetReferenceGeneric(), + {referenced_type}); } static const std::vector& @@ -245,7 +257,6 @@ class TypeOracle : public ContextualClass { Deduplicator function_pointer_types_; std::vector all_builtin_pointer_types_; Deduplicator union_types_; - Deduplicator reference_types_; std::vector> nominal_types_; std::vector> aggregate_types_; std::vector> top_types_; diff --git a/src/torque/type-visitor.cc b/src/torque/type-visitor.cc index 37be0df006..fedc0bb603 100644 --- a/src/torque/type-visitor.cc +++ b/src/torque/type-visitor.cc @@ -110,25 +110,12 @@ void DeclareMethods(AggregateType* container_type, } } -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(); - }); - } - return StructType::ComputeName(decl->name->value, args); -} -} // namespace - -const StructType* TypeVisitor::ComputeType(StructDeclaration* decl) { +const StructType* TypeVisitor::ComputeType( + StructDeclaration* decl, + StructType::MaybeSpecializationKey specialized_from) { CurrentSourcePosition::Scope position_activator(decl->pos); - StructType* struct_type = TypeOracle::GetStructType(ComputeStructName(decl)); + StructType* struct_type = + TypeOracle::GetStructType(decl->name->value, specialized_from); size_t offset = 0; for (auto& field : decl->fields) { CurrentSourcePosition::Scope position_activator( @@ -214,34 +201,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 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 +215,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; diff --git a/src/torque/type-visitor.h b/src/torque/type-visitor.h index 93de02b860..95f5e63e05 100644 --- a/src/torque/type-visitor.h +++ b/src/torque/type-visitor.h @@ -31,10 +31,13 @@ class TypeVisitor { 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/src/torque/types.cc b/src/torque/types.cc index 37a328b1dc..5ec7c93370 100644 --- a/src/torque/types.cc +++ b/src/torque/types.cc @@ -276,13 +276,14 @@ std::string StructType::GetGeneratedTypeNameImpl() const { } // static -std::string StructType::ComputeName(const std::string& basename, - const std::vector& 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 << basename_; + 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 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 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 AggregateType::Methods(const std::string& name) const { if (!is_finalized_) Finalize(); std::vector result; @@ -560,9 +598,6 @@ void AppendLoweredTypes(const Type* type, std::vector* 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); } diff --git a/src/torque/types.h b/src/torque/types.h index f6180c4250..77da82bea8 100644 --- a/src/torque/types.h +++ b/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 +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(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>; + 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; - static std::string ComputeName(const std::string& basename, - const std::vector& args); + static base::Optional MatchUnaryGeneric( + const Type* type, GenericStructType* generic); + static base::Optional 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 std::string& basename, + MaybeSpecializationKey specialized_from = base::nullopt) + : AggregateType(Kind::kStructType, nullptr, nspace, + ComputeName(basename, specialized_from)), + basename_(basename), + specialized_from_(specialized_from) {} void Finalize() const override { is_finalized_ = true; CheckForDuplicateFields(); } - const std::string& GetStructName() const { return name(); } + static std::string ComputeName(const std::string& basename, + MaybeSpecializationKey specialized_from); + + std::string basename_; + MaybeSpecializationKey specialized_from_; }; class TypeAlias; diff --git a/test/torque/test-torque.tq b/test/torque/test-torque.tq index 6d2aee1479..9f5867a5f5 100644 --- a/test/torque/test-torque.tq +++ b/test/torque/test-torque.tq @@ -898,7 +898,8 @@ namespace test { const ref:&Smi = & array.a; * ref = 3 + * ref; -- * ref; - Swap(& array.b, array.GetA()); + // TODO(gsps): Remove explicit type arg once inference works + Swap(& array.b, array.GetA()); check(array.a == 2); check(array.b == 9); } @@ -993,7 +994,7 @@ namespace test { const snd: T2; } - macro Swap(tuple: TestTuple): + macro TupleSwap(tuple: TestTuple): TestTuple { return TestTuple{fst: tuple.snd, snd: tuple.fst}; } @@ -1001,7 +1002,7 @@ namespace test { @export macro TestGenericStruct2(): TestTuple { const intptrAndSmi = TestTuple{fst: 1, snd: 2}; - const smiAndIntptr = Swap(intptrAndSmi); + const smiAndIntptr = TupleSwap(intptrAndSmi); check(intptrAndSmi.fst == smiAndIntptr.snd); check(intptrAndSmi.snd == smiAndIntptr.fst); return smiAndIntptr; diff --git a/test/unittests/torque/torque-unittest.cc b/test/unittests/torque/torque-unittest.cc index 1366f86ce7..22ee754321 100644 --- a/test/unittests/torque/torque-unittest.cc +++ b/test/unittests/torque/torque-unittest.cc @@ -20,6 +20,13 @@ constexpr const char* kTestTorquePrelude = R"( type void; type never; +namespace torque_internal { + struct Reference { + const object: HeapObject; + const offset: intptr; + } +} + type Tagged generates 'TNode' constexpr 'ObjectPtr'; type Smi extends Tagged generates 'TNode' constexpr 'Smi';