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

Side by Side Diff: src/wasm/function-body-decoder.cc

Issue 2610813009: [wasm] factor lower level utilties out of WasmFullDecoder (Closed)
Patch Set: harden decl decoding Created 3 years, 11 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/function-body-decoder.h ('k') | src/wasm/wasm-interpreter.cc » ('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/signature.h" 5 #include "src/signature.h"
6 6
7 #include "src/bit-vector.h" 7 #include "src/bit-vector.h"
8 #include "src/flags.h" 8 #include "src/flags.h"
9 #include "src/handles.h" 9 #include "src/handles.h"
10 #include "src/zone/zone-containers.h" 10 #include "src/zone/zone-containers.h"
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 162
163 // Generic Wasm bytecode decoder with utilities for decoding operands, 163 // Generic Wasm bytecode decoder with utilities for decoding operands,
164 // lengths, etc. 164 // lengths, etc.
165 class WasmDecoder : public Decoder { 165 class WasmDecoder : public Decoder {
166 public: 166 public:
167 WasmDecoder(const WasmModule* module, FunctionSig* sig, const byte* start, 167 WasmDecoder(const WasmModule* module, FunctionSig* sig, const byte* start,
168 const byte* end) 168 const byte* end)
169 : Decoder(start, end), 169 : Decoder(start, end),
170 module_(module), 170 module_(module),
171 sig_(sig), 171 sig_(sig),
172 total_locals_(0),
173 local_types_(nullptr) {} 172 local_types_(nullptr) {}
174 const WasmModule* module_; 173 const WasmModule* module_;
175 FunctionSig* sig_; 174 FunctionSig* sig_;
176 size_t total_locals_; 175
177 ZoneVector<ValueType>* local_types_; 176 ZoneVector<ValueType>* local_types_;
178 177
178 size_t total_locals() const {
179 return local_types_ == nullptr ? 0 : local_types_->size();
180 }
181
182 static bool DecodeLocals(Decoder* decoder, const FunctionSig* sig,
183 ZoneVector<ValueType>* type_list) {
184 DCHECK_NOT_NULL(type_list);
185 // Initialize from signature.
186 if (sig != nullptr) {
187 type_list->reserve(sig->parameter_count());
188 for (size_t i = 0; i < sig->parameter_count(); ++i) {
189 type_list->push_back(sig->GetParam(i));
190 }
191 }
192 // Decode local declarations, if any.
193 uint32_t entries = decoder->consume_u32v("local decls count");
194 if (decoder->failed()) return false;
195
196 TRACE("local decls count: %u\n", entries);
197 while (entries-- > 0 && decoder->ok() && decoder->more()) {
198 uint32_t count = decoder->consume_u32v("local count");
199 if (decoder->failed()) return false;
200
201 if ((count + type_list->size()) > kMaxNumWasmLocals) {
202 decoder->error(decoder->pc() - 1, "local count too large");
203 return false;
204 }
205 byte code = decoder->consume_u8("local type");
206 if (decoder->failed()) return false;
207
208 ValueType type;
209 switch (code) {
210 case kLocalI32:
211 type = kWasmI32;
212 break;
213 case kLocalI64:
214 type = kWasmI64;
215 break;
216 case kLocalF32:
217 type = kWasmF32;
218 break;
219 case kLocalF64:
220 type = kWasmF64;
221 break;
222 case kLocalS128:
223 type = kWasmS128;
224 break;
225 default:
226 decoder->error(decoder->pc() - 1, "invalid local type");
227 return false;
228 }
229 type_list->insert(type_list->end(), count, type);
230 }
231 DCHECK(decoder->ok());
232 return true;
233 }
234
235 static BitVector* AnalyzeLoopAssignment(Decoder* decoder, const byte* pc,
236 int locals_count, Zone* zone) {
237 if (pc >= decoder->end()) return nullptr;
238 if (*pc != kExprLoop) return nullptr;
239
240 BitVector* assigned = new (zone) BitVector(locals_count, zone);
241 int depth = 0;
242 // Iteratively process all AST nodes nested inside the loop.
243 while (pc < decoder->end() && decoder->ok()) {
244 WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
245 unsigned length = 1;
246 switch (opcode) {
247 case kExprLoop:
248 case kExprIf:
249 case kExprBlock:
250 case kExprTry:
251 length = OpcodeLength(decoder, pc);
252 depth++;
253 break;
254 case kExprSetLocal: // fallthru
255 case kExprTeeLocal: {
256 LocalIndexOperand operand(decoder, pc);
257 if (assigned->length() > 0 &&
258 operand.index < static_cast<uint32_t>(assigned->length())) {
259 // Unverified code might have an out-of-bounds index.
260 assigned->Add(operand.index);
261 }
262 length = 1 + operand.length;
263 break;
264 }
265 case kExprEnd:
266 depth--;
267 break;
268 default:
269 length = OpcodeLength(decoder, pc);
270 break;
271 }
272 if (depth <= 0) break;
273 pc += length;
274 }
275 return decoder->ok() ? assigned : nullptr;
276 }
277
179 inline bool Validate(const byte* pc, LocalIndexOperand& operand) { 278 inline bool Validate(const byte* pc, LocalIndexOperand& operand) {
180 if (operand.index < total_locals_) { 279 if (operand.index < total_locals()) {
181 if (local_types_) { 280 if (local_types_) {
182 operand.type = local_types_->at(operand.index); 281 operand.type = local_types_->at(operand.index);
183 } else { 282 } else {
184 operand.type = kWasmStmt; 283 operand.type = kWasmStmt;
185 } 284 }
186 return true; 285 return true;
187 } 286 }
188 error(pc, pc + 1, "invalid local index: %u", operand.index); 287 error(pc, pc + 1, "invalid local index: %u", operand.index);
189 return false; 288 return false;
190 } 289 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 352
254 inline bool Validate(const byte* pc, LaneOperand& operand) { 353 inline bool Validate(const byte* pc, LaneOperand& operand) {
255 if (operand.lane < 0 || operand.lane > 3) { 354 if (operand.lane < 0 || operand.lane > 3) {
256 error(pc_, pc_ + 2, "invalid extract lane value"); 355 error(pc_, pc_ + 2, "invalid extract lane value");
257 return false; 356 return false;
258 } else { 357 } else {
259 return true; 358 return true;
260 } 359 }
261 } 360 }
262 361
263 unsigned OpcodeLength(const byte* pc) { 362 static unsigned OpcodeLength(Decoder* decoder, const byte* pc) {
264 switch (static_cast<byte>(*pc)) { 363 switch (static_cast<byte>(*pc)) {
265 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: 364 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
266 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) 365 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
267 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE) 366 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
268 #undef DECLARE_OPCODE_CASE 367 #undef DECLARE_OPCODE_CASE
269 { 368 {
270 MemoryAccessOperand operand(this, pc, UINT32_MAX); 369 MemoryAccessOperand operand(decoder, pc, UINT32_MAX);
271 return 1 + operand.length; 370 return 1 + operand.length;
272 } 371 }
273 case kExprBr: 372 case kExprBr:
274 case kExprBrIf: { 373 case kExprBrIf: {
275 BreakDepthOperand operand(this, pc); 374 BreakDepthOperand operand(decoder, pc);
276 return 1 + operand.length; 375 return 1 + operand.length;
277 } 376 }
278 case kExprSetGlobal: 377 case kExprSetGlobal:
279 case kExprGetGlobal: { 378 case kExprGetGlobal: {
280 GlobalIndexOperand operand(this, pc); 379 GlobalIndexOperand operand(decoder, pc);
281 return 1 + operand.length; 380 return 1 + operand.length;
282 } 381 }
283 382
284 case kExprCallFunction: { 383 case kExprCallFunction: {
285 CallFunctionOperand operand(this, pc); 384 CallFunctionOperand operand(decoder, pc);
286 return 1 + operand.length; 385 return 1 + operand.length;
287 } 386 }
288 case kExprCallIndirect: { 387 case kExprCallIndirect: {
289 CallIndirectOperand operand(this, pc); 388 CallIndirectOperand operand(decoder, pc);
290 return 1 + operand.length; 389 return 1 + operand.length;
291 } 390 }
292 391
293 case kExprTry: 392 case kExprTry:
294 case kExprIf: // fall thru 393 case kExprIf: // fall thru
295 case kExprLoop: 394 case kExprLoop:
296 case kExprBlock: { 395 case kExprBlock: {
297 BlockTypeOperand operand(this, pc); 396 BlockTypeOperand operand(decoder, pc);
298 return 1 + operand.length; 397 return 1 + operand.length;
299 } 398 }
300 399
301 case kExprSetLocal: 400 case kExprSetLocal:
302 case kExprTeeLocal: 401 case kExprTeeLocal:
303 case kExprGetLocal: 402 case kExprGetLocal:
304 case kExprCatch: { 403 case kExprCatch: {
305 LocalIndexOperand operand(this, pc); 404 LocalIndexOperand operand(decoder, pc);
306 return 1 + operand.length; 405 return 1 + operand.length;
307 } 406 }
308 case kExprBrTable: { 407 case kExprBrTable: {
309 BranchTableOperand operand(this, pc); 408 BranchTableOperand operand(decoder, pc);
310 BranchTableIterator iterator(this, operand); 409 BranchTableIterator iterator(decoder, operand);
311 return 1 + iterator.length(); 410 return 1 + iterator.length();
312 } 411 }
313 case kExprI32Const: { 412 case kExprI32Const: {
314 ImmI32Operand operand(this, pc); 413 ImmI32Operand operand(decoder, pc);
315 return 1 + operand.length; 414 return 1 + operand.length;
316 } 415 }
317 case kExprI64Const: { 416 case kExprI64Const: {
318 ImmI64Operand operand(this, pc); 417 ImmI64Operand operand(decoder, pc);
319 return 1 + operand.length; 418 return 1 + operand.length;
320 } 419 }
321 case kExprGrowMemory: 420 case kExprGrowMemory:
322 case kExprMemorySize: { 421 case kExprMemorySize: {
323 MemoryIndexOperand operand(this, pc); 422 MemoryIndexOperand operand(decoder, pc);
324 return 1 + operand.length; 423 return 1 + operand.length;
325 } 424 }
326 case kExprI8Const: 425 case kExprI8Const:
327 return 2; 426 return 2;
328 case kExprF32Const: 427 case kExprF32Const:
329 return 5; 428 return 5;
330 case kExprF64Const: 429 case kExprF64Const:
331 return 9; 430 return 9;
332 case kSimdPrefix: { 431 case kSimdPrefix: {
333 byte simd_index = checked_read_u8(pc, 1, "simd_index"); 432 byte simd_index = decoder->checked_read_u8(pc, 1, "simd_index");
334 WasmOpcode opcode = 433 WasmOpcode opcode =
335 static_cast<WasmOpcode>(kSimdPrefix << 8 | simd_index); 434 static_cast<WasmOpcode>(kSimdPrefix << 8 | simd_index);
336 switch (opcode) { 435 switch (opcode) {
337 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: 436 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
338 FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE) 437 FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
339 #undef DECLARE_OPCODE_CASE 438 #undef DECLARE_OPCODE_CASE
340 { 439 {
341 return 2; 440 return 2;
342 } 441 }
343 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: 442 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
344 FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE) 443 FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
345 #undef DECLARE_OPCODE_CASE 444 #undef DECLARE_OPCODE_CASE
346 { 445 {
347 return 3; 446 return 3;
348 } 447 }
349 default: 448 default:
350 error("invalid SIMD opcode"); 449 decoder->error(pc, "invalid SIMD opcode");
351 return 2; 450 return 2;
352 } 451 }
353 } 452 }
354 default: 453 default:
355 return 1; 454 return 1;
356 } 455 }
357 } 456 }
358 }; 457 };
359 458
360 static const int32_t kNullCatch = -1; 459 static const int32_t kNullCatch = -1;
361 460
362 // The full WASM decoder for bytecode. Verifies bytecode and, optionally, 461 // The full WASM decoder for bytecode. Verifies bytecode and, optionally,
363 // generates a TurboFan IR graph. 462 // generates a TurboFan IR graph.
364 class WasmFullDecoder : public WasmDecoder { 463 class WasmFullDecoder : public WasmDecoder {
365 public: 464 public:
366 WasmFullDecoder(Zone* zone, const FunctionBody& body)
367 : WasmFullDecoder(zone, nullptr, nullptr, body) {}
368
369 WasmFullDecoder(Zone* zone, const wasm::WasmModule* module, 465 WasmFullDecoder(Zone* zone, const wasm::WasmModule* module,
370 const FunctionBody& body) 466 const FunctionBody& body)
371 : WasmFullDecoder(zone, module, nullptr, body) {} 467 : WasmFullDecoder(zone, module, nullptr, body) {}
372 468
373 WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body) 469 WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body)
374 : WasmFullDecoder(zone, builder->module_env() == nullptr 470 : WasmFullDecoder(zone, builder->module_env() == nullptr
375 ? nullptr 471 ? nullptr
376 : builder->module_env()->module, 472 : builder->module_env()->module,
377 builder, body) {} 473 builder, body) {}
378 474
379 bool Decode() { 475 bool Decode() {
380 if (FLAG_wasm_code_fuzzer_gen_test) { 476 if (FLAG_wasm_code_fuzzer_gen_test) {
381 PrintWasmCodeForDebugging(start_, end_); 477 PrintWasmCodeForDebugging(start_, end_);
382 } 478 }
383 base::ElapsedTimer decode_timer; 479 base::ElapsedTimer decode_timer;
384 if (FLAG_trace_wasm_decode_time) { 480 if (FLAG_trace_wasm_decode_time) {
385 decode_timer.Start(); 481 decode_timer.Start();
386 } 482 }
387 stack_.clear(); 483 stack_.clear();
388 control_.clear(); 484 control_.clear();
389 485
390 if (end_ < pc_) { 486 if (end_ < pc_) {
391 error("function body end < start"); 487 error("function body end < start");
392 return false; 488 return false;
393 } 489 }
394 490
395 DecodeLocalDecls(); 491 DCHECK_EQ(0, local_types_->size());
492 WasmDecoder::DecodeLocals(this, sig_, local_types_);
396 InitSsaEnv(); 493 InitSsaEnv();
397 DecodeFunctionBody(); 494 DecodeFunctionBody();
398 495
399 if (failed()) return TraceFailed(); 496 if (failed()) return TraceFailed();
400 497
401 #if IMPLICIT_FUNCTION_END 498 #if IMPLICIT_FUNCTION_END
402 // With implicit end support (old style), the function block 499 // With implicit end support (old style), the function block
403 // remains on the stack. Other control blocks are an error. 500 // remains on the stack. Other control blocks are an error.
404 if (control_.size() > 1) { 501 if (control_.size() > 1) {
405 error(pc_, control_.back().pc, "unterminated control structure"); 502 error(pc_, control_.back().pc, "unterminated control structure");
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 548
452 return true; 549 return true;
453 } 550 }
454 551
455 bool TraceFailed() { 552 bool TraceFailed() {
456 TRACE("wasm-error module+%-6d func+%d: %s\n\n", baserel(error_pc_), 553 TRACE("wasm-error module+%-6d func+%d: %s\n\n", baserel(error_pc_),
457 startrel(error_pc_), error_msg_.get()); 554 startrel(error_pc_), error_msg_.get());
458 return false; 555 return false;
459 } 556 }
460 557
461 bool DecodeLocalDecls(BodyLocalDecls& decls) {
462 DecodeLocalDecls();
463 if (failed()) return false;
464 decls.decls_encoded_size = pc_offset();
465 decls.local_types.reserve(local_type_vec_.size());
466 for (size_t pos = 0; pos < local_type_vec_.size();) {
467 uint32_t count = 0;
468 ValueType type = local_type_vec_[pos];
469 while (pos < local_type_vec_.size() && local_type_vec_[pos] == type) {
470 pos++;
471 count++;
472 }
473 decls.local_types.push_back(std::pair<ValueType, uint32_t>(type, count));
474 }
475 decls.total_local_count = static_cast<uint32_t>(local_type_vec_.size());
476 return true;
477 }
478
479 BitVector* AnalyzeLoopAssignmentForTesting(const byte* pc,
480 size_t num_locals) {
481 total_locals_ = num_locals;
482 local_type_vec_.reserve(num_locals);
483 if (num_locals > local_type_vec_.size()) {
484 local_type_vec_.insert(local_type_vec_.end(),
485 num_locals - local_type_vec_.size(), kWasmI32);
486 }
487 return AnalyzeLoopAssignment(pc);
488 }
489
490 private: 558 private:
491 WasmFullDecoder(Zone* zone, const wasm::WasmModule* module, 559 WasmFullDecoder(Zone* zone, const wasm::WasmModule* module,
492 TFBuilder* builder, const FunctionBody& body) 560 TFBuilder* builder, const FunctionBody& body)
493 : WasmDecoder(module, body.sig, body.start, body.end), 561 : WasmDecoder(module, body.sig, body.start, body.end),
494 zone_(zone), 562 zone_(zone),
495 builder_(builder), 563 builder_(builder),
496 base_(body.base), 564 base_(body.base),
497 local_type_vec_(zone), 565 local_type_vec_(zone),
498 stack_(zone), 566 stack_(zone),
499 control_(zone), 567 control_(zone),
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 static const int kMaxIndent = 64; 645 static const int kMaxIndent = 64;
578 static char bytes[kMaxIndent + 1]; 646 static char bytes[kMaxIndent + 1];
579 for (int i = 0; i < kMaxIndent; ++i) bytes[i] = ' '; 647 for (int i = 0; i < kMaxIndent; ++i) bytes[i] = ' ';
580 bytes[kMaxIndent] = 0; 648 bytes[kMaxIndent] = 0;
581 if (stack_.size() < kMaxIndent / 2) { 649 if (stack_.size() < kMaxIndent / 2) {
582 bytes[stack_.size() * 2] = 0; 650 bytes[stack_.size() * 2] = 0;
583 } 651 }
584 return bytes; 652 return bytes;
585 } 653 }
586 654
587 // Decodes the locals declarations, if any, populating {local_type_vec_}.
588 void DecodeLocalDecls() {
589 DCHECK_EQ(0, local_type_vec_.size());
590 // Initialize {local_type_vec} from signature.
591 if (sig_) {
592 local_type_vec_.reserve(sig_->parameter_count());
593 for (size_t i = 0; i < sig_->parameter_count(); ++i) {
594 local_type_vec_.push_back(sig_->GetParam(i));
595 }
596 }
597 // Decode local declarations, if any.
598 uint32_t entries = consume_u32v("local decls count");
599 TRACE("local decls count: %u\n", entries);
600 while (entries-- > 0 && pc_ < end_) {
601 uint32_t count = consume_u32v("local count");
602 if ((count + local_type_vec_.size()) > kMaxNumWasmLocals) {
603 error(pc_ - 1, "local count too large");
604 return;
605 }
606 byte code = consume_u8("local type");
607 ValueType type;
608 switch (code) {
609 case kLocalI32:
610 type = kWasmI32;
611 break;
612 case kLocalI64:
613 type = kWasmI64;
614 break;
615 case kLocalF32:
616 type = kWasmF32;
617 break;
618 case kLocalF64:
619 type = kWasmF64;
620 break;
621 case kLocalS128:
622 type = kWasmS128;
623 break;
624 default:
625 error(pc_ - 1, "invalid local type");
626 return;
627 }
628 local_type_vec_.insert(local_type_vec_.end(), count, type);
629 }
630 total_locals_ = local_type_vec_.size();
631 }
632
633 // Decodes the body of a function. 655 // Decodes the body of a function.
634 void DecodeFunctionBody() { 656 void DecodeFunctionBody() {
635 TRACE("wasm-decode %p...%p (module+%d, %d bytes) %s\n", 657 TRACE("wasm-decode %p...%p (module+%d, %d bytes) %s\n",
636 reinterpret_cast<const void*>(start_), 658 reinterpret_cast<const void*>(start_),
637 reinterpret_cast<const void*>(end_), baserel(pc_), 659 reinterpret_cast<const void*>(end_), baserel(pc_),
638 static_cast<int>(end_ - start_), builder_ ? "graph building" : ""); 660 static_cast<int>(end_ - start_), builder_ ? "graph building" : "");
639 661
640 { 662 {
641 // Set up initial function block. 663 // Set up initial function block.
642 SsaEnv* break_env = ssa_env_; 664 SsaEnv* break_env = ssa_env_;
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
1737 1759
1738 SsaEnv* PrepareForLoop(const byte* pc, SsaEnv* env) { 1760 SsaEnv* PrepareForLoop(const byte* pc, SsaEnv* env) {
1739 if (!builder_) return Split(env); 1761 if (!builder_) return Split(env);
1740 if (!env->go()) return Split(env); 1762 if (!env->go()) return Split(env);
1741 env->state = SsaEnv::kMerged; 1763 env->state = SsaEnv::kMerged;
1742 1764
1743 env->control = builder_->Loop(env->control); 1765 env->control = builder_->Loop(env->control);
1744 env->effect = builder_->EffectPhi(1, &env->effect, env->control); 1766 env->effect = builder_->EffectPhi(1, &env->effect, env->control);
1745 builder_->Terminate(env->effect, env->control); 1767 builder_->Terminate(env->effect, env->control);
1746 if (FLAG_wasm_loop_assignment_analysis) { 1768 if (FLAG_wasm_loop_assignment_analysis) {
1747 BitVector* assigned = AnalyzeLoopAssignment(pc); 1769 BitVector* assigned = AnalyzeLoopAssignment(
1770 this, pc, static_cast<int>(total_locals()), zone_);
1748 if (failed()) return env; 1771 if (failed()) return env;
1749 if (assigned != nullptr) { 1772 if (assigned != nullptr) {
1750 // Only introduce phis for variables assigned in this loop. 1773 // Only introduce phis for variables assigned in this loop.
1751 for (int i = EnvironmentCount() - 1; i >= 0; i--) { 1774 for (int i = EnvironmentCount() - 1; i >= 0; i--) {
1752 if (!assigned->Contains(i)) continue; 1775 if (!assigned->Contains(i)) continue;
1753 env->locals[i] = builder_->Phi(local_type_vec_[i], 1, &env->locals[i], 1776 env->locals[i] = builder_->Phi(local_type_vec_[i], 1, &env->locals[i],
1754 env->control); 1777 env->control);
1755 } 1778 }
1756 SsaEnv* loop_body_env = Split(env); 1779 SsaEnv* loop_body_env = Split(env);
1757 builder_->StackCheck(position(), &(loop_body_env->effect), 1780 builder_->StackCheck(position(), &(loop_body_env->effect),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1820 int EnvironmentCount() { 1843 int EnvironmentCount() {
1821 if (builder_) return static_cast<int>(local_type_vec_.size()); 1844 if (builder_) return static_cast<int>(local_type_vec_.size());
1822 return 0; // if we aren't building a graph, don't bother with SSA renaming. 1845 return 0; // if we aren't building a graph, don't bother with SSA renaming.
1823 } 1846 }
1824 1847
1825 virtual void onFirstError() { 1848 virtual void onFirstError() {
1826 end_ = start_; // Terminate decoding loop. 1849 end_ = start_; // Terminate decoding loop.
1827 builder_ = nullptr; // Don't build any more nodes. 1850 builder_ = nullptr; // Don't build any more nodes.
1828 TRACE(" !%s\n", error_msg_.get()); 1851 TRACE(" !%s\n", error_msg_.get());
1829 } 1852 }
1830 BitVector* AnalyzeLoopAssignment(const byte* pc) {
1831 if (pc >= end_) return nullptr;
1832 if (*pc != kExprLoop) return nullptr;
1833
1834 BitVector* assigned =
1835 new (zone_) BitVector(static_cast<int>(local_type_vec_.size()), zone_);
1836 int depth = 0;
1837 // Iteratively process all AST nodes nested inside the loop.
1838 while (pc < end_ && ok()) {
1839 WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
1840 unsigned length = 1;
1841 switch (opcode) {
1842 case kExprLoop:
1843 case kExprIf:
1844 case kExprBlock:
1845 case kExprTry:
1846 length = OpcodeLength(pc);
1847 depth++;
1848 break;
1849 case kExprSetLocal: // fallthru
1850 case kExprTeeLocal: {
1851 LocalIndexOperand operand(this, pc);
1852 if (assigned->length() > 0 &&
1853 operand.index < static_cast<uint32_t>(assigned->length())) {
1854 // Unverified code might have an out-of-bounds index.
1855 assigned->Add(operand.index);
1856 }
1857 length = 1 + operand.length;
1858 break;
1859 }
1860 case kExprEnd:
1861 depth--;
1862 break;
1863 default:
1864 length = OpcodeLength(pc);
1865 break;
1866 }
1867 if (depth <= 0) break;
1868 pc += length;
1869 }
1870 return ok() ? assigned : nullptr;
1871 }
1872 1853
1873 inline wasm::WasmCodePosition position() { 1854 inline wasm::WasmCodePosition position() {
1874 int offset = static_cast<int>(pc_ - start_); 1855 int offset = static_cast<int>(pc_ - start_);
1875 DCHECK_EQ(pc_ - start_, offset); // overflows cannot happen 1856 DCHECK_EQ(pc_ - start_, offset); // overflows cannot happen
1876 return offset; 1857 return offset;
1877 } 1858 }
1878 1859
1879 inline void BuildSimpleOperator(WasmOpcode opcode, FunctionSig* sig) { 1860 inline void BuildSimpleOperator(WasmOpcode opcode, FunctionSig* sig) {
1880 TFNode* node; 1861 TFNode* node;
1881 switch (sig->parameter_count()) { 1862 switch (sig->parameter_count()) {
(...skipping 10 matching lines...) Expand all
1892 } 1873 }
1893 default: 1874 default:
1894 UNREACHABLE(); 1875 UNREACHABLE();
1895 node = nullptr; 1876 node = nullptr;
1896 break; 1877 break;
1897 } 1878 }
1898 Push(GetReturnType(sig), node); 1879 Push(GetReturnType(sig), node);
1899 } 1880 }
1900 }; 1881 };
1901 1882
1902 bool DecodeLocalDecls(BodyLocalDecls& decls, const byte* start, 1883 bool DecodeLocalDecls(BodyLocalDecls* decls, const byte* start,
1903 const byte* end) { 1884 const byte* end) {
1904 AccountingAllocator allocator; 1885 Decoder decoder(start, end);
1905 Zone tmp(&allocator, ZONE_NAME); 1886 if (WasmDecoder::DecodeLocals(&decoder, nullptr, &decls->type_list)) {
1906 FunctionBody body = {nullptr, nullptr, start, end}; 1887 DCHECK(decoder.ok());
1907 WasmFullDecoder decoder(&tmp, body); 1888 decls->encoded_size = decoder.pc_offset();
1908 return decoder.DecodeLocalDecls(decls); 1889 return true;
1890 }
1891 return false;
1909 } 1892 }
1910 1893
1911 BytecodeIterator::BytecodeIterator(const byte* start, const byte* end, 1894 BytecodeIterator::BytecodeIterator(const byte* start, const byte* end,
1912 BodyLocalDecls* decls) 1895 BodyLocalDecls* decls)
1913 : Decoder(start, end) { 1896 : Decoder(start, end) {
1914 if (decls != nullptr) { 1897 if (decls != nullptr) {
1915 if (DecodeLocalDecls(*decls, start, end)) { 1898 if (DecodeLocalDecls(decls, start, end)) {
1916 pc_ += decls->decls_encoded_size; 1899 pc_ += decls->encoded_size;
1917 if (pc_ > end_) pc_ = end_; 1900 if (pc_ > end_) pc_ = end_;
1918 } 1901 }
1919 } 1902 }
1920 } 1903 }
1921 1904
1922 DecodeResult VerifyWasmCode(AccountingAllocator* allocator, 1905 DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
1923 const wasm::WasmModule* module, 1906 const wasm::WasmModule* module,
1924 FunctionBody& body) { 1907 FunctionBody& body) {
1925 Zone zone(allocator, ZONE_NAME); 1908 Zone zone(allocator, ZONE_NAME);
1926 WasmFullDecoder decoder(&zone, module, body); 1909 WasmFullDecoder decoder(&zone, module, body);
1927 decoder.Decode(); 1910 decoder.Decode();
1928 return decoder.toResult<DecodeStruct*>(nullptr); 1911 return decoder.toResult<DecodeStruct*>(nullptr);
1929 } 1912 }
1930 1913
1931 DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder, 1914 DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder,
1932 FunctionBody& body) { 1915 FunctionBody& body) {
1933 Zone zone(allocator, ZONE_NAME); 1916 Zone zone(allocator, ZONE_NAME);
1934 WasmFullDecoder decoder(&zone, builder, body); 1917 WasmFullDecoder decoder(&zone, builder, body);
1935 decoder.Decode(); 1918 decoder.Decode();
1936 return decoder.toResult<DecodeStruct*>(nullptr); 1919 return decoder.toResult<DecodeStruct*>(nullptr);
1937 } 1920 }
1938 1921
1939 unsigned OpcodeLength(const byte* pc, const byte* end) { 1922 unsigned OpcodeLength(const byte* pc, const byte* end) {
1940 WasmDecoder decoder(nullptr, nullptr, pc, end); 1923 Decoder decoder(pc, end);
1941 return decoder.OpcodeLength(pc); 1924 return WasmDecoder::OpcodeLength(&decoder, pc);
1942 } 1925 }
1943 1926
1944 void PrintWasmCodeForDebugging(const byte* start, const byte* end) { 1927 void PrintWasmCodeForDebugging(const byte* start, const byte* end) {
1945 AccountingAllocator allocator; 1928 AccountingAllocator allocator;
1946 OFStream os(stdout); 1929 OFStream os(stdout);
1947 PrintWasmCode(&allocator, FunctionBodyForTesting(start, end), nullptr, os, 1930 PrintWasmCode(&allocator, FunctionBodyForTesting(start, end), nullptr, os,
1948 nullptr); 1931 nullptr);
1949 } 1932 }
1950 1933
1951 bool PrintWasmCode(AccountingAllocator* allocator, const FunctionBody& body, 1934 bool PrintWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
1952 const wasm::WasmModule* module, std::ostream& os, 1935 const wasm::WasmModule* module, std::ostream& os,
1953 std::vector<std::tuple<uint32_t, int, int>>* offset_table) { 1936 std::vector<std::tuple<uint32_t, int, int>>* offset_table) {
1954 Zone zone(allocator, ZONE_NAME); 1937 Zone zone(allocator, ZONE_NAME);
1955 WasmFullDecoder decoder(&zone, module, body); 1938 WasmFullDecoder decoder(&zone, module, body);
1956 int line_nr = 0; 1939 int line_nr = 0;
1957 1940
1958 // Print the function signature. 1941 // Print the function signature.
1959 if (body.sig) { 1942 if (body.sig) {
1960 os << "// signature: " << *body.sig << std::endl; 1943 os << "// signature: " << *body.sig << std::endl;
1961 ++line_nr; 1944 ++line_nr;
1962 } 1945 }
1963 1946
1964 // Print the local declarations. 1947 // Print the local declarations.
1965 BodyLocalDecls decls(&zone); 1948 BodyLocalDecls decls(&zone);
1966 BytecodeIterator i(body.start, body.end, &decls); 1949 BytecodeIterator i(body.start, body.end, &decls);
1967 if (body.start != i.pc() && !FLAG_wasm_code_fuzzer_gen_test) { 1950 if (body.start != i.pc() && !FLAG_wasm_code_fuzzer_gen_test) {
1968 os << "// locals: "; 1951 os << "// locals: ";
1969 for (auto p : decls.local_types) { 1952 if (!decls.type_list.empty()) {
1970 ValueType type = p.first; 1953 ValueType type = decls.type_list[0];
1971 uint32_t count = p.second; 1954 uint32_t count = 0;
1972 os << " " << count << " " << WasmOpcodes::TypeName(type); 1955 for (size_t pos = 0; pos < decls.type_list.size(); ++pos) {
1956 if (decls.type_list[pos] == type) {
1957 ++count;
1958 } else {
1959 os << " " << count << " " << WasmOpcodes::TypeName(type);
1960 type = decls.type_list[pos];
1961 count = 1;
1962 }
1963 }
1973 } 1964 }
1974 os << std::endl; 1965 os << std::endl;
1975 ++line_nr; 1966 ++line_nr;
1976 1967
1977 for (const byte* locals = body.start; locals < i.pc(); locals++) { 1968 for (const byte* locals = body.start; locals < i.pc(); locals++) {
1978 os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ","; 1969 os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ",";
1979 } 1970 }
1980 os << std::endl; 1971 os << std::endl;
1981 ++line_nr; 1972 ++line_nr;
1982 } 1973 }
1983 1974
1984 os << "// body: " << std::endl; 1975 os << "// body: " << std::endl;
1985 ++line_nr; 1976 ++line_nr;
1986 unsigned control_depth = 0; 1977 unsigned control_depth = 0;
1987 for (; i.has_next(); i.next()) { 1978 for (; i.has_next(); i.next()) {
1988 unsigned length = decoder.OpcodeLength(i.pc()); 1979 unsigned length = WasmDecoder::OpcodeLength(&decoder, i.pc());
1989 1980
1990 WasmOpcode opcode = i.current(); 1981 WasmOpcode opcode = i.current();
1991 if (opcode == kExprElse) control_depth--; 1982 if (opcode == kExprElse) control_depth--;
1992 1983
1993 int num_whitespaces = control_depth < 32 ? 2 * control_depth : 64; 1984 int num_whitespaces = control_depth < 32 ? 2 * control_depth : 64;
1994 if (offset_table) { 1985 if (offset_table) {
1995 offset_table->push_back( 1986 offset_table->push_back(
1996 std::make_tuple(i.pc_offset(), line_nr, num_whitespaces)); 1987 std::make_tuple(i.pc_offset(), line_nr, num_whitespaces));
1997 } 1988 }
1998 1989
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2063 } 2054 }
2064 os << std::endl; 2055 os << std::endl;
2065 ++line_nr; 2056 ++line_nr;
2066 } 2057 }
2067 2058
2068 return decoder.ok(); 2059 return decoder.ok();
2069 } 2060 }
2070 2061
2071 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, 2062 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
2072 const byte* start, const byte* end) { 2063 const byte* start, const byte* end) {
2073 FunctionBody body = {nullptr, nullptr, start, end}; 2064 Decoder decoder(start, end);
2074 WasmFullDecoder decoder(zone, body); 2065 return WasmDecoder::AnalyzeLoopAssignment(&decoder, start,
2075 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); 2066 static_cast<int>(num_locals), zone);
2076 } 2067 }
2077 2068
2078 } // namespace wasm 2069 } // namespace wasm
2079 } // namespace internal 2070 } // namespace internal
2080 } // namespace v8 2071 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/function-body-decoder.h ('k') | src/wasm/wasm-interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698