Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(698)

Unified Diff: lib/compiler/implementation/constant_system_dart.dart

Issue 10825386: Use JavaScript runtime semantics when constant folding. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Comment and test update. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();
+}

Powered by Google App Engine
This is Rietveld 408576698