Commit 73a35c35 authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm][generic-wrapper] Fix number of parameters popped off the stack

In the generic wrapper we popped the wrong number of parameters off the
stack. We always popped the number of parameters needed by the generic
wrapper, according to the signature. The correct number though is
max(parameters provide, parameters needed).

R=victorgomes@chromium.org, thibaudm@chromium.org
CC=vkont@google.com

Bug: v8:10982
Change-Id: If9b8d4dbe093eb6df08ddf9f3594d5c60b9be33f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2558317
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarVictor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71406}
parent 7f15f3e7
......@@ -2995,7 +2995,11 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
constexpr int kFrameMarkerOffset = -kSystemPointerSize;
constexpr int kGCScanSlotCountOffset =
kFrameMarkerOffset - kSystemPointerSize;
constexpr int kParamCountOffset = kGCScanSlotCountOffset - kSystemPointerSize;
// The number of parameters passed to this function.
constexpr int kInParamCountOffset =
kGCScanSlotCountOffset - kSystemPointerSize;
// The number of parameters according to the signature.
constexpr int kParamCountOffset = kInParamCountOffset - kSystemPointerSize;
constexpr int kReturnCountOffset = kParamCountOffset - kSystemPointerSize;
constexpr int kValueTypesArrayStartOffset =
kReturnCountOffset - kSystemPointerSize;
......@@ -3004,8 +3008,13 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
constexpr int kFunctionDataOffset =
kValueTypesArrayStartOffset - kSystemPointerSize;
constexpr int kLastSpillOffset = kFunctionDataOffset;
constexpr int kNumSpillSlots = 5;
constexpr int kNumSpillSlots = 6;
__ subq(rsp, Immediate(kNumSpillSlots * kSystemPointerSize));
// Put the in_parameter count on the stack, we only need it at the very end
// when we pop the parameters off the stack.
Register in_param_count = rax;
__ movq(MemOperand(rbp, kInParamCountOffset), in_param_count);
in_param_count = no_reg;
// -------------------------------------------
// Load the Wasm exported function data and the Wasm instance.
......@@ -3158,20 +3167,19 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
// We will loop through the params starting with the 1st param.
// The order of processing the params is important. We have to evaluate them
// in an increasing order.
// Not reversed Reversed
// +-----------------+------+-----------------+---------------
// | receiver | | param n |
// |- - - - - - - - -| |- - - - - - - - -|
// | param 1 | | param n-1 | Caller
// | ... | | ... | frame slots
// | param n-1 | | param 1 |
// |- - - - - - - - -| |- - - - - - - - -|
// | param n | | receiver |
// -+-----------------+------+-----------------+---------------
// | return addr | | return addr |
// |- - - - - - - - -|<-FP->|- - - - - - - - -|
// | rbp | | rbp | Spill slots
// |- - - - - - - - -| |- - - - - - - - -|
// +-----------------+---------------
// | param n |
// |- - - - - - - - -|
// | param n-1 | Caller
// | ... | frame slots
// | param 1 |
// |- - - - - - - - -|
// | receiver |
// +-----------------+---------------
// | return addr |
// FP->|- - - - - - - - -|
// | rbp | Spill slots
// |- - - - - - - - -|
//
// [rbp + current_param] gives us the parameter we are processing.
// We iterate through half-open interval <1st param, [rbp + param_limit]).
......@@ -3456,6 +3464,13 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
__ bind(&return_done);
__ movq(param_count, MemOperand(rbp, kParamCountOffset));
// Calculate the number of parameters we have to pop off the stack. This
// number is max(in_param_count, param_count).
in_param_count = rdx;
__ movq(in_param_count, MemOperand(rbp, kInParamCountOffset));
__ cmpq(param_count, in_param_count);
__ cmovq(less, param_count, in_param_count);
// -------------------------------------------
// Deconstrunct the stack frame.
// -------------------------------------------
......@@ -3471,6 +3486,9 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
Register return_addr = rbx;
__ popq(return_addr);
Register caller_frame_slots_count = param_count;
// Add one to also pop the receiver. The receiver is passed to a JSFunction
// over the stack but is neither included in the number of parameters passed
// to this function nor in the number of parameters expected in this function.
__ addq(caller_frame_slots_count, Immediate(1));
__ shlq(caller_frame_slots_count, Immediate(kSystemPointerSizeLog2));
__ addq(rsp, caller_frame_slots_count);
......
......@@ -762,3 +762,28 @@ let kSig_f_iiliiiffddlifffdi = makeSig([kWasmI32, kWasmI32, kWasmI64, kWasmI32,
let instance = builder.instantiate();
assertEquals(15, instance.exports.f1());
})();
(function testDeoptWithIncorrectNumberOfParams() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_v_ii);
let imp = builder.addImport('q', 'func', sig_index);
builder.addFunction('main', sig_index)
.addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprCallFunction, imp])
.exportAs('main');
function deopt() {
%DeoptimizeFunction(caller);
}
let main = builder.instantiate({q: {func: deopt}}).exports.main;
function caller() {
main(1, 2, 3, 4, 5);
main(1, 2, 3, 4);
main(1, 2, 3);
main(1, 2);
main(1);
main();
}
caller();
})();
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