diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index 45efde6ece..2dfca6404f 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -41,6 +41,8 @@ class MovableLabel { Label* get() { return label_.get(); } MovableLabel() : MovableLabel(new Label()) {} + operator bool() const { return label_ != nullptr; } + static MovableLabel None() { return MovableLabel(nullptr); } private: @@ -53,6 +55,8 @@ class MovableLabel { public: Label* get() { return &label_; } + operator bool() const { return true; } + static MovableLabel None() { return MovableLabel(); } private: @@ -148,6 +152,8 @@ class LiftoffCompiler { codegen_zone_(codegen_zone), safepoint_table_builder_(compilation_zone_) {} + ~LiftoffCompiler() { BindUnboundLabels(nullptr); } + bool ok() const { return ok_; } void unsupported(Decoder* decoder, const char* reason) { @@ -185,7 +191,8 @@ class LiftoffCompiler { #ifdef DEBUG // Bind all labels now, otherwise their destructor will fire a DCHECK error // if they where referenced before. - for (uint32_t i = 0, e = decoder->control_depth(); i < e; ++i) { + uint32_t control_depth = decoder ? decoder->control_depth() : 0; + for (uint32_t i = 0; i < control_depth; ++i) { Control* c = decoder->control_at(i); Label* label = c->label.get(); if (!label->is_bound()) __ bind(label); @@ -258,7 +265,7 @@ class LiftoffCompiler { OutOfLineCode::StackCheck(position, __ cache_state()->used_registers)); OutOfLineCode& ool = out_of_line_code_.back(); __ StackCheck(ool.label.get()); - __ bind(ool.continuation.get()); + if (ool.continuation) __ bind(ool.continuation.get()); } void StartFunctionBody(Decoder* decoder, Control* block) { diff --git a/src/wasm/function-body-decoder-impl.h b/src/wasm/function-body-decoder-impl.h index bfe6c761b9..050d42fe52 100644 --- a/src/wasm/function-body-decoder-impl.h +++ b/src/wasm/function-body-decoder-impl.h @@ -682,7 +682,8 @@ class WasmDecoder : public Decoder { uint32_t count = decoder->consume_u32v("local count"); if (decoder->failed()) return false; - if ((count + type_list->size()) > kV8MaxWasmFunctionLocals) { + DCHECK_LE(type_list->size(), kV8MaxWasmFunctionLocals); + if (count > kV8MaxWasmFunctionLocals - type_list->size()) { decoder->error(decoder->pc() - 1, "local count too large"); return false; } diff --git a/test/mjsunit/regress/wasm/regress-819869.js b/test/mjsunit/regress/wasm/regress-819869.js new file mode 100644 index 0000000000..f2606fb610 --- /dev/null +++ b/test/mjsunit/regress/wasm/regress-819869.js @@ -0,0 +1,12 @@ +// 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. + +load('test/mjsunit/wasm/wasm-constants.js'); +load('test/mjsunit/wasm/wasm-module-builder.js'); + +var builder = new WasmModuleBuilder(); +builder.addFunction(undefined, kSig_i_i) + .addLocals({i32_count: 0xffffffff}) + .addBody([]); +assertThrows(() => builder.instantiate(), WebAssembly.CompileError);