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