diff --git a/js/src/jit-test/tests/wasm/tail-calls/bug1851568.js b/js/src/jit-test/tests/wasm/tail-calls/bug1851568.js new file mode 100644 index 000000000000..b9622042d8db --- /dev/null +++ b/js/src/jit-test/tests/wasm/tail-calls/bug1851568.js @@ -0,0 +1,20 @@ +wasmFailValidateText(`(module + (func (result i32 f64) + i32.const 1 + f64.const 2.0 + ) + (func (export "f") (result f64) + return_call 0 + ) +)`, /type mismatch/); + +wasmFailValidateText(`(module + (func (result i32 f64) + i32.const 1 + f64.const 2.0 + ) + (func (export "f") (result f32 i32 f64) + f32.const 3.14 + return_call 0 + ) +)`, /type mismatch/); diff --git a/js/src/jit-test/tests/wasm/tail-calls/gc.js b/js/src/jit-test/tests/wasm/tail-calls/gc.js index bf8ded15a73e..27ddcb9ac299 100644 --- a/js/src/jit-test/tests/wasm/tail-calls/gc.js +++ b/js/src/jit-test/tests/wasm/tail-calls/gc.js @@ -168,3 +168,53 @@ let fns = i.exports; assertEq(fns.churn(800), -575895114); assertEq(fns.churn(1200), -1164697516); + +wasmValidateText(`(module + (rec + (type $s1 (sub (struct i32))) + (type $s2 (sub $s1 (struct i32 f32))) + ) + (func (result (ref $s2)) + struct.new_default $s2 + ) + (func (export "f") (result (ref $s1)) + return_call 0 + ) +)`); + +wasmFailValidateText(`(module + (rec + (type $s1 (sub (struct i32))) + (type $s2 (sub $s1 (struct i32 f32))) + ) + (func (result (ref $s1)) + struct.new_default $s1 + ) + (func (export "f") (result (ref $s2)) + return_call 0 + ) +)`, /type mismatch/); + +wasmValidateText(`(module + (rec + (type $s1 (sub (struct i32))) + (type $s2 (sub $s1 (struct i32 f32))) + ) + (type $t (func (result (ref $s2)))) + (func (export "f") (param (ref $t)) (result (ref $s1)) + local.get 0 + return_call_ref $t + ) +)`); + +wasmFailValidateText(`(module + (rec + (type $s1 (sub (struct i32))) + (type $s2 (sub $s1 (struct i32 f32))) + ) + (type $t (func (result (ref $s1)))) + (func (export "f") (param (ref $t)) (result (ref $s2)) + local.get 0 + return_call_ref $t + ) +)`, /type mismatch/); diff --git a/js/src/jit-test/tests/wasm/tail-calls/return-call-indirect-validate.js b/js/src/jit-test/tests/wasm/tail-calls/return-call-indirect-validate.js index b12f50183609..f87660ddadd0 100644 --- a/js/src/jit-test/tests/wasm/tail-calls/return-call-indirect-validate.js +++ b/js/src/jit-test/tests/wasm/tail-calls/return-call-indirect-validate.js @@ -143,7 +143,7 @@ wasmFailValidateText( (table 0 anyfunc) (func $type-void-vs-num (result i32) (i32.eqz (return_call_indirect (type 0) (i32.const 0)))))`, - /popping value from empty stack/); + /type mismatch: expected 1 values, got 0 values/); wasmFailValidateText( `(module @@ -151,7 +151,7 @@ wasmFailValidateText( (table 0 anyfunc) (func $type-num-vs-num (i32.eqz (return_call_indirect (type 0) (i32.const 0)))))`, - /unused values not explicitly dropped/); + /type mismatch: expected 0 values, got 1 values/); wasmFailValidateText( `(module diff --git a/js/src/jit-test/tests/wasm/tail-calls/return-call-validate.js b/js/src/jit-test/tests/wasm/tail-calls/return-call-validate.js index 70210471e4b2..344549f58f37 100644 --- a/js/src/jit-test/tests/wasm/tail-calls/return-call-validate.js +++ b/js/src/jit-test/tests/wasm/tail-calls/return-call-validate.js @@ -97,7 +97,7 @@ wasmFailValidateText( (func $type-void-vs-num (result i32) (return_call 1) (i32.const 0)) (func))`, - /popping value from empty stack/); + /type mismatch: expected 1 values, got 0 values/); wasmFailValidateText( `(module diff --git a/js/src/jit-test/tests/wasm/tail-calls/return_call_indirect.js b/js/src/jit-test/tests/wasm/tail-calls/return_call_indirect.js index 9bc94eded996..b7aa5c83e24b 100644 --- a/js/src/jit-test/tests/wasm/tail-calls/return_call_indirect.js +++ b/js/src/jit-test/tests/wasm/tail-calls/return_call_indirect.js @@ -52,12 +52,13 @@ check_stub1: { var ins = wasmEvalText(`(module (import "" "fac-acc" (func $fac-acc (param i64 i64) (result i64))) (type $ty (func (param i64 i64) (result i64))) + (type $tz (func (param i64) (result i64))) (table $t 1 1 funcref) (func $f (export "fac") (param i64) (result i64) local.get 0 i64.const 1 i32.const 0 - return_call_indirect $t + return_call_indirect $t (type $tz) ) (elem $t (i32.const 0) $fac-acc) diff --git a/js/src/wasm/WasmBaselineCompile.cpp b/js/src/wasm/WasmBaselineCompile.cpp index 8bce0ce191ee..ff3536c27f42 100644 --- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -4817,8 +4817,7 @@ bool BaseCompiler::emitCall() { bool BaseCompiler::emitReturnCall() { uint32_t funcIndex; BaseNothingVector args_{}; - BaseNothingVector unused_values{}; - if (!iter_.readReturnCall(&funcIndex, &args_, &unused_values)) { + if (!iter_.readReturnCall(&funcIndex, &args_)) { return false; } @@ -4934,9 +4933,8 @@ bool BaseCompiler::emitReturnCallIndirect() { uint32_t tableIndex; Nothing callee_; BaseNothingVector args_{}; - BaseNothingVector unused_values{}; if (!iter_.readReturnCallIndirect(&funcTypeIndex, &tableIndex, &callee_, - &args_, &unused_values)) { + &args_)) { return false; } @@ -5042,9 +5040,7 @@ bool BaseCompiler::emitReturnCallRef() { const FuncType* funcType; Nothing unused_callee; BaseNothingVector unused_args{}; - BaseNothingVector unused_values{}; - if (!iter_.readReturnCallRef(&funcType, &unused_callee, &unused_args, - &unused_values)) { + if (!iter_.readReturnCallRef(&funcType, &unused_callee, &unused_args)) { return false; } diff --git a/js/src/wasm/WasmIonCompile.cpp b/js/src/wasm/WasmIonCompile.cpp index d70ae328ba19..308f0ad2376d 100644 --- a/js/src/wasm/WasmIonCompile.cpp +++ b/js/src/wasm/WasmIonCompile.cpp @@ -5101,8 +5101,7 @@ static bool EmitReturnCall(FunctionCompiler& f) { uint32_t funcIndex; DefVector args; - DefVector unused_values; - if (!f.iter().readReturnCall(&funcIndex, &args, &unused_values)) { + if (!f.iter().readReturnCall(&funcIndex, &args)) { return false; } @@ -5142,9 +5141,8 @@ static bool EmitReturnCallIndirect(FunctionCompiler& f) { uint32_t tableIndex; MDefinition* callee; DefVector args; - DefVector unused_values; if (!f.iter().readReturnCallIndirect(&funcTypeIndex, &tableIndex, &callee, - &args, &unused_values)) { + &args)) { return false; } @@ -5176,9 +5174,8 @@ static bool EmitReturnCallRef(FunctionCompiler& f) { const FuncType* funcType; MDefinition* callee; DefVector args; - DefVector unused_values; - if (!f.iter().readReturnCallRef(&funcType, &callee, &args, &unused_values)) { + if (!f.iter().readReturnCallRef(&funcType, &callee, &args)) { return false; } diff --git a/js/src/wasm/WasmOpIter.h b/js/src/wasm/WasmOpIter.h index f212357dcca7..4f91f57c7d9a 100644 --- a/js/src/wasm/WasmOpIter.h +++ b/js/src/wasm/WasmOpIter.h @@ -690,12 +690,10 @@ class MOZ_STACK_CLASS OpIter : private Policy { ValueVector* argValues); #ifdef ENABLE_WASM_TAIL_CALLS [[nodiscard]] bool readReturnCall(uint32_t* funcTypeIndex, - ValueVector* argValues, - ValueVector* values); + ValueVector* argValues); [[nodiscard]] bool readReturnCallIndirect(uint32_t* funcTypeIndex, uint32_t* tableIndex, Value* callee, - ValueVector* argValues, - ValueVector* values); + ValueVector* argValues); #endif #ifdef ENABLE_WASM_FUNCTION_REFERENCES [[nodiscard]] bool readCallRef(const FuncType** funcType, Value* callee, @@ -703,8 +701,7 @@ class MOZ_STACK_CLASS OpIter : private Policy { # ifdef ENABLE_WASM_TAIL_CALLS [[nodiscard]] bool readReturnCallRef(const FuncType** funcType, Value* callee, - ValueVector* argValues, - ValueVector* values); + ValueVector* argValues); # endif #endif [[nodiscard]] bool readOldCallDirect(uint32_t numFuncImports, @@ -2462,8 +2459,7 @@ inline bool OpIter::readCall(uint32_t* funcTypeIndex, #ifdef ENABLE_WASM_TAIL_CALLS template inline bool OpIter::readReturnCall(uint32_t* funcTypeIndex, - ValueVector* argValues, - ValueVector* values) { + ValueVector* argValues) { MOZ_ASSERT(Classify(op_) == OpKind::ReturnCall); if (!readVarU32(funcTypeIndex)) { @@ -2480,15 +2476,11 @@ inline bool OpIter::readReturnCall(uint32_t* funcTypeIndex, return false; } - if (!push(ResultType::Vector(funcType.results()))) { - return false; - } - + // Check if callee results are subtypes of caller's. Control& body = controlStack_[0]; MOZ_ASSERT(body.kind() == LabelKind::Body); - - // Pop function results as the instruction will cause a return. - if (!popWithType(body.resultType(), values)) { + if (!checkIsSubtypeOf(ResultType::Vector(funcType.results()), + body.resultType())) { return false; } @@ -2549,8 +2541,7 @@ template inline bool OpIter::readReturnCallIndirect(uint32_t* funcTypeIndex, uint32_t* tableIndex, Value* callee, - ValueVector* argValues, - ValueVector* values) { + ValueVector* argValues) { MOZ_ASSERT(Classify(op_) == OpKind::ReturnCallIndirect); MOZ_ASSERT(funcTypeIndex != tableIndex); @@ -2589,15 +2580,11 @@ inline bool OpIter::readReturnCallIndirect(uint32_t* funcTypeIndex, return false; } - if (!push(ResultType::Vector(funcType.results()))) { - return false; - } - + // Check if callee results are subtypes of caller's. Control& body = controlStack_[0]; MOZ_ASSERT(body.kind() == LabelKind::Body); - - // Pop function results as the instruction will cause a return. - if (!popWithType(body.resultType(), values)) { + if (!checkIsSubtypeOf(ResultType::Vector(funcType.results()), + body.resultType())) { return false; } @@ -2636,8 +2623,7 @@ inline bool OpIter::readCallRef(const FuncType** funcType, template inline bool OpIter::readReturnCallRef(const FuncType** funcType, Value* callee, - ValueVector* argValues, - ValueVector* values) { + ValueVector* argValues) { MOZ_ASSERT(Classify(op_) == OpKind::ReturnCallRef); uint32_t funcTypeIndex; @@ -2656,15 +2642,11 @@ inline bool OpIter::readReturnCallRef(const FuncType** funcType, return false; } - if (!push(ResultType::Vector((*funcType)->results()))) { - return false; - } - + // Check if callee results are subtypes of caller's. Control& body = controlStack_[0]; MOZ_ASSERT(body.kind() == LabelKind::Body); - - // Pop function results as the instruction will cause a return. - if (!popWithType(body.resultType(), values)) { + if (!checkIsSubtypeOf(ResultType::Vector((*funcType)->results()), + body.resultType())) { return false; } diff --git a/js/src/wasm/WasmValidate.cpp b/js/src/wasm/WasmValidate.cpp index 045bab6198aa..6aa5fadc8ffa 100644 --- a/js/src/wasm/WasmValidate.cpp +++ b/js/src/wasm/WasmValidate.cpp @@ -223,8 +223,7 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env, } uint32_t unusedIndex; NothingVector unusedArgs{}; - NothingVector unusedValues{}; - CHECK(iter.readReturnCall(&unusedIndex, &unusedArgs, &unusedValues)); + CHECK(iter.readReturnCall(&unusedIndex, &unusedArgs)); } case uint16_t(Op::ReturnCallIndirect): { if (!env.tailCallsEnabled()) { @@ -232,9 +231,8 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env, } uint32_t unusedIndex, unusedIndex2; NothingVector unusedArgs{}; - NothingVector unusedValues{}; CHECK(iter.readReturnCallIndirect(&unusedIndex, &unusedIndex2, ¬hing, - &unusedArgs, &unusedValues)); + &unusedArgs)); } #endif #ifdef ENABLE_WASM_FUNCTION_REFERENCES @@ -253,9 +251,7 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env, } const FuncType* unusedType; NothingVector unusedArgs{}; - NothingVector unusedValues{}; - CHECK(iter.readReturnCallRef(&unusedType, ¬hing, &unusedArgs, - &unusedValues)); + CHECK(iter.readReturnCallRef(&unusedType, ¬hing, &unusedArgs)); } # endif #endif