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 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 // A loop just leaves the values on the stack. | 793 // A loop just leaves the values on the stack. |
794 TypeCheckLoopFallThru(c); | 794 TypeCheckLoopFallThru(c); |
795 PopControl(); | 795 PopControl(); |
796 SetEnv("loop:end", ssa_env_); | 796 SetEnv("loop:end", ssa_env_); |
797 break; | 797 break; |
798 } | 798 } |
799 if (c->is_if()) { | 799 if (c->is_if()) { |
800 if (c->false_env != nullptr) { | 800 if (c->false_env != nullptr) { |
801 // End the true branch of a one-armed if. | 801 // End the true branch of a one-armed if. |
802 Goto(c->false_env, c->end_env); | 802 Goto(c->false_env, c->end_env); |
803 if (ssa_env_->go() && stack_.size() != c->stack_depth) { | 803 if (ssa_env_->go() && |
| 804 static_cast<int>(stack_.size()) != c->stack_depth) { |
804 error("end of if expected empty stack"); | 805 error("end of if expected empty stack"); |
805 stack_.resize(c->stack_depth); | 806 stack_.resize(c->stack_depth); |
806 } | 807 } |
807 if (c->merge.arity > 0) { | 808 if (c->merge.arity > 0) { |
808 error("non-void one-armed if"); | 809 error("non-void one-armed if"); |
809 } | 810 } |
810 name = "if:merge"; | 811 name = "if:merge"; |
811 } else { | 812 } else { |
812 // End the false branch of a two-armed if. | 813 // End the false branch of a two-armed if. |
813 name = "if_else:merge"; | 814 name = "if_else:merge"; |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 Value val = stack_.back(); | 1429 Value val = stack_.back(); |
1429 stack_.pop_back(); | 1430 stack_.pop_back(); |
1430 return val; | 1431 return val; |
1431 } | 1432 } |
1432 | 1433 |
1433 Value PopUpTo(int stack_depth) { | 1434 Value PopUpTo(int stack_depth) { |
1434 if (!ssa_env_->go()) { | 1435 if (!ssa_env_->go()) { |
1435 // Unreachable code is essentially not typechecked. | 1436 // Unreachable code is essentially not typechecked. |
1436 return {pc_, nullptr, kAstEnd}; | 1437 return {pc_, nullptr, kAstEnd}; |
1437 } | 1438 } |
1438 if (stack_depth == stack_.size()) { | 1439 if (stack_depth == static_cast<int>(stack_.size())) { |
1439 Value val = {pc_, nullptr, kAstStmt}; | 1440 Value val = {pc_, nullptr, kAstStmt}; |
1440 return val; | 1441 return val; |
1441 } else { | 1442 } else { |
1442 DCHECK_LE(stack_depth, static_cast<int>(stack_.size())); | 1443 DCHECK_LE(stack_depth, static_cast<int>(stack_.size())); |
1443 Value val = Pop(); | 1444 Value val = Pop(); |
1444 stack_.resize(stack_depth); | 1445 stack_.resize(stack_depth); |
1445 return val; | 1446 return val; |
1446 } | 1447 } |
1447 } | 1448 } |
1448 | 1449 |
1449 int baserel(const byte* ptr) { | 1450 int baserel(const byte* ptr) { |
1450 return base_ ? static_cast<int>(ptr - base_) : 0; | 1451 return base_ ? static_cast<int>(ptr - base_) : 0; |
1451 } | 1452 } |
1452 | 1453 |
1453 int startrel(const byte* ptr) { return static_cast<int>(ptr - start_); } | 1454 int startrel(const byte* ptr) { return static_cast<int>(ptr - start_); } |
1454 | 1455 |
1455 void BreakTo(unsigned depth) { | 1456 void BreakTo(unsigned depth) { |
1456 if (!ssa_env_->go()) return; | 1457 if (!ssa_env_->go()) return; |
1457 Control* c = &control_[control_.size() - depth - 1]; | 1458 Control* c = &control_[control_.size() - depth - 1]; |
1458 if (c->is_loop()) { | 1459 if (c->is_loop()) { |
1459 // This is the inner loop block, which does not have a value. | 1460 // This is the inner loop block, which does not have a value. |
1460 Goto(ssa_env_, c->end_env); | 1461 Goto(ssa_env_, c->end_env); |
1461 } else { | 1462 } else { |
1462 // Merge the value(s) into the end of the block. | 1463 // Merge the value(s) into the end of the block. |
1463 if (static_cast<size_t>(c->stack_depth + c->merge.arity) > | 1464 if (c->stack_depth + c->merge.arity > stack_.size()) { |
1464 stack_.size()) { | |
1465 error( | 1465 error( |
1466 pc_, pc_, | 1466 pc_, pc_, |
1467 "expected at least %d values on the stack for br to @%d, found %d", | 1467 "expected at least %d values on the stack for br to @%d, found %d", |
1468 c->merge.arity, startrel(c->pc), | 1468 c->merge.arity, startrel(c->pc), |
1469 static_cast<int>(stack_.size() - c->stack_depth)); | 1469 static_cast<int>(stack_.size() - c->stack_depth)); |
1470 return; | 1470 return; |
1471 } | 1471 } |
1472 MergeValuesInto(c); | 1472 MergeValuesInto(c); |
1473 } | 1473 } |
1474 } | 1474 } |
1475 | 1475 |
1476 void FallThruTo(Control* c) { | 1476 void FallThruTo(Control* c) { |
1477 if (!ssa_env_->go()) return; | 1477 if (!ssa_env_->go()) return; |
1478 // Merge the value(s) into the end of the block. | 1478 // Merge the value(s) into the end of the block. |
1479 int arity = static_cast<int>(c->merge.arity); | 1479 int arity = static_cast<int>(c->merge.arity); |
1480 if (c->stack_depth + arity != stack_.size()) { | 1480 if (c->stack_depth + arity != static_cast<int>(stack_.size())) { |
1481 error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d", | 1481 error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d", |
1482 arity, startrel(c->pc)); | 1482 arity, startrel(c->pc)); |
1483 return; | 1483 return; |
1484 } | 1484 } |
1485 MergeValuesInto(c); | 1485 MergeValuesInto(c); |
1486 } | 1486 } |
1487 | 1487 |
1488 inline Value& GetMergeValueFromStack(Control* c, int i) { | 1488 inline Value& GetMergeValueFromStack(Control* c, int i) { |
1489 return stack_[stack_.size() - c->merge.arity + i]; | 1489 return stack_[stack_.size() - c->merge.arity + i]; |
1490 } | 1490 } |
1491 | 1491 |
1492 void TypeCheckLoopFallThru(Control* c) { | 1492 void TypeCheckLoopFallThru(Control* c) { |
1493 if (!ssa_env_->go()) return; | 1493 if (!ssa_env_->go()) return; |
1494 // Fallthru must match arity exactly. | 1494 // Fallthru must match arity exactly. |
1495 int arity = static_cast<int>(c->merge.arity); | 1495 int arity = static_cast<int>(c->merge.arity); |
1496 if (c->stack_depth + arity != stack_.size()) { | 1496 if (c->stack_depth + arity != static_cast<int>(stack_.size())) { |
1497 error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d", | 1497 error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d", |
1498 arity, startrel(c->pc)); | 1498 arity, startrel(c->pc)); |
1499 return; | 1499 return; |
1500 } | 1500 } |
1501 // Typecheck the values left on the stack. | 1501 // Typecheck the values left on the stack. |
1502 for (unsigned i = 0; i < c->merge.arity; i++) { | 1502 for (unsigned i = 0; i < c->merge.arity; i++) { |
1503 Value& val = GetMergeValueFromStack(c, i); | 1503 Value& val = GetMergeValueFromStack(c, i); |
1504 Value& old = | 1504 Value& old = |
1505 c->merge.arity == 1 ? c->merge.vals.first : c->merge.vals.array[i]; | 1505 c->merge.arity == 1 ? c->merge.vals.first : c->merge.vals.array[i]; |
1506 if (val.type != old.type) { | 1506 if (val.type != old.type) { |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2035 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 2035 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
2036 const byte* start, const byte* end) { | 2036 const byte* start, const byte* end) { |
2037 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 2037 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
2038 WasmFullDecoder decoder(zone, nullptr, body); | 2038 WasmFullDecoder decoder(zone, nullptr, body); |
2039 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 2039 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
2040 } | 2040 } |
2041 | 2041 |
2042 } // namespace wasm | 2042 } // namespace wasm |
2043 } // namespace internal | 2043 } // namespace internal |
2044 } // namespace v8 | 2044 } // namespace v8 |
OLD | NEW |