Index: lib/compiler/implementation/constant_system_dart.dart |
diff --git a/lib/compiler/implementation/operations.dart b/lib/compiler/implementation/constant_system_dart.dart |
similarity index 61% |
rename from lib/compiler/implementation/operations.dart |
rename to lib/compiler/implementation/constant_system_dart.dart |
index 0fb34cb6d6513145fab4d2d01d3292855487c744..65528043de6d67a0d27b2bf1cbc44dd0386cece3 100644 |
--- a/lib/compiler/implementation/operations.dart |
+++ b/lib/compiler/implementation/constant_system_dart.dart |
@@ -2,6 +2,8 @@ |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |
+const DART_CONSTANT_SYSTEM = const DartConstantSystem(); |
+ |
interface Operation { |
final SourceString name; |
bool isUserDefinable(); |
@@ -19,7 +21,7 @@ class BitNotOperation implements UnaryOperation { |
Constant fold(Constant constant) { |
if (constant.isInt()) { |
IntConstant intConstant = constant; |
- return new IntConstant(~intConstant.value); |
+ return DART_CONSTANT_SYSTEM.createInt(~intConstant.value); |
} |
return null; |
} |
@@ -32,11 +34,11 @@ class NegateOperation implements UnaryOperation { |
Constant fold(Constant constant) { |
if (constant.isInt()) { |
IntConstant intConstant = constant; |
- return new IntConstant(-intConstant.value); |
+ return DART_CONSTANT_SYSTEM.createInt(-intConstant.value); |
} |
if (constant.isDouble()) { |
DoubleConstant doubleConstant = constant; |
- return new DoubleConstant(-doubleConstant.value); |
+ return DART_CONSTANT_SYSTEM.createDouble(-doubleConstant.value); |
} |
return null; |
} |
@@ -49,7 +51,7 @@ class NotOperation implements UnaryOperation { |
Constant fold(Constant constant) { |
if (constant.isBool()) { |
BoolConstant boolConstant = constant; |
- return boolConstant.negate(); |
+ return DART_CONSTANT_SYSTEM.createBool(!boolConstant.value); |
} |
return null; |
} |
@@ -63,16 +65,16 @@ interface BinaryOperation extends Operation { |
/** |
* Operations that only work if both arguments are integers. |
*/ |
-class BinaryIntOperation implements BinaryOperation { |
+class BinaryBitOperation implements BinaryOperation { |
bool isUserDefinable() => true; |
- const BinaryIntOperation(); |
+ const BinaryBitOperation(); |
Constant fold(Constant left, Constant right) { |
if (left.isInt() && right.isInt()) { |
IntConstant leftInt = left; |
IntConstant rightInt = right; |
int resultValue = foldInts(leftInt.value, rightInt.value); |
if (resultValue === null) return null; |
- return new IntConstant(resultValue); |
+ return DART_CONSTANT_SYSTEM.createInt(resultValue); |
} |
return null; |
} |
@@ -80,25 +82,25 @@ class BinaryIntOperation implements BinaryOperation { |
abstract int foldInts(int left, int right); |
} |
-class BitOrOperation extends BinaryIntOperation { |
+class BitOrOperation extends BinaryBitOperation { |
final SourceString name = const SourceString('|'); |
const BitOrOperation(); |
int foldInts(int left, int right) => left | right; |
} |
-class BitAndOperation extends BinaryIntOperation { |
+class BitAndOperation extends BinaryBitOperation { |
final SourceString name = const SourceString('&'); |
const BitAndOperation(); |
int foldInts(int left, int right) => left & right; |
} |
-class BitXorOperation extends BinaryIntOperation { |
+class BitXorOperation extends BinaryBitOperation { |
final SourceString name = const SourceString('^'); |
const BitXorOperation(); |
int foldInts(int left, int right) => left ^ right; |
} |
-class ShiftLeftOperation extends BinaryIntOperation { |
+class ShiftLeftOperation extends BinaryBitOperation { |
final SourceString name = const SourceString('<<'); |
const ShiftLeftOperation(); |
int foldInts(int left, int right) { |
@@ -109,7 +111,7 @@ class ShiftLeftOperation extends BinaryIntOperation { |
} |
} |
-class ShiftRightOperation extends BinaryIntOperation { |
+class ShiftRightOperation extends BinaryBitOperation { |
final SourceString name = const SourceString('>>'); |
const ShiftRightOperation(); |
int foldInts(int left, int right) { |
@@ -126,7 +128,7 @@ class BinaryBoolOperation implements BinaryOperation { |
BoolConstant leftBool = left; |
BoolConstant rightBool = right; |
bool resultValue = foldBools(leftBool.value, rightBool.value); |
- return new BoolConstant(resultValue); |
+ return DART_CONSTANT_SYSTEM.createBool(resultValue); |
} |
return null; |
} |
@@ -134,15 +136,15 @@ class BinaryBoolOperation implements BinaryOperation { |
abstract bool foldBools(bool left, bool right); |
} |
-class BooleanAnd extends BinaryBoolOperation { |
+class BooleanAndOperation extends BinaryBoolOperation { |
final SourceString name = const SourceString('&&'); |
- const BooleanAnd(); |
+ const BooleanAndOperation(); |
bool foldBools(bool left, bool right) => left && right; |
} |
-class BooleanOr extends BinaryBoolOperation { |
+class BooleanOrOperation extends BinaryBoolOperation { |
final SourceString name = const SourceString('||'); |
- const BooleanOr(); |
+ const BooleanOrOperation(); |
bool foldBools(bool left, bool right) => left || right; |
} |
@@ -163,9 +165,9 @@ class ArithmeticNumOperation implements BinaryOperation { |
if (foldedValue === null) return null; |
if (left.isInt() && right.isInt() && !isDivide()) { |
assert(foldedValue is int); |
- return new IntConstant(foldedValue); |
+ return DART_CONSTANT_SYSTEM.createInt(foldedValue); |
} else { |
- return new DoubleConstant(foldedValue); |
+ return DART_CONSTANT_SYSTEM.createDouble(foldedValue); |
} |
} |
return null; |
@@ -223,11 +225,13 @@ class AddOperation implements BinaryOperation { |
if (left.isInt() && right.isInt()) { |
IntConstant leftInt = left; |
IntConstant rightInt = right; |
- return new IntConstant(leftInt.value + rightInt.value); |
+ int result = leftInt.value + rightInt.value; |
+ return DART_CONSTANT_SYSTEM.createInt(result); |
} else if (left.isNum() && right.isNum()) { |
NumConstant leftNum = left; |
NumConstant rightNum = right; |
- return new DoubleConstant(leftNum.value + rightNum.value); |
+ double result = leftNum.value + rightNum.value; |
+ return DART_CONSTANT_SYSTEM.createDouble(result); |
} else { |
return null; |
} |
@@ -243,7 +247,7 @@ class RelationalNumOperation implements BinaryOperation { |
NumConstant rightNum = right; |
bool foldedValue = foldNums(leftNum.value, rightNum.value); |
assert(foldedValue != null); |
- return new BoolConstant(foldedValue); |
+ return DART_CONSTANT_SYSTEM.createBool(foldedValue); |
} |
} |
@@ -284,14 +288,15 @@ class EqualsOperation implements BinaryOperation { |
// and 1 == 1.0. |
NumConstant leftNum = left; |
NumConstant rightNum = right; |
- return new BoolConstant(leftNum.value == rightNum.value); |
+ bool result = leftNum.value == rightNum.value; |
+ return DART_CONSTANT_SYSTEM.createBool(result); |
} |
if (left.isConstructedObject()) { |
// Unless we know that the user-defined object does not implement the |
// equality operator we cannot fold here. |
return null; |
} |
- return new BoolConstant(left == right); |
+ return DART_CONSTANT_SYSTEM.createBool(left == right); |
} |
} |
@@ -299,11 +304,103 @@ class IdentityOperation implements BinaryOperation { |
final SourceString name = const SourceString('==='); |
bool isUserDefinable() => false; |
const IdentityOperation(); |
- Constant fold(Constant left, Constant right) { |
+ BoolConstant fold(Constant left, Constant right) { |
// In order to preserve runtime semantics which says that NaN !== NaN don't |
// constant fold NaN === NaN. Otherwise the output depends on inlined |
// variables and other optimizations. |
if (left.isNaN() && right.isNaN()) return null; |
- return new BoolConstant(left == right); |
+ return DART_CONSTANT_SYSTEM.createBool(left == right); |
} |
} |
+ |
+/** |
+ * A [ConstantSystem] is responsible for creating constants and folding them. |
+ */ |
+interface ConstantSystem { |
+ BinaryOperation get add(); |
+ BinaryOperation get bitAnd(); |
+ UnaryOperation get bitNot(); |
+ BinaryOperation get bitOr(); |
+ BinaryOperation get bitXor(); |
+ BinaryOperation get booleanAnd(); |
+ BinaryOperation get booleanOr(); |
+ BinaryOperation get divide(); |
+ BinaryOperation get equal(); |
+ BinaryOperation get greaterEqual(); |
+ BinaryOperation get greater(); |
+ BinaryOperation get identity(); |
+ BinaryOperation get lessEqual(); |
+ BinaryOperation get less(); |
+ BinaryOperation get modulo(); |
+ BinaryOperation get multiply(); |
+ UnaryOperation get negate(); |
+ UnaryOperation get not(); |
+ BinaryOperation get shiftLeft(); |
+ BinaryOperation get shiftRight(); |
+ BinaryOperation get subtract(); |
+ BinaryOperation get truncatingDivide(); |
+ |
+ Constant createInt(int i); |
+ Constant createDouble(double d); |
+ // We need a diagnostic node to report errors in case the string is malformed. |
+ Constant createString(DartString string, Node diagnosticNode); |
+ Constant createBool(bool value); |
+ Constant createNull(); |
+ |
+ /** Returns true if the [constant] is an integer at runtime. */ |
+ bool isInt(Constant constant); |
+ /** Returns true if the [constant] is a double at runtime. */ |
+ bool isDouble(Constant constant); |
+ /** Returns true if the [constant] is a string at runtime. */ |
+ bool isString(Constant constant); |
+ /** Returns true if the [constant] is a boolean at runtime. */ |
+ bool isBool(Constant constant); |
+ /** Returns true if the [constant] is null at runtime. */ |
+ bool isNull(Constant constant); |
+} |
+ |
+/** |
+ * A constant system implementing the Dart semantics. This system relies on |
+ * the underlying runtime-system. That is, if dart2js is run in an environment |
+ * that doesn't correctly implement Dart's semantics this constant system will |
+ * not return the correct values. |
+ */ |
+class DartConstantSystem implements ConstantSystem { |
+ const add = const AddOperation(); |
+ const bitAnd = const BitAndOperation(); |
+ const bitNot = const BitNotOperation(); |
+ const bitOr = const BitOrOperation(); |
+ const bitXor = const BitXorOperation(); |
+ const booleanAnd = const BooleanAndOperation(); |
+ const booleanOr = const BooleanOrOperation(); |
+ const divide = const DivideOperation(); |
+ const equal = const EqualsOperation(); |
+ const greaterEqual = const GreaterEqualOperation(); |
+ const greater = const GreaterOperation(); |
+ const identity = const IdentityOperation(); |
+ const lessEqual = const LessEqualOperation(); |
+ const less = const LessOperation(); |
+ const modulo = const ModuloOperation(); |
+ const multiply = const MultiplyOperation(); |
+ const negate = const NegateOperation(); |
+ const not = const NotOperation(); |
+ const shiftLeft = const ShiftLeftOperation(); |
+ const shiftRight = const ShiftRightOperation(); |
+ const subtract = const SubtractOperation(); |
+ const truncatingDivide = const TruncatingDivideOperation(); |
+ |
+ const DartConstantSystem(); |
+ |
+ IntConstant createInt(int i) => new IntConstant(i); |
+ DoubleConstant createDouble(double d) => new DoubleConstant(d); |
+ StringConstant createString(DartString string, Node diagnosticNode) |
+ => new StringConstant(string, diagnosticNode); |
+ BoolConstant createBool(bool value) => new BoolConstant(value); |
+ NullConstant createNull() => new NullConstant(); |
+ |
+ bool isInt(Constant constant) => constant.isInt(); |
+ bool isDouble(Constant constant) => constant.isDouble(); |
+ bool isString(Constant constant) => constant.isString(); |
+ bool isBool(Constant constant) => constant.isBool(); |
+ bool isNull(Constant constant) => constant.isNull(); |
+} |