| 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 |