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/base/platform/elapsed-timer.h" | 5 #include "src/base/platform/elapsed-timer.h" |
6 #include "src/signature.h" | 6 #include "src/signature.h" |
7 | 7 |
8 #include "src/bit-vector.h" | 8 #include "src/bit-vector.h" |
9 #include "src/flags.h" | 9 #include "src/flags.h" |
10 #include "src/handles.h" | 10 #include "src/handles.h" |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 inline bool Validate(const byte* pc, SignatureIndexOperand& operand) { | 168 inline bool Validate(const byte* pc, SignatureIndexOperand& operand) { |
169 ModuleEnv* m = function_env_->module; | 169 ModuleEnv* m = function_env_->module; |
170 if (m && m->module && operand.index < m->module->signatures->size()) { | 170 if (m && m->module && operand.index < m->module->signatures->size()) { |
171 operand.sig = m->module->signatures->at(operand.index); | 171 operand.sig = m->module->signatures->at(operand.index); |
172 return true; | 172 return true; |
173 } | 173 } |
174 error(pc, pc + 1, "invalid signature index"); | 174 error(pc, pc + 1, "invalid signature index"); |
175 return false; | 175 return false; |
176 } | 176 } |
177 | 177 |
| 178 inline bool Validate(const byte* pc, ImportIndexOperand& operand) { |
| 179 ModuleEnv* m = function_env_->module; |
| 180 if (m && m->module && operand.index < m->module->import_table->size()) { |
| 181 operand.sig = m->module->import_table->at(operand.index).sig; |
| 182 return true; |
| 183 } |
| 184 error(pc, pc + 1, "invalid signature index"); |
| 185 return false; |
| 186 } |
| 187 |
178 inline bool Validate(const byte* pc, BreakDepthOperand& operand, | 188 inline bool Validate(const byte* pc, BreakDepthOperand& operand, |
179 ZoneVector<Block>& blocks) { | 189 ZoneVector<Block>& blocks) { |
180 if (operand.depth < blocks.size()) { | 190 if (operand.depth < blocks.size()) { |
181 operand.target = &blocks[blocks.size() - operand.depth - 1]; | 191 operand.target = &blocks[blocks.size() - operand.depth - 1]; |
182 return true; | 192 return true; |
183 } | 193 } |
184 error(pc, pc + 1, "invalid break depth"); | 194 error(pc, pc + 1, "invalid break depth"); |
185 return false; | 195 return false; |
186 } | 196 } |
187 | 197 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 return static_cast<int>( | 264 return static_cast<int>( |
255 function_env_->module->GetFunctionSignature(operand.index) | 265 function_env_->module->GetFunctionSignature(operand.index) |
256 ->parameter_count()); | 266 ->parameter_count()); |
257 } | 267 } |
258 case kExprCallIndirect: { | 268 case kExprCallIndirect: { |
259 SignatureIndexOperand operand(this, pc); | 269 SignatureIndexOperand operand(this, pc); |
260 return 1 + static_cast<int>( | 270 return 1 + static_cast<int>( |
261 function_env_->module->GetSignature(operand.index) | 271 function_env_->module->GetSignature(operand.index) |
262 ->parameter_count()); | 272 ->parameter_count()); |
263 } | 273 } |
| 274 case kExprCallImport: { |
| 275 ImportIndexOperand operand(this, pc); |
| 276 return static_cast<int>( |
| 277 function_env_->module->GetImportSignature(operand.index) |
| 278 ->parameter_count()); |
| 279 } |
264 case kExprReturn: { | 280 case kExprReturn: { |
265 return static_cast<int>(function_env_->sig->return_count()); | 281 return static_cast<int>(function_env_->sig->return_count()); |
266 } | 282 } |
267 case kExprTableSwitch: { | 283 case kExprTableSwitch: { |
268 TableSwitchOperand operand(this, pc); | 284 TableSwitchOperand operand(this, pc); |
269 return 1 + operand.case_count; | 285 return 1 + operand.case_count; |
270 } | 286 } |
271 | 287 |
272 #define DECLARE_OPCODE_CASE(name, opcode, sig) \ | 288 #define DECLARE_OPCODE_CASE(name, opcode, sig) \ |
273 case kExpr##name: \ | 289 case kExpr##name: \ |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 } | 326 } |
311 | 327 |
312 case kExprCallFunction: { | 328 case kExprCallFunction: { |
313 FunctionIndexOperand operand(this, pc); | 329 FunctionIndexOperand operand(this, pc); |
314 return 1 + operand.length; | 330 return 1 + operand.length; |
315 } | 331 } |
316 case kExprCallIndirect: { | 332 case kExprCallIndirect: { |
317 SignatureIndexOperand operand(this, pc); | 333 SignatureIndexOperand operand(this, pc); |
318 return 1 + operand.length; | 334 return 1 + operand.length; |
319 } | 335 } |
| 336 case kExprCallImport: { |
| 337 ImportIndexOperand operand(this, pc); |
| 338 return 1 + operand.length; |
| 339 } |
320 | 340 |
321 case kExprSetLocal: | 341 case kExprSetLocal: |
322 case kExprGetLocal: { | 342 case kExprGetLocal: { |
323 LocalIndexOperand operand(this, pc); | 343 LocalIndexOperand operand(this, pc); |
324 return 1 + operand.length; | 344 return 1 + operand.length; |
325 } | 345 } |
326 case kExprTableSwitch: { | 346 case kExprTableSwitch: { |
327 TableSwitchOperand operand(this, pc); | 347 TableSwitchOperand operand(this, pc); |
328 return 1 + operand.length; | 348 return 1 + operand.length; |
329 } | 349 } |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 SignatureIndexOperand operand(this, pc_); | 803 SignatureIndexOperand operand(this, pc_); |
784 if (Validate(pc_, operand)) { | 804 if (Validate(pc_, operand)) { |
785 LocalType type = operand.sig->return_count() == 0 | 805 LocalType type = operand.sig->return_count() == 0 |
786 ? kAstStmt | 806 ? kAstStmt |
787 : operand.sig->GetReturn(); | 807 : operand.sig->GetReturn(); |
788 Shift(type, static_cast<int>(1 + operand.sig->parameter_count())); | 808 Shift(type, static_cast<int>(1 + operand.sig->parameter_count())); |
789 } | 809 } |
790 len = 1 + operand.length; | 810 len = 1 + operand.length; |
791 break; | 811 break; |
792 } | 812 } |
| 813 case kExprCallImport: { |
| 814 ImportIndexOperand operand(this, pc_); |
| 815 if (Validate(pc_, operand)) { |
| 816 LocalType type = operand.sig->return_count() == 0 |
| 817 ? kAstStmt |
| 818 : operand.sig->GetReturn(); |
| 819 Shift(type, static_cast<int>(operand.sig->parameter_count())); |
| 820 } |
| 821 len = 1 + operand.length; |
| 822 break; |
| 823 } |
793 default: | 824 default: |
794 error("Invalid opcode"); | 825 error("Invalid opcode"); |
795 return; | 826 return; |
796 } | 827 } |
797 pc_ += len; | 828 pc_ += len; |
798 if (pc_ >= limit_) { | 829 if (pc_ >= limit_) { |
799 // End of code reached or exceeded. | 830 // End of code reached or exceeded. |
800 if (pc_ > limit_ && ok()) { | 831 if (pc_ > limit_ && ok()) { |
801 error("Beyond end of code"); | 832 error("Beyond end of code"); |
802 } | 833 } |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 if (p->done() && build()) { | 1236 if (p->done() && build()) { |
1206 uint32_t count = p->tree->count; | 1237 uint32_t count = p->tree->count; |
1207 TFNode** buffer = builder_->Buffer(count); | 1238 TFNode** buffer = builder_->Buffer(count); |
1208 for (uint32_t i = 0; i < count; i++) { | 1239 for (uint32_t i = 0; i < count; i++) { |
1209 buffer[i] = p->tree->children[i]->node; | 1240 buffer[i] = p->tree->children[i]->node; |
1210 } | 1241 } |
1211 p->tree->node = builder_->CallIndirect(operand.index, buffer); | 1242 p->tree->node = builder_->CallIndirect(operand.index, buffer); |
1212 } | 1243 } |
1213 break; | 1244 break; |
1214 } | 1245 } |
| 1246 case kExprCallImport: { |
| 1247 ImportIndexOperand operand(this, p->pc()); |
| 1248 CHECK(Validate(p->pc(), operand)); |
| 1249 if (p->index > 0) { |
| 1250 TypeCheckLast(p, operand.sig->GetParam(p->index - 1)); |
| 1251 } |
| 1252 if (p->done() && build()) { |
| 1253 uint32_t count = p->tree->count + 1; |
| 1254 TFNode** buffer = builder_->Buffer(count); |
| 1255 buffer[0] = nullptr; // reserved for code object. |
| 1256 for (uint32_t i = 1; i < count; i++) { |
| 1257 buffer[i] = p->tree->children[i - 1]->node; |
| 1258 } |
| 1259 p->tree->node = builder_->CallImport(operand.index, buffer); |
| 1260 } |
| 1261 break; |
| 1262 } |
1215 default: | 1263 default: |
1216 break; | 1264 break; |
1217 } | 1265 } |
1218 } | 1266 } |
1219 | 1267 |
1220 void ReduceBreakToExprBlock(Production* p, Block* block) { | 1268 void ReduceBreakToExprBlock(Production* p, Block* block) { |
1221 ReduceBreakToExprBlock(p, block, p->tree->count > 0 ? p->last() : nullptr); | 1269 ReduceBreakToExprBlock(p, block, p->tree->count > 0 ? p->last() : nullptr); |
1222 } | 1270 } |
1223 | 1271 |
1224 void ReduceBreakToExprBlock(Production* p, Block* block, Tree* val) { | 1272 void ReduceBreakToExprBlock(Production* p, Block* block, Tree* val) { |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1657 | 1705 |
1658 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, FunctionEnv* env, | 1706 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, FunctionEnv* env, |
1659 const byte* start, const byte* end) { | 1707 const byte* start, const byte* end) { |
1660 LoopAssignmentAnalyzer analyzer(zone, env); | 1708 LoopAssignmentAnalyzer analyzer(zone, env); |
1661 return analyzer.Analyze(start, end); | 1709 return analyzer.Analyze(start, end); |
1662 } | 1710 } |
1663 | 1711 |
1664 } // namespace wasm | 1712 } // namespace wasm |
1665 } // namespace internal | 1713 } // namespace internal |
1666 } // namespace v8 | 1714 } // namespace v8 |
OLD | NEW |