diff options
-rw-r--r-- | src/interp/binary-reader-interp.cc | 7 | ||||
-rw-r--r-- | test/interp/return-call-set-local.txt | 20 |
2 files changed, 25 insertions, 2 deletions
diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc index 7a1bc26e..699fdd20 100644 --- a/src/interp/binary-reader-interp.cc +++ b/src/interp/binary-reader-interp.cc @@ -576,7 +576,7 @@ Result BinaryReaderInterp::OnFunctionCount(Index count) { Result BinaryReaderInterp::OnFunction(Index index, Index sig_index) { CHECK_RESULT(validator_.OnFunction(GetLocation(), Var(sig_index))); FuncType& func_type = module_.func_types[sig_index]; - module_.funcs.push_back(FuncDesc{func_type, {}, 0, {}}); + module_.funcs.push_back(FuncDesc{func_type, {}, Istream::kInvalidOffset, {}}); func_types_.push_back(func_type); return Result::Ok; } @@ -1132,7 +1132,10 @@ Result BinaryReaderInterp::OnReturnCallExpr(Index func_index) { if (func_index >= num_func_imports()) { istream_.Emit(Opcode::InterpAdjustFrameForReturnCall, func_index); - istream_.Emit(Opcode::Br, GetFuncOffset(func_index)); + istream_.Emit(Opcode::Br); + // We emit this separately to ensure that the fixup generated by + // GetFuncOffset comes after the Br opcode. + istream_.Emit(GetFuncOffset(func_index)); } else { istream_.Emit(Opcode::InterpCallImport, func_index); istream_.Emit(Opcode::Return); diff --git a/test/interp/return-call-set-local.txt b/test/interp/return-call-set-local.txt new file mode 100644 index 00000000..5b566361 --- /dev/null +++ b/test/interp/return-call-set-local.txt @@ -0,0 +1,20 @@ +;;; TOOL: run-interp +;;; ARGS*: --enable-tail-call +(module + (func (export "f") (result i32) + (i64.const 1) + (return_call $g)) + + (func $g (param i64) (result i32) + (i32.const 3) + (return_call $h)) + + (func $h (param i32) (result i32) + (i32.const 2) + (local.set 0) + (local.get 0) + return) +) +(;; STDOUT ;;; +f() => i32:2 +;;; STDOUT ;;) |