Commit bb56b7ec authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[asm.js] Limit number of local variables

We have an internal limit of 50000 local variables per wasm function.
This limit is checked when decoding the function body. For asm.js, we
skip function body validation, since by construction the code we
generate is correct. This makes us fail unexpectedly when trying to
(lazily) compile an asm.js function with more than 50000 locals.
Hence, check this limit in the asm parser and bail out if it is
exceeded.

R=mstarzinger@chromium.org

Bug: chromium:775710
Change-Id: I89d2069e133fb0f84947d477ae1ac5eda85571aa
Reviewed-on: https://chromium-review.googlesource.com/732660Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48929}
parent 3b67d7a0
......@@ -14,6 +14,7 @@
#include "src/base/optional.h"
#include "src/flags.h"
#include "src/parsing/scanner.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-opcodes.h"
namespace v8 {
......@@ -781,6 +782,11 @@ void AsmJsParser::ValidateFunction() {
current_function_builder_->AddLocal(kWasmI32);
}
// Check against limit on number of local variables.
if (locals.size() + function_temp_locals_used_ > kV8MaxWasmFunctionLocals) {
FAIL("Number of local variables exceeds internal limit");
}
// End function
current_function_builder_->Emit(kExprEnd);
......@@ -866,6 +872,7 @@ void AsmJsParser::ValidateFunctionParams(ZoneVector<AsmType*>* params) {
// 6.4 ValidateFunction - locals
void AsmJsParser::ValidateFunctionLocals(size_t param_count,
ZoneVector<ValueType>* locals) {
DCHECK(locals->empty());
// Local Variables.
while (Peek(TOK(var))) {
scanner_.EnterLocalScope();
......
// Copyright 2017 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: --validate-asm --allow-natives-syntax
const kMaxLocals = 50000;
const fn_template = '"use asm";\nfunction f() { LOCALS }\nreturn f;';
for (var num_locals = kMaxLocals; num_locals < kMaxLocals + 2; ++num_locals) {
const fn_code = fn_template.replace(
'LOCALS',
Array(num_locals)
.fill()
.map((_, idx) => 'var l' + idx + ' = 0;')
.join('\n'));
const asm_fn = new Function(fn_code);
const f = asm_fn();
f();
assertEquals(num_locals <= kMaxLocals, %IsAsmWasmCode(asm_fn));
}
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