Index: runtime/vm/parser.cc |
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
index 26f2ad7adb095eb5f22a4e1473c56684e15d4ad5..4df590bfcf42f38e8056d849d672cb839084346e 100644 |
--- a/runtime/vm/parser.cc |
+++ b/runtime/vm/parser.cc |
@@ -10552,6 +10552,21 @@ AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, |
} |
if (binary_op == Token::kIFNULL) { |
// Handle a ?? b. |
+ if (lhs->IsPotentiallyConst() && lhs->EvalConstExpr() != NULL) { |
Ivan Posva
2015/12/03 21:29:04
() ditto: Please keep the style of the file.
Lasse Reichstein Nielsen
2015/12/04 12:11:46
Done.
|
+ // If we know at compile time whether the lhs is null |
+ // and side-effect free, just reduce it to either the lhs or rhs. |
+ // This enables ?? to be compile-time constant. |
+ Instance& expr_value = Instance::ZoneHandle(Z); |
+ intptr_t lhs_pos = lhs->token_pos(); |
+ if (!GetCachedConstant(lhs_pos, &expr_value)) { |
+ expr_value = EvaluateConstExpr(lhs_pos, lhs).raw(); |
+ CacheConstantValue(lhs_pos, expr_value); |
+ } |
+ if (expr_value.IsNull()) return rhs; |
Ivan Posva
2015/12/03 21:29:04
ditto
Lasse Reichstein Nielsen
2015/12/04 12:11:46
Done.
|
+ return new(Z) LiteralNode(lhs_pos, expr_value); |
+ } |
+ // Otherwise create a temporary variable for the lhs so we can both |
+ // check it against null and return it if necessary. |
LetNode* result = new(Z) LetNode(op_pos); |
LocalVariable* left_temp = result->AddInitializer(lhs); |
const intptr_t no_pos = Scanner::kNoSourcePos; |