Commit 2a1a7bf2 authored by Victor Gomes's avatar Victor Gomes Committed by Commit Bot

[runtime] Reverse JS arguments: fix tests and builtin arguments

Bug: v8:10201
Change-Id: I72cbe15912395b9b06ffdccce935abae6e7a050e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2093508Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66808}
parent 905d38f5
......@@ -206,6 +206,18 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Isolate* isolate,
} else {
argv = new Address[frame_argc];
}
#ifdef V8_REVERSE_JSARGS
argv[BuiltinArguments::kNewTargetOffset] = new_target->ptr();
argv[BuiltinArguments::kTargetOffset] = function->ptr();
argv[BuiltinArguments::kArgcOffset] = Smi::FromInt(frame_argc).ptr();
argv[BuiltinArguments::kPaddingOffset] =
ReadOnlyRoots(isolate).the_hole_value().ptr();
int cursor = BuiltinArguments::kNumExtraArgs;
argv[cursor++] = receiver->ptr();
for (int i = 0; i < argc; ++i) {
argv[cursor++] = args[i]->ptr();
}
#else
int cursor = frame_argc - 1;
argv[cursor--] = receiver->ptr();
for (int i = 0; i < argc; ++i) {
......@@ -217,6 +229,7 @@ MaybeHandle<Object> Builtins::InvokeApiFunction(Isolate* isolate,
argv[BuiltinArguments::kArgcOffset] = Smi::FromInt(frame_argc).ptr();
argv[BuiltinArguments::kTargetOffset] = function->ptr();
argv[BuiltinArguments::kNewTargetOffset] = new_target->ptr();
#endif
MaybeHandle<Object> result;
{
RelocatableArguments arguments(isolate, frame_argc, &argv[frame_argc - 1]);
......
......@@ -1870,8 +1870,8 @@ void ArrayBuiltinsAssembler::GenerateConstructor(
BIND(&call_runtime);
{
TailCallRuntime(Runtime::kNewArray, context, array_function, array_size,
array_function, allocation_site);
TailCallRuntimeNewArray(context, array_function, array_size, array_function,
allocation_site);
}
}
......
......@@ -13,20 +13,35 @@
namespace v8 {
namespace internal {
#define REVERSE_0(a) a
#define REVERSE_1(a, b) b, a
#define REVERSE_2(a, b, c) c, b, a
#define REVERSE_3(a, b, c, d) d, c, b, a
#define REVERSE_4(a, b, c, d, e) e, d, c, b, a
#define REVERSE_5(a, b, c, d, e, f) f, e, d, c, b, a
#define REVERSE_6(a, b, c, d, e, f, g) g, f, e, d, c, b, a
#define REVERSE_7(a, b, c, d, e, f, g, h) h, g, f, e, d, c, b, a
#define REVERSE_8(a, b, c, d, e, f, g, h, i) i, h, g, f, e, d, c, b, a
#define REVERSE_0(a) a,
#define REVERSE_1(a, b) b, a,
#define REVERSE_2(a, b, c) c, b, a,
#define REVERSE_3(a, b, c, d) d, c, b, a,
#define REVERSE_4(a, b, c, d, e) e, d, c, b, a,
#define REVERSE_5(a, b, c, d, e, f) f, e, d, c, b, a,
#define REVERSE_6(a, b, c, d, e, f, g) g, f, e, d, c, b, a,
#define REVERSE_7(a, b, c, d, e, f, g, h) h, g, f, e, d, c, b, a,
#define REVERSE_8(a, b, c, d, e, f, g, h, i) i, h, g, f, e, d, c, b, a,
#define REVERSE_kDontAdaptArgumentsSentinel(...)
#define REVERSE(N, ...) REVERSE_##N(__VA_ARGS__)
// Define interface descriptors for builtins with JS linkage.
#define DEFINE_TFJ_INTERFACE_DESCRIPTOR_HELPER(Name, Argc, ...) \
#ifdef V8_REVERSE_JSARGS
#define DEFINE_TFJ_INTERFACE_DESCRIPTOR(Name, Argc, ...) \
struct Builtin_##Name##_InterfaceDescriptor { \
enum ParameterIndices { \
kJSTarget = compiler::CodeAssembler::kTargetParameterIndex, \
REVERSE_##Argc(__VA_ARGS__) kJSNewTarget, \
kJSActualArgumentsCount, \
kContext, \
kParameterCount, \
}; \
static_assert((Argc) == static_cast<uint16_t>(kParameterCount - 4), \
"Inconsistent set of arguments"); \
static_assert(kJSTarget == -1, "Unexpected kJSTarget index value"); \
};
#else
#define DEFINE_TFJ_INTERFACE_DESCRIPTOR(Name, Argc, ...) \
struct Builtin_##Name##_InterfaceDescriptor { \
enum ParameterIndices { \
kJSTarget = compiler::CodeAssembler::kTargetParameterIndex, \
......@@ -40,13 +55,6 @@ namespace internal {
"Inconsistent set of arguments"); \
static_assert(kJSTarget == -1, "Unexpected kJSTarget index value"); \
};
#ifdef V8_REVERSE_JSARGS
#define DEFINE_TFJ_INTERFACE_DESCRIPTOR(Name, Argc, ...) \
DEFINE_TFJ_INTERFACE_DESCRIPTOR_HELPER(Name, Argc, REVERSE(Argc, __VA_ARGS__))
#else
#define DEFINE_TFJ_INTERFACE_DESCRIPTOR(Name, Argc, ...) \
DEFINE_TFJ_INTERFACE_DESCRIPTOR_HELPER(Name, Argc, ##__VA_ARGS__)
#endif
// Define interface descriptors for builtins with StubCall linkage.
......
......@@ -39,6 +39,8 @@ class BuiltinArguments : public JavaScriptArguments {
*address_of_arg_at(index + kArgsOffset) = value.ptr();
}
// Note: this should return the address after the receiver,
// even when length() == 1.
inline Address* address_of_first_argument() const {
return address_of_arg_at(kArgsOffset + 1); // Skips receiver.
}
......
......@@ -12547,19 +12547,29 @@ CodeStubArguments::CodeStubArguments(CodeStubAssembler* assembler,
TNode<Object> CodeStubArguments::GetReceiver() const {
DCHECK_EQ(receiver_mode_, ReceiverMode::kHasReceiver);
return assembler_->UncheckedCast<Object>(assembler_->LoadFullTagged(
base_, assembler_->IntPtrConstant(kSystemPointerSize)));
#ifdef V8_REVERSE_JSARGS
intptr_t offset = -kSystemPointerSize;
#else
intptr_t offset = kSystemPointerSize;
#endif
return assembler_->LoadFullTagged(base_, assembler_->IntPtrConstant(offset));
}
void CodeStubArguments::SetReceiver(TNode<Object> object) const {
DCHECK_EQ(receiver_mode_, ReceiverMode::kHasReceiver);
#ifdef V8_REVERSE_JSARGS
intptr_t offset = -kSystemPointerSize;
#else
intptr_t offset = kSystemPointerSize;
#endif
assembler_->StoreFullTaggedNoWriteBarrier(
base_, assembler_->IntPtrConstant(kSystemPointerSize), object);
base_, assembler_->IntPtrConstant(offset), object);
}
TNode<RawPtrT> CodeStubArguments::AtIndexPtr(TNode<IntPtrT> index) const {
#ifdef V8_REVERSE_JSARGS
TNode<IntPtrT> offset = index;
TNode<IntPtrT> offset =
assembler_->ElementOffsetFromIndex(index, SYSTEM_POINTER_ELEMENTS, 0);
#else
TNode<IntPtrT> negated_index =
assembler_->IntPtrOrSmiSub(assembler_->IntPtrConstant(0), index);
......@@ -13067,6 +13077,62 @@ void CodeStubAssembler::InitializeSyntheticFunctionContext(
UndefinedConstant());
}
TNode<Object> CodeStubAssembler::CallApiCallback(
TNode<Object> context, TNode<RawPtrT> callback, TNode<IntPtrT> argc,
TNode<Object> data, TNode<Object> holder, TNode<Object> receiver) {
Callable callable = CodeFactory::CallApiCallback(isolate());
return CallStub(callable, context, callback, argc, data, holder, receiver);
}
TNode<Object> CodeStubAssembler::CallApiCallback(
TNode<Object> context, TNode<RawPtrT> callback, TNode<IntPtrT> argc,
TNode<Object> data, TNode<Object> holder, TNode<Object> receiver,
TNode<Object> value) {
// CallApiCallback receives the first four arguments in registers
// (callback, argc, data and holder). The last arguments are in the stack in
// JS ordering. See ApiCallbackDescriptor.
Callable callable = CodeFactory::CallApiCallback(isolate());
#ifdef V8_REVERSE_JSARGS
return CallStub(callable, context, callback, argc, data, holder, value,
receiver);
#else
return CallStub(callable, context, callback, argc, data, holder, receiver,
value);
#endif
}
TNode<Object> CodeStubAssembler::CallRuntimeNewArray(
TNode<Context> context, TNode<Object> receiver, TNode<Object> length,
TNode<Object> new_target, TNode<Object> allocation_site) {
// Runtime_NewArray receives arguments in the JS order (to avoid unnecessary
// copy). Except the last two (new_target and allocation_site) which are add
// on top of the stack later.
#ifdef V8_REVERSE_JSARGS
return CallRuntime(Runtime::kNewArray, context, length, receiver, new_target,
allocation_site);
#else
return CallRuntime(Runtime::kNewArray, context, receiver, length, new_target,
allocation_site);
#endif
}
void CodeStubAssembler::TailCallRuntimeNewArray(TNode<Context> context,
TNode<Object> receiver,
TNode<Object> length,
TNode<Object> new_target,
TNode<Object> allocation_site) {
// Runtime_NewArray receives arguments in the JS order (to avoid unnecessary
// copy). Except the last two (new_target and allocation_site) which are add
// on top of the stack later.
#ifdef V8_REVERSE_JSARGS
return TailCallRuntime(Runtime::kNewArray, context, length, receiver,
new_target, allocation_site);
#else
return TailCallRuntime(Runtime::kNewArray, context, receiver, length,
new_target, allocation_site);
#endif
}
TNode<JSArray> CodeStubAssembler::ArrayCreate(TNode<Context> context,
TNode<Number> length) {
TVARIABLE(JSArray, array);
......@@ -13089,8 +13155,8 @@ TNode<JSArray> CodeStubAssembler::ArrayCreate(TNode<Context> context,
TNode<NativeContext> native_context = LoadNativeContext(context);
TNode<JSFunction> array_function =
CAST(LoadContextElement(native_context, Context::ARRAY_FUNCTION_INDEX));
array = CAST(CallRuntime(Runtime::kNewArray, context, array_function,
length, array_function, UndefinedConstant()));
array = CAST(CallRuntimeNewArray(context, array_function, length,
array_function, UndefinedConstant()));
Goto(&done);
}
......
......@@ -892,6 +892,25 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
callable, receiver, args...));
}
TNode<Object> CallApiCallback(TNode<Object> context, TNode<RawPtrT> callback,
TNode<IntPtrT> argc, TNode<Object> data,
TNode<Object> holder, TNode<Object> receiver);
TNode<Object> CallApiCallback(TNode<Object> context, TNode<RawPtrT> callback,
TNode<IntPtrT> argc, TNode<Object> data,
TNode<Object> holder, TNode<Object> receiver,
TNode<Object> value);
TNode<Object> CallRuntimeNewArray(TNode<Context> context,
TNode<Object> receiver,
TNode<Object> length,
TNode<Object> new_target,
TNode<Object> allocation_site);
void TailCallRuntimeNewArray(TNode<Context> context, TNode<Object> receiver,
TNode<Object> length, TNode<Object> new_target,
TNode<Object> allocation_site);
template <class... TArgs>
TNode<JSReceiver> ConstructWithTarget(TNode<Context> context,
TNode<JSReceiver> target,
......
......@@ -1047,6 +1047,7 @@ class ArrayNoArgumentConstructorDescriptor
ArrayNArgumentsConstructorDescriptor)
};
#ifdef V8_REVERSE_JSARGS
class ArraySingleArgumentConstructorDescriptor
: public ArrayNArgumentsConstructorDescriptor {
public:
......@@ -1054,15 +1055,35 @@ class ArraySingleArgumentConstructorDescriptor
// ArrayNArgumentsConstructorDescriptor and it declares indices for
// JS arguments passed on the expression stack.
DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
kFunctionParameter, kArraySizeSmiParameter)
kArraySizeSmiParameter, kReceiverParameter)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
MachineType::AnyTagged(), // kAllocationSite
MachineType::Int32(), // kActualArgumentsCount
MachineType::AnyTagged(), // kFunctionParameter
// JS arguments on the stack
MachineType::AnyTagged(), // kArraySizeSmiParameter
MachineType::AnyTagged()) // kReceiverParameter
DECLARE_DESCRIPTOR(ArraySingleArgumentConstructorDescriptor,
ArrayNArgumentsConstructorDescriptor)
};
#else
class ArraySingleArgumentConstructorDescriptor
: public ArrayNArgumentsConstructorDescriptor {
public:
// This descriptor declares same register arguments as the parent
// ArrayNArgumentsConstructorDescriptor and it declares indices for
// JS arguments passed on the expression stack.
DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
kReceiverParameter, kArraySizeSmiParameter)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
MachineType::AnyTagged(), // kAllocationSite
MachineType::Int32(), // kActualArgumentsCount
// JS arguments on the stack
MachineType::AnyTagged(), // kReceiverParameter
MachineType::AnyTagged()) // kArraySizeSmiParameter
DECLARE_DESCRIPTOR(ArraySingleArgumentConstructorDescriptor,
ArrayNArgumentsConstructorDescriptor)
};
#endif
class CompareDescriptor : public CallInterfaceDescriptor {
public:
......
......@@ -60,8 +60,8 @@ class Arguments {
}
inline Address* address_of_arg_at(int index) const {
DCHECK_LT(static_cast<uint32_t>(index), static_cast<uint32_t>(length_));
int offset = index * kSystemPointerSize;
DCHECK_LE(static_cast<uint32_t>(index), static_cast<uint32_t>(length_));
uintptr_t offset = index * kSystemPointerSize;
#ifdef V8_REVERSE_JSARGS
if (arguments_type == ArgumentsType::kJS) {
offset = (length_ - index - 1) * kSystemPointerSize;
......
......@@ -226,10 +226,9 @@ void AccessorAssembler::HandleLoadAccessor(
Goto(&load);
BIND(&load);
Callable callable = CodeFactory::CallApiCallback(isolate());
TNode<IntPtrT> argc = IntPtrConstant(0);
exit_point->Return(CallStub(callable, context, callback, argc, data,
api_holder.value(), p->receiver()));
exit_point->Return(CallApiCallback(context, callback, argc, data,
api_holder.value(), p->receiver()));
}
void AccessorAssembler::HandleLoadField(TNode<JSObject> holder,
......@@ -1674,10 +1673,9 @@ void AccessorAssembler::HandleStoreICProtoHandler(
Goto(&store);
BIND(&store);
Callable callable = CodeFactory::CallApiCallback(isolate());
TNode<IntPtrT> argc = IntPtrConstant(1);
Return(CallStub(callable, context, callback, argc, data,
api_holder.value(), p->receiver(), p->value()));
Return(CallApiCallback(context, callback, argc, data, api_holder.value(),
p->receiver(), p->value()));
}
BIND(&if_store_global_proxy);
......
......@@ -645,23 +645,22 @@ class ElementsAccessorBase : public InternalElementsAccessor {
UNREACHABLE();
}
uint32_t Push(Handle<JSArray> receiver, JavaScriptArguments* args,
uint32_t Push(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t push_size) final {
return Subclass::PushImpl(receiver, args, push_size);
}
static uint32_t PushImpl(Handle<JSArray> receiver, JavaScriptArguments* args,
static uint32_t PushImpl(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t push_sized) {
UNREACHABLE();
}
uint32_t Unshift(Handle<JSArray> receiver, JavaScriptArguments* args,
uint32_t Unshift(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t unshift_size) final {
return Subclass::UnshiftImpl(receiver, args, unshift_size);
}
static uint32_t UnshiftImpl(Handle<JSArray> receiver,
JavaScriptArguments* args,
static uint32_t UnshiftImpl(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t unshift_size) {
UNREACHABLE();
}
......@@ -2092,7 +2091,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
return Subclass::RemoveElement(receiver, AT_START);
}
static uint32_t PushImpl(Handle<JSArray> receiver, JavaScriptArguments* args,
static uint32_t PushImpl(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t push_size) {
Handle<FixedArrayBase> backing_store(receiver->elements(),
receiver->GetIsolate());
......@@ -2100,8 +2099,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
AT_END);
}
static uint32_t UnshiftImpl(Handle<JSArray> receiver,
JavaScriptArguments* args,
static uint32_t UnshiftImpl(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t unshift_size) {
Handle<FixedArrayBase> backing_store(receiver->elements(),
receiver->GetIsolate());
......@@ -2349,7 +2347,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
static uint32_t AddArguments(Handle<JSArray> receiver,
Handle<FixedArrayBase> backing_store,
JavaScriptArguments* args, uint32_t add_size,
BuiltinArguments* args, uint32_t add_size,
Where add_position) {
uint32_t length = Smi::ToInt(receiver->length());
DCHECK_LT(0, add_size);
......@@ -2384,7 +2382,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
return new_length;
}
static void CopyArguments(JavaScriptArguments* args,
static void CopyArguments(BuiltinArguments* args,
Handle<FixedArrayBase> dst_store,
uint32_t copy_size, uint32_t src_index,
uint32_t dst_index) {
......@@ -2567,7 +2565,7 @@ class FastNonextensibleObjectElementsAccessor
public:
using BackingStore = typename KindTraits::BackingStore;
static uint32_t PushImpl(Handle<JSArray> receiver, JavaScriptArguments* args,
static uint32_t PushImpl(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t push_size) {
UNREACHABLE();
}
......@@ -2662,7 +2660,7 @@ class FastSealedObjectElementsAccessor
static Handle<Object> PopImpl(Handle<JSArray> receiver) { UNREACHABLE(); }
static uint32_t PushImpl(Handle<JSArray> receiver, JavaScriptArguments* args,
static uint32_t PushImpl(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t push_size) {
UNREACHABLE();
}
......@@ -2772,7 +2770,7 @@ class FastFrozenObjectElementsAccessor
static Handle<Object> PopImpl(Handle<JSArray> receiver) { UNREACHABLE(); }
static uint32_t PushImpl(Handle<JSArray> receiver, JavaScriptArguments* args,
static uint32_t PushImpl(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t push_size) {
UNREACHABLE();
}
......@@ -4668,7 +4666,7 @@ MaybeHandle<Object> ArrayConstructInitializeElements(
// Set length and elements on the array.
int number_of_elements = args->length();
JSObject::EnsureCanContainElements(array, args, 0, number_of_elements,
JSObject::EnsureCanContainElements(array, args, number_of_elements,
ALLOW_CONVERTED_DOUBLE_ELEMENTS);
// Allocate an appropriately typed elements array.
......@@ -4792,7 +4790,7 @@ void ElementsAccessor::TearDown() {
}
Handle<JSArray> ElementsAccessor::Concat(Isolate* isolate,
JavaScriptArguments* args,
BuiltinArguments* args,
uint32_t concat_size,
uint32_t result_len) {
ElementsKind result_elements_kind = GetInitialFastElementsKind();
......
......@@ -5,6 +5,7 @@
#ifndef V8_OBJECTS_ELEMENTS_H_
#define V8_OBJECTS_ELEMENTS_H_
#include "src/builtins/builtins-utils.h"
#include "src/objects/elements-kind.h"
#include "src/objects/internal-index.h"
#include "src/objects/keys.h"
......@@ -111,13 +112,13 @@ class ElementsAccessor {
Handle<Object> value, PropertyAttributes attributes,
uint32_t new_capacity) = 0;
static Handle<JSArray> Concat(Isolate* isolate, JavaScriptArguments* args,
static Handle<JSArray> Concat(Isolate* isolate, BuiltinArguments* args,
uint32_t concat_size, uint32_t result_length);
virtual uint32_t Push(Handle<JSArray> receiver, JavaScriptArguments* args,
virtual uint32_t Push(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t push_size) = 0;
virtual uint32_t Unshift(Handle<JSArray> receiver, JavaScriptArguments* args,
virtual uint32_t Unshift(Handle<JSArray> receiver, BuiltinArguments* args,
uint32_t unshift_size) = 0;
virtual Handle<Object> Pop(Handle<JSArray> receiver) = 0;
......
......@@ -4565,13 +4565,9 @@ void JSObject::SetImmutableProto(Handle<JSObject> object) {
void JSObject::EnsureCanContainElements(Handle<JSObject> object,
JavaScriptArguments* args,
uint32_t first_arg, uint32_t arg_count,
uint32_t arg_count,
EnsureElementsMode mode) {
// Elements in |Arguments| are ordered backwards (because they're on the
// stack), but the method that's called here iterates over them in forward
// direction.
return EnsureCanContainElements(
object, args->slot_at(first_arg + arg_count - 1), arg_count, mode);
return EnsureCanContainElements(object, args->first_slot(), arg_count, mode);
}
void JSObject::ValidateElements(JSObject object) {
......
......@@ -516,7 +516,7 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
EnsureElementsMode mode);
static void EnsureCanContainElements(Handle<JSObject> object,
JavaScriptArguments* arguments,
uint32_t first_arg, uint32_t arg_count,
uint32_t arg_count,
EnsureElementsMode mode);
// Would we convert a fast elements array to dictionary mode given
......
......@@ -47,8 +47,13 @@ RUNTIME_FUNCTION(Runtime_NewArray) {
DCHECK_LE(3, args.length());
int const argc = args.length() - 3;
// argv points to the arguments constructed by the JavaScript call.
#ifdef V8_REVERSE_JSARGS
JavaScriptArguments argv(argc, args.address_of_arg_at(0));
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, argc);
#else
JavaScriptArguments argv(argc, args.address_of_arg_at(1));
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
#endif
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, argc + 1);
CONVERT_ARG_HANDLE_CHECKED(HeapObject, type_info, argc + 2);
// TODO(bmeurer): Use MaybeHandle to pass around the AllocationSite.
......
......@@ -3506,8 +3506,13 @@ TEST(DetailedErrorStackTraceBuiltinExit) {
FixedArray parameters = stack_trace->Parameters(0);
CHECK_EQ(parameters.length(), 2);
#ifdef V8_REVERSE_JSARGS
CHECK(parameters.get(1).IsSmi());
CHECK_EQ(Smi::ToInt(parameters.get(1)), 9999);
#else
CHECK(parameters.get(0).IsSmi());
CHECK_EQ(Smi::ToInt(parameters.get(0)), 9999);
#endif
});
}
......
......@@ -28,9 +28,23 @@ class InvokeIntrinsicHelper {
template <class... A>
Handle<Object> Invoke(A... args) {
CHECK(IntrinsicsHelper::IsSupported(function_id_));
BytecodeArrayBuilder builder(zone_, sizeof...(args), 0, nullptr);
int parameter_count = sizeof...(args);
#ifdef V8_REVERSE_JSARGS
// Move the parameter to locals, since the order of the
// arguments in the stack is reversed.
BytecodeArrayBuilder builder(zone_, parameter_count + 1, parameter_count,
nullptr);
for (int i = 0; i < parameter_count; i++) {
builder.MoveRegister(builder.Parameter(i), builder.Local(i));
}
RegisterList reg_list =
InterpreterTester::NewRegisterList(0, parameter_count);
#else
// Add the receiver in the parameter count.
BytecodeArrayBuilder builder(zone_, parameter_count + 1, 0, nullptr);
RegisterList reg_list = InterpreterTester::NewRegisterList(
builder.Receiver().index(), sizeof...(args));
builder.Parameter(0).index(), parameter_count);
#endif
builder.CallRuntime(function_id_, reg_list).Return();
InterpreterTester tester(isolate_, builder.ToBytecodeArray(isolate_));
auto callable = tester.GetCallable<A...>();
......
......@@ -535,7 +535,11 @@ TEST_F(BytecodeArrayBuilderTest, Parameters) {
Register receiver(builder.Receiver());
Register param8(builder.Parameter(8));
#ifdef V8_REVERSE_JSARGS
CHECK_EQ(receiver.index() - param8.index(), 9);
#else
CHECK_EQ(param8.index() - receiver.index(), 9);
#endif
}
TEST_F(BytecodeArrayBuilderTest, Constants) {
......
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