[torque] Replace ReferenceType by generic Torque struct Reference<T>

This CL removes the built-in reference type in favor of a Torque-implemented generic struct, i.e., internal::Reference<T>. It also adds various infrastructure for getting and creating new generic struct instances, as well as matching against them.

R=tebbi@chromium.org

Change-Id: I1e3d6afe355a0603fa9c3ad789c6b8a97d1b3c26
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1718148
Commit-Queue: Georg Schmid <gsps@google.com>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62939}
This commit is contained in:
Georg Schmid 2019-07-26 15:30:02 +02:00 committed by Commit Bot
parent 0a424ac1a5
commit 35a613555c
22 changed files with 199 additions and 173 deletions

View File

@ -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",

View File

@ -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<T: type> {
const object: HeapObject;
const offset: intptr;
}
} // namespace torque_internal

View File

@ -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<HeapObject> object;
TNode<IntPtrT> offset;

View File

@ -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)

View File

@ -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)) ==

View File

@ -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()

View File

@ -74,11 +74,7 @@ base::Optional<const Type*> 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;
}

View File

@ -505,11 +505,6 @@ class Generic : public Declarable {
SpecializationMap<Callable> specializations_;
};
struct SpecializationKey {
Generic* generic;
TypeVector specialized_types;
};
class GenericStructType : public Declarable {
public:
DECLARE_DECLARABLE_BOILERPLATE(GenericStructType, generic_type)

View File

@ -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>{
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>{
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<Generic>{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<Generic>& 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<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.
@ -299,7 +301,8 @@ Signature DeclarationVisitor::MakeSpecializedSignature(
key.generic->declaration()->callable->signature.get());
}
Callable* DeclarationVisitor::SpecializeImplicit(const SpecializationKey& key) {
Callable* DeclarationVisitor::SpecializeImplicit(
const SpecializationKey<Generic>& 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<Generic>& key, CallableNode* declaration,
base::Optional<const CallableNodeSignature*> signature,
base::Optional<Statement*> body, SourcePosition position) {
CurrentSourcePosition::Scope pos_scope(position);

View File

@ -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<Generic>& key);
static Callable* SpecializeImplicit(const SpecializationKey<Generic>& key);
static Callable* Specialize(
const SpecializationKey& key, CallableNode* declaration,
const SpecializationKey<Generic>& key, CallableNode* declaration,
base::Optional<const CallableNodeSignature*> signature,
base::Optional<Statement*> body, SourcePosition position);
private:
static void DeclareSpecializedTypes(const SpecializationKey& key);
static void DeclareSpecializedTypes(const SpecializationKey<Generic>& key);
};
} // namespace torque

View File

@ -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<Generic>& key) {
if (base::Optional<Callable*> 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>{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, *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>{
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);

View File

@ -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();
}

View File

@ -297,6 +297,7 @@ void CreateFieldReferenceInstruction::TypeInstruction(
stack->Push(TypeOracle::GetIntPtrType());
}
// TODO(gsps): Remove in favor of a method on Reference<T>
void LoadReferenceInstruction::TypeInstruction(Stack<const Type*>* stack,
ControlFlowGraph* cfg) const {
ExpectType(TypeOracle::GetIntPtrType(), stack->Pop());
@ -305,6 +306,7 @@ void LoadReferenceInstruction::TypeInstruction(Stack<const Type*>* stack,
stack->Push(type);
}
// TODO(gsps): Remove in favor of a method on Reference<T>
void StoreReferenceInstruction::TypeInstruction(Stack<const Type*>* stack,
ControlFlowGraph* cfg) const {
ExpectSubtype(stack->Pop(), type);

View File

@ -879,7 +879,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};
}

View File

@ -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

View File

@ -30,8 +30,11 @@ class TypeOracle : public ContextualClass<TypeOracle> {
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<StructType>(result));
return result;
}
@ -60,8 +63,17 @@ 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 const StructType* GetReferenceType(const Type* referenced_type) {
return GetGenericStructTypeInstance(GetReferenceGeneric(),
{referenced_type});
}
static const std::vector<const BuiltinPointerType*>&
@ -245,7 +257,6 @@ 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_;

View File

@ -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<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 +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;

View File

@ -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);
};

View File

@ -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 << 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<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;
@ -560,9 +598,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);
}

View File

@ -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;
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 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;

View File

@ -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<Smi>(& array.b, array.GetA());
check(array.a == 2);
check(array.b == 9);
}
@ -993,7 +994,7 @@ namespace test {
const snd: T2;
}
macro Swap<T1: type, T2: type>(tuple: TestTuple<T1, T2>):
macro TupleSwap<T1: type, T2: type>(tuple: TestTuple<T1, T2>):
TestTuple<T2, T1> {
return TestTuple<T2, T1>{fst: tuple.snd, snd: tuple.fst};
}
@ -1001,7 +1002,7 @@ namespace test {
@export
macro TestGenericStruct2(): TestTuple<Smi, intptr> {
const intptrAndSmi = TestTuple<intptr, Smi>{fst: 1, snd: 2};
const smiAndIntptr = Swap<intptr, Smi>(intptrAndSmi);
const smiAndIntptr = TupleSwap<intptr, Smi>(intptrAndSmi);
check(intptrAndSmi.fst == smiAndIntptr.snd);
check(intptrAndSmi.snd == smiAndIntptr.fst);
return smiAndIntptr;

View File

@ -20,6 +20,13 @@ constexpr const char* kTestTorquePrelude = R"(
type void;
type never;
namespace torque_internal {
struct Reference<T: type> {
const object: HeapObject;
const offset: intptr;
}
}
type Tagged generates 'TNode<Object>' constexpr 'ObjectPtr';
type Smi extends Tagged generates 'TNode<Smi>' constexpr 'Smi';