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 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 TRACE(" @%-6d #%02x:%-20s|", startrel(pc_), opcode, | 608 TRACE(" @%-6d #%02x:%-20s|", startrel(pc_), opcode, |
609 WasmOpcodes::ShortOpcodeName(opcode)); | 609 WasmOpcodes::ShortOpcodeName(opcode)); |
610 | 610 |
611 FunctionSig* sig = WasmOpcodes::Signature(opcode); | 611 FunctionSig* sig = WasmOpcodes::Signature(opcode); |
612 if (sig) { | 612 if (sig) { |
613 // Fast case of a simple operator. | 613 // Fast case of a simple operator. |
614 TFNode* node; | 614 TFNode* node; |
615 switch (sig->parameter_count()) { | 615 switch (sig->parameter_count()) { |
616 case 1: { | 616 case 1: { |
617 Value val = Pop(0, sig->GetParam(0)); | 617 Value val = Pop(0, sig->GetParam(0)); |
618 node = BUILD(Unop, opcode, val.node); | 618 node = BUILD(Unop, opcode, val.node, position()); |
619 break; | 619 break; |
620 } | 620 } |
621 case 2: { | 621 case 2: { |
622 Value rval = Pop(1, sig->GetParam(1)); | 622 Value rval = Pop(1, sig->GetParam(1)); |
623 Value lval = Pop(0, sig->GetParam(0)); | 623 Value lval = Pop(0, sig->GetParam(0)); |
624 node = BUILD(Binop, opcode, lval.node, rval.node); | 624 node = BUILD(Binop, opcode, lval.node, rval.node, position()); |
625 break; | 625 break; |
626 } | 626 } |
627 default: | 627 default: |
628 UNREACHABLE(); | 628 UNREACHABLE(); |
629 node = nullptr; | 629 node = nullptr; |
630 break; | 630 break; |
631 } | 631 } |
632 Push(GetReturnType(sig), node); | 632 Push(GetReturnType(sig), node); |
633 } else { | 633 } else { |
634 // Complex bytecode. | 634 // Complex bytecode. |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 case kExprReturn: { | 822 case kExprReturn: { |
823 ReturnArityOperand operand(this, pc_); | 823 ReturnArityOperand operand(this, pc_); |
824 if (operand.arity != sig_->return_count()) { | 824 if (operand.arity != sig_->return_count()) { |
825 error(pc_, pc_ + 1, "arity mismatch in return"); | 825 error(pc_, pc_ + 1, "arity mismatch in return"); |
826 } | 826 } |
827 DoReturn(); | 827 DoReturn(); |
828 len = 1 + operand.length; | 828 len = 1 + operand.length; |
829 break; | 829 break; |
830 } | 830 } |
831 case kExprUnreachable: { | 831 case kExprUnreachable: { |
832 // TODO(clemensh): add source position for unreachable | 832 Push(kAstEnd, BUILD(Unreachable, position())); |
833 Push(kAstEnd, BUILD0(Unreachable)); | |
834 ssa_env_->Kill(SsaEnv::kControlEnd); | 833 ssa_env_->Kill(SsaEnv::kControlEnd); |
835 break; | 834 break; |
836 } | 835 } |
837 case kExprI8Const: { | 836 case kExprI8Const: { |
838 ImmI8Operand operand(this, pc_); | 837 ImmI8Operand operand(this, pc_); |
839 Push(kAstI32, BUILD(Int32Constant, operand.value)); | 838 Push(kAstI32, BUILD(Int32Constant, operand.value)); |
840 len = 1 + operand.length; | 839 len = 1 + operand.length; |
841 break; | 840 break; |
842 } | 841 } |
843 case kExprI32Const: { | 842 case kExprI32Const: { |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 case kExprGrowMemory: { | 980 case kExprGrowMemory: { |
982 Value val = Pop(0, kAstI32); | 981 Value val = Pop(0, kAstI32); |
983 USE(val); // TODO(titzer): build node for grow memory | 982 USE(val); // TODO(titzer): build node for grow memory |
984 Push(kAstI32, BUILD(Int32Constant, 0)); | 983 Push(kAstI32, BUILD(Int32Constant, 0)); |
985 break; | 984 break; |
986 } | 985 } |
987 case kExprCallFunction: { | 986 case kExprCallFunction: { |
988 CallFunctionOperand operand(this, pc_); | 987 CallFunctionOperand operand(this, pc_); |
989 if (Validate(pc_, operand)) { | 988 if (Validate(pc_, operand)) { |
990 TFNode** buffer = PopArgs(operand.sig); | 989 TFNode** buffer = PopArgs(operand.sig); |
991 TFNode* call = BUILD(CallDirect, operand.index, buffer); | 990 TFNode* call = |
| 991 BUILD(CallDirect, operand.index, buffer, position()); |
992 Push(GetReturnType(operand.sig), call); | 992 Push(GetReturnType(operand.sig), call); |
993 AddSourcePosition(call, pc_); | |
994 } | 993 } |
995 len = 1 + operand.length; | 994 len = 1 + operand.length; |
996 break; | 995 break; |
997 } | 996 } |
998 case kExprCallIndirect: { | 997 case kExprCallIndirect: { |
999 CallIndirectOperand operand(this, pc_); | 998 CallIndirectOperand operand(this, pc_); |
1000 if (Validate(pc_, operand)) { | 999 if (Validate(pc_, operand)) { |
1001 TFNode** buffer = PopArgs(operand.sig); | 1000 TFNode** buffer = PopArgs(operand.sig); |
1002 Value index = Pop(0, kAstI32); | 1001 Value index = Pop(0, kAstI32); |
1003 if (buffer) buffer[0] = index.node; | 1002 if (buffer) buffer[0] = index.node; |
1004 TFNode* call = BUILD(CallIndirect, operand.index, buffer); | 1003 TFNode* call = |
| 1004 BUILD(CallIndirect, operand.index, buffer, position()); |
1005 Push(GetReturnType(operand.sig), call); | 1005 Push(GetReturnType(operand.sig), call); |
1006 AddSourcePosition(call, pc_); | |
1007 } | 1006 } |
1008 len = 1 + operand.length; | 1007 len = 1 + operand.length; |
1009 break; | 1008 break; |
1010 } | 1009 } |
1011 case kExprCallImport: { | 1010 case kExprCallImport: { |
1012 CallImportOperand operand(this, pc_); | 1011 CallImportOperand operand(this, pc_); |
1013 if (Validate(pc_, operand)) { | 1012 if (Validate(pc_, operand)) { |
1014 TFNode** buffer = PopArgs(operand.sig); | 1013 TFNode** buffer = PopArgs(operand.sig); |
1015 TFNode* call = BUILD(CallImport, operand.index, buffer); | 1014 TFNode* call = |
| 1015 BUILD(CallImport, operand.index, buffer, position()); |
1016 Push(GetReturnType(operand.sig), call); | 1016 Push(GetReturnType(operand.sig), call); |
1017 AddSourcePosition(call, pc_); | |
1018 } | 1017 } |
1019 len = 1 + operand.length; | 1018 len = 1 + operand.length; |
1020 break; | 1019 break; |
1021 } | 1020 } |
1022 default: | 1021 default: |
1023 error("Invalid opcode"); | 1022 error("Invalid opcode"); |
1024 return; | 1023 return; |
1025 } | 1024 } |
1026 } // end complex bytecode | 1025 } // end complex bytecode |
1027 | 1026 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 | 1100 |
1102 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { | 1101 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { |
1103 int stack_depth = static_cast<int>(stack_.size()); | 1102 int stack_depth = static_cast<int>(stack_.size()); |
1104 control_.push_back( | 1103 control_.push_back( |
1105 {pc_, stack_depth, end_env, false_env, nullptr, kAstStmt, false}); | 1104 {pc_, stack_depth, end_env, false_env, nullptr, kAstStmt, false}); |
1106 } | 1105 } |
1107 | 1106 |
1108 int DecodeLoadMem(LocalType type, MachineType mem_type) { | 1107 int DecodeLoadMem(LocalType type, MachineType mem_type) { |
1109 MemoryAccessOperand operand(this, pc_); | 1108 MemoryAccessOperand operand(this, pc_); |
1110 Value index = Pop(0, kAstI32); | 1109 Value index = Pop(0, kAstI32); |
1111 TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset); | 1110 TFNode* node = |
| 1111 BUILD(LoadMem, type, mem_type, index.node, operand.offset, position()); |
1112 Push(type, node); | 1112 Push(type, node); |
1113 return 1 + operand.length; | 1113 return 1 + operand.length; |
1114 } | 1114 } |
1115 | 1115 |
1116 int DecodeStoreMem(LocalType type, MachineType mem_type) { | 1116 int DecodeStoreMem(LocalType type, MachineType mem_type) { |
1117 MemoryAccessOperand operand(this, pc_); | 1117 MemoryAccessOperand operand(this, pc_); |
1118 Value val = Pop(1, type); | 1118 Value val = Pop(1, type); |
1119 Value index = Pop(0, kAstI32); | 1119 Value index = Pop(0, kAstI32); |
1120 BUILD(StoreMem, mem_type, index.node, operand.offset, val.node); | 1120 BUILD(StoreMem, mem_type, index.node, operand.offset, val.node, position()); |
1121 Push(type, val.node); | 1121 Push(type, val.node); |
1122 return 1 + operand.length; | 1122 return 1 + operand.length; |
1123 } | 1123 } |
1124 | 1124 |
1125 void DoReturn() { | 1125 void DoReturn() { |
1126 int count = static_cast<int>(sig_->return_count()); | 1126 int count = static_cast<int>(sig_->return_count()); |
1127 TFNode** buffer = nullptr; | 1127 TFNode** buffer = nullptr; |
1128 if (build()) buffer = builder_->Buffer(count); | 1128 if (build()) buffer = builder_->Buffer(count); |
1129 | 1129 |
1130 // Pop return values off the stack in reverse order. | 1130 // Pop return values off the stack in reverse order. |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1288 } | 1288 } |
1289 break; | 1289 break; |
1290 } | 1290 } |
1291 case SsaEnv::kMerged: { | 1291 case SsaEnv::kMerged: { |
1292 if (!builder_) break; | 1292 if (!builder_) break; |
1293 TFNode* merge = to->control; | 1293 TFNode* merge = to->control; |
1294 // Extend the existing merge. | 1294 // Extend the existing merge. |
1295 builder_->AppendToMerge(merge, from->control); | 1295 builder_->AppendToMerge(merge, from->control); |
1296 // Merge effects. | 1296 // Merge effects. |
1297 if (builder_->IsPhiWithMerge(to->effect, merge)) { | 1297 if (builder_->IsPhiWithMerge(to->effect, merge)) { |
1298 builder_->AppendToPhi(merge, to->effect, from->effect); | 1298 builder_->AppendToPhi(to->effect, from->effect); |
1299 } else if (to->effect != from->effect) { | 1299 } else if (to->effect != from->effect) { |
1300 uint32_t count = builder_->InputCount(merge); | 1300 uint32_t count = builder_->InputCount(merge); |
1301 TFNode** effects = builder_->Buffer(count); | 1301 TFNode** effects = builder_->Buffer(count); |
1302 for (uint32_t j = 0; j < count - 1; j++) { | 1302 for (uint32_t j = 0; j < count - 1; j++) { |
1303 effects[j] = to->effect; | 1303 effects[j] = to->effect; |
1304 } | 1304 } |
1305 effects[count - 1] = from->effect; | 1305 effects[count - 1] = from->effect; |
1306 to->effect = builder_->EffectPhi(count, effects, merge); | 1306 to->effect = builder_->EffectPhi(count, effects, merge); |
1307 } | 1307 } |
1308 // Merge locals. | 1308 // Merge locals. |
1309 for (int i = EnvironmentCount() - 1; i >= 0; i--) { | 1309 for (int i = EnvironmentCount() - 1; i >= 0; i--) { |
1310 TFNode* tnode = to->locals[i]; | 1310 TFNode* tnode = to->locals[i]; |
1311 TFNode* fnode = from->locals[i]; | 1311 TFNode* fnode = from->locals[i]; |
1312 if (builder_->IsPhiWithMerge(tnode, merge)) { | 1312 if (builder_->IsPhiWithMerge(tnode, merge)) { |
1313 builder_->AppendToPhi(merge, tnode, fnode); | 1313 builder_->AppendToPhi(tnode, fnode); |
1314 } else if (tnode != fnode) { | 1314 } else if (tnode != fnode) { |
1315 uint32_t count = builder_->InputCount(merge); | 1315 uint32_t count = builder_->InputCount(merge); |
1316 TFNode** vals = builder_->Buffer(count); | 1316 TFNode** vals = builder_->Buffer(count); |
1317 for (uint32_t j = 0; j < count - 1; j++) { | 1317 for (uint32_t j = 0; j < count - 1; j++) { |
1318 vals[j] = tnode; | 1318 vals[j] = tnode; |
1319 } | 1319 } |
1320 vals[count - 1] = fnode; | 1320 vals[count - 1] = fnode; |
1321 to->locals[i] = | 1321 to->locals[i] = |
1322 builder_->Phi(local_type_vec_[i], count, vals, merge); | 1322 builder_->Phi(local_type_vec_[i], count, vals, merge); |
1323 } | 1323 } |
1324 } | 1324 } |
1325 break; | 1325 break; |
1326 } | 1326 } |
1327 default: | 1327 default: |
1328 UNREACHABLE(); | 1328 UNREACHABLE(); |
1329 } | 1329 } |
1330 return from->Kill(); | 1330 return from->Kill(); |
1331 } | 1331 } |
1332 | 1332 |
1333 TFNode* CreateOrMergeIntoPhi(LocalType type, TFNode* merge, TFNode* tnode, | 1333 TFNode* CreateOrMergeIntoPhi(LocalType type, TFNode* merge, TFNode* tnode, |
1334 TFNode* fnode) { | 1334 TFNode* fnode) { |
1335 if (builder_->IsPhiWithMerge(tnode, merge)) { | 1335 if (builder_->IsPhiWithMerge(tnode, merge)) { |
1336 builder_->AppendToPhi(merge, tnode, fnode); | 1336 builder_->AppendToPhi(tnode, fnode); |
1337 } else if (tnode != fnode) { | 1337 } else if (tnode != fnode) { |
1338 uint32_t count = builder_->InputCount(merge); | 1338 uint32_t count = builder_->InputCount(merge); |
1339 TFNode** vals = builder_->Buffer(count); | 1339 TFNode** vals = builder_->Buffer(count); |
1340 for (uint32_t j = 0; j < count - 1; j++) vals[j] = tnode; | 1340 for (uint32_t j = 0; j < count - 1; j++) vals[j] = tnode; |
1341 vals[count - 1] = fnode; | 1341 vals[count - 1] = fnode; |
1342 return builder_->Phi(type, count, vals, merge); | 1342 return builder_->Phi(type, count, vals, merge); |
1343 } | 1343 } |
1344 return tnode; | 1344 return tnode; |
1345 } | 1345 } |
1346 | 1346 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1461 default: | 1461 default: |
1462 length = OpcodeLength(pc); | 1462 length = OpcodeLength(pc); |
1463 break; | 1463 break; |
1464 } | 1464 } |
1465 if (depth <= 0) break; | 1465 if (depth <= 0) break; |
1466 pc += length; | 1466 pc += length; |
1467 } | 1467 } |
1468 return assigned; | 1468 return assigned; |
1469 } | 1469 } |
1470 | 1470 |
1471 void AddSourcePosition(TFNode* node, const byte* pc) { | 1471 inline wasm::WasmCodePosition position() { |
1472 if (node) { | 1472 int offset = static_cast<int>(pc_ - start_); |
1473 int offset = static_cast<int>(pc - start_); | 1473 DCHECK_EQ(pc_ - start_, offset); // overflows cannot happen |
1474 DCHECK_EQ(pc - start_, offset); // overflows cannot happen | 1474 return offset; |
1475 builder_->SetSourcePosition(node, offset); | |
1476 } | |
1477 } | 1475 } |
1478 }; | 1476 }; |
1479 | 1477 |
1480 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, | 1478 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, |
1481 const byte* end) { | 1479 const byte* end) { |
1482 base::AccountingAllocator allocator; | 1480 base::AccountingAllocator allocator; |
1483 Zone tmp(&allocator); | 1481 Zone tmp(&allocator); |
1484 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1482 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
1485 SR_WasmDecoder decoder(&tmp, nullptr, body); | 1483 SR_WasmDecoder decoder(&tmp, nullptr, body); |
1486 return decoder.DecodeLocalDecls(decls); | 1484 return decoder.DecodeLocalDecls(decls); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1620 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 1618 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
1621 const byte* start, const byte* end) { | 1619 const byte* start, const byte* end) { |
1622 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1620 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
1623 SR_WasmDecoder decoder(zone, nullptr, body); | 1621 SR_WasmDecoder decoder(zone, nullptr, body); |
1624 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 1622 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
1625 } | 1623 } |
1626 | 1624 |
1627 } // namespace wasm | 1625 } // namespace wasm |
1628 } // namespace internal | 1626 } // namespace internal |
1629 } // namespace v8 | 1627 } // namespace v8 |
OLD | NEW |