summaryrefslogtreecommitdiff
path: root/deps/v8/src/torque/implementation-visitor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/torque/implementation-visitor.cc')
-rw-r--r--deps/v8/src/torque/implementation-visitor.cc255
1 files changed, 133 insertions, 122 deletions
diff --git a/deps/v8/src/torque/implementation-visitor.cc b/deps/v8/src/torque/implementation-visitor.cc
index 8f36afd020..0c50a70099 100644
--- a/deps/v8/src/torque/implementation-visitor.cc
+++ b/deps/v8/src/torque/implementation-visitor.cc
@@ -526,7 +526,6 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
source_out() << " USE(" << parameter0 << ");\n";
for (size_t i = 1; i < signature.parameter_names.size(); ++i) {
- const std::string& parameter_name = signature.parameter_names[i]->value;
const Type* type = signature.types()[i];
const bool mark_as_used = signature.implicit_count > i;
std::string var = AddParameter(i, builtin, &parameters, &parameter_types,
@@ -534,8 +533,8 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
source_out() << " " << type->GetGeneratedTypeName() << " " << var
<< " = "
<< "UncheckedCast<" << type->GetGeneratedTNodeTypeName()
- << ">(Parameter(Descriptor::k"
- << CamelifyString(parameter_name) << "));\n";
+ << ">(Parameter(Descriptor::ParameterIndex<" << (i - 1)
+ << ">()));\n";
source_out() << " USE(" << var << ");\n";
}
}
@@ -1008,48 +1007,40 @@ const Type* ImplementationVisitor::Visit(AssertStatement* stmt) {
#if defined(DEBUG)
do_check = true;
#endif
- if (do_check) {
- // CSA_ASSERT & co. are not used here on purpose for two reasons. First,
- // Torque allows and handles two types of expressions in the if protocol
- // automagically, ones that return TNode<BoolT> and those that use the
- // BranchIf(..., Label* true, Label* false) idiom. Because the machinery to
- // handle this is embedded in the expression handling and to it's not
- // possible to make the decision to use CSA_ASSERT or CSA_ASSERT_BRANCH
- // isn't trivial up-front. Secondly, on failure, the assert text should be
- // the corresponding Torque code, not the -gen.cc code, which would be the
- // case when using CSA_ASSERT_XXX.
- Block* true_block = assembler().NewBlock(assembler().CurrentStack());
- Block* false_block = assembler().NewBlock(assembler().CurrentStack(), true);
- GenerateExpressionBranch(stmt->expression, true_block, false_block);
+ Block* resume_block;
+
+ if (!do_check) {
+ Block* unreachable_block = assembler().NewBlock(assembler().CurrentStack());
+ resume_block = assembler().NewBlock(assembler().CurrentStack());
+ assembler().Goto(resume_block);
+ assembler().Bind(unreachable_block);
+ }
+
+ // CSA_ASSERT & co. are not used here on purpose for two reasons. First,
+ // Torque allows and handles two types of expressions in the if protocol
+ // automagically, ones that return TNode<BoolT> and those that use the
+ // BranchIf(..., Label* true, Label* false) idiom. Because the machinery to
+ // handle this is embedded in the expression handling and to it's not
+ // possible to make the decision to use CSA_ASSERT or CSA_ASSERT_BRANCH
+ // isn't trivial up-front. Secondly, on failure, the assert text should be
+ // the corresponding Torque code, not the -gen.cc code, which would be the
+ // case when using CSA_ASSERT_XXX.
+ Block* true_block = assembler().NewBlock(assembler().CurrentStack());
+ Block* false_block = assembler().NewBlock(assembler().CurrentStack(), true);
+ GenerateExpressionBranch(stmt->expression, true_block, false_block);
- assembler().Bind(false_block);
+ assembler().Bind(false_block);
- assembler().Emit(AbortInstruction{
- AbortInstruction::Kind::kAssertionFailure,
- "Torque assert '" + FormatAssertSource(stmt->source) + "' failed"});
+ assembler().Emit(AbortInstruction{
+ AbortInstruction::Kind::kAssertionFailure,
+ "Torque assert '" + FormatAssertSource(stmt->source) + "' failed"});
- assembler().Bind(true_block);
- } else {
- // Visit the expression so bindings only used in asserts are marked
- // as such. Otherwise they might be wrongly reported as unused bindings
- // in release builds.
- stmt->expression->VisitAllSubExpressions([](Expression* expression) {
- if (auto id = IdentifierExpression::DynamicCast(expression)) {
- ValueBindingsManager::Get().TryLookup(id->name->value);
- } else if (auto call = CallExpression::DynamicCast(expression)) {
- for (Identifier* label : call->labels) {
- LabelBindingsManager::Get().TryLookup(label->value);
- }
- // TODO(szuend): In case the call expression resolves to a macro
- // callable, mark the macro as used as well.
- } else if (auto call = CallMethodExpression::DynamicCast(expression)) {
- for (Identifier* label : call->labels) {
- LabelBindingsManager::Get().TryLookup(label->value);
- }
- // TODO(szuend): Mark the underlying macro as used.
- }
- });
+ assembler().Bind(true_block);
+
+ if (!do_check) {
+ assembler().Bind(resume_block);
}
+
return TypeOracle::GetVoidType();
}
@@ -1214,16 +1205,16 @@ InitializerResults ImplementationVisitor::VisitInitializerResults(
result.names.push_back(initializer.name);
Expression* e = initializer.expression;
const Field& field = class_type->LookupField(initializer.name->value);
- auto field_index = field.index;
+ bool has_index = field.index.has_value();
if (SpreadExpression* s = SpreadExpression::DynamicCast(e)) {
- if (!field_index) {
+ if (!has_index) {
ReportError(
"spread expressions can only be used to initialize indexed class "
"fields ('",
initializer.name->value, "' is not)");
}
e = s->spreadee;
- } else if (field_index) {
+ } else if (has_index) {
ReportError("the indexed class field '", initializer.name->value,
"' must be initialized with a spread operator");
}
@@ -1261,7 +1252,7 @@ void ImplementationVisitor::InitializeClass(
void ImplementationVisitor::InitializeFieldFromSpread(
VisitResult object, const Field& field,
const InitializerResults& initializer_results) {
- NameAndType index = (*field.index)->name_and_type;
+ const NameAndType& index = *field.index;
VisitResult iterator =
initializer_results.field_value_map.at(field.name_and_type.name);
VisitResult length = initializer_results.field_value_map.at(index.name);
@@ -1289,15 +1280,14 @@ VisitResult ImplementationVisitor::AddVariableObjectSize(
}
VisitResult index_field_size =
VisitResult(TypeOracle::GetConstInt31Type(), "kTaggedSize");
- VisitResult initializer_value = initializer_results.field_value_map.at(
- (*current_field->index)->name_and_type.name);
+ VisitResult initializer_value =
+ initializer_results.field_value_map.at(current_field->index->name);
Arguments args;
args.parameters.push_back(object_size);
args.parameters.push_back(initializer_value);
args.parameters.push_back(index_field_size);
- object_size =
- GenerateCall("%AddIndexedFieldSizeToObjectSize", args,
- {(*current_field->index)->name_and_type.type}, false);
+ object_size = GenerateCall("%AddIndexedFieldSizeToObjectSize", args,
+ {current_field->index->type}, false);
}
++current_field;
}
@@ -1860,12 +1850,12 @@ LocationReference ImplementationVisitor::GetLocationReference(
{
StackScope length_scope(this);
// Get a reference to the length
- const Field* index_field = field.index.value();
+ const NameAndType& index_field = field.index.value();
GenerateCopy(object_result);
- assembler().Emit(CreateFieldReferenceInstruction{
- object_result.type(), index_field->name_and_type.name});
+ assembler().Emit(CreateFieldReferenceInstruction{object_result.type(),
+ index_field.name});
VisitResult length_reference(
- TypeOracle::GetReferenceType(index_field->name_and_type.type),
+ TypeOracle::GetReferenceType(index_field.type),
assembler().TopRange(2));
// Load the length from the reference and convert it to intptr
@@ -2670,13 +2660,34 @@ void ImplementationVisitor::Visit(Declarable* declarable) {
}
}
-void ImplementationVisitor::GenerateBuiltinDefinitions(
+std::string MachineTypeString(const Type* type) {
+ if (type->IsSubtypeOf(TypeOracle::GetSmiType())) {
+ return "MachineType::TaggedSigned()";
+ }
+ if (type->IsSubtypeOf(TypeOracle::GetHeapObjectType())) {
+ return "MachineType::TaggedPointer()";
+ }
+ if (type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
+ return "MachineType::AnyTagged()";
+ }
+ return "MachineTypeOf<" + type->GetGeneratedTNodeTypeName() + ">::value";
+}
+
+void ImplementationVisitor::GenerateBuiltinDefinitionsAndInterfaceDescriptors(
const std::string& output_directory) {
- std::stringstream new_contents_stream;
- std::string file_name = "builtin-definitions-tq.h";
+ std::stringstream builtin_definitions;
+ std::string builtin_definitions_file_name = "builtin-definitions-tq.h";
+
+ // This file contains plain interface descriptor definitions and has to be
+ // included in the middle of interface-descriptors.h. Thus it is not a normal
+ // header file and uses the .inc suffix instead of the .h suffix.
+ std::stringstream interface_descriptors;
+ std::string interface_descriptors_file_name = "interface-descriptors-tq.inc";
{
- IncludeGuardScope include_guard(new_contents_stream, file_name);
- new_contents_stream
+ IncludeGuardScope builtin_definitions_include_guard(
+ builtin_definitions, builtin_definitions_file_name);
+
+ builtin_definitions
<< "\n"
"#define BUILTIN_LIST_FROM_TORQUE(CPP, TFJ, TFC, TFS, TFH, "
"ASM) "
@@ -2684,40 +2695,67 @@ void ImplementationVisitor::GenerateBuiltinDefinitions(
for (auto& declarable : GlobalContext::AllDeclarables()) {
Builtin* builtin = Builtin::DynamicCast(declarable.get());
if (!builtin || builtin->IsExternal()) continue;
- size_t firstParameterIndex = 1;
- bool declareParameters = true;
if (builtin->IsStub()) {
- new_contents_stream << "TFS(" << builtin->ExternalName();
+ builtin_definitions << "TFC(" << builtin->ExternalName() << ", "
+ << builtin->ExternalName();
+ std::string descriptor_name = builtin->ExternalName() + "Descriptor";
+ constexpr size_t kFirstNonContextParameter = 1;
+ size_t parameter_count =
+ builtin->parameter_names().size() - kFirstNonContextParameter;
+
+ interface_descriptors << "class " << descriptor_name
+ << " : public TorqueInterfaceDescriptor<"
+ << parameter_count << "> {\n";
+ interface_descriptors << " DECLARE_DESCRIPTOR_WITH_BASE("
+ << descriptor_name
+ << ", TorqueInterfaceDescriptor)\n";
+
+ interface_descriptors << " MachineType ReturnType() override {\n";
+ interface_descriptors
+ << " return "
+ << MachineTypeString(builtin->signature().return_type) << ";\n";
+ interface_descriptors << " }\n";
+
+ interface_descriptors << " std::array<MachineType, " << parameter_count
+ << "> ParameterTypes() override {\n";
+ interface_descriptors << " return {";
+ for (size_t i = kFirstNonContextParameter;
+ i < builtin->parameter_names().size(); ++i) {
+ bool last = i + 1 == builtin->parameter_names().size();
+ const Type* type = builtin->signature().parameter_types.types[i];
+ interface_descriptors << MachineTypeString(type)
+ << (last ? "" : ", ");
+ }
+ interface_descriptors << "};\n";
+
+ interface_descriptors << " }\n";
+ interface_descriptors << "};\n\n";
} else {
- new_contents_stream << "TFJ(" << builtin->ExternalName();
+ builtin_definitions << "TFJ(" << builtin->ExternalName();
if (builtin->IsVarArgsJavaScript()) {
- new_contents_stream
+ builtin_definitions
<< ", SharedFunctionInfo::kDontAdaptArgumentsSentinel";
- declareParameters = false;
} else {
DCHECK(builtin->IsFixedArgsJavaScript());
// FixedArg javascript builtins need to offer the parameter
// count.
int parameter_count =
static_cast<int>(builtin->signature().ExplicitCount());
- new_contents_stream << ", " << parameter_count;
+ builtin_definitions << ", " << parameter_count;
// And the receiver is explicitly declared.
- new_contents_stream << ", kReceiver";
- firstParameterIndex = builtin->signature().implicit_count;
- }
- }
- if (declareParameters) {
- for (size_t i = firstParameterIndex;
- i < builtin->parameter_names().size(); ++i) {
- Identifier* parameter = builtin->parameter_names()[i];
- new_contents_stream << ", k" << CamelifyString(parameter->value);
+ builtin_definitions << ", kReceiver";
+ for (size_t i = builtin->signature().implicit_count;
+ i < builtin->parameter_names().size(); ++i) {
+ Identifier* parameter = builtin->parameter_names()[i];
+ builtin_definitions << ", k" << CamelifyString(parameter->value);
+ }
}
}
- new_contents_stream << ") \\\n";
+ builtin_definitions << ") \\\n";
}
- new_contents_stream << "\n";
+ builtin_definitions << "\n";
- new_contents_stream
+ builtin_definitions
<< "#define TORQUE_FUNCTION_POINTER_TYPE_TO_BUILTIN_MAP(V) \\\n";
for (const BuiltinPointerType* type :
TypeOracle::AllBuiltinPointerTypes()) {
@@ -2728,13 +2766,15 @@ void ImplementationVisitor::GenerateBuiltinDefinitions(
SourcePosition{CurrentSourceFile::Get(), {-1, -1}, {-1, -1}});
ReportError("unable to find any builtin with type \"", *type, "\"");
}
- new_contents_stream << " V(" << type->function_pointer_type_id() << ","
+ builtin_definitions << " V(" << type->function_pointer_type_id() << ","
<< example_builtin->ExternalName() << ")\\\n";
}
- new_contents_stream << "\n";
+ builtin_definitions << "\n";
}
- std::string new_contents(new_contents_stream.str());
- WriteFile(output_directory + "/" + file_name, new_contents);
+ WriteFile(output_directory + "/" + builtin_definitions_file_name,
+ builtin_definitions.str());
+ WriteFile(output_directory + "/" + interface_descriptors_file_name,
+ interface_descriptors.str());
}
namespace {
@@ -2894,40 +2934,8 @@ class MacroFieldOffsetsGenerator : public FieldOffsetsGenerator {
private:
std::ostream& out_;
};
-} // namespace
-
-void ImplementationVisitor::GenerateInstanceTypes(
- const std::string& output_directory) {
- std::stringstream header;
- std::string file_name = "instance-types-tq.h";
- {
- IncludeGuardScope(header, file_name);
- header << "#define TORQUE_DEFINED_INSTANCE_TYPES(V) \\\n";
- for (const TypeAlias* alias : GlobalContext::GetClasses()) {
- const ClassType* type = ClassType::DynamicCast(alias->type());
- if (type->IsExtern()) continue;
- std::string type_name =
- CapifyStringWithUnderscores(type->name()) + "_TYPE";
- header << " V(" << type_name << ") \\\n";
- }
- header << "\n\n";
-
- header << "#define TORQUE_STRUCT_LIST_GENERATOR(V, _) \\\n";
- for (const TypeAlias* alias : GlobalContext::GetClasses()) {
- const ClassType* type = ClassType::DynamicCast(alias->type());
- if (type->IsExtern()) continue;
- std::string type_name =
- CapifyStringWithUnderscores(type->name()) + "_TYPE";
- std::string variable_name = SnakeifyString(type->name());
- header << " V(_, " << type_name << ", " << type->name() << ", "
- << variable_name << ") \\\n";
- }
- header << "\n";
- }
- std::string output_header_path = output_directory + "/" + file_name;
- WriteFile(output_header_path, header.str());
-}
+} // namespace
void ImplementationVisitor::GenerateCppForInternalClasses(
const std::string& output_directory) {
@@ -3148,7 +3156,7 @@ void CppClassGenerator::GenerateClassConstructors() {
if (type_->IsInstantiatedAbstractClass()) {
// This is a hack to prevent wrong instance type checks.
inl_ << " // Instance check omitted because class is annotated with "
- "@dirtyInstantiatedAbstractClass.\n";
+ << ANNOTATION_INSTANTIATED_ABSTRACT_CLASS << ".\n";
} else {
inl_ << " SLOW_DCHECK(this->Is" << name_ << "());\n";
}
@@ -3241,7 +3249,8 @@ void CppClassGenerator::GenerateFieldAccessorForObject(const Field& f) {
const std::string offset = "k" + CamelifyString(name) + "Offset";
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)->GetGeneratedTNodeTypeName() : "Object";
// Generate declarations in header.
if (!class_type && field_type != TypeOracle::GetObjectType()) {
@@ -3302,7 +3311,6 @@ void ImplementationVisitor::GenerateClassDefinitions(
{
IncludeGuardScope header_guard(header, basename + ".h");
- header << "#include \"src/objects/heap-number.h\"\n";
header << "#include \"src/objects/objects.h\"\n";
header << "#include \"src/objects/smi.h\"\n";
header << "#include \"torque-generated/field-offsets-tq.h\"\n";
@@ -3314,9 +3322,11 @@ 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/js-promise.h\"\n";
+ inline_header << "#include \"src/objects/js-weak-refs.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";
+ inline_header << "#include \"src/objects/script.h\"\n";
+ inline_header << "#include \"src/objects/shared-function-info.h\"\n\n";
IncludeObjectMacrosScope inline_header_macros(inline_header);
NamespaceScope inline_header_namespaces(inline_header, {"v8", "internal"});
@@ -3328,6 +3338,7 @@ void ImplementationVisitor::GenerateClassDefinitions(
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-weak-refs-inl.h\"\n";
implementation
<< "#include \"src/objects/js-regexp-string-iterator-inl.h\"\n";
implementation << "#include \"src/objects/literal-objects-inl.h\"\n";
@@ -3346,7 +3357,7 @@ void ImplementationVisitor::GenerateClassDefinitions(
// Generate forward declarations for every class.
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
const ClassType* type = ClassType::DynamicCast(alias->type());
- header << "class " << type->name() << ";\n";
+ header << "class " << type->GetGeneratedTNodeTypeName() << ";\n";
}
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
@@ -3439,13 +3450,13 @@ void GenerateClassFieldVerifier(const std::string& class_name,
if (!field_type->IsSubtypeOf(TypeOracle::GetObjectType())) return;
if (f.index) {
- if ((*f.index)->name_and_type.type != TypeOracle::GetSmiType()) {
+ if (f.index->type != TypeOracle::GetSmiType()) {
ReportError("Non-SMI values are not (yet) supported as indexes.");
}
// We already verified the index field because it was listed earlier, so we
// can assume it's safe to read here.
cc_contents << " for (int i = 0; i < TaggedField<Smi, " << class_name
- << "::k" << CamelifyString((*f.index)->name_and_type.name)
+ << "::k" << CamelifyString(f.index->name)
<< "Offset>::load(o).value(); ++i) {\n";
} else {
cc_contents << " {\n";