| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/verifier.h" | 5 #include "src/compiler/verifier.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <deque> | 8 #include <deque> |
| 9 #include <queue> | 9 #include <queue> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 class Verifier::Visitor { | 44 class Verifier::Visitor { |
| 45 public: | 45 public: |
| 46 Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {} | 46 Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {} |
| 47 | 47 |
| 48 void Check(Node* node); | 48 void Check(Node* node); |
| 49 | 49 |
| 50 Zone* zone; | 50 Zone* zone; |
| 51 Typing typing; | 51 Typing typing; |
| 52 | 52 |
| 53 private: | 53 private: |
| 54 // TODO(rossberg): Get rid of these once we got rid of NodeProperties. | |
| 55 Type* type_of(Node* node) { return NodeProperties::GetType(node); } | |
| 56 Node* ValueInput(Node* node, int i = 0) { | |
| 57 return NodeProperties::GetValueInput(node, i); | |
| 58 } | |
| 59 void CheckNotTyped(Node* node) { | 54 void CheckNotTyped(Node* node) { |
| 60 if (NodeProperties::IsTyped(node)) { | 55 if (NodeProperties::IsTyped(node)) { |
| 61 std::ostringstream str; | 56 std::ostringstream str; |
| 62 str << "TypeError: node #" << node->id() << ":" << *node->op() | 57 str << "TypeError: node #" << node->id() << ":" << *node->op() |
| 63 << " should never have a type"; | 58 << " should never have a type"; |
| 64 FATAL(str.str().c_str()); | 59 FATAL(str.str().c_str()); |
| 65 } | 60 } |
| 66 } | 61 } |
| 67 void CheckUpperIs(Node* node, Type* type) { | 62 void CheckUpperIs(Node* node, Type* type) { |
| 68 if (typing == TYPED && !type_of(node)->Is(type)) { | 63 if (typing == TYPED && !NodeProperties::GetType(node)->Is(type)) { |
| 69 std::ostringstream str; | 64 std::ostringstream str; |
| 70 str << "TypeError: node #" << node->id() << ":" << *node->op() | 65 str << "TypeError: node #" << node->id() << ":" << *node->op() |
| 71 << " type "; | 66 << " type "; |
| 72 type_of(node)->PrintTo(str); | 67 NodeProperties::GetType(node)->PrintTo(str); |
| 73 str << " is not "; | 68 str << " is not "; |
| 74 type->PrintTo(str); | 69 type->PrintTo(str); |
| 75 FATAL(str.str().c_str()); | 70 FATAL(str.str().c_str()); |
| 76 } | 71 } |
| 77 } | 72 } |
| 78 void CheckUpperMaybe(Node* node, Type* type) { | 73 void CheckUpperMaybe(Node* node, Type* type) { |
| 79 if (typing == TYPED && !type_of(node)->Maybe(type)) { | 74 if (typing == TYPED && !NodeProperties::GetType(node)->Maybe(type)) { |
| 80 std::ostringstream str; | 75 std::ostringstream str; |
| 81 str << "TypeError: node #" << node->id() << ":" << *node->op() | 76 str << "TypeError: node #" << node->id() << ":" << *node->op() |
| 82 << " type "; | 77 << " type "; |
| 83 type_of(node)->PrintTo(str); | 78 NodeProperties::GetType(node)->PrintTo(str); |
| 84 str << " must intersect "; | 79 str << " must intersect "; |
| 85 type->PrintTo(str); | 80 type->PrintTo(str); |
| 86 FATAL(str.str().c_str()); | 81 FATAL(str.str().c_str()); |
| 87 } | 82 } |
| 88 } | 83 } |
| 89 void CheckValueInputIs(Node* node, int i, Type* type) { | 84 void CheckValueInputIs(Node* node, int i, Type* type) { |
| 90 Node* input = ValueInput(node, i); | 85 Node* input = NodeProperties::GetValueInput(node, i); |
| 91 if (typing == TYPED && !type_of(input)->Is(type)) { | 86 if (typing == TYPED && !NodeProperties::GetType(input)->Is(type)) { |
| 92 std::ostringstream str; | 87 std::ostringstream str; |
| 93 str << "TypeError: node #" << node->id() << ":" << *node->op() | 88 str << "TypeError: node #" << node->id() << ":" << *node->op() |
| 94 << "(input @" << i << " = " << input->opcode() << ":" | 89 << "(input @" << i << " = " << input->opcode() << ":" |
| 95 << input->op()->mnemonic() << ") type "; | 90 << input->op()->mnemonic() << ") type "; |
| 96 type_of(input)->PrintTo(str); | 91 NodeProperties::GetType(input)->PrintTo(str); |
| 97 str << " is not "; | 92 str << " is not "; |
| 98 type->PrintTo(str); | 93 type->PrintTo(str); |
| 99 FATAL(str.str().c_str()); | 94 FATAL(str.str().c_str()); |
| 100 } | 95 } |
| 101 } | 96 } |
| 102 void CheckOutput(Node* node, Node* use, int count, const char* kind) { | 97 void CheckOutput(Node* node, Node* use, int count, const char* kind) { |
| 103 if (count <= 0) { | 98 if (count <= 0) { |
| 104 std::ostringstream str; | 99 std::ostringstream str; |
| 105 str << "GraphError: node #" << node->id() << ":" << *node->op() | 100 str << "GraphError: node #" << node->id() << ":" << *node->op() |
| 106 << " does not produce " << kind << " output used by node #" | 101 << " does not produce " << kind << " output used by node #" |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 CHECK_LT(1, effect_count); | 413 CHECK_LT(1, effect_count); |
| 419 break; | 414 break; |
| 420 } | 415 } |
| 421 case IrOpcode::kValueEffect: | 416 case IrOpcode::kValueEffect: |
| 422 // TODO(rossberg): what are the constraints on these? | 417 // TODO(rossberg): what are the constraints on these? |
| 423 break; | 418 break; |
| 424 case IrOpcode::kFinish: { | 419 case IrOpcode::kFinish: { |
| 425 // TODO(rossberg): what are the constraints on these? | 420 // TODO(rossberg): what are the constraints on these? |
| 426 // Type must be subsumed by input type. | 421 // Type must be subsumed by input type. |
| 427 if (typing == TYPED) { | 422 if (typing == TYPED) { |
| 428 CHECK(type_of(ValueInput(node))->Is(type_of(node))); | 423 Node* val = NodeProperties::GetValueInput(node, 0); |
| 424 CHECK(NodeProperties::GetType(val)->Is(NodeProperties::GetType(node))); |
| 429 } | 425 } |
| 430 break; | 426 break; |
| 431 } | 427 } |
| 432 case IrOpcode::kFrameState: | 428 case IrOpcode::kFrameState: |
| 433 // TODO(jarin): what are the constraints on these? | 429 // TODO(jarin): what are the constraints on these? |
| 434 CHECK_EQ(5, value_count); | 430 CHECK_EQ(5, value_count); |
| 435 CHECK_EQ(0, control_count); | 431 CHECK_EQ(0, control_count); |
| 436 CHECK_EQ(0, effect_count); | 432 CHECK_EQ(0, effect_count); |
| 437 CHECK_EQ(6, input_count); | 433 CHECK_EQ(6, input_count); |
| 438 break; | 434 break; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 case IrOpcode::kJSCreateCatchContext: | 554 case IrOpcode::kJSCreateCatchContext: |
| 559 case IrOpcode::kJSCreateWithContext: | 555 case IrOpcode::kJSCreateWithContext: |
| 560 case IrOpcode::kJSCreateBlockContext: | 556 case IrOpcode::kJSCreateBlockContext: |
| 561 case IrOpcode::kJSCreateModuleContext: | 557 case IrOpcode::kJSCreateModuleContext: |
| 562 case IrOpcode::kJSCreateScriptContext: { | 558 case IrOpcode::kJSCreateScriptContext: { |
| 563 // Type is Context, and operand is Internal. | 559 // Type is Context, and operand is Internal. |
| 564 Node* context = NodeProperties::GetContextInput(node); | 560 Node* context = NodeProperties::GetContextInput(node); |
| 565 // TODO(rossberg): This should really be Is(Internal), but the typer | 561 // TODO(rossberg): This should really be Is(Internal), but the typer |
| 566 // currently can't do backwards propagation. | 562 // currently can't do backwards propagation. |
| 567 CheckUpperMaybe(context, Type::Internal()); | 563 CheckUpperMaybe(context, Type::Internal()); |
| 568 if (typing == TYPED) CHECK(type_of(node)->IsContext()); | 564 if (typing == TYPED) CHECK(NodeProperties::GetType(node)->IsContext()); |
| 569 break; | 565 break; |
| 570 } | 566 } |
| 571 | 567 |
| 572 case IrOpcode::kJSCallConstruct: | 568 case IrOpcode::kJSCallConstruct: |
| 573 // Type is Receiver. | 569 // Type is Receiver. |
| 574 CheckUpperIs(node, Type::Receiver()); | 570 CheckUpperIs(node, Type::Receiver()); |
| 575 break; | 571 break; |
| 576 case IrOpcode::kJSCallFunction: | 572 case IrOpcode::kJSCallFunction: |
| 577 case IrOpcode::kJSCallRuntime: | 573 case IrOpcode::kJSCallRuntime: |
| 578 case IrOpcode::kJSYield: | 574 case IrOpcode::kJSYield: |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1212 replacement->op()->EffectOutputCount() > 0); | 1208 replacement->op()->EffectOutputCount() > 0); |
| 1213 DCHECK(!NodeProperties::IsFrameStateEdge(edge) || | 1209 DCHECK(!NodeProperties::IsFrameStateEdge(edge) || |
| 1214 replacement->opcode() == IrOpcode::kFrameState); | 1210 replacement->opcode() == IrOpcode::kFrameState); |
| 1215 } | 1211 } |
| 1216 | 1212 |
| 1217 #endif // DEBUG | 1213 #endif // DEBUG |
| 1218 | 1214 |
| 1219 } // namespace compiler | 1215 } // namespace compiler |
| 1220 } // namespace internal | 1216 } // namespace internal |
| 1221 } // namespace v8 | 1217 } // namespace v8 |
| OLD | NEW |