Commit 9323085a authored by Manos Koukoutos's avatar Manos Koukoutos Committed by V8 LUCI CQ

[wasm-gc] Add ArrayTooLarge trap

This will be thrown during array allocations if the requested size is
larger than kV8MaxWasmArrayLength.

Additional changes:
- In test-gc.cc, add the possibility to check against the trap message
  in CheckHasThrown.
- Small reorganization of WasmGCTester in test-gc.cc.

Bug: v8:7748
Change-Id: I6f74b525bd7087fcc66f43c451ef130df022b0f9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2922247Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74867}
parent 5895436b
......@@ -405,6 +405,7 @@ extern enum MessageTemplate {
kWasmTrapNullDereference,
kWasmTrapIllegalCast,
kWasmTrapArrayOutOfBounds,
kWasmTrapArrayTooLarge,
kWeakRefsRegisterTargetAndHoldingsMustNotBeSame,
kWeakRefsRegisterTargetMustBeObject,
kWeakRefsUnregisterTokenMustBeObject,
......
......@@ -524,4 +524,8 @@ builtin ThrowWasmTrapIllegalCast(): JSAny {
builtin ThrowWasmTrapArrayOutOfBounds(): JSAny {
tail WasmTrap(SmiConstant(MessageTemplate::kWasmTrapArrayOutOfBounds));
}
builtin ThrowWasmTrapArrayTooLarge(): JSAny {
tail WasmTrap(SmiConstant(MessageTemplate::kWasmTrapArrayTooLarge));
}
}
......@@ -1693,7 +1693,8 @@ enum class LoadSensitivity {
V(TrapRethrowNull) \
V(TrapNullDereference) \
V(TrapIllegalCast) \
V(TrapArrayOutOfBounds)
V(TrapArrayOutOfBounds) \
V(TrapArrayTooLarge)
enum KeyedAccessLoadMode {
STANDARD_LOAD,
......
......@@ -576,6 +576,7 @@ namespace internal {
T(WasmTrapNullDereference, "dereferencing a null pointer") \
T(WasmTrapIllegalCast, "illegal cast") \
T(WasmTrapArrayOutOfBounds, "array element access out of bounds") \
T(WasmTrapArrayTooLarge, "requested new array is too large") \
T(WasmExceptionError, "wasm exception") \
/* Asm.js validation related */ \
T(AsmJsInvalid, "Invalid asm.js: %") \
......
......@@ -5572,7 +5572,7 @@ Node* WasmGraphBuilder::ArrayNewWithRtt(uint32_t array_index,
Node* length, Node* initial_value,
Node* rtt,
wasm::WasmCodePosition position) {
TrapIfFalse(wasm::kTrapArrayOutOfBounds,
TrapIfFalse(wasm::kTrapArrayTooLarge,
gasm_->Uint32LessThanOrEqual(
length, gasm_->Uint32Constant(wasm::kV8MaxWasmArrayLength)),
position);
......
......@@ -4946,7 +4946,7 @@ class LiftoffCompiler {
LiftoffRegister length =
__ LoadToRegister(__ cache_state()->stack_state.end()[-2], {});
Label* trap_label =
AddOutOfLineTrap(decoder, WasmCode::kThrowWasmTrapArrayOutOfBounds);
AddOutOfLineTrap(decoder, WasmCode::kThrowWasmTrapArrayTooLarge);
__ emit_i32_cond_jumpi(kUnsignedGreaterThan, trap_label, length.gp(),
static_cast<int>(wasm::kV8MaxWasmArrayLength));
}
......
......@@ -111,48 +111,25 @@ class WasmGCTester {
instance_ = maybe_instance.ToHandleChecked();
}
void CallFunctionImpl(uint32_t function_index, const FunctionSig* sig,
CWasmArgumentsPacker* packer) {
WasmCodeRefScope scope;
NativeModule* native_module = instance_->module_object().native_module();
WasmCode* code = native_module->GetCode(function_index);
Address wasm_call_target = code->instruction_start();
Handle<Object> object_ref = instance_;
Handle<Code> c_wasm_entry =
compiler::CompileCWasmEntry(isolate_, sig, native_module->module());
Execution::CallWasm(isolate_, c_wasm_entry, wasm_call_target, object_ref,
packer->argv());
}
void CheckResult(uint32_t function_index, int32_t expected) {
FunctionSig* sig = sigs.i_v();
const FunctionSig* sig = sigs.i_v();
DCHECK(*sig == *instance_->module()->functions[function_index].sig);
CWasmArgumentsPacker packer(CWasmArgumentsPacker::TotalSize(sig));
CallFunctionImpl(function_index, sig, &packer);
CHECK(!isolate_->has_pending_exception());
packer.Reset();
CHECK_EQ(expected, packer.Pop<int32_t>());
CheckResultImpl(function_index, sig, &packer, expected);
}
void CheckResult(uint32_t function_index, int32_t expected, int32_t arg) {
FunctionSig* sig = sigs.i_i();
const FunctionSig* sig = sigs.i_i();
DCHECK(*sig == *instance_->module()->functions[function_index].sig);
CWasmArgumentsPacker packer(CWasmArgumentsPacker::TotalSize(sig));
packer.Push(arg);
CallFunctionImpl(function_index, sig, &packer);
if (isolate_->has_pending_exception()) {
Handle<String> message =
ErrorUtils::ToString(isolate_,
handle(isolate_->pending_exception(), isolate_))
.ToHandleChecked();
FATAL("%s", message->ToCString().get());
}
packer.Reset();
CHECK_EQ(expected, packer.Pop<int32_t>());
CheckResultImpl(function_index, sig, &packer, expected);
}
MaybeHandle<Object> GetResultObject(uint32_t function_index) {
const FunctionSig* sig = instance_->module()->functions[function_index].sig;
DCHECK_EQ(sig->parameter_count(), 0);
DCHECK_EQ(sig->return_count(), 1);
CWasmArgumentsPacker packer(CWasmArgumentsPacker::TotalSize(sig));
CallFunctionImpl(function_index, sig, &packer);
CHECK(!isolate_->has_pending_exception());
......@@ -163,6 +140,7 @@ class WasmGCTester {
MaybeHandle<Object> GetResultObject(uint32_t function_index, int32_t arg) {
const FunctionSig* sig = instance_->module()->functions[function_index].sig;
DCHECK_EQ(sig->parameter_count(), 1);
DCHECK_EQ(sig->return_count(), 1);
DCHECK(sig->parameters()[0] == kWasmI32);
CWasmArgumentsPacker packer(CWasmArgumentsPacker::TotalSize(sig));
packer.Push(arg);
......@@ -172,22 +150,21 @@ class WasmGCTester {
return Handle<Object>(Object(packer.Pop<Address>()), isolate_);
}
void CheckHasThrown(uint32_t function_index) {
void CheckHasThrown(uint32_t function_index, const char* expected = "") {
const FunctionSig* sig = instance_->module()->functions[function_index].sig;
DCHECK_EQ(sig->parameter_count(), 0);
CWasmArgumentsPacker packer(CWasmArgumentsPacker::TotalSize(sig));
CallFunctionImpl(function_index, sig, &packer);
CHECK(isolate_->has_pending_exception());
isolate_->clear_pending_exception();
CheckHasThrownImpl(function_index, sig, &packer, expected);
}
void CheckHasThrown(uint32_t function_index, int32_t arg) {
FunctionSig* sig = sigs.i_i();
DCHECK(*sig == *instance_->module()->functions[function_index].sig);
void CheckHasThrown(uint32_t function_index, int32_t arg,
const char* expected = "") {
const FunctionSig* sig = instance_->module()->functions[function_index].sig;
DCHECK_EQ(sig->parameter_count(), 1);
DCHECK(sig->parameters()[0] == kWasmI32);
CWasmArgumentsPacker packer(CWasmArgumentsPacker::TotalSize(sig));
packer.Push(arg);
CallFunctionImpl(function_index, sig, &packer);
CHECK(isolate_->has_pending_exception());
isolate_->clear_pending_exception();
CheckHasThrownImpl(function_index, sig, &packer, expected);
}
Handle<WasmInstanceObject> instance() { return instance_; }
......@@ -205,6 +182,46 @@ class WasmGCTester {
const FlagScope<bool> flag_liftoff_only;
const FlagScope<bool> flag_tierup;
void CheckResultImpl(uint32_t function_index, const FunctionSig* sig,
CWasmArgumentsPacker* packer, int32_t expected) {
CallFunctionImpl(function_index, sig, packer);
if (isolate_->has_pending_exception()) {
Handle<String> message =
ErrorUtils::ToString(isolate_,
handle(isolate_->pending_exception(), isolate_))
.ToHandleChecked();
FATAL("%s", message->ToCString().get());
}
packer->Reset();
CHECK_EQ(expected, packer->Pop<int32_t>());
}
void CheckHasThrownImpl(uint32_t function_index, const FunctionSig* sig,
CWasmArgumentsPacker* packer, const char* expected) {
CallFunctionImpl(function_index, sig, packer);
CHECK(isolate_->has_pending_exception());
Handle<String> message =
ErrorUtils::ToString(isolate_,
handle(isolate_->pending_exception(), isolate_))
.ToHandleChecked();
std::string message_str(message->ToCString().get());
CHECK_NE(message_str.find(expected), std::string::npos);
isolate_->clear_pending_exception();
}
void CallFunctionImpl(uint32_t function_index, const FunctionSig* sig,
CWasmArgumentsPacker* packer) {
WasmCodeRefScope scope;
NativeModule* native_module = instance_->module_object().native_module();
WasmCode* code = native_module->GetCode(function_index);
Address wasm_call_target = code->instruction_start();
Handle<Object> object_ref = instance_;
Handle<Code> c_wasm_entry =
compiler::CompileCWasmEntry(isolate_, sig, native_module->module());
Execution::CallWasm(isolate_, c_wasm_entry, wasm_call_target, object_ref,
packer->argv());
}
v8::internal::AccountingAllocator allocator;
Zone zone_;
WasmModuleBuilder builder_;
......@@ -813,7 +830,7 @@ WASM_COMPILED_EXEC_TEST(WasmBasicArray) {
CHECK(Handle<WasmArray>::cast(large_result)->Size() >
kMaxRegularHeapObjectSize);
tester.CheckHasThrown(kAllocateTooLarge);
tester.CheckHasThrown(kAllocateTooLarge, "requested new array is too large");
}
WASM_COMPILED_EXEC_TEST(WasmPackedArrayU) {
......
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