[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: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#75082}
This commit is contained in:
parent
74dde2fce1
commit
f1acce32c5
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user