Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Unified Diff: src/wasm/function-body-decoder.cc

Issue 2696813002: [wasm] Inspect right control frames for unreachable flag (Closed)
Patch Set: Avoid conversion warning Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/mjsunit/wasm/function-names.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/wasm/function-body-decoder.cc
diff --git a/src/wasm/function-body-decoder.cc b/src/wasm/function-body-decoder.cc
index 114926d36b1a9aefe177d36d94275c7b4f420113..3311caa3e233574499818fea8c6609815af3b937 100644
--- a/src/wasm/function-body-decoder.cc
+++ b/src/wasm/function-body-decoder.cc
@@ -89,9 +89,9 @@ struct MergeValues {
Value first;
} vals; // Either multiple values or a single value.
- Value& first() {
- DCHECK_GT(arity, 0);
- return arity == 1 ? vals.first : vals.array[0];
+ Value& operator[](size_t i) {
+ DCHECK_GT(arity, i);
+ return arity == 1 ? vals.first : vals.array[i];
}
};
@@ -960,6 +960,7 @@ class WasmFullDecoder : public WasmDecoder {
SsaEnv* copy = Steal(break_env);
ssa_env_ = copy;
+ MergeValues* merge = nullptr;
while (ok() && iterator.has_next()) {
uint32_t i = iterator.cur_index();
const byte* pos = iterator.pc();
@@ -973,6 +974,26 @@ class WasmFullDecoder : public WasmDecoder {
? BUILD(IfDefault, sw)
: BUILD(IfValue, i, sw);
BreakTo(target);
+
+ // Check that label types match up.
+ Control* c = &control_[control_.size() - target - 1];
+ if (i == 0) {
+ merge = &c->merge;
+ } else if (merge->arity != c->merge.arity) {
+ error(pos, pos, "inconsistent arity in br_table target %d"
+ " (previous was %u, this one %u)",
+ i, merge->arity, c->merge.arity);
+ } else if (control_.back().unreachable) {
+ for (uint32_t j = 0; ok() && j < merge->arity; ++j) {
+ if ((*merge)[j].type != c->merge[j].type) {
+ error(pos, pos,
+ "type error in br_table target %d operand %d"
+ " (previous expected %s, this one %s)", i, j,
+ WasmOpcodes::TypeName((*merge)[j].type),
+ WasmOpcodes::TypeName(c->merge[j].type));
+ }
+ }
+ }
}
if (failed()) break;
} else {
@@ -1507,6 +1528,7 @@ class WasmFullDecoder : public WasmDecoder {
}
void PushEndValues(Control* c) {
+ DCHECK_EQ(c, &control_.back());
stack_.resize(c->stack_depth);
if (c->merge.arity == 1) {
stack_.push_back(c->merge.vals.first);
@@ -1568,8 +1590,8 @@ class WasmFullDecoder : public WasmDecoder {
Goto(ssa_env_, c->end_env);
} else {
// Merge the value(s) into the end of the block.
- size_t expected = c->stack_depth + c->merge.arity;
- if (!c->unreachable && stack_.size() < expected) {
+ size_t expected = control_.back().stack_depth + c->merge.arity;
+ if (stack_.size() < expected && !control_.back().unreachable) {
error(
pc_, pc_,
"expected at least %u values on the stack for br to @%d, found %d",
@@ -1582,10 +1604,11 @@ class WasmFullDecoder : public WasmDecoder {
}
void FallThruTo(Control* c) {
+ DCHECK_EQ(c, &control_.back());
// Merge the value(s) into the end of the block.
size_t expected = c->stack_depth + c->merge.arity;
if (stack_.size() == expected ||
- (c->unreachable && stack_.size() < expected)) {
+ (stack_.size() < expected && c->unreachable)) {
MergeValuesInto(c);
c->unreachable = false;
return;
@@ -1599,10 +1622,11 @@ class WasmFullDecoder : public WasmDecoder {
}
void TypeCheckFallThru(Control* c) {
+ DCHECK_EQ(c, &control_.back());
// Fallthru must match arity exactly.
int arity = static_cast<int>(c->merge.arity);
if (c->stack_depth + arity < stack_.size() ||
- (!c->unreachable && c->stack_depth + arity != stack_.size())) {
+ (c->stack_depth + arity != stack_.size() && !c->unreachable)) {
error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d",
arity, startrel(c->pc));
return;
@@ -1612,8 +1636,7 @@ class WasmFullDecoder : public WasmDecoder {
for (size_t i = avail >= c->merge.arity ? 0 : c->merge.arity - avail;
i < c->merge.arity; i++) {
Value& val = GetMergeValueFromStack(c, i);
- Value& old =
- c->merge.arity == 1 ? c->merge.vals.first : c->merge.vals.array[i];
+ Value& old = c->merge[i];
if (val.type != old.type) {
error(pc_, pc_, "type error in merge[%zu] (expected %s, got %s)", i,
WasmOpcodes::TypeName(old.type), WasmOpcodes::TypeName(val.type));
@@ -1628,12 +1651,11 @@ class WasmFullDecoder : public WasmDecoder {
bool reachable = ssa_env_->go();
Goto(ssa_env_, target);
- size_t avail = stack_.size() - c->stack_depth;
+ size_t avail = stack_.size() - control_.back().stack_depth;
for (size_t i = avail >= c->merge.arity ? 0 : c->merge.arity - avail;
i < c->merge.arity; i++) {
Value& val = GetMergeValueFromStack(c, i);
- Value& old =
- c->merge.arity == 1 ? c->merge.vals.first : c->merge.vals.array[i];
+ Value& old = c->merge[i];
if (val.type != old.type && val.type != kWasmVar) {
error(pc_, pc_, "type error in merge[%zu] (expected %s, got %s)", i,
WasmOpcodes::TypeName(old.type), WasmOpcodes::TypeName(val.type));
« no previous file with comments | « no previous file | test/mjsunit/wasm/function-names.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698