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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 return false; | 140 return false; |
141 } | 141 } |
142 return true; | 142 return true; |
143 } | 143 } |
144 error(pc, pc + 1, "invalid function index"); | 144 error(pc, pc + 1, "invalid function index"); |
145 return false; | 145 return false; |
146 } | 146 } |
147 | 147 |
148 inline bool Complete(const byte* pc, CallIndirectOperand& operand) { | 148 inline bool Complete(const byte* pc, CallIndirectOperand& operand) { |
149 ModuleEnv* m = module_; | 149 ModuleEnv* m = module_; |
150 if (m && m->module && operand.index < m->module->signatures.size()) { | 150 if (m && m->module && operand.sig_index < m->module->signatures.size() && |
151 operand.sig = m->module->signatures[operand.index]; | 151 operand.table_index < m->module->function_tables.size()) { |
| 152 operand.sig = m->module->signatures[operand.sig_index]; |
| 153 operand.table = |
| 154 m->module->signatures[m->module->function_tables[operand.table_index] |
| 155 .sig_index]; |
152 return true; | 156 return true; |
153 } | 157 } |
154 return false; | 158 return false; |
155 } | 159 } |
156 | 160 |
157 inline bool Validate(const byte* pc, CallIndirectOperand& operand) { | 161 inline bool Validate(const byte* pc, CallIndirectOperand& operand) { |
158 if (Complete(pc, operand)) { | 162 if (Complete(pc, operand)) { |
159 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count()); | 163 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count()); |
| 164 uint32_t table_sig = |
| 165 module_->module->function_tables[operand.table_index].sig_index; |
160 if (operand.arity != expected) { | 166 if (operand.arity != expected) { |
161 error(pc, pc + 1, | 167 error(pc, pc + 1, |
162 "arity mismatch in indirect function call (expected %u, got %u)", | 168 "arity mismatch in indirect function call (expected %u, got %u)", |
163 expected, operand.arity); | 169 expected, operand.arity); |
164 return false; | 170 return false; |
| 171 } else if (!isAnyFuncType(operand.table) && |
| 172 operand.sig_index != table_sig) { |
| 173 error(pc, pc + 1, |
| 174 "signature mismatch in indirect function call (expected %u, got " |
| 175 "%u)", |
| 176 operand.sig_index, table_sig); |
165 } | 177 } |
166 return true; | 178 return true; |
167 } | 179 } |
168 error(pc, pc + 1, "invalid signature index"); | 180 error(pc, pc + 1, "invalid signature index"); |
169 return false; | 181 return false; |
170 } | 182 } |
171 | 183 |
172 inline bool Complete(const byte* pc, CallImportOperand& operand) { | 184 inline bool Complete(const byte* pc, CallImportOperand& operand) { |
173 ModuleEnv* m = module_; | 185 ModuleEnv* m = module_; |
174 if (m && m->module && operand.index < m->module->import_table.size()) { | 186 if (m && m->module && operand.index < m->module->import_table.size()) { |
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
970 } | 982 } |
971 len = 1 + operand.length; | 983 len = 1 + operand.length; |
972 break; | 984 break; |
973 } | 985 } |
974 case kExprCallIndirect: { | 986 case kExprCallIndirect: { |
975 CallIndirectOperand operand(this, pc_); | 987 CallIndirectOperand operand(this, pc_); |
976 if (Validate(pc_, operand)) { | 988 if (Validate(pc_, operand)) { |
977 TFNode** buffer = PopArgs(operand.sig); | 989 TFNode** buffer = PopArgs(operand.sig); |
978 Value index = Pop(0, kAstI32); | 990 Value index = Pop(0, kAstI32); |
979 if (buffer) buffer[0] = index.node; | 991 if (buffer) buffer[0] = index.node; |
980 TFNode* call = | 992 TFNode* call = BUILD(CallIndirect, operand.sig_index, |
981 BUILD(CallIndirect, operand.index, buffer, position()); | 993 operand.table_index, buffer, position()); |
982 Push(GetReturnType(operand.sig), call); | 994 Push(GetReturnType(operand.sig), call); |
983 } | 995 } |
984 len = 1 + operand.length; | 996 len = 1 + operand.length; |
985 break; | 997 break; |
986 } | 998 } |
987 case kExprCallImport: { | 999 case kExprCallImport: { |
988 CallImportOperand operand(this, pc_); | 1000 CallImportOperand operand(this, pc_); |
989 if (Validate(pc_, operand)) { | 1001 if (Validate(pc_, operand)) { |
990 TFNode** buffer = PopArgs(operand.sig); | 1002 TFNode** buffer = PopArgs(operand.sig); |
991 TFNode* call = | 1003 TFNode* call = |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1608 } | 1620 } |
1609 case kExprBrTable: { | 1621 case kExprBrTable: { |
1610 BranchTableOperand operand(&i, i.pc()); | 1622 BranchTableOperand operand(&i, i.pc()); |
1611 os << " // arity=" << operand.arity | 1623 os << " // arity=" << operand.arity |
1612 << " entries=" << operand.table_count; | 1624 << " entries=" << operand.table_count; |
1613 break; | 1625 break; |
1614 } | 1626 } |
1615 case kExprCallIndirect: { | 1627 case kExprCallIndirect: { |
1616 CallIndirectOperand operand(&i, i.pc()); | 1628 CallIndirectOperand operand(&i, i.pc()); |
1617 if (decoder.Complete(i.pc(), operand)) { | 1629 if (decoder.Complete(i.pc(), operand)) { |
1618 os << " // sig #" << operand.index << ": " << *operand.sig; | 1630 os << " // sig #" << operand.sig_index << ": " << *operand.sig |
| 1631 << ", table # " << operand.table_index; |
1619 } else { | 1632 } else { |
1620 os << " // arity=" << operand.arity << " sig #" << operand.index; | 1633 os << " // arity=" << operand.arity << " sig #" << operand.sig_index |
| 1634 << "table # " << operand.table_index; |
1621 } | 1635 } |
1622 break; | 1636 break; |
1623 } | 1637 } |
1624 case kExprCallImport: { | 1638 case kExprCallImport: { |
1625 CallImportOperand operand(&i, i.pc()); | 1639 CallImportOperand operand(&i, i.pc()); |
1626 if (decoder.Complete(i.pc(), operand)) { | 1640 if (decoder.Complete(i.pc(), operand)) { |
1627 os << " // import #" << operand.index << ": " << *operand.sig; | 1641 os << " // import #" << operand.index << ": " << *operand.sig; |
1628 } else { | 1642 } else { |
1629 os << " // arity=" << operand.arity << " import #" << operand.index; | 1643 os << " // arity=" << operand.arity << " import #" << operand.index; |
1630 } | 1644 } |
(...skipping 26 matching lines...) Expand all Loading... |
1657 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 1671 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
1658 const byte* start, const byte* end) { | 1672 const byte* start, const byte* end) { |
1659 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1673 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
1660 WasmFullDecoder decoder(zone, nullptr, body); | 1674 WasmFullDecoder decoder(zone, nullptr, body); |
1661 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 1675 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
1662 } | 1676 } |
1663 | 1677 |
1664 } // namespace wasm | 1678 } // namespace wasm |
1665 } // namespace internal | 1679 } // namespace internal |
1666 } // namespace v8 | 1680 } // namespace v8 |
OLD | NEW |