Chromium Code Reviews| Index: src/wasm/function-body-decoder.cc |
| diff --git a/src/wasm/function-body-decoder.cc b/src/wasm/function-body-decoder.cc |
| index 86b83c069c1280acda3cf1439f2c91c2706197f0..ff775ebf02ce493ad50bfc009fbe9915b96cb496 100644 |
| --- a/src/wasm/function-body-decoder.cc |
| +++ b/src/wasm/function-body-decoder.cc |
| @@ -99,7 +99,7 @@ enum ControlKind { kControlIf, kControlBlock, kControlLoop, kControlTry }; |
| struct Control { |
| const byte* pc; |
| ControlKind kind; |
| - int stack_depth; // stack height at the beginning of the construct. |
| + size_t stack_depth; // stack height at the beginning of the construct. |
| SsaEnv* end_env; // end environment for the construct. |
| SsaEnv* false_env; // false environment (only for if). |
| TryInfo* try_info; // Information used for compiling try statements. |
| @@ -114,25 +114,25 @@ struct Control { |
| inline bool is_try() const { return kind == kControlTry; } |
| // Named constructors. |
| - static Control Block(const byte* pc, int stack_depth, SsaEnv* end_env, |
| + static Control Block(const byte* pc, size_t stack_depth, SsaEnv* end_env, |
| int32_t previous_catch) { |
| return {pc, kControlBlock, stack_depth, end_env, |
| nullptr, nullptr, previous_catch, {0, {NO_VALUE}}}; |
| } |
| - static Control If(const byte* pc, int stack_depth, SsaEnv* end_env, |
| + static Control If(const byte* pc, size_t stack_depth, SsaEnv* end_env, |
| SsaEnv* false_env, int32_t previous_catch) { |
| return {pc, kControlIf, stack_depth, end_env, |
| false_env, nullptr, previous_catch, {0, {NO_VALUE}}}; |
| } |
| - static Control Loop(const byte* pc, int stack_depth, SsaEnv* end_env, |
| + static Control Loop(const byte* pc, size_t stack_depth, SsaEnv* end_env, |
| int32_t previous_catch) { |
| return {pc, kControlLoop, stack_depth, end_env, |
| nullptr, nullptr, previous_catch, {0, {NO_VALUE}}}; |
| } |
| - static Control Try(const byte* pc, int stack_depth, SsaEnv* end_env, |
| + static Control Try(const byte* pc, size_t stack_depth, SsaEnv* end_env, |
| Zone* zone, SsaEnv* catch_env, int32_t previous_catch) { |
| DCHECK_NOT_NULL(catch_env); |
| TryInfo* try_info = new (zone) TryInfo(catch_env); |
| @@ -811,8 +811,7 @@ class WasmFullDecoder : public WasmDecoder { |
| if (c->false_env != nullptr) { |
| // End the true branch of a one-armed if. |
| Goto(c->false_env, c->end_env); |
| - if (ssa_env_->go() && |
| - static_cast<int>(stack_.size()) != c->stack_depth) { |
| + if (ssa_env_->go() && stack_.size() != c->stack_depth) { |
| error("end of if expected empty stack"); |
| stack_.resize(c->stack_depth); |
| } |
| @@ -846,12 +845,11 @@ class WasmFullDecoder : public WasmDecoder { |
| } |
| } |
| - PopControl(); |
| - |
| - if (control_.empty()) { |
| + if (control_.size() == 1) { |
| // If the last (implicit) control was popped, check we are at end. |
|
rossberg
2017/01/18 16:21:42
Nit: s/was/is/
titzer
2017/01/18 17:22:17
Done.
|
| if (pc_ + 1 != end_) { |
| error(pc_, pc_ + 1, "trailing code after function end"); |
| + break; |
| } |
| last_end_found_ = true; |
| if (ssa_env_->go()) { |
| @@ -860,8 +858,8 @@ class WasmFullDecoder : public WasmDecoder { |
| DoReturn(); |
| TRACE("\n"); |
| } |
| - return; |
| } |
| + PopControl(); |
| break; |
| } |
| case kExprSelect: { |
| @@ -1286,26 +1284,22 @@ class WasmFullDecoder : public WasmDecoder { |
| } |
| void PushBlock(SsaEnv* end_env) { |
| - const int stack_depth = static_cast<int>(stack_.size()); |
| control_.emplace_back( |
| - Control::Block(pc_, stack_depth, end_env, current_catch_)); |
| + Control::Block(pc_, stack_.size(), end_env, current_catch_)); |
| } |
| void PushLoop(SsaEnv* end_env) { |
| - const int stack_depth = static_cast<int>(stack_.size()); |
| control_.emplace_back( |
| - Control::Loop(pc_, stack_depth, end_env, current_catch_)); |
| + Control::Loop(pc_, stack_.size(), end_env, current_catch_)); |
| } |
| void PushIf(SsaEnv* end_env, SsaEnv* false_env) { |
| - const int stack_depth = static_cast<int>(stack_.size()); |
| control_.emplace_back( |
| - Control::If(pc_, stack_depth, end_env, false_env, current_catch_)); |
| + Control::If(pc_, stack_.size(), end_env, false_env, current_catch_)); |
| } |
| void PushTry(SsaEnv* end_env, SsaEnv* catch_env) { |
| - const int stack_depth = static_cast<int>(stack_.size()); |
| - control_.emplace_back(Control::Try(pc_, stack_depth, end_env, zone_, |
| + control_.emplace_back(Control::Try(pc_, stack_.size(), end_env, zone_, |
| catch_env, current_catch_)); |
| current_catch_ = static_cast<int32_t>(control_.size() - 1); |
| } |
| @@ -1431,10 +1425,6 @@ class WasmFullDecoder : public WasmDecoder { |
| } |
| Value Pop(int index, ValueType expected) { |
| - if (!ssa_env_->go()) { |
| - // Unreachable code is essentially not typechecked. |
| - return {pc_, nullptr, expected}; |
| - } |
| Value val = Pop(); |
| if (val.type != expected) { |
| if (val.type != kWasmEnd) { |
| @@ -1447,14 +1437,13 @@ class WasmFullDecoder : public WasmDecoder { |
| } |
| Value Pop() { |
| - if (!ssa_env_->go()) { |
| - // Unreachable code is essentially not typechecked. |
| - return {pc_, nullptr, kWasmEnd}; |
| - } |
| size_t limit = control_.empty() ? 0 : control_.back().stack_depth; |
| if (stack_.size() <= limit) { |
| - Value val = {pc_, nullptr, kWasmStmt}; |
| - error(pc_, pc_, "%s found empty stack", SafeOpcodeNameAt(pc_)); |
| + Value val = {pc_, nullptr, kWasmEnd}; |
| + if (ssa_env_->go()) { |
| + // Popping past the current control start in reachable code. |
| + error(pc_, pc_, "%s found empty stack", SafeOpcodeNameAt(pc_)); |
| + } |
| return val; |
| } |
| Value val = stack_.back(); |
| @@ -1462,22 +1451,6 @@ class WasmFullDecoder : public WasmDecoder { |
| return val; |
| } |
| - Value PopUpTo(int stack_depth) { |
| - if (!ssa_env_->go()) { |
| - // Unreachable code is essentially not typechecked. |
| - return {pc_, nullptr, kWasmEnd}; |
| - } |
| - if (stack_depth == static_cast<int>(stack_.size())) { |
| - Value val = {pc_, nullptr, kWasmStmt}; |
| - return val; |
| - } else { |
| - DCHECK_LE(stack_depth, stack_.size()); |
| - Value val = Pop(); |
| - stack_.resize(stack_depth); |
| - return val; |
| - } |
| - } |
| - |
| int baserel(const byte* ptr) { |
| return base_ ? static_cast<int>(ptr - base_) : 0; |
| } |
| @@ -1508,7 +1481,7 @@ class WasmFullDecoder : public WasmDecoder { |
| if (!ssa_env_->go()) return; |
| // Merge the value(s) into the end of the block. |
| int arity = static_cast<int>(c->merge.arity); |
| - if (c->stack_depth + arity != static_cast<int>(stack_.size())) { |
| + if (c->stack_depth + arity != stack_.size()) { |
| error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d", |
| arity, startrel(c->pc)); |
| return; |
| @@ -1524,7 +1497,7 @@ class WasmFullDecoder : public WasmDecoder { |
| if (!ssa_env_->go()) return; |
| // Fallthru must match arity exactly. |
| int arity = static_cast<int>(c->merge.arity); |
| - if (c->stack_depth + arity != static_cast<int>(stack_.size())) { |
| + if (c->stack_depth + arity != stack_.size()) { |
| error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d", |
| arity, startrel(c->pc)); |
| return; |