wasm/c-api: fix the index of StackTraceFrame

CreateFrameFromInternal always creates StackFrame from the frame at the index zero,
which is fine for the usage in Trap::origin, but is a bug for Trap::trace

Change-Id: Ia9471f600c5165ffc1c165b2f114b40acbe5b1e9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2465353
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70465}
This commit is contained in:
mathetake 2020-10-13 15:57:30 +09:00 committed by Commit Bot
parent 0dc21d81d0
commit 8deb0fd3ed
4 changed files with 29 additions and 11 deletions

View File

@ -225,3 +225,4 @@ Zhao Jiazhong <kyslie3100@gmail.com>
Zhongping Wang <kewpie.w.zp@gmail.com>
柳荣一 <admin@web-tinker.com>
Tianping Yang <yangtianping@oppo.com>
Takeshi Yoneda <takeshi@tetrate.io>

View File

@ -209,8 +209,7 @@ auto seal(const typename implement<C>::type* x) -> const C* {
// Configuration
struct ConfigImpl {
};
struct ConfigImpl {};
template <>
struct implement<Config> {
@ -888,8 +887,8 @@ own<Instance> GetInstance(StoreImpl* store,
own<Frame> CreateFrameFromInternal(i::Handle<i::FixedArray> frames, int index,
i::Isolate* isolate, StoreImpl* store) {
i::Handle<i::StackTraceFrame> frame(i::StackTraceFrame::cast(frames->get(0)),
isolate);
i::Handle<i::StackTraceFrame> frame(
i::StackTraceFrame::cast(frames->get(index)), isolate);
i::Handle<i::WasmInstanceObject> instance =
i::StackTraceFrame::GetWasmInstance(frame);
uint32_t func_index = i::StackTraceFrame::GetWasmFunctionIndex(frame);

View File

@ -40,10 +40,13 @@ TEST_F(WasmCapiTest, Traps) {
uint32_t callback_index = builder()->AddImport(CStrVector("callback"), &sig);
byte code[] = {WASM_CALL_FUNCTION0(callback_index)};
AddExportedFunction(CStrVector("callback"), code, sizeof(code), &sig);
// The first constant is a 4-byte dummy so that the {unreachable} trap
// has a more interesting offset.
byte code2[] = {WASM_I32V_3(0), WASM_UNREACHABLE, WASM_I32V_1(1)};
byte code2[] = {WASM_CALL_FUNCTION0(3)};
AddExportedFunction(CStrVector("unreachable"), code2, sizeof(code2), &sig);
// The first constant is a 4-byte dummy so that the {unreachable} trap
// has a more interesting offset. This is called by code2.
byte code3[] = {WASM_I32V_3(0), WASM_UNREACHABLE, WASM_I32V_1(1)};
AddFunction(code3, sizeof(code3), &sig);
own<FuncType> func_type =
FuncType::make(ownvec<ValType>::make(),
@ -65,8 +68,10 @@ TEST_F(WasmCapiTest, Traps) {
ASSERT_TRUE(result.ok());
const WasmFunction* func1 = &result.value()->functions[1];
const WasmFunction* func2 = &result.value()->functions[2];
const WasmFunction* func3 = &result.value()->functions[3];
const uint32_t func1_offset = func1->code.offset();
const uint32_t func2_offset = func2->code.offset();
const uint32_t func3_offset = func3->code.offset();
Func* cpp_trapping_func = GetExportedFunction(0);
own<Trap> cpp_trap = cpp_trapping_func->call();
@ -91,15 +96,22 @@ TEST_F(WasmCapiTest, Traps) {
ExpectMessage("Uncaught RuntimeError: unreachable", wasm_trap->message());
frame = wasm_trap->origin();
EXPECT_TRUE(frame->instance()->same(instance()));
EXPECT_EQ(2u, frame->func_index());
EXPECT_EQ(3u, frame->func_index());
EXPECT_EQ(5u, frame->func_offset());
EXPECT_EQ(func2_offset + frame->func_offset(), frame->module_offset());
EXPECT_EQ(func3_offset + frame->func_offset(), frame->module_offset());
trace = wasm_trap->trace();
EXPECT_EQ(1u, trace.size());
EXPECT_EQ(2u, trace.size());
frame.reset(trace[0].release());
EXPECT_TRUE(frame->instance()->same(instance()));
EXPECT_EQ(2u, frame->func_index());
EXPECT_EQ(3u, frame->func_index());
EXPECT_EQ(5u, frame->func_offset());
EXPECT_EQ(func3_offset + frame->func_offset(), frame->module_offset());
frame.reset(trace[1].release());
EXPECT_TRUE(frame->instance()->same(instance()));
EXPECT_EQ(2u, frame->func_index());
EXPECT_EQ(1u, frame->func_offset());
EXPECT_EQ(func2_offset + frame->func_offset(), frame->module_offset());
}

View File

@ -79,6 +79,12 @@ class WasmCapiTest : public ::testing::Test {
builder()->AddExport(name, fun);
}
void AddFunction(byte code[], size_t code_size, FunctionSig* sig) {
WasmFunctionBuilder* fun = builder()->AddFunction(sig);
fun->EmitCode(code, static_cast<uint32_t>(code_size));
fun->Emit(kExprEnd);
}
Func* GetExportedFunction(size_t index) {
DCHECK_GT(exports_.size(), index);
Extern* exported = exports_[index].get();