Commit 892a04a0 authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

[wasm][decoder] Type check one-armed if blocks

Type check the implicit else-branch of multi-value one-armed if blocks.

R=ahaas@chromium.org
BUG=chromium:1019648

Change-Id: I939d712e9cffd531c764f105cfb2e7c148d3b7dc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1890095
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64681}
parent cc641f6b
...@@ -1928,8 +1928,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1928,8 +1928,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
"start-arity and end-arity of one-armed if must match"); "start-arity and end-arity of one-armed if must match");
break; break;
} }
if (!TypeCheckOneArmedIf(c)) break;
} }
if (!TypeCheckFallThru()) break; if (!TypeCheckFallThru()) break;
if (control_.size() == 1) { if (control_.size() == 1) {
...@@ -3033,12 +3033,28 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3033,12 +3033,28 @@ class WasmFullDecoder : public WasmDecoder<validate> {
return true; return true;
} }
bool TypeCheckOneArmedIf(Control* c) {
static_assert(validate, "Call this function only within VALIDATE");
DCHECK(c->is_onearmed_if());
DCHECK_EQ(c->start_merge.arity, c->end_merge.arity);
for (uint32_t i = 0; i < c->start_merge.arity; ++i) {
Value& start = c->start_merge[i];
Value& end = c->end_merge[i];
if (!ValueTypes::IsSubType(start.type, end.type)) {
this->errorf(this->pc_, "type error in merge[%u] (expected %s, got %s)",
i, ValueTypes::TypeName(end.type),
ValueTypes::TypeName(start.type));
return false;
}
}
return true;
}
bool TypeCheckFallThru() { bool TypeCheckFallThru() {
static_assert(validate, "Call this function only whithin VALIDATE");
Control& c = control_.back(); Control& c = control_.back();
if (V8_LIKELY(c.reachable())) { if (V8_LIKELY(c.reachable())) {
// We only do type-checking here. This is only needed during validation.
if (!validate) return true;
uint32_t expected = c.end_merge.arity; uint32_t expected = c.end_merge.arity;
DCHECK_GE(stack_.size(), c.stack_depth); DCHECK_GE(stack_.size(), c.stack_depth);
uint32_t actual = static_cast<uint32_t>(stack_.size()) - c.stack_depth; uint32_t actual = static_cast<uint32_t>(stack_.size()) - c.stack_depth;
......
...@@ -295,6 +295,24 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -295,6 +295,24 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(instance.exports.main(1), 6); assertEquals(instance.exports.main(1), 6);
})(); })();
(function MultiIfOneArmedNoTypeCheckTest() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_i_l = builder.addType(kSig_i_l);
builder.addFunction("main", kSig_i_v)
.addBody([
kExprI64Const, 0,
kExprI32Const, 0,
kExprIf, sig_i_l,
kExprDrop,
kExprI32Const, 0,
kExprEnd]);
assertThrows(() => new WebAssembly.Module(builder.toBuffer()),
WebAssembly.CompileError, /expected i32, got i64/);
})();
(function MultiResultTest() { (function MultiResultTest() {
print("MultiResultTest"); print("MultiResultTest");
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
......
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