Commit f1acce32 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by V8 LUCI CQ

[wasm] Make a few more traps uncatchable

With the upcoming "exception handling" proposal, we have to ensure
that traps are not catchable. This patch adds missing "uncatchable"
annotations to traps in the C-API and table-related instructions.

Fixed: v8:11813
Change-Id: I7bbd5043ede58a5315bd5117eb496ed014e79e91
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2953160
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75082}
parent 74dde2fc
......@@ -85,7 +85,6 @@ class V8_NODISCARD ClearThreadInWasmScope {
};
Object ThrowWasmError(Isolate* isolate, MessageTemplate message) {
HandleScope scope(isolate);
Handle<JSObject> error_obj = isolate->factory()->NewWasmRuntimeError(message);
JSObject::AddProperty(isolate, error_obj,
isolate->factory()->wasm_uncatchable_symbol(),
......@@ -133,6 +132,7 @@ RUNTIME_FUNCTION(Runtime_WasmMemoryGrow) {
RUNTIME_FUNCTION(Runtime_ThrowWasmError) {
ClearThreadInWasmScope flag_scope(isolate);
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_SMI_ARG_CHECKED(message_id, 0);
return ThrowWasmError(isolate, MessageTemplateFromInt(message_id));
......@@ -381,9 +381,7 @@ Object ThrowTableOutOfBounds(Isolate* isolate,
if (isolate->context().is_null()) {
isolate->set_context(instance->native_context());
}
Handle<Object> error_obj = isolate->factory()->NewWasmRuntimeError(
MessageTemplate::kWasmTrapTableOutOfBounds);
return isolate->Throw(*error_obj);
return ThrowWasmError(isolate, MessageTemplate::kWasmTrapTableOutOfBounds);
}
} // namespace
......
......@@ -1006,8 +1006,11 @@ auto Trap::make(Store* store_abs, const Message& message) -> own<Trap> {
i::Isolate* isolate = store->i_isolate();
i::HandleScope handle_scope(isolate);
i::Handle<i::String> string = VecToString(isolate, message);
i::Handle<i::JSReceiver> exception = i::Handle<i::JSReceiver>::cast(
isolate->factory()->NewError(isolate->error_function(), string));
i::Handle<i::JSObject> exception =
isolate->factory()->NewError(isolate->error_function(), string);
i::JSObject::AddProperty(isolate, exception,
isolate->factory()->wasm_uncatchable_symbol(),
isolate->factory()->true_value(), i::NONE);
return implement<Trap>::type::make(store, exception);
}
......
......@@ -531,6 +531,10 @@ void TestTrapNotCaught(byte* code, size_t code_size,
constexpr uint32_t kResultSuccess = 23;
constexpr uint32_t kResultCaught = 47;
// Add an indirect function table.
const int kTableSize = 2;
r.builder().AddIndirectFunctionTable(nullptr, kTableSize);
// Build a trapping helper function.
WasmFunctionCompiler& trap_func = r.NewFunction(sigs.i_ii());
trap_func.Build(code, code + code_size);
......@@ -574,6 +578,17 @@ WASM_EXEC_TEST(TryCatchTrapRemByZero) {
TestTrapNotCaught(code, arraysize(code), execution_tier);
}
WASM_EXEC_TEST(TryCatchTrapTableFill) {
EXPERIMENTAL_FLAG_SCOPE(reftypes);
int table_index = 0;
int length = 10; // OOB.
int start = 10; // OOB.
byte code[] = {WASM_TABLE_FILL(table_index, WASM_I32V(length),
WASM_REF_NULL(kFuncRefCode), WASM_I32V(start)),
WASM_I32V_1(42)};
TestTrapNotCaught(code, arraysize(code), execution_tier);
}
namespace {
// TODO(cleanup): Define in cctest.h and re-use where appropriate.
class IsolateScope {
......
......@@ -35,6 +35,7 @@ void ExpectMessage(const char* expected, const Message& message) {
} // namespace
TEST_F(WasmCapiTest, Traps) {
FLAG_experimental_wasm_eh = true;
ValueType i32_type[] = {kWasmI32};
FunctionSig sig(1, 0, i32_type);
uint32_t callback_index = builder()->AddImport(CStrVector("callback"), &sig);
......@@ -48,6 +49,11 @@ TEST_F(WasmCapiTest, Traps) {
byte code3[] = {WASM_I32V_3(0), WASM_UNREACHABLE, WASM_I32V_1(1)};
AddFunction(code3, sizeof(code3), &sig);
// Check that traps returned from a C callback are uncatchable in Wasm.
byte code4[] = {WASM_TRY_CATCH_ALL_T(
kWasmI32, WASM_CALL_FUNCTION0(callback_index), WASM_I32V(42))};
AddExportedFunction(CStrVector("uncatchable"), code4, sizeof(code4), &sig);
own<FuncType> func_type =
FuncType::make(ownvec<ValType>::make(),
ownvec<ValType>::make(ValType::make(::wasm::I32)));
......@@ -113,6 +119,13 @@ TEST_F(WasmCapiTest, Traps) {
EXPECT_EQ(2u, frame->func_index());
EXPECT_EQ(1u, frame->func_offset());
EXPECT_EQ(func2_offset + frame->func_offset(), frame->module_offset());
Func* wasm_uncatchable_func = GetExportedFunction(2);
Val* args = nullptr;
Val results[1] = {Val(3.14)}; // Sentinel value.
own<Trap> uncatchable_trap = wasm_uncatchable_func->call(args, results);
EXPECT_NE(nullptr, uncatchable_trap.get());
EXPECT_EQ(::wasm::F64, results[0].kind());
}
} // namespace wasm
......
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