| Index: src/wasm/ast-decoder.cc
|
| diff --git a/src/wasm/ast-decoder.cc b/src/wasm/ast-decoder.cc
|
| index a56510db1da303256e4ee5a7ad418d2c3edbfcbf..2943e3914ba050e8d5b7beb63a9e7dddc91fb590 100644
|
| --- a/src/wasm/ast-decoder.cc
|
| +++ b/src/wasm/ast-decoder.cc
|
| @@ -907,36 +907,22 @@ class LR_WasmDecoder : public WasmDecoder {
|
| break;
|
| }
|
| case kExprTableSwitch: {
|
| - uint16_t table_count = *reinterpret_cast<const uint16_t*>(p->pc() + 3);
|
| - if (table_count == 1) {
|
| - // Degenerate switch with only a default target.
|
| - if (p->index == 1) {
|
| - SsaEnv* break_env = ssa_env_;
|
| - PushBlock(break_env);
|
| - SetEnv("switch:default", Steal(break_env));
|
| - }
|
| - if (p->done()) {
|
| - Block* block = &blocks_.back();
|
| - // fall through to the end.
|
| - ReduceBreakToExprBlock(p, block);
|
| - SetEnv("switch:end", block->ssa_env);
|
| - blocks_.pop_back();
|
| - }
|
| - break;
|
| - }
|
| -
|
| if (p->index == 1) {
|
| // Switch key finished.
|
| TypeCheckLast(p, kAstI32);
|
|
|
| - TFNode* sw = BUILD(Switch, table_count, p->last()->node);
|
| + uint16_t table_count =
|
| + *reinterpret_cast<const uint16_t*>(p->pc() + 3);
|
| +
|
| + // Build the switch only if it has more than just a default target.
|
| + bool build_switch = table_count > 1;
|
| + TFNode* sw = nullptr;
|
| + if (build_switch) sw = BUILD(Switch, table_count, p->last()->node);
|
|
|
| // Allocate environments for each case.
|
| uint16_t case_count = *reinterpret_cast<const uint16_t*>(p->pc() + 1);
|
| SsaEnv** case_envs = zone_->NewArray<SsaEnv*>(case_count);
|
| - for (int i = 0; i < case_count; i++) {
|
| - case_envs[i] = UnreachableEnv();
|
| - }
|
| + for (int i = 0; i < case_count; i++) case_envs[i] = UnreachableEnv();
|
|
|
| ifs_.push_back({nullptr, nullptr, case_envs});
|
| SsaEnv* break_env = ssa_env_;
|
| @@ -949,9 +935,12 @@ class LR_WasmDecoder : public WasmDecoder {
|
| reinterpret_cast<const uint16_t*>(p->pc() + 5);
|
| for (int i = 0; i < table_count; i++) {
|
| uint16_t target = table[i];
|
| - SsaEnv* env = Split(copy);
|
| - env->control = (i == table_count - 1) ? BUILD(IfDefault, sw)
|
| - : BUILD(IfValue, i, sw);
|
| + SsaEnv* env = copy;
|
| + if (build_switch) {
|
| + env = Split(env);
|
| + env->control = (i == table_count - 1) ? BUILD(IfDefault, sw)
|
| + : BUILD(IfValue, i, sw);
|
| + }
|
| if (target >= 0x8000) {
|
| // Targets an outer block.
|
| int depth = target - 0x8000;
|
| @@ -962,25 +951,21 @@ class LR_WasmDecoder : public WasmDecoder {
|
| Goto(env, case_envs[target]);
|
| }
|
| }
|
| + }
|
|
|
| - // Switch to the environment for the first case.
|
| - SetEnv("switch:case", case_envs[0]);
|
| + if (p->done()) {
|
| + // Last case. Fall through to the end.
|
| + Block* block = &blocks_.back();
|
| + if (p->index > 1) ReduceBreakToExprBlock(p, block);
|
| + SsaEnv* next = block->ssa_env;
|
| + blocks_.pop_back();
|
| + ifs_.pop_back();
|
| + SetEnv("switch:end", next);
|
| } else {
|
| - // Switch case finished.
|
| - if (p->done()) {
|
| - // Last case. Fall through to the end.
|
| - Block* block = &blocks_.back();
|
| - ReduceBreakToExprBlock(p, block);
|
| - SsaEnv* next = block->ssa_env;
|
| - blocks_.pop_back();
|
| - ifs_.pop_back();
|
| - SetEnv("switch:end", next);
|
| - } else {
|
| - // Interior case. Maybe fall through to the next case.
|
| - SsaEnv* next = ifs_.back().case_envs[p->index - 1];
|
| - if (ssa_env_->go()) Goto(ssa_env_, next);
|
| - SetEnv("switch:case", next);
|
| - }
|
| + // Interior case. Maybe fall through to the next case.
|
| + SsaEnv* next = ifs_.back().case_envs[p->index - 1];
|
| + if (p->index > 1 && ssa_env_->go()) Goto(ssa_env_, next);
|
| + SetEnv("switch:case", next);
|
| }
|
| break;
|
| }
|
|
|