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-containers.h" | 10 #include "src/zone-containers.h" |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 return false; | 242 return false; |
243 } | 243 } |
244 | 244 |
245 bool Validate(const byte* pc, BranchTableOperand& operand, | 245 bool Validate(const byte* pc, BranchTableOperand& operand, |
246 size_t block_depth) { | 246 size_t block_depth) { |
247 if (operand.arity > 1) { | 247 if (operand.arity > 1) { |
248 error(pc, pc + 1, "invalid arity for break"); | 248 error(pc, pc + 1, "invalid arity for break"); |
249 return false; | 249 return false; |
250 } | 250 } |
251 // Verify table. | 251 // Verify table. |
252 for (uint32_t i = 0; i < operand.table_count + 1; i++) { | 252 for (uint32_t i = 0; i < operand.table_count + 1; ++i) { |
253 uint32_t target = operand.read_entry(this, i); | 253 uint32_t target = operand.read_entry(this, i); |
254 if (target >= block_depth) { | 254 if (target >= block_depth) { |
255 error(operand.table + i * 2, "improper branch in br_table"); | 255 error(operand.table + i * 2, "improper branch in br_table"); |
256 return false; | 256 return false; |
257 } | 257 } |
258 } | 258 } |
259 return true; | 259 return true; |
260 } | 260 } |
261 | 261 |
262 int OpcodeArity(const byte* pc) { | 262 int OpcodeArity(const byte* pc) { |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 return builder_->Float64Constant(0); | 558 return builder_->Float64Constant(0); |
559 default: | 559 default: |
560 UNREACHABLE(); | 560 UNREACHABLE(); |
561 return nullptr; | 561 return nullptr; |
562 } | 562 } |
563 } | 563 } |
564 | 564 |
565 char* indentation() { | 565 char* indentation() { |
566 static const int kMaxIndent = 64; | 566 static const int kMaxIndent = 64; |
567 static char bytes[kMaxIndent + 1]; | 567 static char bytes[kMaxIndent + 1]; |
568 for (int i = 0; i < kMaxIndent; i++) bytes[i] = ' '; | 568 for (int i = 0; i < kMaxIndent; ++i) bytes[i] = ' '; |
569 bytes[kMaxIndent] = 0; | 569 bytes[kMaxIndent] = 0; |
570 if (stack_.size() < kMaxIndent / 2) { | 570 if (stack_.size() < kMaxIndent / 2) { |
571 bytes[stack_.size() * 2] = 0; | 571 bytes[stack_.size() * 2] = 0; |
572 } | 572 } |
573 return bytes; | 573 return bytes; |
574 } | 574 } |
575 | 575 |
576 // Decodes the locals declarations, if any, populating {local_type_vec_}. | 576 // Decodes the locals declarations, if any, populating {local_type_vec_}. |
577 void DecodeLocalDecls() { | 577 void DecodeLocalDecls() { |
578 DCHECK_EQ(0, local_type_vec_.size()); | 578 DCHECK_EQ(0, local_type_vec_.size()); |
579 // Initialize {local_type_vec} from signature. | 579 // Initialize {local_type_vec} from signature. |
580 if (sig_) { | 580 if (sig_) { |
581 local_type_vec_.reserve(sig_->parameter_count()); | 581 local_type_vec_.reserve(sig_->parameter_count()); |
582 for (size_t i = 0; i < sig_->parameter_count(); i++) { | 582 for (size_t i = 0; i < sig_->parameter_count(); ++i) { |
583 local_type_vec_.push_back(sig_->GetParam(i)); | 583 local_type_vec_.push_back(sig_->GetParam(i)); |
584 } | 584 } |
585 } | 585 } |
586 // Decode local declarations, if any. | 586 // Decode local declarations, if any. |
587 int length; | 587 int length; |
588 uint32_t entries = consume_u32v(&length, "local decls count"); | 588 uint32_t entries = consume_u32v(&length, "local decls count"); |
589 while (entries-- > 0 && pc_ < limit_) { | 589 while (entries-- > 0 && pc_ < limit_) { |
590 uint32_t count = consume_u32v(&length, "local count"); | 590 uint32_t count = consume_u32v(&length, "local count"); |
591 byte code = consume_u8("local type"); | 591 byte code = consume_u8("local type"); |
592 LocalType type; | 592 LocalType type; |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 if (operand.arity == 1) val = Pop(); | 807 if (operand.arity == 1) val = Pop(); |
808 if (failed()) break; | 808 if (failed()) break; |
809 | 809 |
810 SsaEnv* break_env = ssa_env_; | 810 SsaEnv* break_env = ssa_env_; |
811 if (operand.table_count > 0) { | 811 if (operand.table_count > 0) { |
812 // Build branches to the various blocks based on the table. | 812 // Build branches to the various blocks based on the table. |
813 TFNode* sw = BUILD(Switch, operand.table_count + 1, key.node); | 813 TFNode* sw = BUILD(Switch, operand.table_count + 1, key.node); |
814 | 814 |
815 SsaEnv* copy = Steal(break_env); | 815 SsaEnv* copy = Steal(break_env); |
816 ssa_env_ = copy; | 816 ssa_env_ = copy; |
817 for (uint32_t i = 0; i < operand.table_count + 1; i++) { | 817 for (uint32_t i = 0; i < operand.table_count + 1; ++i) { |
818 uint16_t target = operand.read_entry(this, i); | 818 uint16_t target = operand.read_entry(this, i); |
819 ssa_env_ = Split(copy); | 819 ssa_env_ = Split(copy); |
820 ssa_env_->control = (i == operand.table_count) | 820 ssa_env_->control = (i == operand.table_count) |
821 ? BUILD(IfDefault, sw) | 821 ? BUILD(IfDefault, sw) |
822 : BUILD(IfValue, i, sw); | 822 : BUILD(IfValue, i, sw); |
823 int depth = target; | 823 int depth = target; |
824 Control* c = &control_[control_.size() - depth - 1]; | 824 Control* c = &control_[control_.size() - depth - 1]; |
825 MergeInto(c->end_env, &c->node, &c->type, val); | 825 MergeInto(c->end_env, &c->node, &c->type, val); |
826 } | 826 } |
827 } else { | 827 } else { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 break; | 1038 break; |
1039 } | 1039 } |
1040 default: | 1040 default: |
1041 error("Invalid opcode"); | 1041 error("Invalid opcode"); |
1042 return; | 1042 return; |
1043 } | 1043 } |
1044 } // end complex bytecode | 1044 } // end complex bytecode |
1045 | 1045 |
1046 #if DEBUG | 1046 #if DEBUG |
1047 if (FLAG_trace_wasm_decoder) { | 1047 if (FLAG_trace_wasm_decoder) { |
1048 for (size_t i = 0; i < stack_.size(); i++) { | 1048 for (size_t i = 0; i < stack_.size(); ++i) { |
1049 Value& val = stack_[i]; | 1049 Value& val = stack_[i]; |
1050 WasmOpcode opcode = static_cast<WasmOpcode>(*val.pc); | 1050 WasmOpcode opcode = static_cast<WasmOpcode>(*val.pc); |
1051 PrintF(" %c@%d:%s", WasmOpcodes::ShortNameOf(val.type), | 1051 PrintF(" %c@%d:%s", WasmOpcodes::ShortNameOf(val.type), |
1052 static_cast<int>(val.pc - start_), | 1052 static_cast<int>(val.pc - start_), |
1053 WasmOpcodes::ShortOpcodeName(opcode)); | 1053 WasmOpcodes::ShortOpcodeName(opcode)); |
1054 switch (opcode) { | 1054 switch (opcode) { |
1055 case kExprI32Const: { | 1055 case kExprI32Const: { |
1056 ImmI32Operand operand(this, val.pc); | 1056 ImmI32Operand operand(this, val.pc); |
1057 PrintF("[%d]", operand.value); | 1057 PrintF("[%d]", operand.value); |
1058 break; | 1058 break; |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1521 return decoder.toResult<Tree*>(nullptr); | 1521 return decoder.toResult<Tree*>(nullptr); |
1522 } | 1522 } |
1523 | 1523 |
1524 std::ostream& operator<<(std::ostream& os, const Tree& tree) { | 1524 std::ostream& operator<<(std::ostream& os, const Tree& tree) { |
1525 if (tree.pc == nullptr) { | 1525 if (tree.pc == nullptr) { |
1526 os << "null"; | 1526 os << "null"; |
1527 return os; | 1527 return os; |
1528 } | 1528 } |
1529 PrintF("%s", WasmOpcodes::OpcodeName(tree.opcode())); | 1529 PrintF("%s", WasmOpcodes::OpcodeName(tree.opcode())); |
1530 if (tree.count > 0) os << "("; | 1530 if (tree.count > 0) os << "("; |
1531 for (uint32_t i = 0; i < tree.count; i++) { | 1531 for (uint32_t i = 0; i < tree.count; ++i) { |
1532 if (i > 0) os << ", "; | 1532 if (i > 0) os << ", "; |
1533 os << *tree.children[i]; | 1533 os << *tree.children[i]; |
1534 } | 1534 } |
1535 if (tree.count > 0) os << ")"; | 1535 if (tree.count > 0) os << ")"; |
1536 return os; | 1536 return os; |
1537 } | 1537 } |
1538 | 1538 |
1539 int OpcodeLength(const byte* pc, const byte* end) { | 1539 int OpcodeLength(const byte* pc, const byte* end) { |
1540 WasmDecoder decoder(nullptr, nullptr, pc, end); | 1540 WasmDecoder decoder(nullptr, nullptr, pc, end); |
1541 return decoder.OpcodeLength(pc); | 1541 return decoder.OpcodeLength(pc); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1599 offset_table->push_back( | 1599 offset_table->push_back( |
1600 std::make_tuple(pc - body.start, line_nr, num_whitespaces)); | 1600 std::make_tuple(pc - body.start, line_nr, num_whitespaces)); |
1601 } | 1601 } |
1602 | 1602 |
1603 // 64 whitespaces | 1603 // 64 whitespaces |
1604 const char* padding = | 1604 const char* padding = |
1605 " "; | 1605 " "; |
1606 os.write(padding, num_whitespaces); | 1606 os.write(padding, num_whitespaces); |
1607 os << "k" << WasmOpcodes::OpcodeName(opcode) << ","; | 1607 os << "k" << WasmOpcodes::OpcodeName(opcode) << ","; |
1608 | 1608 |
1609 for (size_t i = 1; i < length; i++) { | 1609 for (size_t i = 1; i < length; ++i) { |
1610 os << " " << AsHex(pc[i], 2) << ","; | 1610 os << " " << AsHex(pc[i], 2) << ","; |
1611 } | 1611 } |
1612 | 1612 |
1613 switch (opcode) { | 1613 switch (opcode) { |
1614 case kExprIf: | 1614 case kExprIf: |
1615 case kExprElse: | 1615 case kExprElse: |
1616 case kExprLoop: | 1616 case kExprLoop: |
1617 case kExprBlock: | 1617 case kExprBlock: |
1618 os << " // @" << static_cast<int>(pc - body.start); | 1618 os << " // @" << static_cast<int>(pc - body.start); |
1619 control_depth++; | 1619 control_depth++; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1685 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 1685 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
1686 const byte* start, const byte* end) { | 1686 const byte* start, const byte* end) { |
1687 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1687 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
1688 SR_WasmDecoder decoder(zone, nullptr, body); | 1688 SR_WasmDecoder decoder(zone, nullptr, body); |
1689 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 1689 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
1690 } | 1690 } |
1691 | 1691 |
1692 } // namespace wasm | 1692 } // namespace wasm |
1693 } // namespace internal | 1693 } // namespace internal |
1694 } // namespace v8 | 1694 } // namespace v8 |
OLD | NEW |