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

[wasm-gc] Fix max array length

The static limit didn't account for possible S128 elements.
This patch makes the limit element type specific.

Fixed: chromium:1237024
Change-Id: Ic1e37656e2882c0eb7ea6400c83e4094eb747e88
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3097269Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76303}
parent c357f447
...@@ -5545,7 +5545,7 @@ Node* WasmGraphBuilder::ArrayNewWithRtt(uint32_t array_index, ...@@ -5545,7 +5545,7 @@ Node* WasmGraphBuilder::ArrayNewWithRtt(uint32_t array_index,
wasm::WasmCodePosition position) { wasm::WasmCodePosition position) {
TrapIfFalse(wasm::kTrapArrayTooLarge, TrapIfFalse(wasm::kTrapArrayTooLarge,
gasm_->Uint32LessThanOrEqual( gasm_->Uint32LessThanOrEqual(
length, gasm_->Uint32Constant(wasm::kV8MaxWasmArrayLength)), length, gasm_->Uint32Constant(WasmArray::MaxLength(type))),
position); position);
wasm::ValueType element_type = type->element_type(); wasm::ValueType element_type = type->element_type();
Builtin stub = ChooseArrayAllocationBuiltin(element_type, initial_value); Builtin stub = ChooseArrayAllocationBuiltin(element_type, initial_value);
......
...@@ -5018,7 +5018,7 @@ class LiftoffCompiler { ...@@ -5018,7 +5018,7 @@ class LiftoffCompiler {
Label* trap_label = Label* trap_label =
AddOutOfLineTrap(decoder, WasmCode::kThrowWasmTrapArrayTooLarge); AddOutOfLineTrap(decoder, WasmCode::kThrowWasmTrapArrayTooLarge);
__ emit_i32_cond_jumpi(kUnsignedGreaterThan, trap_label, length.gp(), __ emit_i32_cond_jumpi(kUnsignedGreaterThan, trap_label, length.gp(),
static_cast<int>(wasm::kV8MaxWasmArrayLength)); WasmArray::MaxLength(imm.array_type));
} }
ValueKind elem_kind = imm.array_type->element_type().kind(); ValueKind elem_kind = imm.array_type->element_type().kind();
int elem_size = element_size_bytes(elem_kind); int elem_size = element_size_bytes(elem_kind);
......
...@@ -58,9 +58,6 @@ constexpr size_t kV8MaxWasmMemories = 1; ...@@ -58,9 +58,6 @@ constexpr size_t kV8MaxWasmMemories = 1;
// GC proposal. These limits are not standardized yet. // GC proposal. These limits are not standardized yet.
constexpr size_t kV8MaxWasmStructFields = 999; constexpr size_t kV8MaxWasmStructFields = 999;
constexpr uint32_t kV8MaxRttSubtypingDepth = 31; constexpr uint32_t kV8MaxRttSubtypingDepth = 31;
// Maximum supported by implementation: ((1<<27)-3).
// Reason: total object size in bytes must fit into a Smi, for filler objects.
constexpr size_t kV8MaxWasmArrayLength = 1u << 26;
constexpr size_t kV8MaxWasmArrayInitLength = 999; constexpr size_t kV8MaxWasmArrayInitLength = 999;
static_assert(kV8MaxWasmTableSize <= 4294967295, // 2^32 - 1 static_assert(kV8MaxWasmTableSize <= 4294967295, // 2^32 - 1
......
...@@ -2209,10 +2209,6 @@ Handle<AsmWasmData> AsmWasmData::New( ...@@ -2209,10 +2209,6 @@ Handle<AsmWasmData> AsmWasmData::New(
return result; return result;
} }
static_assert(wasm::kV8MaxWasmArrayLength <=
(Smi::kMaxValue - WasmArray::kHeaderSize) / kDoubleSize,
"max Wasm array size must fit into max object size");
namespace wasm { namespace wasm {
bool TypecheckJSObject(Isolate* isolate, const WasmModule* module, bool TypecheckJSObject(Isolate* isolate, const WasmModule* module,
......
...@@ -947,6 +947,14 @@ class WasmArray : public TorqueGeneratedWasmArray<WasmArray, WasmObject> { ...@@ -947,6 +947,14 @@ class WasmArray : public TorqueGeneratedWasmArray<WasmArray, WasmObject> {
// Returns the Address of the element at {index}. // Returns the Address of the element at {index}.
Address ElementAddress(uint32_t index); Address ElementAddress(uint32_t index);
static int MaxLength(const wasm::ArrayType* type) {
// The total object size must fit into a Smi, for filler objects. To make
// the behavior of Wasm programs independent from the Smi configuration,
// we hard-code the smaller of the two supported ranges.
int element_shift = type->element_type().element_size_log2();
return (SmiTagging<4>::kSmiMaxValue - kHeaderSize) >> element_shift;
}
DECL_PRINTER(WasmArray) DECL_PRINTER(WasmArray)
class BodyDescriptor; class BodyDescriptor;
......
...@@ -786,7 +786,8 @@ WASM_COMPILED_EXEC_TEST(WasmBasicArray) { ...@@ -786,7 +786,8 @@ WASM_COMPILED_EXEC_TEST(WasmBasicArray) {
WASM_RTT_CANON(type_index)), WASM_RTT_CANON(type_index)),
kExprEnd}); kExprEnd});
const uint32_t kTooLong = kV8MaxWasmArrayLength + 1; ArrayType array_type(kWasmI32, true);
const uint32_t kTooLong = WasmArray::MaxLength(&array_type) + 1;
const byte kAllocateTooLarge = tester.DefineFunction( const byte kAllocateTooLarge = tester.DefineFunction(
&sig_q_v, {}, &sig_q_v, {},
{WASM_ARRAY_NEW_DEFAULT(type_index, WASM_I32V(kTooLong), {WASM_ARRAY_NEW_DEFAULT(type_index, WASM_I32V(kTooLong),
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --experimental-wasm-gc
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
var builder = new WasmModuleBuilder();
let array_index = builder.addArray(kWasmS128, true);
builder.addFunction("main", kSig_i_i)
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprRttCanon, array_index,
kGCPrefix, kExprArrayNewDefault, array_index,
kGCPrefix, kExprArrayLen, array_index,
])
.exportFunc();
var instance = builder.instantiate();
assertThrows(
() => instance.exports.main(1 << 26), WebAssembly.RuntimeError,
'requested new array is too large');
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