Commit b5ab5c7b authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[torque] allow builtins without context parameter

Bug: v8:10404, v8:7793
Change-Id: I7ed5fc790bd97af0dd3671669779e416101731ce
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2162877
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67435}
parent 2ce3a8e9
...@@ -494,9 +494,9 @@ extern transitioning macro ToThisValue(implicit context: Context)( ...@@ -494,9 +494,9 @@ extern transitioning macro ToThisValue(implicit context: Context)(
extern transitioning macro GetProperty(implicit context: Context)( extern transitioning macro GetProperty(implicit context: Context)(
JSAny, JSAny): JSAny; JSAny, JSAny): JSAny;
extern transitioning builtin SetProperty(implicit context: Context)( extern transitioning builtin SetProperty(implicit context: Context)(
JSAny, JSAny, JSAny); JSAny, JSAny, JSAny): JSAny;
extern transitioning builtin SetPropertyInLiteral(implicit context: Context)( extern transitioning builtin SetPropertyInLiteral(implicit context: Context)(
JSAny, JSAny, JSAny); JSAny, JSAny, JSAny): JSAny;
extern transitioning builtin DeleteProperty(implicit context: Context)( extern transitioning builtin DeleteProperty(implicit context: Context)(
JSAny, JSAny | PrivateSymbol, LanguageModeSmi): Boolean; JSAny, JSAny | PrivateSymbol, LanguageModeSmi): Boolean;
extern transitioning builtin HasProperty(implicit context: Context)( extern transitioning builtin HasProperty(implicit context: Context)(
......
...@@ -46,8 +46,6 @@ namespace iterator { ...@@ -46,8 +46,6 @@ namespace iterator {
extern macro IteratorBuiltinsAssembler::StringListFromIterable( extern macro IteratorBuiltinsAssembler::StringListFromIterable(
implicit context: Context)(JSAny): JSArray; implicit context: Context)(JSAny): JSArray;
extern builtin IterableToListMayPreserveHoles(implicit context:
Context)(JSAny, JSAny);
extern builtin IterableToListWithSymbolLookup(implicit context: extern builtin IterableToListWithSymbolLookup(implicit context:
Context)(JSAny): JSArray; Context)(JSAny): JSArray;
extern builtin IterableToFixedArrayWithSymbolLookupSlow( extern builtin IterableToFixedArrayWithSymbolLookupSlow(
......
...@@ -127,7 +127,7 @@ namespace typed_array { ...@@ -127,7 +127,7 @@ namespace typed_array {
const work2: FixedArray = AllocateZeroedFixedArray(Convert<intptr>(len)); const work2: FixedArray = AllocateZeroedFixedArray(Convert<intptr>(len));
for (let i: uintptr = 0; i < len; ++i) { for (let i: uintptr = 0; i < len; ++i) {
const element: Numeric = accessor.LoadNumeric(context, array, i); const element: Numeric = accessor.LoadNumeric(array, i);
work1.objects[i] = element; work1.objects[i] = element;
work2.objects[i] = element; work2.objects[i] = element;
} }
......
...@@ -81,7 +81,7 @@ namespace typed_array { ...@@ -81,7 +81,7 @@ namespace typed_array {
Context, JSTypedArray, uintptr, JSAny, Context, JSTypedArray, uintptr, JSAny,
constexpr ElementsKind) labels IfDetached; constexpr ElementsKind) labels IfDetached;
type LoadNumericFn = builtin(Context, JSTypedArray, uintptr) => Numeric; type LoadNumericFn = builtin(JSTypedArray, uintptr) => Numeric;
type StoreNumericFn = builtin(Context, JSTypedArray, uintptr, Numeric) => Smi; type StoreNumericFn = builtin(Context, JSTypedArray, uintptr, Numeric) => Smi;
type StoreJSAnyFn = builtin(Context, JSTypedArray, uintptr, JSAny) => Smi; type StoreJSAnyFn = builtin(Context, JSTypedArray, uintptr, JSAny) => Smi;
...@@ -90,10 +90,9 @@ namespace typed_array { ...@@ -90,10 +90,9 @@ namespace typed_array {
const kStoreFailureArrayDetached: Smi = 1; const kStoreFailureArrayDetached: Smi = 1;
struct TypedArrayAccessor { struct TypedArrayAccessor {
macro LoadNumeric( macro LoadNumeric(array: JSTypedArray, index: uintptr): Numeric {
context: Context, array: JSTypedArray, index: uintptr): Numeric {
const loadfn: LoadNumericFn = this.loadNumericFn; const loadfn: LoadNumericFn = this.loadNumericFn;
return loadfn(context, array, index); return loadfn(array, index);
} }
macro StoreNumeric( macro StoreNumeric(
...@@ -189,7 +188,7 @@ namespace typed_array { ...@@ -189,7 +188,7 @@ namespace typed_array {
macro Load(implicit context: Context)(k: uintptr): JSAny { macro Load(implicit context: Context)(k: uintptr): JSAny {
const lf: LoadNumericFn = this.loadfn; const lf: LoadNumericFn = this.loadfn;
return lf(context, this.unstable, k); return lf(this.unstable, k);
} }
stable: JSTypedArray; stable: JSTypedArray;
...@@ -245,7 +244,7 @@ namespace typed_array { ...@@ -245,7 +244,7 @@ namespace typed_array {
} }
builtin LoadTypedElement<T : type extends ElementsKind>( builtin LoadTypedElement<T : type extends ElementsKind>(
_context: Context, array: JSTypedArray, index: uintptr): Numeric { array: JSTypedArray, index: uintptr): Numeric {
return LoadFixedTypedArrayElementAsTagged( return LoadFixedTypedArrayElementAsTagged(
array.data_ptr, index, KindForArrayType<T>()); array.data_ptr, index, KindForArrayType<T>());
} }
......
...@@ -520,10 +520,12 @@ class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor { ...@@ -520,10 +520,12 @@ class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor {
}; };
// This class is subclassed by Torque-generated call interface descriptors. // This class is subclassed by Torque-generated call interface descriptors.
template <int parameter_count> template <int parameter_count, bool has_context_parameter>
class TorqueInterfaceDescriptor : public CallInterfaceDescriptor { class TorqueInterfaceDescriptor : public CallInterfaceDescriptor {
public: public:
static constexpr int kDescriptorFlags = CallInterfaceDescriptorData::kNoFlags; static constexpr int kDescriptorFlags =
has_context_parameter ? CallInterfaceDescriptorData::kNoFlags
: CallInterfaceDescriptorData::kNoContext;
static constexpr int kParameterCount = parameter_count; static constexpr int kParameterCount = parameter_count;
enum ParameterIndices { kContext = kParameterCount }; enum ParameterIndices { kContext = kParameterCount };
template <int i> template <int i>
......
...@@ -512,8 +512,14 @@ void CSAGenerator::EmitInstruction(const CallBuiltinInstruction& instruction, ...@@ -512,8 +512,14 @@ void CSAGenerator::EmitInstruction(const CallBuiltinInstruction& instruction,
LowerType(instruction.builtin->signature().return_type); LowerType(instruction.builtin->signature().return_type);
if (instruction.is_tailcall) { if (instruction.is_tailcall) {
out() << " CodeStubAssembler(state_).TailCallBuiltin(Builtins::k" out() << " CodeStubAssembler(state_).TailCallBuiltin(Builtins::k"
<< instruction.builtin->ExternalName() << ", "; << instruction.builtin->ExternalName();
PrintCommaSeparatedList(out(), arguments); if (!instruction.builtin->signature().HasContextParameter()) {
// Add dummy context parameter to satisfy the TailCallBuiltin signature.
out() << ", TNode<Object>()";
}
for (const std::string& argument : arguments) {
out() << ", " << argument;
}
out() << ");\n"; out() << ");\n";
} else { } else {
std::string result_name; std::string result_name;
...@@ -525,25 +531,24 @@ void CSAGenerator::EmitInstruction(const CallBuiltinInstruction& instruction, ...@@ -525,25 +531,24 @@ void CSAGenerator::EmitInstruction(const CallBuiltinInstruction& instruction,
std::string catch_name = std::string catch_name =
PreCallableExceptionPreparation(instruction.catch_block); PreCallableExceptionPreparation(instruction.catch_block);
Stack<std::string> pre_call_stack = *stack; Stack<std::string> pre_call_stack = *stack;
if (result_types.size() == 1) {
std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName(); DCHECK_EQ(1, result_types.size());
stack->Push(result_name); std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
out() << " " << result_name << " = "; stack->Push(result_name);
if (generated_type != "Object") out() << "TORQUE_CAST("; out() << " " << result_name << " = ";
out() << "CodeStubAssembler(state_).CallBuiltin(Builtins::k" if (generated_type != "Object") out() << "TORQUE_CAST(";
<< instruction.builtin->ExternalName() << ", "; out() << "CodeStubAssembler(state_).CallBuiltin(Builtins::k"
PrintCommaSeparatedList(out(), arguments); << instruction.builtin->ExternalName();
if (generated_type != "Object") out() << ")"; if (!instruction.builtin->signature().HasContextParameter()) {
out() << ");\n"; // Add dummy context parameter to satisfy the CallBuiltin signature.
} else { out() << ", TNode<Object>()";
DCHECK_EQ(0, result_types.size()); }
// TODO(tebbi): Actually, builtins have to return a value, so we should for (const std::string& argument : arguments) {
// not have to handle this case. out() << ", " << argument;
out() << " CodeStubAssembler(state_).CallBuiltin(Builtins::k"
<< instruction.builtin->ExternalName() << ", ";
PrintCommaSeparatedList(out(), arguments);
out() << ");\n";
} }
if (generated_type != "Object") out() << ")";
out() << ");\n";
PostCallableExceptionPreparation( PostCallableExceptionPreparation(
catch_name, catch_name,
result_types.size() == 0 ? TypeOracle::GetVoidType() : result_types[0], result_types.size() == 0 ? TypeOracle::GetVoidType() : result_types[0],
...@@ -555,8 +560,8 @@ void CSAGenerator::EmitInstruction(const CallBuiltinInstruction& instruction, ...@@ -555,8 +560,8 @@ void CSAGenerator::EmitInstruction(const CallBuiltinInstruction& instruction,
void CSAGenerator::EmitInstruction( void CSAGenerator::EmitInstruction(
const CallBuiltinPointerInstruction& instruction, const CallBuiltinPointerInstruction& instruction,
Stack<std::string>* stack) { Stack<std::string>* stack) {
std::vector<std::string> function_and_arguments = std::vector<std::string> arguments = stack->PopMany(instruction.argc);
stack->PopMany(1 + instruction.argc); std::string function = stack->Pop();
std::vector<const Type*> result_types = std::vector<const Type*> result_types =
LowerType(instruction.type->return_type()); LowerType(instruction.type->return_type());
if (result_types.size() != 1) { if (result_types.size() != 1) {
...@@ -576,8 +581,15 @@ void CSAGenerator::EmitInstruction( ...@@ -576,8 +581,15 @@ void CSAGenerator::EmitInstruction(
"CallableFor(ca_." "CallableFor(ca_."
"isolate()," "isolate(),"
"ExampleBuiltinForTorqueFunctionPointerType(" "ExampleBuiltinForTorqueFunctionPointerType("
<< instruction.type->function_pointer_type_id() << ")).descriptor(), "; << instruction.type->function_pointer_type_id() << ")).descriptor(), "
PrintCommaSeparatedList(out(), function_and_arguments); << function;
if (!instruction.type->HasContextParameter()) {
// Add dummy context parameter to satisfy the CallBuiltinPointer signature.
out() << ", TNode<Object>()";
}
for (const std::string& argument : arguments) {
out() << ", " << argument;
}
out() << ")"; out() << ")";
if (generated_type != "Object") out() << ")"; if (generated_type != "Object") out() << ")";
out() << ";\n"; out() << ";\n";
......
...@@ -103,6 +103,10 @@ Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl, ...@@ -103,6 +103,10 @@ Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl,
*signature.return_type, "."); *signature.return_type, ".");
} }
if (signature.return_type == TypeOracle::GetVoidType()) {
Error("Builtins cannot have return type void.");
}
return Declarations::CreateBuiltin(std::move(external_name), return Declarations::CreateBuiltin(std::move(external_name),
std::move(readable_name), kind, std::move(readable_name), kind,
std::move(signature), body); std::move(signature), body);
......
...@@ -530,17 +530,8 @@ void ImplementationVisitor::Visit(Builtin* builtin) { ...@@ -530,17 +530,8 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
} else { } else {
DCHECK(builtin->IsStub()); DCHECK(builtin->IsStub());
// Context bool has_context_parameter = signature.HasContextParameter();
const bool context_is_implicit = signature.implicit_count > 0; for (size_t i = 0; i < signature.parameter_names.size(); ++i) {
std::string parameter0 =
AddParameter(0, builtin, &parameters, &parameter_types,
&parameter_bindings, context_is_implicit);
source_out() << " TNode<Context> " << parameter0
<< " = UncheckedCast<Context>(Parameter("
<< "Descriptor::kContext));\n";
source_out() << " USE(" << parameter0 << ");\n";
for (size_t i = 1; i < signature.parameter_names.size(); ++i) {
const Type* type = signature.types()[i]; const Type* type = signature.types()[i];
const bool mark_as_used = signature.implicit_count > i; const bool mark_as_used = signature.implicit_count > i;
std::string var = AddParameter(i, builtin, &parameters, &parameter_types, std::string var = AddParameter(i, builtin, &parameters, &parameter_types,
...@@ -548,8 +539,14 @@ void ImplementationVisitor::Visit(Builtin* builtin) { ...@@ -548,8 +539,14 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
source_out() << " " << type->GetGeneratedTypeName() << " " << var source_out() << " " << type->GetGeneratedTypeName() << " " << var
<< " = " << " = "
<< "UncheckedCast<" << type->GetGeneratedTNodeTypeName() << "UncheckedCast<" << type->GetGeneratedTNodeTypeName()
<< ">(Parameter(Descriptor::ParameterIndex<" << (i - 1) << ">(Parameter(";
<< ">()));\n"; if (i == 0 && has_context_parameter) {
source_out() << "Descriptor::kContext";
} else {
source_out() << "Descriptor::ParameterIndex<"
<< (has_context_parameter ? i - 1 : i) << ">()";
}
source_out() << "));\n";
source_out() << " USE(" << var << ");\n"; source_out() << " USE(" << var << ");\n";
} }
} }
...@@ -2980,13 +2977,15 @@ void ImplementationVisitor::GenerateBuiltinDefinitionsAndInterfaceDescriptors( ...@@ -2980,13 +2977,15 @@ void ImplementationVisitor::GenerateBuiltinDefinitionsAndInterfaceDescriptors(
builtin_definitions << "TFC(" << builtin->ExternalName() << ", " builtin_definitions << "TFC(" << builtin->ExternalName() << ", "
<< builtin->ExternalName(); << builtin->ExternalName();
std::string descriptor_name = builtin->ExternalName() + "Descriptor"; std::string descriptor_name = builtin->ExternalName() + "Descriptor";
constexpr size_t kFirstNonContextParameter = 1; bool has_context_parameter = builtin->signature().HasContextParameter();
size_t kFirstNonContextParameter = has_context_parameter ? 1 : 0;
size_t parameter_count = size_t parameter_count =
builtin->parameter_names().size() - kFirstNonContextParameter; builtin->parameter_names().size() - kFirstNonContextParameter;
interface_descriptors << "class " << descriptor_name interface_descriptors
<< " : public TorqueInterfaceDescriptor<" << "class " << descriptor_name
<< parameter_count << "> {\n"; << " : public TorqueInterfaceDescriptor<" << parameter_count << ", "
<< (has_context_parameter ? "true" : "false") << "> {\n";
interface_descriptors << " DECLARE_DESCRIPTOR_WITH_BASE(" interface_descriptors << " DECLARE_DESCRIPTOR_WITH_BASE("
<< descriptor_name << descriptor_name
<< ", TorqueInterfaceDescriptor)\n"; << ", TorqueInterfaceDescriptor)\n";
......
...@@ -705,6 +705,21 @@ bool Signature::HasSameTypesAs(const Signature& other, ...@@ -705,6 +705,21 @@ bool Signature::HasSameTypesAs(const Signature& other,
return true; return true;
} }
namespace {
bool FirstTypeIsContext(const std::vector<const Type*> parameter_types) {
return !parameter_types.empty() &&
parameter_types[0] == TypeOracle::GetContextType();
}
} // namespace
bool Signature::HasContextParameter() const {
return FirstTypeIsContext(types());
}
bool BuiltinPointerType::HasContextParameter() const {
return FirstTypeIsContext(parameter_types());
}
bool IsAssignableFrom(const Type* to, const Type* from) { bool IsAssignableFrom(const Type* to, const Type* from) {
if (to == from) return true; if (to == from) return true;
if (from->IsSubtypeOf(to)) return true; if (from->IsSubtypeOf(to)) return true;
......
...@@ -347,6 +347,8 @@ class V8_EXPORT_PRIVATE BuiltinPointerType final : public Type { ...@@ -347,6 +347,8 @@ class V8_EXPORT_PRIVATE BuiltinPointerType final : public Type {
return {{"Smi", ""}}; return {{"Smi", ""}};
} }
bool HasContextParameter() const;
private: private:
friend class TypeOracle; friend class TypeOracle;
BuiltinPointerType(const Type* parent, TypeVector parameter_types, BuiltinPointerType(const Type* parent, TypeVector parameter_types,
...@@ -800,6 +802,7 @@ struct Signature { ...@@ -800,6 +802,7 @@ struct Signature {
return TypeVector(parameter_types.types.begin() + implicit_count, return TypeVector(parameter_types.types.begin() + implicit_count,
parameter_types.types.end()); parameter_types.types.end());
} }
bool HasContextParameter() const;
}; };
void PrintSignature(std::ostream& os, const Signature& sig, bool with_names); void PrintSignature(std::ostream& os, const Signature& sig, bool with_names);
......
...@@ -113,8 +113,7 @@ TEST(TestBuiltinSpecialization) { ...@@ -113,8 +113,7 @@ TEST(TestBuiltinSpecialization) {
CodeAssemblerTester asm_tester(isolate, 0); CodeAssemblerTester asm_tester(isolate, 0);
TestTorqueAssembler m(asm_tester.state()); TestTorqueAssembler m(asm_tester.state());
{ {
TNode<Object> temp = m.SmiConstant(0); m.TestBuiltinSpecialization();
m.TestBuiltinSpecialization(m.UncheckedCast<Context>(temp));
m.Return(m.UndefinedConstant()); m.Return(m.UndefinedConstant());
} }
FunctionTester ft(asm_tester.GenerateCode(), 0); FunctionTester ft(asm_tester.GenerateCode(), 0);
...@@ -170,8 +169,7 @@ TEST(TestFunctionPointerToGeneric) { ...@@ -170,8 +169,7 @@ TEST(TestFunctionPointerToGeneric) {
CodeAssemblerTester asm_tester(isolate, 0); CodeAssemblerTester asm_tester(isolate, 0);
TestTorqueAssembler m(asm_tester.state()); TestTorqueAssembler m(asm_tester.state());
{ {
TNode<Object> temp = m.SmiConstant(0); m.TestFunctionPointerToGeneric();
m.TestFunctionPointerToGeneric(m.UncheckedCast<Context>(temp));
m.Return(m.UndefinedConstant()); m.Return(m.UndefinedConstant());
} }
FunctionTester ft(asm_tester.GenerateCode(), 0); FunctionTester ft(asm_tester.GenerateCode(), 0);
......
...@@ -97,20 +97,20 @@ namespace test { ...@@ -97,20 +97,20 @@ namespace test {
} }
} }
builtin GenericBuiltinTest<T: type>(_c: Context, _param: T): JSAny { builtin GenericBuiltinTest<T: type>(_param: T): JSAny {
return Null; return Null;
} }
GenericBuiltinTest<JSAny>(_c: Context, param: JSAny): JSAny { GenericBuiltinTest<JSAny>(param: JSAny): JSAny {
return param; return param;
} }
@export @export
macro TestBuiltinSpecialization(c: Context) { macro TestBuiltinSpecialization() {
check(GenericBuiltinTest<Smi>(c, 0) == Null); check(GenericBuiltinTest<Smi>(0) == Null);
check(GenericBuiltinTest<Smi>(c, 1) == Null); check(GenericBuiltinTest<Smi>(1) == Null);
check(GenericBuiltinTest<JSAny>(c, Undefined) == Undefined); check(GenericBuiltinTest<JSAny>(Undefined) == Undefined);
check(GenericBuiltinTest<JSAny>(c, Undefined) == Undefined); check(GenericBuiltinTest<JSAny>(Undefined) == Undefined);
} }
macro LabelTestHelper4(flag: constexpr bool): never macro LabelTestHelper4(flag: constexpr bool): never
...@@ -185,19 +185,19 @@ namespace test { ...@@ -185,19 +185,19 @@ namespace test {
} }
} }
builtin TestHelperPlus1(_context: Context, x: Smi): Smi { builtin TestHelperPlus1(x: Smi): Smi {
return x + 1; return x + 1;
} }
builtin TestHelperPlus2(_context: Context, x: Smi): Smi { builtin TestHelperPlus2(x: Smi): Smi {
return x + 2; return x + 2;
} }
@export @export
macro TestFunctionPointers(implicit context: Context)(): Boolean { macro TestFunctionPointers(implicit context: Context)(): Boolean {
let fptr: builtin(Context, Smi) => Smi = TestHelperPlus1; let fptr: builtin(Smi) => Smi = TestHelperPlus1;
check(fptr(context, 42) == 43); check(fptr(42) == 43);
fptr = TestHelperPlus2; fptr = TestHelperPlus2;
check(fptr(context, 42) == 44); check(fptr(42) == 44);
return True; return True;
} }
...@@ -215,14 +215,14 @@ namespace test { ...@@ -215,14 +215,14 @@ namespace test {
} }
@export @export
macro TestFunctionPointerToGeneric(c: Context) { macro TestFunctionPointerToGeneric() {
const fptr1: builtin(Context, Smi) => JSAny = GenericBuiltinTest<Smi>; const fptr1: builtin(Smi) => JSAny = GenericBuiltinTest<Smi>;
const fptr2: builtin(Context, JSAny) => JSAny = GenericBuiltinTest<JSAny>; const fptr2: builtin(JSAny) => JSAny = GenericBuiltinTest<JSAny>;
check(fptr1(c, 0) == Null); check(fptr1(0) == Null);
check(fptr1(c, 1) == Null); check(fptr1(1) == Null);
check(fptr2(c, Undefined) == Undefined); check(fptr2(Undefined) == Undefined);
check(fptr2(c, Undefined) == Undefined); check(fptr2(Undefined) == Undefined);
} }
type ObjectToObject = builtin(Context, JSAny) => JSAny; type ObjectToObject = builtin(Context, JSAny) => JSAny;
...@@ -236,7 +236,7 @@ namespace test { ...@@ -236,7 +236,7 @@ namespace test {
if (TaggedIsSmi(n)) { if (TaggedIsSmi(n)) {
const m: Smi = UnsafeCast<Smi>(n); const m: Smi = UnsafeCast<Smi>(n);
check(TestHelperPlus1(context, m) == 11); check(TestHelperPlus1(m) == 11);
return True; return True;
} }
return False; return False;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment