Commit a05ee6cb authored by Victor Gomes's avatar Victor Gomes Committed by Commit Bot

[compiler] Add CallJSStub

The arguments order in a JS stack is now controlled by
V8_REVERSE_JSARGS macro.
This CL creates two stubs that allow the order of the arguments
to be reversed without changing CallStub.

Bug: v8:10201
Change-Id: I8f70adf3ced1f45a00f5c4ddd47d5f604f2d3100
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2093506
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66647}
parent 1c922f0f
...@@ -994,6 +994,33 @@ Node* CodeAssembler::CallStubRImpl(StubCallMode call_mode, ...@@ -994,6 +994,33 @@ Node* CodeAssembler::CallStubRImpl(StubCallMode call_mode,
inputs.data()); inputs.data());
} }
Node* CodeAssembler::CallJSStubImpl(const CallInterfaceDescriptor& descriptor,
TNode<Object> target, TNode<Object> context,
TNode<Object> function,
TNode<Object> new_target,
TNode<Int32T> arity,
std::initializer_list<Node*> args) {
constexpr size_t kMaxNumArgs = 10;
DCHECK_GE(kMaxNumArgs, args.size());
NodeArray<kMaxNumArgs + 5> inputs;
inputs.Add(target);
inputs.Add(function);
if (!new_target.is_null()) {
inputs.Add(new_target);
}
inputs.Add(arity);
#ifdef V8_REVERSE_JSARGS
for (auto arg : base::Reversed(args)) inputs.Add(arg);
#else
for (auto arg : args) inputs.Add(arg);
#endif
if (descriptor.HasContextParameter()) {
inputs.Add(context);
}
return CallStubN(StubCallMode::kCallCodeObject, descriptor, 1, inputs.size(),
inputs.data());
}
void CodeAssembler::TailCallStubThenBytecodeDispatchImpl( void CodeAssembler::TailCallStubThenBytecodeDispatchImpl(
const CallInterfaceDescriptor& descriptor, Node* target, Node* context, const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
std::initializer_list<Node*> args) { std::initializer_list<Node*> args) {
......
...@@ -1051,20 +1051,22 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -1051,20 +1051,22 @@ class V8_EXPORT_PRIVATE CodeAssembler {
Node* receiver, TArgs... args) { Node* receiver, TArgs... args) {
int argc = static_cast<int>(sizeof...(args)); int argc = static_cast<int>(sizeof...(args));
TNode<Int32T> arity = Int32Constant(argc); TNode<Int32T> arity = Int32Constant(argc);
return CallStub(callable, CAST(context), function, arity, receiver, TNode<Code> target = HeapConstant(callable.code());
args...); return CAST(CallJSStubImpl(callable.descriptor(), target, CAST(context),
CAST(function), TNode<Object>(), arity,
{receiver, args...}));
} }
template <class... TArgs> template <class... TArgs>
Node* ConstructJSWithTarget(Callable const& callable, Node* context, Node* ConstructJSWithTarget(Callable const& callable, Node* context,
Node* target, Node* new_target, TArgs... args) { Node* function, Node* new_target, TArgs... args) {
int argc = static_cast<int>(sizeof...(args)); int argc = static_cast<int>(sizeof...(args));
TNode<Int32T> arity = Int32Constant(argc); TNode<Int32T> arity = Int32Constant(argc);
TNode<Object> receiver = LoadRoot(RootIndex::kUndefinedValue); TNode<Object> receiver = LoadRoot(RootIndex::kUndefinedValue);
TNode<Code> target = HeapConstant(callable.code());
// Construct(target, new_target, arity, receiver, arguments...) return CallJSStubImpl(callable.descriptor(), target, CAST(context),
return CallStub(callable, CAST(context), target, new_target, arity, CAST(function), CAST(new_target), arity,
receiver, args...); {receiver, args...});
} }
template <class... TArgs> template <class... TArgs>
Node* ConstructJS(Callable const& callable, Node* context, Node* new_target, Node* ConstructJS(Callable const& callable, Node* context, Node* new_target,
...@@ -1173,6 +1175,11 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -1173,6 +1175,11 @@ class V8_EXPORT_PRIVATE CodeAssembler {
size_t result_size, TNode<Object> target, size_t result_size, TNode<Object> target,
TNode<Object> context, std::initializer_list<Node*> args); TNode<Object> context, std::initializer_list<Node*> args);
Node* CallJSStubImpl(const CallInterfaceDescriptor& descriptor,
TNode<Object> target, TNode<Object> context,
TNode<Object> function, TNode<Object> new_target,
TNode<Int32T> arity, std::initializer_list<Node*> args);
// These two don't have definitions and are here only for catching use cases // These two don't have definitions and are here only for catching use cases
// where the cast is not necessary. // where the cast is not necessary.
TNode<Int32T> Signed(TNode<Int32T> x); TNode<Int32T> Signed(TNode<Int32T> x);
......
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