| OLD | NEW |
| 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 } | 63 } |
| 64 void SetNotMerged() { | 64 void SetNotMerged() { |
| 65 if (state == kMerged) state = kReached; | 65 if (state == kMerged) state = kReached; |
| 66 } | 66 } |
| 67 }; | 67 }; |
| 68 | 68 |
| 69 // An entry on the value stack. | 69 // An entry on the value stack. |
| 70 struct Value { | 70 struct Value { |
| 71 const byte* pc; | 71 const byte* pc; |
| 72 TFNode* node; | 72 TFNode* node; |
| 73 LocalType type; | 73 ValueType type; |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 struct TryInfo : public ZoneObject { | 76 struct TryInfo : public ZoneObject { |
| 77 SsaEnv* catch_env; | 77 SsaEnv* catch_env; |
| 78 TFNode* exception; | 78 TFNode* exception; |
| 79 | 79 |
| 80 explicit TryInfo(SsaEnv* c) : catch_env(c), exception(nullptr) {} | 80 explicit TryInfo(SsaEnv* c) : catch_env(c), exception(nullptr) {} |
| 81 }; | 81 }; |
| 82 | 82 |
| 83 struct MergeValues { | 83 struct MergeValues { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 WasmDecoder(ModuleEnv* module, FunctionSig* sig, const byte* start, | 167 WasmDecoder(ModuleEnv* 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), | 172 total_locals_(0), |
| 173 local_types_(nullptr) {} | 173 local_types_(nullptr) {} |
| 174 ModuleEnv* module_; | 174 ModuleEnv* module_; |
| 175 FunctionSig* sig_; | 175 FunctionSig* sig_; |
| 176 size_t total_locals_; | 176 size_t total_locals_; |
| 177 ZoneVector<LocalType>* local_types_; | 177 ZoneVector<ValueType>* local_types_; |
| 178 | 178 |
| 179 inline bool Validate(const byte* pc, LocalIndexOperand& operand) { | 179 inline bool Validate(const byte* pc, LocalIndexOperand& operand) { |
| 180 if (operand.index < total_locals_) { | 180 if (operand.index < total_locals_) { |
| 181 if (local_types_) { | 181 if (local_types_) { |
| 182 operand.type = local_types_->at(operand.index); | 182 operand.type = local_types_->at(operand.index); |
| 183 } else { | 183 } else { |
| 184 operand.type = kAstStmt; | 184 operand.type = kWasmStmt; |
| 185 } | 185 } |
| 186 return true; | 186 return true; |
| 187 } | 187 } |
| 188 error(pc, pc + 1, "invalid local index: %u", operand.index); | 188 error(pc, pc + 1, "invalid local index: %u", operand.index); |
| 189 return false; | 189 return false; |
| 190 } | 190 } |
| 191 | 191 |
| 192 inline bool Validate(const byte* pc, GlobalIndexOperand& operand) { | 192 inline bool Validate(const byte* pc, GlobalIndexOperand& operand) { |
| 193 ModuleEnv* m = module_; | 193 ModuleEnv* m = module_; |
| 194 if (m && m->module && operand.index < m->module->globals.size()) { | 194 if (m && m->module && operand.index < m->module->globals.size()) { |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 return false; | 462 return false; |
| 463 } | 463 } |
| 464 | 464 |
| 465 bool DecodeLocalDecls(BodyLocalDecls& decls) { | 465 bool DecodeLocalDecls(BodyLocalDecls& decls) { |
| 466 DecodeLocalDecls(); | 466 DecodeLocalDecls(); |
| 467 if (failed()) return false; | 467 if (failed()) return false; |
| 468 decls.decls_encoded_size = pc_offset(); | 468 decls.decls_encoded_size = pc_offset(); |
| 469 decls.local_types.reserve(local_type_vec_.size()); | 469 decls.local_types.reserve(local_type_vec_.size()); |
| 470 for (size_t pos = 0; pos < local_type_vec_.size();) { | 470 for (size_t pos = 0; pos < local_type_vec_.size();) { |
| 471 uint32_t count = 0; | 471 uint32_t count = 0; |
| 472 LocalType type = local_type_vec_[pos]; | 472 ValueType type = local_type_vec_[pos]; |
| 473 while (pos < local_type_vec_.size() && local_type_vec_[pos] == type) { | 473 while (pos < local_type_vec_.size() && local_type_vec_[pos] == type) { |
| 474 pos++; | 474 pos++; |
| 475 count++; | 475 count++; |
| 476 } | 476 } |
| 477 decls.local_types.push_back(std::pair<LocalType, uint32_t>(type, count)); | 477 decls.local_types.push_back(std::pair<ValueType, uint32_t>(type, count)); |
| 478 } | 478 } |
| 479 decls.total_local_count = static_cast<uint32_t>(local_type_vec_.size()); | 479 decls.total_local_count = static_cast<uint32_t>(local_type_vec_.size()); |
| 480 return true; | 480 return true; |
| 481 } | 481 } |
| 482 | 482 |
| 483 BitVector* AnalyzeLoopAssignmentForTesting(const byte* pc, | 483 BitVector* AnalyzeLoopAssignmentForTesting(const byte* pc, |
| 484 size_t num_locals) { | 484 size_t num_locals) { |
| 485 total_locals_ = num_locals; | 485 total_locals_ = num_locals; |
| 486 local_type_vec_.reserve(num_locals); | 486 local_type_vec_.reserve(num_locals); |
| 487 if (num_locals > local_type_vec_.size()) { | 487 if (num_locals > local_type_vec_.size()) { |
| 488 local_type_vec_.insert(local_type_vec_.end(), | 488 local_type_vec_.insert(local_type_vec_.end(), |
| 489 num_locals - local_type_vec_.size(), kAstI32); | 489 num_locals - local_type_vec_.size(), kWasmI32); |
| 490 } | 490 } |
| 491 return AnalyzeLoopAssignment(pc); | 491 return AnalyzeLoopAssignment(pc); |
| 492 } | 492 } |
| 493 | 493 |
| 494 private: | 494 private: |
| 495 static const size_t kErrorMsgSize = 128; | 495 static const size_t kErrorMsgSize = 128; |
| 496 | 496 |
| 497 Zone* zone_; | 497 Zone* zone_; |
| 498 TFBuilder* builder_; | 498 TFBuilder* builder_; |
| 499 const byte* base_; | 499 const byte* base_; |
| 500 | 500 |
| 501 SsaEnv* ssa_env_; | 501 SsaEnv* ssa_env_; |
| 502 | 502 |
| 503 ZoneVector<LocalType> local_type_vec_; // types of local variables. | 503 ZoneVector<ValueType> local_type_vec_; // types of local variables. |
| 504 ZoneVector<Value> stack_; // stack of values. | 504 ZoneVector<Value> stack_; // stack of values. |
| 505 ZoneVector<Control> control_; // stack of blocks, loops, and ifs. | 505 ZoneVector<Control> control_; // stack of blocks, loops, and ifs. |
| 506 bool last_end_found_; | 506 bool last_end_found_; |
| 507 | 507 |
| 508 int32_t current_catch_; | 508 int32_t current_catch_; |
| 509 | 509 |
| 510 TryInfo* current_try_info() { return control_[current_catch_].try_info; } | 510 TryInfo* current_try_info() { return control_[current_catch_].try_info; } |
| 511 | 511 |
| 512 inline bool build() { return builder_ && ssa_env_->go(); } | 512 inline bool build() { return builder_ && ssa_env_->go(); } |
| 513 | 513 |
| 514 void InitSsaEnv() { | 514 void InitSsaEnv() { |
| 515 TFNode* start = nullptr; | 515 TFNode* start = nullptr; |
| 516 SsaEnv* ssa_env = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv))); | 516 SsaEnv* ssa_env = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv))); |
| 517 size_t size = sizeof(TFNode*) * EnvironmentCount(); | 517 size_t size = sizeof(TFNode*) * EnvironmentCount(); |
| 518 ssa_env->state = SsaEnv::kReached; | 518 ssa_env->state = SsaEnv::kReached; |
| 519 ssa_env->locals = | 519 ssa_env->locals = |
| 520 size > 0 ? reinterpret_cast<TFNode**>(zone_->New(size)) : nullptr; | 520 size > 0 ? reinterpret_cast<TFNode**>(zone_->New(size)) : nullptr; |
| 521 | 521 |
| 522 if (builder_) { | 522 if (builder_) { |
| 523 start = builder_->Start(static_cast<int>(sig_->parameter_count() + 1)); | 523 start = builder_->Start(static_cast<int>(sig_->parameter_count() + 1)); |
| 524 // Initialize local variables. | 524 // Initialize local variables. |
| 525 uint32_t index = 0; | 525 uint32_t index = 0; |
| 526 while (index < sig_->parameter_count()) { | 526 while (index < sig_->parameter_count()) { |
| 527 ssa_env->locals[index] = builder_->Param(index); | 527 ssa_env->locals[index] = builder_->Param(index); |
| 528 index++; | 528 index++; |
| 529 } | 529 } |
| 530 while (index < local_type_vec_.size()) { | 530 while (index < local_type_vec_.size()) { |
| 531 LocalType type = local_type_vec_[index]; | 531 ValueType type = local_type_vec_[index]; |
| 532 TFNode* node = DefaultValue(type); | 532 TFNode* node = DefaultValue(type); |
| 533 while (index < local_type_vec_.size() && | 533 while (index < local_type_vec_.size() && |
| 534 local_type_vec_[index] == type) { | 534 local_type_vec_[index] == type) { |
| 535 // Do a whole run of like-typed locals at a time. | 535 // Do a whole run of like-typed locals at a time. |
| 536 ssa_env->locals[index++] = node; | 536 ssa_env->locals[index++] = node; |
| 537 } | 537 } |
| 538 } | 538 } |
| 539 builder_->set_module(module_); | 539 builder_->set_module(module_); |
| 540 } | 540 } |
| 541 ssa_env->control = start; | 541 ssa_env->control = start; |
| 542 ssa_env->effect = start; | 542 ssa_env->effect = start; |
| 543 SetEnv("initial", ssa_env); | 543 SetEnv("initial", ssa_env); |
| 544 if (builder_) { | 544 if (builder_) { |
| 545 builder_->StackCheck(position()); | 545 builder_->StackCheck(position()); |
| 546 } | 546 } |
| 547 } | 547 } |
| 548 | 548 |
| 549 TFNode* DefaultValue(LocalType type) { | 549 TFNode* DefaultValue(ValueType type) { |
| 550 switch (type) { | 550 switch (type) { |
| 551 case kAstI32: | 551 case kWasmI32: |
| 552 return builder_->Int32Constant(0); | 552 return builder_->Int32Constant(0); |
| 553 case kAstI64: | 553 case kWasmI64: |
| 554 return builder_->Int64Constant(0); | 554 return builder_->Int64Constant(0); |
| 555 case kAstF32: | 555 case kWasmF32: |
| 556 return builder_->Float32Constant(0); | 556 return builder_->Float32Constant(0); |
| 557 case kAstF64: | 557 case kWasmF64: |
| 558 return builder_->Float64Constant(0); | 558 return builder_->Float64Constant(0); |
| 559 case kAstS128: | 559 case kWasmS128: |
| 560 return builder_->CreateS128Value(0); | 560 return builder_->CreateS128Value(0); |
| 561 default: | 561 default: |
| 562 UNREACHABLE(); | 562 UNREACHABLE(); |
| 563 return nullptr; | 563 return nullptr; |
| 564 } | 564 } |
| 565 } | 565 } |
| 566 | 566 |
| 567 char* indentation() { | 567 char* indentation() { |
| 568 static const int kMaxIndent = 64; | 568 static const int kMaxIndent = 64; |
| 569 static char bytes[kMaxIndent + 1]; | 569 static char bytes[kMaxIndent + 1]; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 588 // Decode local declarations, if any. | 588 // Decode local declarations, if any. |
| 589 uint32_t entries = consume_u32v("local decls count"); | 589 uint32_t entries = consume_u32v("local decls count"); |
| 590 TRACE("local decls count: %u\n", entries); | 590 TRACE("local decls count: %u\n", entries); |
| 591 while (entries-- > 0 && pc_ < limit_) { | 591 while (entries-- > 0 && pc_ < limit_) { |
| 592 uint32_t count = consume_u32v("local count"); | 592 uint32_t count = consume_u32v("local count"); |
| 593 if ((count + local_type_vec_.size()) > kMaxNumWasmLocals) { | 593 if ((count + local_type_vec_.size()) > kMaxNumWasmLocals) { |
| 594 error(pc_ - 1, "local count too large"); | 594 error(pc_ - 1, "local count too large"); |
| 595 return; | 595 return; |
| 596 } | 596 } |
| 597 byte code = consume_u8("local type"); | 597 byte code = consume_u8("local type"); |
| 598 LocalType type; | 598 ValueType type; |
| 599 switch (code) { | 599 switch (code) { |
| 600 case kLocalI32: | 600 case kLocalI32: |
| 601 type = kAstI32; | 601 type = kWasmI32; |
| 602 break; | 602 break; |
| 603 case kLocalI64: | 603 case kLocalI64: |
| 604 type = kAstI64; | 604 type = kWasmI64; |
| 605 break; | 605 break; |
| 606 case kLocalF32: | 606 case kLocalF32: |
| 607 type = kAstF32; | 607 type = kWasmF32; |
| 608 break; | 608 break; |
| 609 case kLocalF64: | 609 case kLocalF64: |
| 610 type = kAstF64; | 610 type = kWasmF64; |
| 611 break; | 611 break; |
| 612 case kLocalS128: | 612 case kLocalS128: |
| 613 type = kAstS128; | 613 type = kWasmS128; |
| 614 break; | 614 break; |
| 615 default: | 615 default: |
| 616 error(pc_ - 1, "invalid local type"); | 616 error(pc_ - 1, "invalid local type"); |
| 617 return; | 617 return; |
| 618 } | 618 } |
| 619 local_type_vec_.insert(local_type_vec_.end(), count, type); | 619 local_type_vec_.insert(local_type_vec_.end(), count, type); |
| 620 } | 620 } |
| 621 total_locals_ = local_type_vec_.size(); | 621 total_locals_ = local_type_vec_.size(); |
| 622 } | 622 } |
| 623 | 623 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 BlockTypeOperand operand(this, pc_); | 669 BlockTypeOperand operand(this, pc_); |
| 670 SsaEnv* break_env = ssa_env_; | 670 SsaEnv* break_env = ssa_env_; |
| 671 PushBlock(break_env); | 671 PushBlock(break_env); |
| 672 SetEnv("block:start", Steal(break_env)); | 672 SetEnv("block:start", Steal(break_env)); |
| 673 SetBlockType(&control_.back(), operand); | 673 SetBlockType(&control_.back(), operand); |
| 674 len = 1 + operand.length; | 674 len = 1 + operand.length; |
| 675 break; | 675 break; |
| 676 } | 676 } |
| 677 case kExprThrow: { | 677 case kExprThrow: { |
| 678 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); | 678 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
| 679 Value value = Pop(0, kAstI32); | 679 Value value = Pop(0, kWasmI32); |
| 680 BUILD(Throw, value.node); | 680 BUILD(Throw, value.node); |
| 681 break; | 681 break; |
| 682 } | 682 } |
| 683 case kExprTry: { | 683 case kExprTry: { |
| 684 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); | 684 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
| 685 BlockTypeOperand operand(this, pc_); | 685 BlockTypeOperand operand(this, pc_); |
| 686 SsaEnv* outer_env = ssa_env_; | 686 SsaEnv* outer_env = ssa_env_; |
| 687 SsaEnv* try_env = Steal(outer_env); | 687 SsaEnv* try_env = Steal(outer_env); |
| 688 SsaEnv* catch_env = UnreachableEnv(); | 688 SsaEnv* catch_env = UnreachableEnv(); |
| 689 PushTry(outer_env, catch_env); | 689 PushTry(outer_env, catch_env); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 SetEnv("loop:start", loop_body_env); | 742 SetEnv("loop:start", loop_body_env); |
| 743 ssa_env_->SetNotMerged(); | 743 ssa_env_->SetNotMerged(); |
| 744 PushLoop(finish_try_env); | 744 PushLoop(finish_try_env); |
| 745 SetBlockType(&control_.back(), operand); | 745 SetBlockType(&control_.back(), operand); |
| 746 len = 1 + operand.length; | 746 len = 1 + operand.length; |
| 747 break; | 747 break; |
| 748 } | 748 } |
| 749 case kExprIf: { | 749 case kExprIf: { |
| 750 // Condition on top of stack. Split environments for branches. | 750 // Condition on top of stack. Split environments for branches. |
| 751 BlockTypeOperand operand(this, pc_); | 751 BlockTypeOperand operand(this, pc_); |
| 752 Value cond = Pop(0, kAstI32); | 752 Value cond = Pop(0, kWasmI32); |
| 753 TFNode* if_true = nullptr; | 753 TFNode* if_true = nullptr; |
| 754 TFNode* if_false = nullptr; | 754 TFNode* if_false = nullptr; |
| 755 BUILD(BranchNoHint, cond.node, &if_true, &if_false); | 755 BUILD(BranchNoHint, cond.node, &if_true, &if_false); |
| 756 SsaEnv* end_env = ssa_env_; | 756 SsaEnv* end_env = ssa_env_; |
| 757 SsaEnv* false_env = Split(ssa_env_); | 757 SsaEnv* false_env = Split(ssa_env_); |
| 758 false_env->control = if_false; | 758 false_env->control = if_false; |
| 759 SsaEnv* true_env = Steal(ssa_env_); | 759 SsaEnv* true_env = Steal(ssa_env_); |
| 760 true_env->control = if_true; | 760 true_env->control = if_true; |
| 761 PushIf(end_env, false_env); | 761 PushIf(end_env, false_env); |
| 762 SetEnv("if:true", true_env); | 762 SetEnv("if:true", true_env); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 // The result of the block is the return value. | 850 // The result of the block is the return value. |
| 851 TRACE(" @%-8d #xx:%-20s|", startrel(pc_), "ImplicitReturn"); | 851 TRACE(" @%-8d #xx:%-20s|", startrel(pc_), "ImplicitReturn"); |
| 852 DoReturn(); | 852 DoReturn(); |
| 853 TRACE("\n"); | 853 TRACE("\n"); |
| 854 } | 854 } |
| 855 return; | 855 return; |
| 856 } | 856 } |
| 857 break; | 857 break; |
| 858 } | 858 } |
| 859 case kExprSelect: { | 859 case kExprSelect: { |
| 860 Value cond = Pop(2, kAstI32); | 860 Value cond = Pop(2, kWasmI32); |
| 861 Value fval = Pop(); | 861 Value fval = Pop(); |
| 862 Value tval = Pop(); | 862 Value tval = Pop(); |
| 863 if (tval.type == kAstStmt || tval.type != fval.type) { | 863 if (tval.type == kWasmStmt || tval.type != fval.type) { |
| 864 if (tval.type != kAstEnd && fval.type != kAstEnd) { | 864 if (tval.type != kWasmEnd && fval.type != kWasmEnd) { |
| 865 error("type mismatch in select"); | 865 error("type mismatch in select"); |
| 866 break; | 866 break; |
| 867 } | 867 } |
| 868 } | 868 } |
| 869 if (build()) { | 869 if (build()) { |
| 870 DCHECK(tval.type != kAstEnd); | 870 DCHECK(tval.type != kWasmEnd); |
| 871 DCHECK(fval.type != kAstEnd); | 871 DCHECK(fval.type != kWasmEnd); |
| 872 DCHECK(cond.type != kAstEnd); | 872 DCHECK(cond.type != kWasmEnd); |
| 873 TFNode* controls[2]; | 873 TFNode* controls[2]; |
| 874 builder_->BranchNoHint(cond.node, &controls[0], &controls[1]); | 874 builder_->BranchNoHint(cond.node, &controls[0], &controls[1]); |
| 875 TFNode* merge = builder_->Merge(2, controls); | 875 TFNode* merge = builder_->Merge(2, controls); |
| 876 TFNode* vals[2] = {tval.node, fval.node}; | 876 TFNode* vals[2] = {tval.node, fval.node}; |
| 877 TFNode* phi = builder_->Phi(tval.type, 2, vals, merge); | 877 TFNode* phi = builder_->Phi(tval.type, 2, vals, merge); |
| 878 Push(tval.type, phi); | 878 Push(tval.type, phi); |
| 879 ssa_env_->control = merge; | 879 ssa_env_->control = merge; |
| 880 } else { | 880 } else { |
| 881 Push(tval.type, nullptr); | 881 Push(tval.type, nullptr); |
| 882 } | 882 } |
| 883 break; | 883 break; |
| 884 } | 884 } |
| 885 case kExprBr: { | 885 case kExprBr: { |
| 886 BreakDepthOperand operand(this, pc_); | 886 BreakDepthOperand operand(this, pc_); |
| 887 if (Validate(pc_, operand, control_)) { | 887 if (Validate(pc_, operand, control_)) { |
| 888 BreakTo(operand.depth); | 888 BreakTo(operand.depth); |
| 889 } | 889 } |
| 890 len = 1 + operand.length; | 890 len = 1 + operand.length; |
| 891 EndControl(); | 891 EndControl(); |
| 892 break; | 892 break; |
| 893 } | 893 } |
| 894 case kExprBrIf: { | 894 case kExprBrIf: { |
| 895 BreakDepthOperand operand(this, pc_); | 895 BreakDepthOperand operand(this, pc_); |
| 896 Value cond = Pop(0, kAstI32); | 896 Value cond = Pop(0, kWasmI32); |
| 897 if (ok() && Validate(pc_, operand, control_)) { | 897 if (ok() && Validate(pc_, operand, control_)) { |
| 898 SsaEnv* fenv = ssa_env_; | 898 SsaEnv* fenv = ssa_env_; |
| 899 SsaEnv* tenv = Split(fenv); | 899 SsaEnv* tenv = Split(fenv); |
| 900 fenv->SetNotMerged(); | 900 fenv->SetNotMerged(); |
| 901 BUILD(BranchNoHint, cond.node, &tenv->control, &fenv->control); | 901 BUILD(BranchNoHint, cond.node, &tenv->control, &fenv->control); |
| 902 ssa_env_ = tenv; | 902 ssa_env_ = tenv; |
| 903 BreakTo(operand.depth); | 903 BreakTo(operand.depth); |
| 904 ssa_env_ = fenv; | 904 ssa_env_ = fenv; |
| 905 } | 905 } |
| 906 len = 1 + operand.length; | 906 len = 1 + operand.length; |
| 907 break; | 907 break; |
| 908 } | 908 } |
| 909 case kExprBrTable: { | 909 case kExprBrTable: { |
| 910 BranchTableOperand operand(this, pc_); | 910 BranchTableOperand operand(this, pc_); |
| 911 BranchTableIterator iterator(this, operand); | 911 BranchTableIterator iterator(this, operand); |
| 912 if (Validate(pc_, operand, control_.size())) { | 912 if (Validate(pc_, operand, control_.size())) { |
| 913 Value key = Pop(0, kAstI32); | 913 Value key = Pop(0, kWasmI32); |
| 914 if (failed()) break; | 914 if (failed()) break; |
| 915 | 915 |
| 916 SsaEnv* break_env = ssa_env_; | 916 SsaEnv* break_env = ssa_env_; |
| 917 if (operand.table_count > 0) { | 917 if (operand.table_count > 0) { |
| 918 // Build branches to the various blocks based on the table. | 918 // Build branches to the various blocks based on the table. |
| 919 TFNode* sw = BUILD(Switch, operand.table_count + 1, key.node); | 919 TFNode* sw = BUILD(Switch, operand.table_count + 1, key.node); |
| 920 | 920 |
| 921 SsaEnv* copy = Steal(break_env); | 921 SsaEnv* copy = Steal(break_env); |
| 922 ssa_env_ = copy; | 922 ssa_env_ = copy; |
| 923 while (ok() && iterator.has_next()) { | 923 while (ok() && iterator.has_next()) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 DoReturn(); | 955 DoReturn(); |
| 956 break; | 956 break; |
| 957 } | 957 } |
| 958 case kExprUnreachable: { | 958 case kExprUnreachable: { |
| 959 BUILD(Unreachable, position()); | 959 BUILD(Unreachable, position()); |
| 960 EndControl(); | 960 EndControl(); |
| 961 break; | 961 break; |
| 962 } | 962 } |
| 963 case kExprI8Const: { | 963 case kExprI8Const: { |
| 964 ImmI8Operand operand(this, pc_); | 964 ImmI8Operand operand(this, pc_); |
| 965 Push(kAstI32, BUILD(Int32Constant, operand.value)); | 965 Push(kWasmI32, BUILD(Int32Constant, operand.value)); |
| 966 len = 1 + operand.length; | 966 len = 1 + operand.length; |
| 967 break; | 967 break; |
| 968 } | 968 } |
| 969 case kExprI32Const: { | 969 case kExprI32Const: { |
| 970 ImmI32Operand operand(this, pc_); | 970 ImmI32Operand operand(this, pc_); |
| 971 Push(kAstI32, BUILD(Int32Constant, operand.value)); | 971 Push(kWasmI32, BUILD(Int32Constant, operand.value)); |
| 972 len = 1 + operand.length; | 972 len = 1 + operand.length; |
| 973 break; | 973 break; |
| 974 } | 974 } |
| 975 case kExprI64Const: { | 975 case kExprI64Const: { |
| 976 ImmI64Operand operand(this, pc_); | 976 ImmI64Operand operand(this, pc_); |
| 977 Push(kAstI64, BUILD(Int64Constant, operand.value)); | 977 Push(kWasmI64, BUILD(Int64Constant, operand.value)); |
| 978 len = 1 + operand.length; | 978 len = 1 + operand.length; |
| 979 break; | 979 break; |
| 980 } | 980 } |
| 981 case kExprF32Const: { | 981 case kExprF32Const: { |
| 982 ImmF32Operand operand(this, pc_); | 982 ImmF32Operand operand(this, pc_); |
| 983 Push(kAstF32, BUILD(Float32Constant, operand.value)); | 983 Push(kWasmF32, BUILD(Float32Constant, operand.value)); |
| 984 len = 1 + operand.length; | 984 len = 1 + operand.length; |
| 985 break; | 985 break; |
| 986 } | 986 } |
| 987 case kExprF64Const: { | 987 case kExprF64Const: { |
| 988 ImmF64Operand operand(this, pc_); | 988 ImmF64Operand operand(this, pc_); |
| 989 Push(kAstF64, BUILD(Float64Constant, operand.value)); | 989 Push(kWasmF64, BUILD(Float64Constant, operand.value)); |
| 990 len = 1 + operand.length; | 990 len = 1 + operand.length; |
| 991 break; | 991 break; |
| 992 } | 992 } |
| 993 case kExprGetLocal: { | 993 case kExprGetLocal: { |
| 994 LocalIndexOperand operand(this, pc_); | 994 LocalIndexOperand operand(this, pc_); |
| 995 if (Validate(pc_, operand)) { | 995 if (Validate(pc_, operand)) { |
| 996 if (build()) { | 996 if (build()) { |
| 997 Push(operand.type, ssa_env_->locals[operand.index]); | 997 Push(operand.type, ssa_env_->locals[operand.index]); |
| 998 } else { | 998 } else { |
| 999 Push(operand.type, nullptr); | 999 Push(operand.type, nullptr); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1041 BUILD(SetGlobal, operand.index, val.node); | 1041 BUILD(SetGlobal, operand.index, val.node); |
| 1042 } else { | 1042 } else { |
| 1043 error(pc_, pc_ + 1, "immutable global #%u cannot be assigned", | 1043 error(pc_, pc_ + 1, "immutable global #%u cannot be assigned", |
| 1044 operand.index); | 1044 operand.index); |
| 1045 } | 1045 } |
| 1046 } | 1046 } |
| 1047 len = 1 + operand.length; | 1047 len = 1 + operand.length; |
| 1048 break; | 1048 break; |
| 1049 } | 1049 } |
| 1050 case kExprI32LoadMem8S: | 1050 case kExprI32LoadMem8S: |
| 1051 len = DecodeLoadMem(kAstI32, MachineType::Int8()); | 1051 len = DecodeLoadMem(kWasmI32, MachineType::Int8()); |
| 1052 break; | 1052 break; |
| 1053 case kExprI32LoadMem8U: | 1053 case kExprI32LoadMem8U: |
| 1054 len = DecodeLoadMem(kAstI32, MachineType::Uint8()); | 1054 len = DecodeLoadMem(kWasmI32, MachineType::Uint8()); |
| 1055 break; | 1055 break; |
| 1056 case kExprI32LoadMem16S: | 1056 case kExprI32LoadMem16S: |
| 1057 len = DecodeLoadMem(kAstI32, MachineType::Int16()); | 1057 len = DecodeLoadMem(kWasmI32, MachineType::Int16()); |
| 1058 break; | 1058 break; |
| 1059 case kExprI32LoadMem16U: | 1059 case kExprI32LoadMem16U: |
| 1060 len = DecodeLoadMem(kAstI32, MachineType::Uint16()); | 1060 len = DecodeLoadMem(kWasmI32, MachineType::Uint16()); |
| 1061 break; | 1061 break; |
| 1062 case kExprI32LoadMem: | 1062 case kExprI32LoadMem: |
| 1063 len = DecodeLoadMem(kAstI32, MachineType::Int32()); | 1063 len = DecodeLoadMem(kWasmI32, MachineType::Int32()); |
| 1064 break; | 1064 break; |
| 1065 case kExprI64LoadMem8S: | 1065 case kExprI64LoadMem8S: |
| 1066 len = DecodeLoadMem(kAstI64, MachineType::Int8()); | 1066 len = DecodeLoadMem(kWasmI64, MachineType::Int8()); |
| 1067 break; | 1067 break; |
| 1068 case kExprI64LoadMem8U: | 1068 case kExprI64LoadMem8U: |
| 1069 len = DecodeLoadMem(kAstI64, MachineType::Uint8()); | 1069 len = DecodeLoadMem(kWasmI64, MachineType::Uint8()); |
| 1070 break; | 1070 break; |
| 1071 case kExprI64LoadMem16S: | 1071 case kExprI64LoadMem16S: |
| 1072 len = DecodeLoadMem(kAstI64, MachineType::Int16()); | 1072 len = DecodeLoadMem(kWasmI64, MachineType::Int16()); |
| 1073 break; | 1073 break; |
| 1074 case kExprI64LoadMem16U: | 1074 case kExprI64LoadMem16U: |
| 1075 len = DecodeLoadMem(kAstI64, MachineType::Uint16()); | 1075 len = DecodeLoadMem(kWasmI64, MachineType::Uint16()); |
| 1076 break; | 1076 break; |
| 1077 case kExprI64LoadMem32S: | 1077 case kExprI64LoadMem32S: |
| 1078 len = DecodeLoadMem(kAstI64, MachineType::Int32()); | 1078 len = DecodeLoadMem(kWasmI64, MachineType::Int32()); |
| 1079 break; | 1079 break; |
| 1080 case kExprI64LoadMem32U: | 1080 case kExprI64LoadMem32U: |
| 1081 len = DecodeLoadMem(kAstI64, MachineType::Uint32()); | 1081 len = DecodeLoadMem(kWasmI64, MachineType::Uint32()); |
| 1082 break; | 1082 break; |
| 1083 case kExprI64LoadMem: | 1083 case kExprI64LoadMem: |
| 1084 len = DecodeLoadMem(kAstI64, MachineType::Int64()); | 1084 len = DecodeLoadMem(kWasmI64, MachineType::Int64()); |
| 1085 break; | 1085 break; |
| 1086 case kExprF32LoadMem: | 1086 case kExprF32LoadMem: |
| 1087 len = DecodeLoadMem(kAstF32, MachineType::Float32()); | 1087 len = DecodeLoadMem(kWasmF32, MachineType::Float32()); |
| 1088 break; | 1088 break; |
| 1089 case kExprF64LoadMem: | 1089 case kExprF64LoadMem: |
| 1090 len = DecodeLoadMem(kAstF64, MachineType::Float64()); | 1090 len = DecodeLoadMem(kWasmF64, MachineType::Float64()); |
| 1091 break; | 1091 break; |
| 1092 case kExprI32StoreMem8: | 1092 case kExprI32StoreMem8: |
| 1093 len = DecodeStoreMem(kAstI32, MachineType::Int8()); | 1093 len = DecodeStoreMem(kWasmI32, MachineType::Int8()); |
| 1094 break; | 1094 break; |
| 1095 case kExprI32StoreMem16: | 1095 case kExprI32StoreMem16: |
| 1096 len = DecodeStoreMem(kAstI32, MachineType::Int16()); | 1096 len = DecodeStoreMem(kWasmI32, MachineType::Int16()); |
| 1097 break; | 1097 break; |
| 1098 case kExprI32StoreMem: | 1098 case kExprI32StoreMem: |
| 1099 len = DecodeStoreMem(kAstI32, MachineType::Int32()); | 1099 len = DecodeStoreMem(kWasmI32, MachineType::Int32()); |
| 1100 break; | 1100 break; |
| 1101 case kExprI64StoreMem8: | 1101 case kExprI64StoreMem8: |
| 1102 len = DecodeStoreMem(kAstI64, MachineType::Int8()); | 1102 len = DecodeStoreMem(kWasmI64, MachineType::Int8()); |
| 1103 break; | 1103 break; |
| 1104 case kExprI64StoreMem16: | 1104 case kExprI64StoreMem16: |
| 1105 len = DecodeStoreMem(kAstI64, MachineType::Int16()); | 1105 len = DecodeStoreMem(kWasmI64, MachineType::Int16()); |
| 1106 break; | 1106 break; |
| 1107 case kExprI64StoreMem32: | 1107 case kExprI64StoreMem32: |
| 1108 len = DecodeStoreMem(kAstI64, MachineType::Int32()); | 1108 len = DecodeStoreMem(kWasmI64, MachineType::Int32()); |
| 1109 break; | 1109 break; |
| 1110 case kExprI64StoreMem: | 1110 case kExprI64StoreMem: |
| 1111 len = DecodeStoreMem(kAstI64, MachineType::Int64()); | 1111 len = DecodeStoreMem(kWasmI64, MachineType::Int64()); |
| 1112 break; | 1112 break; |
| 1113 case kExprF32StoreMem: | 1113 case kExprF32StoreMem: |
| 1114 len = DecodeStoreMem(kAstF32, MachineType::Float32()); | 1114 len = DecodeStoreMem(kWasmF32, MachineType::Float32()); |
| 1115 break; | 1115 break; |
| 1116 case kExprF64StoreMem: | 1116 case kExprF64StoreMem: |
| 1117 len = DecodeStoreMem(kAstF64, MachineType::Float64()); | 1117 len = DecodeStoreMem(kWasmF64, MachineType::Float64()); |
| 1118 break; | 1118 break; |
| 1119 case kExprGrowMemory: { | 1119 case kExprGrowMemory: { |
| 1120 MemoryIndexOperand operand(this, pc_); | 1120 MemoryIndexOperand operand(this, pc_); |
| 1121 if (module_->module->origin != kAsmJsOrigin) { | 1121 if (module_->module->origin != kAsmJsOrigin) { |
| 1122 Value val = Pop(0, kAstI32); | 1122 Value val = Pop(0, kWasmI32); |
| 1123 Push(kAstI32, BUILD(GrowMemory, val.node)); | 1123 Push(kWasmI32, BUILD(GrowMemory, val.node)); |
| 1124 } else { | 1124 } else { |
| 1125 error("grow_memory is not supported for asmjs modules"); | 1125 error("grow_memory is not supported for asmjs modules"); |
| 1126 } | 1126 } |
| 1127 len = 1 + operand.length; | 1127 len = 1 + operand.length; |
| 1128 break; | 1128 break; |
| 1129 } | 1129 } |
| 1130 case kExprMemorySize: { | 1130 case kExprMemorySize: { |
| 1131 MemoryIndexOperand operand(this, pc_); | 1131 MemoryIndexOperand operand(this, pc_); |
| 1132 Push(kAstI32, BUILD(CurrentMemoryPages)); | 1132 Push(kWasmI32, BUILD(CurrentMemoryPages)); |
| 1133 len = 1 + operand.length; | 1133 len = 1 + operand.length; |
| 1134 break; | 1134 break; |
| 1135 } | 1135 } |
| 1136 case kExprCallFunction: { | 1136 case kExprCallFunction: { |
| 1137 CallFunctionOperand operand(this, pc_); | 1137 CallFunctionOperand operand(this, pc_); |
| 1138 if (Validate(pc_, operand)) { | 1138 if (Validate(pc_, operand)) { |
| 1139 TFNode** buffer = PopArgs(operand.sig); | 1139 TFNode** buffer = PopArgs(operand.sig); |
| 1140 TFNode** rets = nullptr; | 1140 TFNode** rets = nullptr; |
| 1141 BUILD(CallDirect, operand.index, buffer, &rets, position()); | 1141 BUILD(CallDirect, operand.index, buffer, &rets, position()); |
| 1142 PushReturns(operand.sig, rets); | 1142 PushReturns(operand.sig, rets); |
| 1143 } | 1143 } |
| 1144 len = 1 + operand.length; | 1144 len = 1 + operand.length; |
| 1145 break; | 1145 break; |
| 1146 } | 1146 } |
| 1147 case kExprCallIndirect: { | 1147 case kExprCallIndirect: { |
| 1148 CallIndirectOperand operand(this, pc_); | 1148 CallIndirectOperand operand(this, pc_); |
| 1149 if (Validate(pc_, operand)) { | 1149 if (Validate(pc_, operand)) { |
| 1150 Value index = Pop(0, kAstI32); | 1150 Value index = Pop(0, kWasmI32); |
| 1151 TFNode** buffer = PopArgs(operand.sig); | 1151 TFNode** buffer = PopArgs(operand.sig); |
| 1152 if (buffer) buffer[0] = index.node; | 1152 if (buffer) buffer[0] = index.node; |
| 1153 TFNode** rets = nullptr; | 1153 TFNode** rets = nullptr; |
| 1154 BUILD(CallIndirect, operand.index, buffer, &rets, position()); | 1154 BUILD(CallIndirect, operand.index, buffer, &rets, position()); |
| 1155 PushReturns(operand.sig, rets); | 1155 PushReturns(operand.sig, rets); |
| 1156 } | 1156 } |
| 1157 len = 1 + operand.length; | 1157 len = 1 + operand.length; |
| 1158 break; | 1158 break; |
| 1159 } | 1159 } |
| 1160 case kSimdPrefix: { | 1160 case kSimdPrefix: { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1269 return buffer; | 1269 return buffer; |
| 1270 } else { | 1270 } else { |
| 1271 int count = static_cast<int>(sig->parameter_count()); | 1271 int count = static_cast<int>(sig->parameter_count()); |
| 1272 for (int i = count - 1; i >= 0; i--) { | 1272 for (int i = count - 1; i >= 0; i--) { |
| 1273 Pop(i, sig->GetParam(i)); | 1273 Pop(i, sig->GetParam(i)); |
| 1274 } | 1274 } |
| 1275 return nullptr; | 1275 return nullptr; |
| 1276 } | 1276 } |
| 1277 } | 1277 } |
| 1278 | 1278 |
| 1279 LocalType GetReturnType(FunctionSig* sig) { | 1279 ValueType GetReturnType(FunctionSig* sig) { |
| 1280 return sig->return_count() == 0 ? kAstStmt : sig->GetReturn(); | 1280 return sig->return_count() == 0 ? kWasmStmt : sig->GetReturn(); |
| 1281 } | 1281 } |
| 1282 | 1282 |
| 1283 void PushBlock(SsaEnv* end_env) { | 1283 void PushBlock(SsaEnv* end_env) { |
| 1284 const int stack_depth = static_cast<int>(stack_.size()); | 1284 const int stack_depth = static_cast<int>(stack_.size()); |
| 1285 control_.emplace_back( | 1285 control_.emplace_back( |
| 1286 Control::Block(pc_, stack_depth, end_env, current_catch_)); | 1286 Control::Block(pc_, stack_depth, end_env, current_catch_)); |
| 1287 } | 1287 } |
| 1288 | 1288 |
| 1289 void PushLoop(SsaEnv* end_env) { | 1289 void PushLoop(SsaEnv* end_env) { |
| 1290 const int stack_depth = static_cast<int>(stack_.size()); | 1290 const int stack_depth = static_cast<int>(stack_.size()); |
| 1291 control_.emplace_back( | 1291 control_.emplace_back( |
| 1292 Control::Loop(pc_, stack_depth, end_env, current_catch_)); | 1292 Control::Loop(pc_, stack_depth, end_env, current_catch_)); |
| 1293 } | 1293 } |
| 1294 | 1294 |
| 1295 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { | 1295 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { |
| 1296 const int stack_depth = static_cast<int>(stack_.size()); | 1296 const int stack_depth = static_cast<int>(stack_.size()); |
| 1297 control_.emplace_back( | 1297 control_.emplace_back( |
| 1298 Control::If(pc_, stack_depth, end_env, false_env, current_catch_)); | 1298 Control::If(pc_, stack_depth, end_env, false_env, current_catch_)); |
| 1299 } | 1299 } |
| 1300 | 1300 |
| 1301 void PushTry(SsaEnv* end_env, SsaEnv* catch_env) { | 1301 void PushTry(SsaEnv* end_env, SsaEnv* catch_env) { |
| 1302 const int stack_depth = static_cast<int>(stack_.size()); | 1302 const int stack_depth = static_cast<int>(stack_.size()); |
| 1303 control_.emplace_back(Control::Try(pc_, stack_depth, end_env, zone_, | 1303 control_.emplace_back(Control::Try(pc_, stack_depth, end_env, zone_, |
| 1304 catch_env, current_catch_)); | 1304 catch_env, current_catch_)); |
| 1305 current_catch_ = static_cast<int32_t>(control_.size() - 1); | 1305 current_catch_ = static_cast<int32_t>(control_.size() - 1); |
| 1306 } | 1306 } |
| 1307 | 1307 |
| 1308 void PopControl() { control_.pop_back(); } | 1308 void PopControl() { control_.pop_back(); } |
| 1309 | 1309 |
| 1310 int DecodeLoadMem(LocalType type, MachineType mem_type) { | 1310 int DecodeLoadMem(ValueType type, MachineType mem_type) { |
| 1311 MemoryAccessOperand operand(this, pc_, | 1311 MemoryAccessOperand operand(this, pc_, |
| 1312 ElementSizeLog2Of(mem_type.representation())); | 1312 ElementSizeLog2Of(mem_type.representation())); |
| 1313 | 1313 |
| 1314 Value index = Pop(0, kAstI32); | 1314 Value index = Pop(0, kWasmI32); |
| 1315 TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset, | 1315 TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset, |
| 1316 operand.alignment, position()); | 1316 operand.alignment, position()); |
| 1317 Push(type, node); | 1317 Push(type, node); |
| 1318 return 1 + operand.length; | 1318 return 1 + operand.length; |
| 1319 } | 1319 } |
| 1320 | 1320 |
| 1321 int DecodeStoreMem(LocalType type, MachineType mem_type) { | 1321 int DecodeStoreMem(ValueType type, MachineType mem_type) { |
| 1322 MemoryAccessOperand operand(this, pc_, | 1322 MemoryAccessOperand operand(this, pc_, |
| 1323 ElementSizeLog2Of(mem_type.representation())); | 1323 ElementSizeLog2Of(mem_type.representation())); |
| 1324 Value val = Pop(1, type); | 1324 Value val = Pop(1, type); |
| 1325 Value index = Pop(0, kAstI32); | 1325 Value index = Pop(0, kWasmI32); |
| 1326 BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment, | 1326 BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment, |
| 1327 val.node, position()); | 1327 val.node, position()); |
| 1328 return 1 + operand.length; | 1328 return 1 + operand.length; |
| 1329 } | 1329 } |
| 1330 | 1330 |
| 1331 unsigned ExtractLane(WasmOpcode opcode, LocalType type) { | 1331 unsigned ExtractLane(WasmOpcode opcode, ValueType type) { |
| 1332 LaneOperand operand(this, pc_); | 1332 LaneOperand operand(this, pc_); |
| 1333 if (Validate(pc_, operand)) { | 1333 if (Validate(pc_, operand)) { |
| 1334 compiler::NodeVector inputs(1, zone_); | 1334 compiler::NodeVector inputs(1, zone_); |
| 1335 inputs[0] = Pop(0, LocalType::kSimd128).node; | 1335 inputs[0] = Pop(0, ValueType::kSimd128).node; |
| 1336 TFNode* node = BUILD(SimdLaneOp, opcode, operand.lane, inputs); | 1336 TFNode* node = BUILD(SimdLaneOp, opcode, operand.lane, inputs); |
| 1337 Push(type, node); | 1337 Push(type, node); |
| 1338 } | 1338 } |
| 1339 return operand.length; | 1339 return operand.length; |
| 1340 } | 1340 } |
| 1341 | 1341 |
| 1342 unsigned ReplaceLane(WasmOpcode opcode, LocalType type) { | 1342 unsigned ReplaceLane(WasmOpcode opcode, ValueType type) { |
| 1343 LaneOperand operand(this, pc_); | 1343 LaneOperand operand(this, pc_); |
| 1344 if (Validate(pc_, operand)) { | 1344 if (Validate(pc_, operand)) { |
| 1345 compiler::NodeVector inputs(2, zone_); | 1345 compiler::NodeVector inputs(2, zone_); |
| 1346 inputs[1] = Pop(1, type).node; | 1346 inputs[1] = Pop(1, type).node; |
| 1347 inputs[0] = Pop(0, LocalType::kSimd128).node; | 1347 inputs[0] = Pop(0, ValueType::kSimd128).node; |
| 1348 TFNode* node = BUILD(SimdLaneOp, opcode, operand.lane, inputs); | 1348 TFNode* node = BUILD(SimdLaneOp, opcode, operand.lane, inputs); |
| 1349 Push(LocalType::kSimd128, node); | 1349 Push(ValueType::kSimd128, node); |
| 1350 } | 1350 } |
| 1351 return operand.length; | 1351 return operand.length; |
| 1352 } | 1352 } |
| 1353 | 1353 |
| 1354 unsigned DecodeSimdOpcode(WasmOpcode opcode) { | 1354 unsigned DecodeSimdOpcode(WasmOpcode opcode) { |
| 1355 unsigned len = 0; | 1355 unsigned len = 0; |
| 1356 switch (opcode) { | 1356 switch (opcode) { |
| 1357 case kExprI32x4ExtractLane: { | 1357 case kExprI32x4ExtractLane: { |
| 1358 len = ExtractLane(opcode, LocalType::kWord32); | 1358 len = ExtractLane(opcode, ValueType::kWord32); |
| 1359 break; | 1359 break; |
| 1360 } | 1360 } |
| 1361 case kExprF32x4ExtractLane: { | 1361 case kExprF32x4ExtractLane: { |
| 1362 len = ExtractLane(opcode, LocalType::kFloat32); | 1362 len = ExtractLane(opcode, ValueType::kFloat32); |
| 1363 break; | 1363 break; |
| 1364 } | 1364 } |
| 1365 case kExprI32x4ReplaceLane: { | 1365 case kExprI32x4ReplaceLane: { |
| 1366 len = ReplaceLane(opcode, LocalType::kWord32); | 1366 len = ReplaceLane(opcode, ValueType::kWord32); |
| 1367 break; | 1367 break; |
| 1368 } | 1368 } |
| 1369 case kExprF32x4ReplaceLane: { | 1369 case kExprF32x4ReplaceLane: { |
| 1370 len = ReplaceLane(opcode, LocalType::kFloat32); | 1370 len = ReplaceLane(opcode, ValueType::kFloat32); |
| 1371 break; | 1371 break; |
| 1372 } | 1372 } |
| 1373 default: { | 1373 default: { |
| 1374 FunctionSig* sig = WasmOpcodes::Signature(opcode); | 1374 FunctionSig* sig = WasmOpcodes::Signature(opcode); |
| 1375 if (sig != nullptr) { | 1375 if (sig != nullptr) { |
| 1376 compiler::NodeVector inputs(sig->parameter_count(), zone_); | 1376 compiler::NodeVector inputs(sig->parameter_count(), zone_); |
| 1377 for (size_t i = sig->parameter_count(); i > 0; i--) { | 1377 for (size_t i = sig->parameter_count(); i > 0; i--) { |
| 1378 Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1)); | 1378 Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1)); |
| 1379 inputs[i - 1] = val.node; | 1379 inputs[i - 1] = val.node; |
| 1380 } | 1380 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1398 // Pop return values off the stack in reverse order. | 1398 // Pop return values off the stack in reverse order. |
| 1399 for (int i = count - 1; i >= 0; i--) { | 1399 for (int i = count - 1; i >= 0; i--) { |
| 1400 Value val = Pop(i, sig_->GetReturn(i)); | 1400 Value val = Pop(i, sig_->GetReturn(i)); |
| 1401 if (buffer) buffer[i] = val.node; | 1401 if (buffer) buffer[i] = val.node; |
| 1402 } | 1402 } |
| 1403 | 1403 |
| 1404 BUILD(Return, count, buffer); | 1404 BUILD(Return, count, buffer); |
| 1405 EndControl(); | 1405 EndControl(); |
| 1406 } | 1406 } |
| 1407 | 1407 |
| 1408 void Push(LocalType type, TFNode* node) { | 1408 void Push(ValueType type, TFNode* node) { |
| 1409 if (type != kAstStmt && type != kAstEnd) { | 1409 if (type != kWasmStmt && type != kWasmEnd) { |
| 1410 stack_.push_back({pc_, node, type}); | 1410 stack_.push_back({pc_, node, type}); |
| 1411 } | 1411 } |
| 1412 } | 1412 } |
| 1413 | 1413 |
| 1414 void PushReturns(FunctionSig* sig, TFNode** rets) { | 1414 void PushReturns(FunctionSig* sig, TFNode** rets) { |
| 1415 for (size_t i = 0; i < sig->return_count(); i++) { | 1415 for (size_t i = 0; i < sig->return_count(); i++) { |
| 1416 // When verifying only, then {rets} will be null, so push null. | 1416 // When verifying only, then {rets} will be null, so push null. |
| 1417 Push(sig->GetReturn(i), rets ? rets[i] : nullptr); | 1417 Push(sig->GetReturn(i), rets ? rets[i] : nullptr); |
| 1418 } | 1418 } |
| 1419 } | 1419 } |
| 1420 | 1420 |
| 1421 const char* SafeOpcodeNameAt(const byte* pc) { | 1421 const char* SafeOpcodeNameAt(const byte* pc) { |
| 1422 if (pc >= end_) return "<end>"; | 1422 if (pc >= end_) return "<end>"; |
| 1423 return WasmOpcodes::ShortOpcodeName(static_cast<WasmOpcode>(*pc)); | 1423 return WasmOpcodes::ShortOpcodeName(static_cast<WasmOpcode>(*pc)); |
| 1424 } | 1424 } |
| 1425 | 1425 |
| 1426 Value Pop(int index, LocalType expected) { | 1426 Value Pop(int index, ValueType expected) { |
| 1427 if (!ssa_env_->go()) { | 1427 if (!ssa_env_->go()) { |
| 1428 // Unreachable code is essentially not typechecked. | 1428 // Unreachable code is essentially not typechecked. |
| 1429 return {pc_, nullptr, expected}; | 1429 return {pc_, nullptr, expected}; |
| 1430 } | 1430 } |
| 1431 Value val = Pop(); | 1431 Value val = Pop(); |
| 1432 if (val.type != expected) { | 1432 if (val.type != expected) { |
| 1433 if (val.type != kAstEnd) { | 1433 if (val.type != kWasmEnd) { |
| 1434 error(pc_, val.pc, "%s[%d] expected type %s, found %s of type %s", | 1434 error(pc_, val.pc, "%s[%d] expected type %s, found %s of type %s", |
| 1435 SafeOpcodeNameAt(pc_), index, WasmOpcodes::TypeName(expected), | 1435 SafeOpcodeNameAt(pc_), index, WasmOpcodes::TypeName(expected), |
| 1436 SafeOpcodeNameAt(val.pc), WasmOpcodes::TypeName(val.type)); | 1436 SafeOpcodeNameAt(val.pc), WasmOpcodes::TypeName(val.type)); |
| 1437 } | 1437 } |
| 1438 } | 1438 } |
| 1439 return val; | 1439 return val; |
| 1440 } | 1440 } |
| 1441 | 1441 |
| 1442 Value Pop() { | 1442 Value Pop() { |
| 1443 if (!ssa_env_->go()) { | 1443 if (!ssa_env_->go()) { |
| 1444 // Unreachable code is essentially not typechecked. | 1444 // Unreachable code is essentially not typechecked. |
| 1445 return {pc_, nullptr, kAstEnd}; | 1445 return {pc_, nullptr, kWasmEnd}; |
| 1446 } | 1446 } |
| 1447 size_t limit = control_.empty() ? 0 : control_.back().stack_depth; | 1447 size_t limit = control_.empty() ? 0 : control_.back().stack_depth; |
| 1448 if (stack_.size() <= limit) { | 1448 if (stack_.size() <= limit) { |
| 1449 Value val = {pc_, nullptr, kAstStmt}; | 1449 Value val = {pc_, nullptr, kWasmStmt}; |
| 1450 error(pc_, pc_, "%s found empty stack", SafeOpcodeNameAt(pc_)); | 1450 error(pc_, pc_, "%s found empty stack", SafeOpcodeNameAt(pc_)); |
| 1451 return val; | 1451 return val; |
| 1452 } | 1452 } |
| 1453 Value val = stack_.back(); | 1453 Value val = stack_.back(); |
| 1454 stack_.pop_back(); | 1454 stack_.pop_back(); |
| 1455 return val; | 1455 return val; |
| 1456 } | 1456 } |
| 1457 | 1457 |
| 1458 Value PopUpTo(int stack_depth) { | 1458 Value PopUpTo(int stack_depth) { |
| 1459 if (!ssa_env_->go()) { | 1459 if (!ssa_env_->go()) { |
| 1460 // Unreachable code is essentially not typechecked. | 1460 // Unreachable code is essentially not typechecked. |
| 1461 return {pc_, nullptr, kAstEnd}; | 1461 return {pc_, nullptr, kWasmEnd}; |
| 1462 } | 1462 } |
| 1463 if (stack_depth == static_cast<int>(stack_.size())) { | 1463 if (stack_depth == static_cast<int>(stack_.size())) { |
| 1464 Value val = {pc_, nullptr, kAstStmt}; | 1464 Value val = {pc_, nullptr, kWasmStmt}; |
| 1465 return val; | 1465 return val; |
| 1466 } else { | 1466 } else { |
| 1467 DCHECK_LE(stack_depth, stack_.size()); | 1467 DCHECK_LE(stack_depth, stack_.size()); |
| 1468 Value val = Pop(); | 1468 Value val = Pop(); |
| 1469 stack_.resize(stack_depth); | 1469 stack_.resize(stack_depth); |
| 1470 return val; | 1470 return val; |
| 1471 } | 1471 } |
| 1472 } | 1472 } |
| 1473 | 1473 |
| 1474 int baserel(const byte* ptr) { | 1474 int baserel(const byte* ptr) { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 exception_env->control = if_exception; | 1619 exception_env->control = if_exception; |
| 1620 TryInfo* try_info = current_try_info(); | 1620 TryInfo* try_info = current_try_info(); |
| 1621 Goto(exception_env, try_info->catch_env); | 1621 Goto(exception_env, try_info->catch_env); |
| 1622 TFNode* exception = try_info->exception; | 1622 TFNode* exception = try_info->exception; |
| 1623 if (exception == nullptr) { | 1623 if (exception == nullptr) { |
| 1624 DCHECK_EQ(SsaEnv::kReached, try_info->catch_env->state); | 1624 DCHECK_EQ(SsaEnv::kReached, try_info->catch_env->state); |
| 1625 try_info->exception = if_exception; | 1625 try_info->exception = if_exception; |
| 1626 } else { | 1626 } else { |
| 1627 DCHECK_EQ(SsaEnv::kMerged, try_info->catch_env->state); | 1627 DCHECK_EQ(SsaEnv::kMerged, try_info->catch_env->state); |
| 1628 try_info->exception = | 1628 try_info->exception = |
| 1629 CreateOrMergeIntoPhi(kAstI32, try_info->catch_env->control, | 1629 CreateOrMergeIntoPhi(kWasmI32, try_info->catch_env->control, |
| 1630 try_info->exception, if_exception); | 1630 try_info->exception, if_exception); |
| 1631 } | 1631 } |
| 1632 | 1632 |
| 1633 SetEnv("if_success", success_env); | 1633 SetEnv("if_success", success_env); |
| 1634 return node; | 1634 return node; |
| 1635 } | 1635 } |
| 1636 | 1636 |
| 1637 void Goto(SsaEnv* from, SsaEnv* to) { | 1637 void Goto(SsaEnv* from, SsaEnv* to) { |
| 1638 DCHECK_NOT_NULL(to); | 1638 DCHECK_NOT_NULL(to); |
| 1639 if (!from->go()) return; | 1639 if (!from->go()) return; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1703 } | 1703 } |
| 1704 } | 1704 } |
| 1705 break; | 1705 break; |
| 1706 } | 1706 } |
| 1707 default: | 1707 default: |
| 1708 UNREACHABLE(); | 1708 UNREACHABLE(); |
| 1709 } | 1709 } |
| 1710 return from->Kill(); | 1710 return from->Kill(); |
| 1711 } | 1711 } |
| 1712 | 1712 |
| 1713 TFNode* CreateOrMergeIntoPhi(LocalType type, TFNode* merge, TFNode* tnode, | 1713 TFNode* CreateOrMergeIntoPhi(ValueType type, TFNode* merge, TFNode* tnode, |
| 1714 TFNode* fnode) { | 1714 TFNode* fnode) { |
| 1715 DCHECK_NOT_NULL(builder_); | 1715 DCHECK_NOT_NULL(builder_); |
| 1716 if (builder_->IsPhiWithMerge(tnode, merge)) { | 1716 if (builder_->IsPhiWithMerge(tnode, merge)) { |
| 1717 builder_->AppendToPhi(tnode, fnode); | 1717 builder_->AppendToPhi(tnode, fnode); |
| 1718 } else if (tnode != fnode) { | 1718 } else if (tnode != fnode) { |
| 1719 uint32_t count = builder_->InputCount(merge); | 1719 uint32_t count = builder_->InputCount(merge); |
| 1720 TFNode** vals = builder_->Buffer(count); | 1720 TFNode** vals = builder_->Buffer(count); |
| 1721 for (uint32_t j = 0; j < count - 1; j++) vals[j] = tnode; | 1721 for (uint32_t j = 0; j < count - 1; j++) vals[j] = tnode; |
| 1722 vals[count - 1] = fnode; | 1722 vals[count - 1] = fnode; |
| 1723 return builder_->Phi(type, count, vals, merge); | 1723 return builder_->Phi(type, count, vals, merge); |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 os << "// signature: " << *body.sig << std::endl; | 1948 os << "// signature: " << *body.sig << std::endl; |
| 1949 ++line_nr; | 1949 ++line_nr; |
| 1950 } | 1950 } |
| 1951 | 1951 |
| 1952 // Print the local declarations. | 1952 // Print the local declarations. |
| 1953 BodyLocalDecls decls(&zone); | 1953 BodyLocalDecls decls(&zone); |
| 1954 BytecodeIterator i(body.start, body.end, &decls); | 1954 BytecodeIterator i(body.start, body.end, &decls); |
| 1955 if (body.start != i.pc() && !FLAG_wasm_code_fuzzer_gen_test) { | 1955 if (body.start != i.pc() && !FLAG_wasm_code_fuzzer_gen_test) { |
| 1956 os << "// locals: "; | 1956 os << "// locals: "; |
| 1957 for (auto p : decls.local_types) { | 1957 for (auto p : decls.local_types) { |
| 1958 LocalType type = p.first; | 1958 ValueType type = p.first; |
| 1959 uint32_t count = p.second; | 1959 uint32_t count = p.second; |
| 1960 os << " " << count << " " << WasmOpcodes::TypeName(type); | 1960 os << " " << count << " " << WasmOpcodes::TypeName(type); |
| 1961 } | 1961 } |
| 1962 os << std::endl; | 1962 os << std::endl; |
| 1963 ++line_nr; | 1963 ++line_nr; |
| 1964 | 1964 |
| 1965 for (const byte* locals = body.start; locals < i.pc(); locals++) { | 1965 for (const byte* locals = body.start; locals < i.pc(); locals++) { |
| 1966 os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ","; | 1966 os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ","; |
| 1967 } | 1967 } |
| 1968 os << std::endl; | 1968 os << std::endl; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2059 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 2059 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
| 2060 const byte* start, const byte* end) { | 2060 const byte* start, const byte* end) { |
| 2061 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 2061 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
| 2062 WasmFullDecoder decoder(zone, nullptr, body); | 2062 WasmFullDecoder decoder(zone, nullptr, body); |
| 2063 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 2063 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
| 2064 } | 2064 } |
| 2065 | 2065 |
| 2066 } // namespace wasm | 2066 } // namespace wasm |
| 2067 } // namespace internal | 2067 } // namespace internal |
| 2068 } // namespace v8 | 2068 } // namespace v8 |
| OLD | NEW |