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/zone-containers.h" | 10 #include "src/zone/zone-containers.h" |
(...skipping 81 matching lines...) Loading... | |
92 }; | 92 }; |
93 | 93 |
94 static Value* NO_VALUE = nullptr; | 94 static Value* NO_VALUE = nullptr; |
95 | 95 |
96 enum ControlKind { kControlIf, kControlBlock, kControlLoop, kControlTry }; | 96 enum ControlKind { kControlIf, kControlBlock, kControlLoop, kControlTry }; |
97 | 97 |
98 // An entry on the control stack (i.e. if, block, loop). | 98 // An entry on the control stack (i.e. if, block, loop). |
99 struct Control { | 99 struct Control { |
100 const byte* pc; | 100 const byte* pc; |
101 ControlKind kind; | 101 ControlKind kind; |
102 int stack_depth; // stack height at the beginning of the construct. | 102 size_t stack_depth; // stack height at the beginning of the construct. |
103 SsaEnv* end_env; // end environment for the construct. | 103 SsaEnv* end_env; // end environment for the construct. |
104 SsaEnv* false_env; // false environment (only for if). | 104 SsaEnv* false_env; // false environment (only for if). |
105 TryInfo* try_info; // Information used for compiling try statements. | 105 TryInfo* try_info; // Information used for compiling try statements. |
106 int32_t previous_catch; // The previous Control (on the stack) with a catch. | 106 int32_t previous_catch; // The previous Control (on the stack) with a catch. |
107 | 107 |
108 // Values merged into the end of this control construct. | 108 // Values merged into the end of this control construct. |
109 MergeValues merge; | 109 MergeValues merge; |
110 | 110 |
111 inline bool is_if() const { return kind == kControlIf; } | 111 inline bool is_if() const { return kind == kControlIf; } |
112 inline bool is_block() const { return kind == kControlBlock; } | 112 inline bool is_block() const { return kind == kControlBlock; } |
113 inline bool is_loop() const { return kind == kControlLoop; } | 113 inline bool is_loop() const { return kind == kControlLoop; } |
114 inline bool is_try() const { return kind == kControlTry; } | 114 inline bool is_try() const { return kind == kControlTry; } |
115 | 115 |
116 // Named constructors. | 116 // Named constructors. |
117 static Control Block(const byte* pc, int stack_depth, SsaEnv* end_env, | 117 static Control Block(const byte* pc, size_t stack_depth, SsaEnv* end_env, |
118 int32_t previous_catch) { | 118 int32_t previous_catch) { |
119 return {pc, kControlBlock, stack_depth, end_env, | 119 return {pc, kControlBlock, stack_depth, end_env, |
120 nullptr, nullptr, previous_catch, {0, {NO_VALUE}}}; | 120 nullptr, nullptr, previous_catch, {0, {NO_VALUE}}}; |
121 } | 121 } |
122 | 122 |
123 static Control If(const byte* pc, int stack_depth, SsaEnv* end_env, | 123 static Control If(const byte* pc, size_t stack_depth, SsaEnv* end_env, |
124 SsaEnv* false_env, int32_t previous_catch) { | 124 SsaEnv* false_env, int32_t previous_catch) { |
125 return {pc, kControlIf, stack_depth, end_env, | 125 return {pc, kControlIf, stack_depth, end_env, |
126 false_env, nullptr, previous_catch, {0, {NO_VALUE}}}; | 126 false_env, nullptr, previous_catch, {0, {NO_VALUE}}}; |
127 } | 127 } |
128 | 128 |
129 static Control Loop(const byte* pc, int stack_depth, SsaEnv* end_env, | 129 static Control Loop(const byte* pc, size_t stack_depth, SsaEnv* end_env, |
130 int32_t previous_catch) { | 130 int32_t previous_catch) { |
131 return {pc, kControlLoop, stack_depth, end_env, | 131 return {pc, kControlLoop, stack_depth, end_env, |
132 nullptr, nullptr, previous_catch, {0, {NO_VALUE}}}; | 132 nullptr, nullptr, previous_catch, {0, {NO_VALUE}}}; |
133 } | 133 } |
134 | 134 |
135 static Control Try(const byte* pc, int stack_depth, SsaEnv* end_env, | 135 static Control Try(const byte* pc, size_t stack_depth, SsaEnv* end_env, |
136 Zone* zone, SsaEnv* catch_env, int32_t previous_catch) { | 136 Zone* zone, SsaEnv* catch_env, int32_t previous_catch) { |
137 DCHECK_NOT_NULL(catch_env); | 137 DCHECK_NOT_NULL(catch_env); |
138 TryInfo* try_info = new (zone) TryInfo(catch_env); | 138 TryInfo* try_info = new (zone) TryInfo(catch_env); |
139 return {pc, kControlTry, stack_depth, end_env, | 139 return {pc, kControlTry, stack_depth, end_env, |
140 nullptr, try_info, previous_catch, {0, {NO_VALUE}}}; | 140 nullptr, try_info, previous_catch, {0, {NO_VALUE}}}; |
141 } | 141 } |
142 }; | 142 }; |
143 | 143 |
144 // Macros that build nodes only if there is a graph and the current SSA | 144 // Macros that build nodes only if there is a graph and the current SSA |
145 // environment is reachable from start. This avoids problems with malformed | 145 // environment is reachable from start. This avoids problems with malformed |
(...skipping 503 matching lines...) Loading... | |
649 } else if (c->merge.arity > 1) { | 649 } else if (c->merge.arity > 1) { |
650 c->merge.vals.array = zone_->NewArray<Value>(c->merge.arity); | 650 c->merge.vals.array = zone_->NewArray<Value>(c->merge.arity); |
651 for (unsigned i = 0; i < c->merge.arity; i++) { | 651 for (unsigned i = 0; i < c->merge.arity; i++) { |
652 c->merge.vals.array[i] = {pc_, nullptr, sig_->GetReturn(i)}; | 652 c->merge.vals.array[i] = {pc_, nullptr, sig_->GetReturn(i)}; |
653 } | 653 } |
654 } | 654 } |
655 } | 655 } |
656 | 656 |
657 if (pc_ >= end_) return; // Nothing to do. | 657 if (pc_ >= end_) return; // Nothing to do. |
658 | 658 |
659 while (true) { // decoding loop. | 659 while (true) { // decoding loop. |
Clemens Hammacher
2017/01/18 15:46:26
You can also simplify this loop by removing the if
titzer
2017/01/18 17:22:17
Yeah, I originally did this on purpose as a manual
| |
660 unsigned len = 1; | 660 unsigned len = 1; |
661 WasmOpcode opcode = static_cast<WasmOpcode>(*pc_); | 661 WasmOpcode opcode = static_cast<WasmOpcode>(*pc_); |
662 if (!WasmOpcodes::IsPrefixOpcode(opcode)) { | 662 if (!WasmOpcodes::IsPrefixOpcode(opcode)) { |
663 TRACE(" @%-8d #%02x:%-20s|", startrel(pc_), opcode, | 663 TRACE(" @%-8d #%02x:%-20s|", startrel(pc_), opcode, |
664 WasmOpcodes::ShortOpcodeName(opcode)); | 664 WasmOpcodes::ShortOpcodeName(opcode)); |
665 } | 665 } |
666 | 666 |
667 FunctionSig* sig = WasmOpcodes::Signature(opcode); | 667 FunctionSig* sig = WasmOpcodes::Signature(opcode); |
668 if (sig) { | 668 if (sig) { |
669 BuildSimpleOperator(opcode, sig); | 669 BuildSimpleOperator(opcode, sig); |
(...skipping 134 matching lines...) Loading... | |
804 // A loop just leaves the values on the stack. | 804 // A loop just leaves the values on the stack. |
805 TypeCheckLoopFallThru(c); | 805 TypeCheckLoopFallThru(c); |
806 PopControl(); | 806 PopControl(); |
807 SetEnv("loop:end", ssa_env_); | 807 SetEnv("loop:end", ssa_env_); |
808 break; | 808 break; |
809 } | 809 } |
810 if (c->is_if()) { | 810 if (c->is_if()) { |
811 if (c->false_env != nullptr) { | 811 if (c->false_env != nullptr) { |
812 // End the true branch of a one-armed if. | 812 // End the true branch of a one-armed if. |
813 Goto(c->false_env, c->end_env); | 813 Goto(c->false_env, c->end_env); |
814 if (ssa_env_->go() && | 814 if (ssa_env_->go() && stack_.size() != c->stack_depth) { |
815 static_cast<int>(stack_.size()) != c->stack_depth) { | |
816 error("end of if expected empty stack"); | 815 error("end of if expected empty stack"); |
817 stack_.resize(c->stack_depth); | 816 stack_.resize(c->stack_depth); |
818 } | 817 } |
819 if (c->merge.arity > 0) { | 818 if (c->merge.arity > 0) { |
820 error("non-void one-armed if"); | 819 error("non-void one-armed if"); |
821 } | 820 } |
822 name = "if:merge"; | 821 name = "if:merge"; |
823 } else { | 822 } else { |
824 // End the false branch of a two-armed if. | 823 // End the false branch of a two-armed if. |
825 name = "if_else:merge"; | 824 name = "if_else:merge"; |
(...skipping 13 matching lines...) Loading... | |
839 // Push the end values onto the stack. | 838 // Push the end values onto the stack. |
840 stack_.resize(c->stack_depth); | 839 stack_.resize(c->stack_depth); |
841 if (c->merge.arity == 1) { | 840 if (c->merge.arity == 1) { |
842 stack_.push_back(c->merge.vals.first); | 841 stack_.push_back(c->merge.vals.first); |
843 } else { | 842 } else { |
844 for (unsigned i = 0; i < c->merge.arity; i++) { | 843 for (unsigned i = 0; i < c->merge.arity; i++) { |
845 stack_.push_back(c->merge.vals.array[i]); | 844 stack_.push_back(c->merge.vals.array[i]); |
846 } | 845 } |
847 } | 846 } |
848 | 847 |
849 PopControl(); | 848 if (control_.size() == 1) { |
850 | |
851 if (control_.empty()) { | |
852 // If the last (implicit) control was popped, check we are at end. | 849 // If the last (implicit) control was popped, check we are at end. |
rossberg
2017/01/18 16:21:42
Nit: s/was/is/
titzer
2017/01/18 17:22:17
Done.
| |
853 if (pc_ + 1 != end_) { | 850 if (pc_ + 1 != end_) { |
854 error(pc_, pc_ + 1, "trailing code after function end"); | 851 error(pc_, pc_ + 1, "trailing code after function end"); |
852 break; | |
855 } | 853 } |
856 last_end_found_ = true; | 854 last_end_found_ = true; |
857 if (ssa_env_->go()) { | 855 if (ssa_env_->go()) { |
858 // The result of the block is the return value. | 856 // The result of the block is the return value. |
859 TRACE(" @%-8d #xx:%-20s|", startrel(pc_), "ImplicitReturn"); | 857 TRACE(" @%-8d #xx:%-20s|", startrel(pc_), "ImplicitReturn"); |
860 DoReturn(); | 858 DoReturn(); |
861 TRACE("\n"); | 859 TRACE("\n"); |
862 } | 860 } |
863 return; | |
864 } | 861 } |
862 PopControl(); | |
865 break; | 863 break; |
866 } | 864 } |
867 case kExprSelect: { | 865 case kExprSelect: { |
868 Value cond = Pop(2, kWasmI32); | 866 Value cond = Pop(2, kWasmI32); |
869 Value fval = Pop(); | 867 Value fval = Pop(); |
870 Value tval = Pop(); | 868 Value tval = Pop(); |
871 if (tval.type == kWasmStmt || tval.type != fval.type) { | 869 if (tval.type == kWasmStmt || tval.type != fval.type) { |
872 if (tval.type != kWasmEnd && fval.type != kWasmEnd) { | 870 if (tval.type != kWasmEnd && fval.type != kWasmEnd) { |
873 error("type mismatch in select"); | 871 error("type mismatch in select"); |
874 break; | 872 break; |
(...skipping 359 matching lines...) Loading... | |
1234 break; | 1232 break; |
1235 } | 1233 } |
1236 default: | 1234 default: |
1237 break; | 1235 break; |
1238 } | 1236 } |
1239 } | 1237 } |
1240 PrintF("\n"); | 1238 PrintF("\n"); |
1241 } | 1239 } |
1242 #endif | 1240 #endif |
1243 pc_ += len; | 1241 pc_ += len; |
1244 if (pc_ >= end_) { | 1242 if (pc_ >= end_) { |
Clemens Hammacher
2017/01/18 15:46:26
This condition could go away then, just put this a
titzer
2017/01/18 17:22:17
Done.
| |
1245 // End of code reached or exceeded. | 1243 // End of code reached or exceeded. |
1246 if (pc_ > end_ && ok()) error("Beyond end of code"); | 1244 if (pc_ > end_ && ok()) error("Beyond end of code"); |
1247 return; | 1245 return; |
1248 } | 1246 } |
1249 } // end decode loop | 1247 } // end decode loop |
1250 } | 1248 } |
1251 | 1249 |
1252 void EndControl() { ssa_env_->Kill(SsaEnv::kControlEnd); } | 1250 void EndControl() { ssa_env_->Kill(SsaEnv::kControlEnd); } |
1253 | 1251 |
1254 void SetBlockType(Control* c, BlockTypeOperand& operand) { | 1252 void SetBlockType(Control* c, BlockTypeOperand& operand) { |
(...skipping 24 matching lines...) Loading... | |
1279 } | 1277 } |
1280 return nullptr; | 1278 return nullptr; |
1281 } | 1279 } |
1282 } | 1280 } |
1283 | 1281 |
1284 ValueType GetReturnType(FunctionSig* sig) { | 1282 ValueType GetReturnType(FunctionSig* sig) { |
1285 return sig->return_count() == 0 ? kWasmStmt : sig->GetReturn(); | 1283 return sig->return_count() == 0 ? kWasmStmt : sig->GetReturn(); |
1286 } | 1284 } |
1287 | 1285 |
1288 void PushBlock(SsaEnv* end_env) { | 1286 void PushBlock(SsaEnv* end_env) { |
1289 const int stack_depth = static_cast<int>(stack_.size()); | |
1290 control_.emplace_back( | 1287 control_.emplace_back( |
1291 Control::Block(pc_, stack_depth, end_env, current_catch_)); | 1288 Control::Block(pc_, stack_.size(), end_env, current_catch_)); |
1292 } | 1289 } |
1293 | 1290 |
1294 void PushLoop(SsaEnv* end_env) { | 1291 void PushLoop(SsaEnv* end_env) { |
1295 const int stack_depth = static_cast<int>(stack_.size()); | |
1296 control_.emplace_back( | 1292 control_.emplace_back( |
1297 Control::Loop(pc_, stack_depth, end_env, current_catch_)); | 1293 Control::Loop(pc_, stack_.size(), end_env, current_catch_)); |
1298 } | 1294 } |
1299 | 1295 |
1300 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { | 1296 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { |
1301 const int stack_depth = static_cast<int>(stack_.size()); | |
1302 control_.emplace_back( | 1297 control_.emplace_back( |
1303 Control::If(pc_, stack_depth, end_env, false_env, current_catch_)); | 1298 Control::If(pc_, stack_.size(), end_env, false_env, current_catch_)); |
1304 } | 1299 } |
1305 | 1300 |
1306 void PushTry(SsaEnv* end_env, SsaEnv* catch_env) { | 1301 void PushTry(SsaEnv* end_env, SsaEnv* catch_env) { |
1307 const int stack_depth = static_cast<int>(stack_.size()); | 1302 control_.emplace_back(Control::Try(pc_, stack_.size(), end_env, zone_, |
1308 control_.emplace_back(Control::Try(pc_, stack_depth, end_env, zone_, | |
1309 catch_env, current_catch_)); | 1303 catch_env, current_catch_)); |
1310 current_catch_ = static_cast<int32_t>(control_.size() - 1); | 1304 current_catch_ = static_cast<int32_t>(control_.size() - 1); |
1311 } | 1305 } |
1312 | 1306 |
1313 void PopControl() { control_.pop_back(); } | 1307 void PopControl() { control_.pop_back(); } |
1314 | 1308 |
1315 int DecodeLoadMem(ValueType type, MachineType mem_type) { | 1309 int DecodeLoadMem(ValueType type, MachineType mem_type) { |
1316 if (!CheckHasMemory()) return 0; | 1310 if (!CheckHasMemory()) return 0; |
1317 MemoryAccessOperand operand(this, pc_, | 1311 MemoryAccessOperand operand(this, pc_, |
1318 ElementSizeLog2Of(mem_type.representation())); | 1312 ElementSizeLog2Of(mem_type.representation())); |
(...skipping 105 matching lines...) Loading... | |
1424 Push(sig->GetReturn(i), rets ? rets[i] : nullptr); | 1418 Push(sig->GetReturn(i), rets ? rets[i] : nullptr); |
1425 } | 1419 } |
1426 } | 1420 } |
1427 | 1421 |
1428 const char* SafeOpcodeNameAt(const byte* pc) { | 1422 const char* SafeOpcodeNameAt(const byte* pc) { |
1429 if (pc >= end_) return "<end>"; | 1423 if (pc >= end_) return "<end>"; |
1430 return WasmOpcodes::ShortOpcodeName(static_cast<WasmOpcode>(*pc)); | 1424 return WasmOpcodes::ShortOpcodeName(static_cast<WasmOpcode>(*pc)); |
1431 } | 1425 } |
1432 | 1426 |
1433 Value Pop(int index, ValueType expected) { | 1427 Value Pop(int index, ValueType expected) { |
1434 if (!ssa_env_->go()) { | |
1435 // Unreachable code is essentially not typechecked. | |
1436 return {pc_, nullptr, expected}; | |
1437 } | |
1438 Value val = Pop(); | 1428 Value val = Pop(); |
1439 if (val.type != expected) { | 1429 if (val.type != expected) { |
1440 if (val.type != kWasmEnd) { | 1430 if (val.type != kWasmEnd) { |
1441 error(pc_, val.pc, "%s[%d] expected type %s, found %s of type %s", | 1431 error(pc_, val.pc, "%s[%d] expected type %s, found %s of type %s", |
1442 SafeOpcodeNameAt(pc_), index, WasmOpcodes::TypeName(expected), | 1432 SafeOpcodeNameAt(pc_), index, WasmOpcodes::TypeName(expected), |
1443 SafeOpcodeNameAt(val.pc), WasmOpcodes::TypeName(val.type)); | 1433 SafeOpcodeNameAt(val.pc), WasmOpcodes::TypeName(val.type)); |
1444 } | 1434 } |
1445 } | 1435 } |
1446 return val; | 1436 return val; |
1447 } | 1437 } |
1448 | 1438 |
1449 Value Pop() { | 1439 Value Pop() { |
1450 if (!ssa_env_->go()) { | |
1451 // Unreachable code is essentially not typechecked. | |
1452 return {pc_, nullptr, kWasmEnd}; | |
1453 } | |
1454 size_t limit = control_.empty() ? 0 : control_.back().stack_depth; | 1440 size_t limit = control_.empty() ? 0 : control_.back().stack_depth; |
1455 if (stack_.size() <= limit) { | 1441 if (stack_.size() <= limit) { |
1456 Value val = {pc_, nullptr, kWasmStmt}; | 1442 Value val = {pc_, nullptr, kWasmEnd}; |
1457 error(pc_, pc_, "%s found empty stack", SafeOpcodeNameAt(pc_)); | 1443 if (ssa_env_->go()) { |
1444 // Popping past the current control start in reachable code. | |
1445 error(pc_, pc_, "%s found empty stack", SafeOpcodeNameAt(pc_)); | |
1446 } | |
1458 return val; | 1447 return val; |
1459 } | 1448 } |
1460 Value val = stack_.back(); | 1449 Value val = stack_.back(); |
1461 stack_.pop_back(); | 1450 stack_.pop_back(); |
1462 return val; | 1451 return val; |
1463 } | 1452 } |
1464 | 1453 |
1465 Value PopUpTo(int stack_depth) { | |
1466 if (!ssa_env_->go()) { | |
1467 // Unreachable code is essentially not typechecked. | |
1468 return {pc_, nullptr, kWasmEnd}; | |
1469 } | |
1470 if (stack_depth == static_cast<int>(stack_.size())) { | |
1471 Value val = {pc_, nullptr, kWasmStmt}; | |
1472 return val; | |
1473 } else { | |
1474 DCHECK_LE(stack_depth, stack_.size()); | |
1475 Value val = Pop(); | |
1476 stack_.resize(stack_depth); | |
1477 return val; | |
1478 } | |
1479 } | |
1480 | |
1481 int baserel(const byte* ptr) { | 1454 int baserel(const byte* ptr) { |
1482 return base_ ? static_cast<int>(ptr - base_) : 0; | 1455 return base_ ? static_cast<int>(ptr - base_) : 0; |
1483 } | 1456 } |
1484 | 1457 |
1485 int startrel(const byte* ptr) { return static_cast<int>(ptr - start_); } | 1458 int startrel(const byte* ptr) { return static_cast<int>(ptr - start_); } |
1486 | 1459 |
1487 void BreakTo(unsigned depth) { | 1460 void BreakTo(unsigned depth) { |
1488 if (!ssa_env_->go()) return; | 1461 if (!ssa_env_->go()) return; |
1489 Control* c = &control_[control_.size() - depth - 1]; | 1462 Control* c = &control_[control_.size() - depth - 1]; |
1490 if (c->is_loop()) { | 1463 if (c->is_loop()) { |
(...skipping 10 matching lines...) Loading... | |
1501 return; | 1474 return; |
1502 } | 1475 } |
1503 MergeValuesInto(c); | 1476 MergeValuesInto(c); |
1504 } | 1477 } |
1505 } | 1478 } |
1506 | 1479 |
1507 void FallThruTo(Control* c) { | 1480 void FallThruTo(Control* c) { |
1508 if (!ssa_env_->go()) return; | 1481 if (!ssa_env_->go()) return; |
1509 // Merge the value(s) into the end of the block. | 1482 // Merge the value(s) into the end of the block. |
1510 int arity = static_cast<int>(c->merge.arity); | 1483 int arity = static_cast<int>(c->merge.arity); |
1511 if (c->stack_depth + arity != static_cast<int>(stack_.size())) { | 1484 if (c->stack_depth + arity != stack_.size()) { |
1512 error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d", | 1485 error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d", |
1513 arity, startrel(c->pc)); | 1486 arity, startrel(c->pc)); |
1514 return; | 1487 return; |
1515 } | 1488 } |
1516 MergeValuesInto(c); | 1489 MergeValuesInto(c); |
1517 } | 1490 } |
1518 | 1491 |
1519 inline Value& GetMergeValueFromStack(Control* c, int i) { | 1492 inline Value& GetMergeValueFromStack(Control* c, int i) { |
1520 return stack_[stack_.size() - c->merge.arity + i]; | 1493 return stack_[stack_.size() - c->merge.arity + i]; |
1521 } | 1494 } |
1522 | 1495 |
1523 void TypeCheckLoopFallThru(Control* c) { | 1496 void TypeCheckLoopFallThru(Control* c) { |
1524 if (!ssa_env_->go()) return; | 1497 if (!ssa_env_->go()) return; |
1525 // Fallthru must match arity exactly. | 1498 // Fallthru must match arity exactly. |
1526 int arity = static_cast<int>(c->merge.arity); | 1499 int arity = static_cast<int>(c->merge.arity); |
1527 if (c->stack_depth + arity != static_cast<int>(stack_.size())) { | 1500 if (c->stack_depth + arity != stack_.size()) { |
1528 error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d", | 1501 error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d", |
1529 arity, startrel(c->pc)); | 1502 arity, startrel(c->pc)); |
1530 return; | 1503 return; |
1531 } | 1504 } |
1532 // Typecheck the values left on the stack. | 1505 // Typecheck the values left on the stack. |
1533 for (unsigned i = 0; i < c->merge.arity; i++) { | 1506 for (unsigned i = 0; i < c->merge.arity; i++) { |
1534 Value& val = GetMergeValueFromStack(c, i); | 1507 Value& val = GetMergeValueFromStack(c, i); |
1535 Value& old = | 1508 Value& old = |
1536 c->merge.arity == 1 ? c->merge.vals.first : c->merge.vals.array[i]; | 1509 c->merge.arity == 1 ? c->merge.vals.first : c->merge.vals.array[i]; |
1537 if (val.type != old.type) { | 1510 if (val.type != old.type) { |
(...skipping 499 matching lines...) Loading... | |
2037 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 2010 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
2038 const byte* start, const byte* end) { | 2011 const byte* start, const byte* end) { |
2039 Decoder decoder(start, end); | 2012 Decoder decoder(start, end); |
2040 return WasmDecoder::AnalyzeLoopAssignment(&decoder, start, | 2013 return WasmDecoder::AnalyzeLoopAssignment(&decoder, start, |
2041 static_cast<int>(num_locals), zone); | 2014 static_cast<int>(num_locals), zone); |
2042 } | 2015 } |
2043 | 2016 |
2044 } // namespace wasm | 2017 } // namespace wasm |
2045 } // namespace internal | 2018 } // namespace internal |
2046 } // namespace v8 | 2019 } // namespace v8 |
OLD | NEW |