| 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 69%
|
| rename from lib/compiler/implementation/operations.dart
|
| rename to lib/compiler/implementation/constant_system_dart.dart
|
| index 0fb34cb6d6513145fab4d2d01d3292855487c744..3756e12ce66d09344eb11ac000a406dfc28bf62a 100644
|
| --- a/lib/compiler/implementation/operations.dart
|
| +++ b/lib/compiler/implementation/constant_system_dart.dart
|
| @@ -2,15 +2,7 @@
|
| // 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.
|
|
|
| -interface Operation {
|
| - final SourceString name;
|
| - bool isUserDefinable();
|
| -}
|
| -
|
| -interface UnaryOperation extends Operation {
|
| - /** Returns [:null:] if it was unable to fold the operation. */
|
| - Constant fold(Constant constant);
|
| -}
|
| +const DART_CONSTANT_SYSTEM = const DartConstantSystem();
|
|
|
| class BitNotOperation implements UnaryOperation {
|
| final SourceString name = const SourceString('~');
|
| @@ -19,7 +11,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 +24,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,30 +41,25 @@ 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;
|
| }
|
| }
|
|
|
| -interface BinaryOperation extends Operation {
|
| - /** Returns [:null:] if it was unable to fold the operation. */
|
| - Constant fold(Constant left, Constant right);
|
| -}
|
| -
|
| /**
|
| * 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 +67,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 +96,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 +113,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 +121,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 +150,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 +210,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 +232,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 +273,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 +289,57 @@ 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 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();
|
| +}
|
|
|