Commit f4e322c3 authored by Sven Sauleau's avatar Sven Sauleau Committed by Commit Bot

[wasm] correct Table limit

Align the Table implementation limits with the JavaScript Embedding
limits defined in the specification (from MAX_UINT32 to 1e7).

Introduce a new helper (max_table_init_entries) that returns the
maximum number of Table entry at initialization. It takes into account
the maximum Table size, which can be passed by a flag.

Bug: v8:8633
Change-Id: Idfa19418e81f478f7886a30876e66c9b216e25ac
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1496971
Commit-Queue: Sven Sauleau <ssauleau@igalia.com>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60036}
parent 7c89c29b
......@@ -4479,9 +4479,9 @@ Node* WasmGraphBuilder::TableInit(uint32_t table_index,
Node* args[] = {
graph()->NewNode(mcgraph()->common()->NumberConstant(table_index)),
graph()->NewNode(mcgraph()->common()->NumberConstant(elem_segment_index)),
BuildConvertUint32ToSmiWithSaturation(dst, wasm::kV8MaxWasmTableSize),
BuildConvertUint32ToSmiWithSaturation(src, wasm::kV8MaxWasmTableSize),
BuildConvertUint32ToSmiWithSaturation(size, wasm::kV8MaxWasmTableSize)};
BuildConvertUint32ToSmiWithSaturation(dst, FLAG_wasm_max_table_size),
BuildConvertUint32ToSmiWithSaturation(src, FLAG_wasm_max_table_size),
BuildConvertUint32ToSmiWithSaturation(size, FLAG_wasm_max_table_size)};
Node* result =
BuildCallToRuntime(Runtime::kWasmTableInit, args, arraysize(args));
......@@ -4507,9 +4507,9 @@ Node* WasmGraphBuilder::TableCopy(uint32_t table_src_index,
Node* args[] = {
graph()->NewNode(mcgraph()->common()->NumberConstant(table_src_index)),
graph()->NewNode(mcgraph()->common()->NumberConstant(table_dst_index)),
BuildConvertUint32ToSmiWithSaturation(dst, wasm::kV8MaxWasmTableSize),
BuildConvertUint32ToSmiWithSaturation(src, wasm::kV8MaxWasmTableSize),
BuildConvertUint32ToSmiWithSaturation(size, wasm::kV8MaxWasmTableSize)};
BuildConvertUint32ToSmiWithSaturation(dst, FLAG_wasm_max_table_size),
BuildConvertUint32ToSmiWithSaturation(src, FLAG_wasm_max_table_size),
BuildConvertUint32ToSmiWithSaturation(size, FLAG_wasm_max_table_size)};
Node* result =
BuildCallToRuntime(Runtime::kWasmTableCopy, args, arraysize(args));
......
......@@ -803,7 +803,7 @@ class ModuleDecoderImpl : public Decoder {
}
uint32_t num_elem =
consume_count("number of elements", kV8MaxWasmTableEntries);
consume_count("number of elements", max_table_init_entries());
if (is_active) {
module_->elem_segments.emplace_back(table_index, offset);
} else {
......
......@@ -548,6 +548,12 @@ uint32_t max_mem_pages() {
return std::min(uint32_t{kV8MaxWasmMemoryPages}, FLAG_wasm_max_mem_pages);
}
// {max_table_init_entries} is declared in wasm-limits.h.
uint32_t max_table_init_entries() {
return std::min(uint32_t{kV8MaxWasmTableInitEntries},
FLAG_wasm_max_table_size);
}
} // namespace wasm
} // namespace internal
} // namespace v8
......@@ -1038,14 +1038,14 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
int64_t initial = 0;
if (!GetRequiredIntegerProperty(isolate, &thrower, context, descriptor,
v8_str(isolate, "initial"), &initial, 0,
i::FLAG_wasm_max_table_size)) {
i::wasm::max_table_init_entries())) {
return;
}
// The descriptor's 'maximum'.
int64_t maximum = -1;
if (!GetOptionalIntegerProperty(isolate, &thrower, context, descriptor,
v8_str(isolate, "maximum"), &maximum, initial,
i::wasm::kSpecMaxWasmTableSize)) {
i::wasm::max_table_init_entries())) {
return;
}
......
......@@ -38,13 +38,16 @@ constexpr size_t kV8MaxWasmFunctionMultiReturns = 1000;
constexpr size_t kV8MaxWasmFunctionReturns = 1;
// Don't use this limit directly, but use the value of FLAG_wasm_max_table_size.
constexpr size_t kV8MaxWasmTableSize = 10000000;
constexpr size_t kV8MaxWasmTableEntries = 10000000;
constexpr size_t kV8MaxWasmTableInitEntries = 10000000;
constexpr size_t kV8MaxWasmTables = 1;
constexpr size_t kV8MaxWasmMemories = 1;
static_assert(kV8MaxWasmMemoryPages <= kSpecMaxWasmMemoryPages,
"v8 should not be more permissive than the spec");
constexpr size_t kSpecMaxWasmTableSize = 0xFFFFFFFFu;
static_assert(kV8MaxWasmTableSize <= 4294967295, // 2^32 - 1
"v8 should not exceed WebAssembly's non-web embedding limits");
static_assert(kV8MaxWasmTableInitEntries <= kV8MaxWasmTableSize,
"JS-API should not exceed v8's limit");
constexpr uint64_t kWasmMaxHeapOffset =
static_cast<uint64_t>(
......@@ -55,6 +58,7 @@ constexpr uint64_t kWasmMaxHeapOffset =
// TODO(wasm): Make this size_t for wasm64. Currently the --wasm-max-mem-pages
// flag is only uint32_t.
uint32_t max_mem_pages();
uint32_t max_table_init_entries();
inline uint64_t max_mem_bytes() {
return uint64_t{max_mem_pages()} * kWasmPageSize;
......
......@@ -582,9 +582,9 @@ assertTrue(new Table({initial: 1, element: 'anyfunc'}) instanceof Table);
assertTrue(new Table({initial: 1.5, element: 'anyfunc'}) instanceof Table);
assertTrue(
new Table({initial: 1, maximum: 1.5, element: 'anyfunc'}) instanceof Table);
assertTrue(
new Table({initial: 1, maximum: Math.pow(2, 32) - 1, element: 'anyfunc'})
instanceof Table);
assertThrows(
() => new Table({initial: 1, maximum: Math.pow(2, 32) - 1, element: 'anyfunc'}),
RangeError, /above the upper bound/);
// 'WebAssembly.Table.prototype' data property
let tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype');
......
// Copyright 2018 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: --wasm-max-table-size=10
load("test/mjsunit/wasm/wasm-module-builder.js");
// With the flags we set the maximum table size to 10, so 11 is out-of-bounds.
const oob = 11;
(function TestJSTableInitialAboveTheLimit() {
print(arguments.callee.name);
assertThrows(
() => new WebAssembly.Table({ initial: oob, element: "anyfunc" }),
RangeError, /above the upper bound/);
})();
(function TestJSTableMaximumAboveTheLimit() {
print(arguments.callee.name);
assertThrows(
() => new WebAssembly.Table({ initial: 1, maximum: oob, element: "anyfunc" }),
RangeError, /above the upper bound/);
})();
(function TestDecodeTableInitialAboveTheLimit() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
builder.setTableBounds(oob);
assertThrows(
() => builder.instantiate(),
WebAssembly.CompileError, /is larger than implementation limit/);
})();
(function TestDecodeTableMaximumAboveTheLimit() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
builder.setTableBounds(1, oob);
assertThrows(
() => builder.instantiate(),
WebAssembly.CompileError, /is larger than implementation limit/);
})();
......@@ -10,11 +10,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
// Basic tests.
var outOfUint32RangeValue = 1e12;
var int32ButOob = 1073741824;
var kMaxUint32 = (4 * 1024 * 1024 * 1024) - 1;
var kMaxUint31 = (2 * 1024 * 1024 * 1024) - 1;
var kV8MaxWasmTableSize = 10000000;
const outOfUint32RangeValue = 1e12;
const kV8MaxWasmTableSize = 10000000;
function assertTableIsValid(table, length) {
assertSame(WebAssembly.Table.prototype, table.__proto__);
......@@ -86,14 +83,16 @@ function assertTableIsValid(table, length) {
table = new WebAssembly.Table({element: "anyfunc", initial: 0, maximum: undefined});
assertTableIsValid(table, 0);
table = new WebAssembly.Table({element: "anyfunc", initial: 0, maximum: kMaxUint31});
table = new WebAssembly.Table({element: "anyfunc", initial: 0, maximum: 1000000});
assertTableIsValid(table, 0);
table = new WebAssembly.Table({element: "anyfunc", initial: 0, maximum: kMaxUint32});
table = new WebAssembly.Table({element: "anyfunc", initial: 0, maximum: kV8MaxWasmTableSize});
assertTableIsValid(table, 0);
table = new WebAssembly.Table({element: "anyfunc", initial: 0, maximum: kV8MaxWasmTableSize + 1});
assertTableIsValid(table, 0);
assertThrows(
() => new WebAssembly.Table(
{element: "anyfunc", initial: 0, maximum: kV8MaxWasmTableSize + 1}),
RangeError, /above the upper bound/);
})();
(function TestMaximumIsReadOnce() {
......
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