Commit cf342100 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Limit number of labels for {br_table} instruction.

This reduces the number of label indices accepted by {br_table} from the
full function body size to specifically 65520 labels. Note that TurboFan
already had a similar limitation on switches, but caused a crash during
compilation up until now. This change just makes the limit explicit and
avoids the crash during compilation.

R=clemensh@chromium.org
TEST=mjsunit/regress/wasm/regress-9759
BUG=v8:9759

Change-Id: I3a9a4406b19a7f98fc36707b3b946be846170a15
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1821457
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarClemens Backes [né Hammacher] <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63944}
parent ee21e390
......@@ -1114,6 +1114,10 @@ Node* WasmGraphBuilder::ZeroCheck64(wasm::TrapReason reason, Node* node,
}
Node* WasmGraphBuilder::Switch(unsigned count, Node* key) {
// The instruction selector will use {kArchTableSwitch} for large switches,
// which has limited input count, see {InstructionSelector::EmitTableSwitch}.
DCHECK_LE(count, Instruction::kMaxInputCount - 2); // value_range + 2
DCHECK_LE(count, wasm::kV8MaxWasmFunctionBrTableSize + 1); // plus IfDefault
return graph()->NewNode(mcgraph()->common()->Switch(count), key, Control());
}
......@@ -6896,6 +6900,7 @@ wasm::WasmCompilationResult ExecuteTurbofanWasmCompilation(
counters->wasm_compile_function_peak_memory_bytes()->AddSample(
static_cast<int>(mcgraph->graph()->zone()->allocation_size()));
auto result = info.ReleaseWasmCompilationResult();
CHECK_NOT_NULL(result); // Compilation expected to succeed.
DCHECK_EQ(wasm::ExecutionTier::kTurbofan, result->result_tier);
return std::move(*result);
}
......
......@@ -1045,8 +1045,8 @@ class WasmDecoder : public Decoder {
bool Validate(const byte* pc, BranchTableImmediate<validate>& imm,
size_t block_depth) {
if (!VALIDATE(imm.table_count < kV8MaxWasmFunctionSize)) {
errorf(pc + 1, "invalid table count (> max function size): %u",
if (!VALIDATE(imm.table_count <= kV8MaxWasmFunctionBrTableSize)) {
errorf(pc + 1, "invalid table count (> max br_table size): %u",
imm.table_count);
return false;
}
......
......@@ -36,6 +36,7 @@ constexpr size_t kV8MaxWasmFunctionLocals = 50000;
constexpr size_t kV8MaxWasmFunctionParams = 1000;
constexpr size_t kV8MaxWasmFunctionMultiReturns = 1000;
constexpr size_t kV8MaxWasmFunctionReturns = 1;
constexpr size_t kV8MaxWasmFunctionBrTableSize = 65520;
// Don't use this limit directly, but use the value of FLAG_wasm_max_table_size.
constexpr size_t kV8MaxWasmTableSize = 10000000;
constexpr size_t kV8MaxWasmTableInitEntries = 10000000;
......
// Copyright 2019 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: --no-wasm-tier-up --no-liftoff
load("test/mjsunit/wasm/wasm-module-builder.js");
// This constant was chosen as it is the smallest number of cases that still
// triggers the input count overflow. The new limit put into place is smaller.
const NUM_CASES = 0xfffd;
(function TestBrTableTooLarge() {
let builder = new WasmModuleBuilder();
let cases = new Array(NUM_CASES).fill(0);
builder.addFunction('main', kSig_v_i)
.addBody([].concat([
kExprBlock, kWasmStmt,
kExprGetLocal, 0,
kExprBrTable], wasmSignedLeb(NUM_CASES),
cases, [0,
kExprEnd
])).exportFunc();
assertThrows(() => new WebAssembly.Module(builder.toBuffer()),
WebAssembly.CompileError, /invalid table count/);
})();
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