Index: runtime/vm/ast.cc |
=================================================================== |
--- runtime/vm/ast.cc (revision 24703) |
+++ runtime/vm/ast.cc (working copy) |
@@ -110,6 +110,11 @@ |
} |
+bool LiteralNode::IsPotentiallyConst() const { |
+ return true; |
+} |
+ |
+ |
// TODO(srdjan): Add code for logical negation. |
AstNode* LiteralNode::ApplyUnaryOp(Token::Kind unary_op_kind) { |
if (unary_op_kind == Token::kNEGATE) { |
@@ -145,6 +150,24 @@ |
} |
+bool ComparisonNode::IsPotentiallyConst() const { |
+ switch (kind_) { |
+ case Token::kLT: |
+ case Token::kGT: |
+ case Token::kLTE: |
+ case Token::kGTE: |
+ case Token::kEQ: |
+ case Token::kNE: |
+ case Token::kEQ_STRICT: |
+ case Token::kNE_STRICT: |
+ return this->left()->IsPotentiallyConst() && |
+ this->right()->IsPotentiallyConst(); |
+ default: |
+ return false; |
+ } |
+} |
+ |
+ |
const Instance* ComparisonNode::EvalConstExpr() const { |
const Instance* left_val = this->left()->EvalConstExpr(); |
if (left_val == NULL) { |
@@ -216,6 +239,30 @@ |
} |
+bool BinaryOpNode::IsPotentiallyConst() const { |
+ switch (kind_) { |
+ case Token::kADD: |
+ case Token::kSUB: |
+ case Token::kMUL: |
+ case Token::kDIV: |
+ case Token::kMOD: |
+ case Token::kTRUNCDIV: |
+ case Token::kBIT_OR: |
+ case Token::kBIT_XOR: |
+ case Token::kBIT_AND: |
+ case Token::kSHL: |
+ case Token::kSHR: |
+ case Token::kOR: |
+ case Token::kAND: |
+ return this->left()->IsPotentiallyConst() && |
+ this->right()->IsPotentiallyConst(); |
+ default: |
+ UNREACHABLE(); |
+ return false; |
+ } |
+} |
+ |
+ |
const Instance* BinaryOpNode::EvalConstExpr() const { |
const Instance* left_val = this->left()->EvalConstExpr(); |
if (left_val == NULL) { |
@@ -294,6 +341,11 @@ |
} |
+bool UnaryOpNode::IsPotentiallyConst() const { |
+ return true; |
Ivan Posva
2013/07/03 20:23:42
Shouldn't the operand also be potentially const?
hausner
2013/07/03 21:20:54
Actually, yes. Fixed.
|
+} |
+ |
+ |
const Instance* UnaryOpNode::EvalConstExpr() const { |
const Instance* val = this->operand()->EvalConstExpr(); |
if (val == NULL) { |
@@ -313,6 +365,14 @@ |
} |
+bool ClosureNode::IsPotentiallyConst() const { |
+ if (function().IsImplicitStaticClosureFunction()) { |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+ |
const Instance* ClosureNode::EvalConstExpr() const { |
if (function().IsImplicitStaticClosureFunction()) { |
// Return a value that represents an instance. Only the type is relevant. |
@@ -347,6 +407,11 @@ |
} |
+bool LoadLocalNode::IsPotentiallyConst() const { |
+ return true; |
Ivan Posva
2013/07/03 20:23:42
Really? Thanks for the offline explanation, it wou
hausner
2013/07/03 21:20:54
Added comment and checked that the local variable/
|
+} |
+ |
+ |
const Instance* LoadLocalNode::EvalConstExpr() const { |
if (local().IsConst()) { |
return local().ConstValue(); |
@@ -447,6 +512,18 @@ |
} |
+bool StaticGetterNode::IsPotentiallyConst() const { |
+ const String& getter_name = |
+ String::Handle(Field::GetterName(this->field_name())); |
+ const Function& getter_func = |
+ Function::Handle(this->cls().LookupStaticFunction(getter_name)); |
+ if (getter_func.IsNull() || !getter_func.is_const()) { |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+ |
const Instance* StaticGetterNode::EvalConstExpr() const { |
const String& getter_name = |
String::Handle(Field::GetterName(this->field_name())); |