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

Side by Side Diff: src/wasm/ast-decoder.cc

Issue 1764723002: [wasm] Remove TableSwitch and replace with br_table. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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 unified diff | Download patch
« no previous file with comments | « src/wasm/ast-decoder.h ('k') | src/wasm/wasm-macro-gen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/base/platform/elapsed-timer.h" 5 #include "src/base/platform/elapsed-timer.h"
6 #include "src/signature.h" 6 #include "src/signature.h"
7 7
8 #include "src/bit-vector.h" 8 #include "src/bit-vector.h"
9 #include "src/flags.h" 9 #include "src/flags.h"
10 #include "src/handles.h" 10 #include "src/handles.h"
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 inline bool Validate(const byte* pc, BreakDepthOperand& operand, 188 inline bool Validate(const byte* pc, BreakDepthOperand& operand,
189 ZoneVector<Block>& blocks) { 189 ZoneVector<Block>& blocks) {
190 if (operand.depth < blocks.size()) { 190 if (operand.depth < blocks.size()) {
191 operand.target = &blocks[blocks.size() - operand.depth - 1]; 191 operand.target = &blocks[blocks.size() - operand.depth - 1];
192 return true; 192 return true;
193 } 193 }
194 error(pc, pc + 1, "invalid break depth"); 194 error(pc, pc + 1, "invalid break depth");
195 return false; 195 return false;
196 } 196 }
197 197
198 bool Validate(const byte* pc, TableSwitchOperand& operand, 198 bool Validate(const byte* pc, BranchTableOperand& operand,
199 size_t block_depth) { 199 size_t block_depth) {
200 if (operand.table_count == 0) {
201 error(pc, "tableswitch with 0 entries");
202 return false;
203 }
204 // Verify table. 200 // Verify table.
205 for (uint32_t i = 0; i < operand.table_count; i++) { 201 for (uint32_t i = 0; i < operand.table_count + 1; i++) {
206 uint16_t target = operand.read_entry(this, i); 202 uint16_t target = operand.read_entry(this, i);
207 if (target >= 0x8000) { 203 if (target >= block_depth) {
208 size_t depth = target - 0x8000; 204 error(operand.table + i * 2, "improper branch in br_table");
209 if (depth > block_depth) { 205 return false;
210 error(operand.table + i * 2, "improper branch in tableswitch");
211 return false;
212 }
213 } else {
214 if (target >= operand.case_count) {
215 error(operand.table + i * 2, "invalid case target in tableswitch");
216 return false;
217 }
218 } 206 }
219 } 207 }
220 return true; 208 return true;
221 } 209 }
222 210
223 int OpcodeArity(const byte* pc) { 211 int OpcodeArity(const byte* pc) {
224 #define DECLARE_ARITY(name, ...) \ 212 #define DECLARE_ARITY(name, ...) \
225 static const LocalType kTypes_##name[] = {__VA_ARGS__}; \ 213 static const LocalType kTypes_##name[] = {__VA_ARGS__}; \
226 static const int kArity_##name = \ 214 static const int kArity_##name = \
227 static_cast<int>(arraysize(kTypes_##name) - 1); 215 static_cast<int>(arraysize(kTypes_##name) - 1);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 } 261 }
274 case kExprCallImport: { 262 case kExprCallImport: {
275 ImportIndexOperand operand(this, pc); 263 ImportIndexOperand operand(this, pc);
276 return static_cast<int>( 264 return static_cast<int>(
277 function_env_->module->GetImportSignature(operand.index) 265 function_env_->module->GetImportSignature(operand.index)
278 ->parameter_count()); 266 ->parameter_count());
279 } 267 }
280 case kExprReturn: { 268 case kExprReturn: {
281 return static_cast<int>(function_env_->sig->return_count()); 269 return static_cast<int>(function_env_->sig->return_count());
282 } 270 }
283 case kExprTableSwitch: { 271 case kExprBrTable: {
284 TableSwitchOperand operand(this, pc); 272 return 1;
285 return 1 + operand.case_count;
286 } 273 }
287 274
288 #define DECLARE_OPCODE_CASE(name, opcode, sig) \ 275 #define DECLARE_OPCODE_CASE(name, opcode, sig) \
289 case kExpr##name: \ 276 case kExpr##name: \
290 return kArity_##sig; 277 return kArity_##sig;
291 278
292 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) 279 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
293 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE) 280 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
294 FOREACH_MISC_MEM_OPCODE(DECLARE_OPCODE_CASE) 281 FOREACH_MISC_MEM_OPCODE(DECLARE_OPCODE_CASE)
295 FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE) 282 FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 case kExprCallImport: { 324 case kExprCallImport: {
338 ImportIndexOperand operand(this, pc); 325 ImportIndexOperand operand(this, pc);
339 return 1 + operand.length; 326 return 1 + operand.length;
340 } 327 }
341 328
342 case kExprSetLocal: 329 case kExprSetLocal:
343 case kExprGetLocal: { 330 case kExprGetLocal: {
344 LocalIndexOperand operand(this, pc); 331 LocalIndexOperand operand(this, pc);
345 return 1 + operand.length; 332 return 1 + operand.length;
346 } 333 }
347 case kExprTableSwitch: { 334 case kExprBrTable: {
348 TableSwitchOperand operand(this, pc); 335 BranchTableOperand operand(this, pc);
349 return 1 + operand.length; 336 return 1 + operand.length;
350 } 337 }
351 case kExprI8Const: 338 case kExprI8Const:
352 return 2; 339 return 2;
353 case kExprI32Const: 340 case kExprI32Const:
354 case kExprF32Const: 341 case kExprF32Const:
355 return 5; 342 return 5;
356 case kExprI64Const: 343 case kExprI64Const:
357 case kExprF64Const: 344 case kExprF64Const:
358 return 9; 345 return 9;
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 break; 636 break;
650 } 637 }
651 case kExprBrIf: { 638 case kExprBrIf: {
652 BreakDepthOperand operand(this, pc_); 639 BreakDepthOperand operand(this, pc_);
653 if (Validate(pc_, operand, blocks_)) { 640 if (Validate(pc_, operand, blocks_)) {
654 Shift(kAstStmt, 2); 641 Shift(kAstStmt, 2);
655 } 642 }
656 len = 1 + operand.length; 643 len = 1 + operand.length;
657 break; 644 break;
658 } 645 }
659 case kExprTableSwitch: { 646 case kExprBrTable: {
660 TableSwitchOperand operand(this, pc_); 647 BranchTableOperand operand(this, pc_);
661 if (Validate(pc_, operand, blocks_.size())) { 648 if (Validate(pc_, operand, blocks_.size())) {
662 Shift(kAstEnd, 1 + operand.case_count); 649 Shift(kAstEnd, 1);
663 } 650 }
664 len = 1 + operand.length; 651 len = 1 + operand.length;
665 break; 652 break;
666 } 653 }
667 case kExprReturn: { 654 case kExprReturn: {
668 int count = static_cast<int>(function_env_->sig->return_count()); 655 int count = static_cast<int>(function_env_->sig->return_count());
669 if (count == 0) { 656 if (count == 0) {
670 BUILD(Return, 0, builder_->Buffer(0)); 657 BUILD(Return, 0, builder_->Buffer(0));
671 ssa_env_->Kill(); 658 ssa_env_->Kill();
672 Leaf(kAstEnd); 659 Leaf(kAstEnd);
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 SsaEnv* fenv = ssa_env_; 1024 SsaEnv* fenv = ssa_env_;
1038 SsaEnv* tenv = Split(fenv); 1025 SsaEnv* tenv = Split(fenv);
1039 BUILD(Branch, p->tree->children[1]->node, &tenv->control, 1026 BUILD(Branch, p->tree->children[1]->node, &tenv->control,
1040 &fenv->control); 1027 &fenv->control);
1041 ssa_env_ = tenv; 1028 ssa_env_ = tenv;
1042 ReduceBreakToExprBlock(p, operand.target, p->tree->children[0]); 1029 ReduceBreakToExprBlock(p, operand.target, p->tree->children[0]);
1043 ssa_env_ = fenv; 1030 ssa_env_ = fenv;
1044 } 1031 }
1045 break; 1032 break;
1046 } 1033 }
1047 case kExprTableSwitch: { 1034 case kExprBrTable: {
1048 if (p->index == 1) { 1035 if (p->index == 1) {
1049 // Switch key finished. 1036 // Switch key finished.
1050 TypeCheckLast(p, kAstI32); 1037 TypeCheckLast(p, kAstI32);
1051 if (failed()) break; 1038 if (failed()) break;
1052 1039
1053 TableSwitchOperand operand(this, p->pc()); 1040 BranchTableOperand operand(this, p->pc());
1054 DCHECK(Validate(p->pc(), operand, blocks_.size())); 1041 DCHECK(Validate(p->pc(), operand, blocks_.size()));
1055 1042
1056 // Build the switch only if it has more than just a default target. 1043 // Build a switch only if it has more than just a default target.
1057 bool build_switch = operand.table_count > 1; 1044 bool build_switch = operand.table_count > 0;
1058 TFNode* sw = nullptr; 1045 TFNode* sw = nullptr;
1059 if (build_switch) 1046 if (build_switch) {
1060 sw = BUILD(Switch, operand.table_count, p->last()->node); 1047 sw = BUILD(Switch, operand.table_count + 1, p->last()->node);
1061
1062 // Allocate environments for each case.
1063 SsaEnv** case_envs = zone_->NewArray<SsaEnv*>(operand.case_count);
1064 for (uint32_t i = 0; i < operand.case_count; i++) {
1065 case_envs[i] = UnreachableEnv();
1066 } 1048 }
1067 1049
1068 ifs_.push_back({nullptr, nullptr, case_envs}); 1050 // Process the targets of the break table.
1069 SsaEnv* break_env = ssa_env_; 1051 SsaEnv* prev = ssa_env_;
1070 PushBlock(break_env); 1052 SsaEnv* copy = Steal(prev);
1071 SsaEnv* copy = Steal(break_env); 1053 for (uint32_t i = 0; i < operand.table_count + 1; i++) {
1072 ssa_env_ = copy;
1073
1074 // Build the environments for each case based on the table.
1075 for (uint32_t i = 0; i < operand.table_count; i++) {
1076 uint16_t target = operand.read_entry(this, i); 1054 uint16_t target = operand.read_entry(this, i);
1077 SsaEnv* env = copy; 1055 SsaEnv* env = copy;
1078 if (build_switch) { 1056 if (build_switch) {
1079 env = Split(env); 1057 ssa_env_ = env = Split(env);
1080 env->control = (i == operand.table_count - 1) 1058 env->control = i == operand.table_count ? BUILD(IfDefault, sw)
1081 ? BUILD(IfDefault, sw) 1059 : BUILD(IfValue, i, sw);
1082 : BUILD(IfValue, i, sw);
1083 } 1060 }
1084 if (target >= 0x8000) { 1061 SsaEnv* tenv = blocks_[blocks_.size() - target - 1].ssa_env;
1085 // Targets an outer block. 1062 Goto(env, tenv);
1086 int depth = target - 0x8000;
1087 SsaEnv* tenv = blocks_[blocks_.size() - depth - 1].ssa_env;
1088 Goto(env, tenv);
1089 } else {
1090 // Targets a case.
1091 Goto(env, case_envs[target]);
1092 }
1093 } 1063 }
1094 } 1064 ssa_env_ = prev;
1095
1096 if (p->done()) {
1097 // Last case. Fall through to the end.
1098 Block* block = &blocks_.back();
1099 if (p->index > 1) ReduceBreakToExprBlock(p, block);
1100 SsaEnv* next = block->ssa_env;
1101 blocks_.pop_back();
1102 ifs_.pop_back();
1103 SetEnv("switch:end", next);
1104 } else {
1105 // Interior case. Maybe fall through to the next case.
1106 SsaEnv* next = ifs_.back().case_envs[p->index - 1];
1107 if (p->index > 1 && ssa_env_->go()) Goto(ssa_env_, next);
1108 SetEnv("switch:case", next);
1109 } 1065 }
1110 break; 1066 break;
1111 } 1067 }
1112 case kExprReturn: { 1068 case kExprReturn: {
1113 TypeCheckLast(p, function_env_->sig->GetReturn(p->index - 1)); 1069 TypeCheckLast(p, function_env_->sig->GetReturn(p->index - 1));
1114 if (p->done()) { 1070 if (p->done()) {
1115 if (build()) { 1071 if (build()) {
1116 int count = p->tree->count; 1072 int count = p->tree->count;
1117 TFNode** buffer = builder_->Buffer(count); 1073 TFNode** buffer = builder_->Buffer(count);
1118 for (int i = 0; i < count; i++) { 1074 for (int i = 0; i < count; i++) {
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 1662
1707 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, FunctionEnv* env, 1663 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, FunctionEnv* env,
1708 const byte* start, const byte* end) { 1664 const byte* start, const byte* end) {
1709 LoopAssignmentAnalyzer analyzer(zone, env); 1665 LoopAssignmentAnalyzer analyzer(zone, env);
1710 return analyzer.Analyze(start, end); 1666 return analyzer.Analyze(start, end);
1711 } 1667 }
1712 1668
1713 } // namespace wasm 1669 } // namespace wasm
1714 } // namespace internal 1670 } // namespace internal
1715 } // namespace v8 1671 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/ast-decoder.h ('k') | src/wasm/wasm-macro-gen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698