[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: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#67435}
This commit is contained in:
parent
2ce3a8e973
commit
b5ab5c7b75
@ -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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 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,
|
|||||||
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,
|
|||||||
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
|
|
||||||
// not have to handle this case.
|
|
||||||
out() << " CodeStubAssembler(state_).CallBuiltin(Builtins::k"
|
|
||||||
<< instruction.builtin->ExternalName() << ", ";
|
|
||||||
PrintCommaSeparatedList(out(), arguments);
|
|
||||||
out() << ");\n";
|
|
||||||
}
|
}
|
||||||
|
for (const std::string& argument : arguments) {
|
||||||
|
out() << ", " << argument;
|
||||||
|
}
|
||||||
|
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,
|
|||||||
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(
|
|||||||
"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,
|
|||||||
*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) {
|
|||||||
} 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, ¶meters, ¶meter_types,
|
|
||||||
¶meter_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, ¶meters, ¶meter_types,
|
std::string var = AddParameter(i, builtin, ¶meters, ¶meter_types,
|
||||||
@ -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(
|
|||||||
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,
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 {
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user