| Index: lib/compiler/implementation/compile_time_constants.dart
|
| diff --git a/lib/compiler/implementation/compile_time_constants.dart b/lib/compiler/implementation/compile_time_constants.dart
|
| index 0b8a3769b80f947a6098954fce48999ee75f5121..ef67d1f8ec66039f24878216696225185a55bcb3 100644
|
| --- a/lib/compiler/implementation/compile_time_constants.dart
|
| +++ b/lib/compiler/implementation/compile_time_constants.dart
|
| @@ -24,6 +24,7 @@ class Constant implements Hashable {
|
| bool isSentinel() => false;
|
|
|
| bool isNaN() => false;
|
| + bool isMinusZero() => false;
|
|
|
| abstract void _writeJsCode(CodeBuffer buffer, ConstantHandler handler);
|
| /**
|
| @@ -193,6 +194,8 @@ class DoubleConstant extends NumConstant {
|
| const DoubleConstant._internal(this.value);
|
| bool isDouble() => true;
|
| bool isNaN() => value.isNaN();
|
| + // We need to check for the negative sign since -0.0 == 0.0.
|
| + bool isMinusZero() => value == 0.0 && value.isNegative();
|
|
|
| void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) {
|
| if (value.isNaN()) {
|
| @@ -230,11 +233,6 @@ class BoolConstant extends PrimitiveConstant {
|
| const BoolConstant._internal();
|
| bool isBool() => true;
|
|
|
| - BoolConstant unaryFold(String op) {
|
| - if (op == "!") return new BoolConstant(!value);
|
| - return null;
|
| - }
|
| -
|
| abstract BoolConstant negate();
|
| }
|
|
|
| @@ -534,6 +532,8 @@ class ConstructedConstant extends ObjectConstant {
|
| * optional parameters.
|
| */
|
| class ConstantHandler extends CompilerTask {
|
| + final ConstantSystem constantSystem;
|
| +
|
| /**
|
| * Contains the initial value of fields. Must contain all static and global
|
| * initializations of const fields. May contain eagerly compiled values for
|
| @@ -551,7 +551,7 @@ class ConstantHandler extends CompilerTask {
|
| final Set<VariableElement> lazyStatics;
|
|
|
|
|
| - ConstantHandler(Compiler compiler)
|
| + ConstantHandler(Compiler compiler, this.constantSystem)
|
| : initialVariableValues = new Map<VariableElement, Dynamic>(),
|
| compiledConstants = new Map<Constant, String>(),
|
| pendingVariables = new Set<VariableElement>(),
|
| @@ -670,8 +670,8 @@ class ConstantHandler extends CompilerTask {
|
| [bool isConst]) {
|
| return measure(() {
|
| assert(node !== null);
|
| - CompileTimeConstantEvaluator evaluator =
|
| - new CompileTimeConstantEvaluator(definitions, compiler, isConst);
|
| + CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
|
| + constantSystem, definitions, compiler, isConst);
|
| return evaluator.evaluate(node);
|
| });
|
| }
|
| @@ -682,7 +682,9 @@ class ConstantHandler extends CompilerTask {
|
| assert(node !== null);
|
| try {
|
| TryCompileTimeConstantEvaluator evaluator =
|
| - new TryCompileTimeConstantEvaluator(definitions, compiler);
|
| + new TryCompileTimeConstantEvaluator(constantSystem,
|
| + definitions,
|
| + compiler);
|
| return evaluator.evaluate(node);
|
| } on CompileTimeConstantError catch (exn) {
|
| return null;
|
| @@ -824,10 +826,14 @@ class ConstantHandler extends CompilerTask {
|
|
|
| class CompileTimeConstantEvaluator extends AbstractVisitor {
|
| bool isEvaluatingConstant;
|
| + final ConstantSystem constantSystem;
|
| final TreeElements elements;
|
| final Compiler compiler;
|
|
|
| - CompileTimeConstantEvaluator(this.elements, this.compiler, [bool isConst])
|
| + CompileTimeConstantEvaluator(this.constantSystem,
|
| + this.elements,
|
| + this.compiler,
|
| + [bool isConst])
|
| : this.isEvaluatingConstant = isConst;
|
|
|
| Constant evaluate(Node node) {
|
| @@ -848,15 +854,15 @@ class CompileTimeConstantEvaluator extends AbstractVisitor {
|
| }
|
|
|
| Constant visitLiteralBool(LiteralBool node) {
|
| - return new BoolConstant(node.value);
|
| + return constantSystem.createBool(node.value);
|
| }
|
|
|
| Constant visitLiteralDouble(LiteralDouble node) {
|
| - return new DoubleConstant(node.value);
|
| + return constantSystem.createDouble(node.value);
|
| }
|
|
|
| Constant visitLiteralInt(LiteralInt node) {
|
| - return new IntConstant(node.value);
|
| + return constantSystem.createInt(node.value);
|
| }
|
|
|
| Constant visitLiteralList(LiteralList node) {
|
| @@ -924,19 +930,19 @@ class CompileTimeConstantEvaluator extends AbstractVisitor {
|
| }
|
|
|
| Constant visitLiteralNull(LiteralNull node) {
|
| - return new NullConstant();
|
| + return constantSystem.createNull();
|
| }
|
|
|
| Constant visitLiteralString(LiteralString node) {
|
| - return new StringConstant(node.dartString, node);
|
| + return constantSystem.createString(node.dartString, node);
|
| }
|
|
|
| Constant visitStringJuxtaposition(StringJuxtaposition node) {
|
| StringConstant left = evaluate(node.first);
|
| StringConstant right = evaluate(node.second);
|
| if (left == null || right == null) return null;
|
| - return new StringConstant(new DartString.concat(left.value, right.value),
|
| - node);
|
| + return constantSystem.createString(
|
| + new DartString.concat(left.value, right.value), node);
|
| }
|
|
|
| Constant visitStringInterpolation(StringInterpolation node) {
|
| @@ -960,7 +966,7 @@ class CompileTimeConstantEvaluator extends AbstractVisitor {
|
| if (partString == null) return null;
|
| accumulator = new DartString.concat(accumulator, partString.value);
|
| };
|
| - return new StringConstant(accumulator, node);
|
| + return constantSystem.createString(accumulator, node);
|
| }
|
|
|
| // TODO(floitsch): provide better error-messages.
|
| @@ -993,13 +999,13 @@ class CompileTimeConstantEvaluator extends AbstractVisitor {
|
| Constant folded;
|
| switch (op.source.stringValue) {
|
| case "!":
|
| - folded = const NotOperation().fold(receiverConstant);
|
| + folded = constantSystem.not.fold(receiverConstant);
|
| break;
|
| case "-":
|
| - folded = const NegateOperation().fold(receiverConstant);
|
| + folded = constantSystem.negate.fold(receiverConstant);
|
| break;
|
| case "~":
|
| - folded = const BitNotOperation().fold(receiverConstant);
|
| + folded = constantSystem.bitNot.fold(receiverConstant);
|
| break;
|
| default:
|
| compiler.internalError("Unexpected operator.", node: op);
|
| @@ -1016,69 +1022,69 @@ class CompileTimeConstantEvaluator extends AbstractVisitor {
|
| Constant folded = null;
|
| switch (op.source.stringValue) {
|
| case "+":
|
| - folded = const AddOperation().fold(left, right);
|
| + folded = constantSystem.add.fold(left, right);
|
| break;
|
| case "-":
|
| - folded = const SubtractOperation().fold(left, right);
|
| + folded = constantSystem.subtract.fold(left, right);
|
| break;
|
| case "*":
|
| - folded = const MultiplyOperation().fold(left, right);
|
| + folded = constantSystem.multiply.fold(left, right);
|
| break;
|
| case "/":
|
| - folded = const DivideOperation().fold(left, right);
|
| + folded = constantSystem.divide.fold(left, right);
|
| break;
|
| case "%":
|
| - folded = const ModuloOperation().fold(left, right);
|
| + folded = constantSystem.modulo.fold(left, right);
|
| break;
|
| case "~/":
|
| - folded = const TruncatingDivideOperation().fold(left, right);
|
| + folded = constantSystem.truncatingDivide.fold(left, right);
|
| break;
|
| case "|":
|
| - folded = const BitOrOperation().fold(left, right);
|
| + folded = constantSystem.bitOr.fold(left, right);
|
| break;
|
| case "&":
|
| - folded = const BitAndOperation().fold(left, right);
|
| + folded = constantSystem.bitAnd.fold(left, right);
|
| break;
|
| case "^":
|
| - folded = const BitXorOperation().fold(left, right);
|
| + folded = constantSystem.bitXor.fold(left, right);
|
| break;
|
| case "||":
|
| - folded = const BooleanOr().fold(left, right);
|
| + folded = constantSystem.booleanOr.fold(left, right);
|
| break;
|
| case "&&":
|
| - folded = const BooleanAnd().fold(left, right);
|
| + folded = constantSystem.booleanAnd.fold(left, right);
|
| break;
|
| case "<<":
|
| - folded = const ShiftLeftOperation().fold(left, right);
|
| + folded = constantSystem.shiftLeft.fold(left, right);
|
| break;
|
| case ">>":
|
| - folded = const ShiftRightOperation().fold(left, right);
|
| + folded = constantSystem.shiftRight.fold(left, right);
|
| break;
|
| case "<":
|
| - folded = const LessOperation().fold(left, right);
|
| + folded = constantSystem.less.fold(left, right);
|
| break;
|
| case "<=":
|
| - folded = const LessEqualOperation().fold(left, right);
|
| + folded = constantSystem.lessEqual.fold(left, right);
|
| break;
|
| case ">":
|
| - folded = const GreaterOperation().fold(left, right);
|
| + folded = constantSystem.greater.fold(left, right);
|
| break;
|
| case ">=":
|
| - folded = const GreaterEqualOperation().fold(left, right);
|
| + folded = constantSystem.greaterEqual.fold(left, right);
|
| break;
|
| case "==":
|
| if (left.isPrimitive() && right.isPrimitive()) {
|
| - folded = const EqualsOperation().fold(left, right);
|
| + folded = constantSystem.equal.fold(left, right);
|
| }
|
| break;
|
| case "===":
|
| if (left.isPrimitive() && right.isPrimitive()) {
|
| - folded = const IdentityOperation().fold(left, right);
|
| + folded = constantSystem.identity.fold(left, right);
|
| }
|
| break;
|
| case "!=":
|
| if (left.isPrimitive() && right.isPrimitive()) {
|
| - BoolConstant areEquals = const EqualsOperation().fold(left, right);
|
| + BoolConstant areEquals = constantSystem.equal.fold(left, right);
|
| if (areEquals === null) {
|
| folded = null;
|
| } else {
|
| @@ -1089,7 +1095,7 @@ class CompileTimeConstantEvaluator extends AbstractVisitor {
|
| case "!==":
|
| if (left.isPrimitive() && right.isPrimitive()) {
|
| BoolConstant areIdentical =
|
| - const IdentityOperation().fold(left, right);
|
| + constantSystem.identity.fold(left, right);
|
| if (areIdentical === null) {
|
| folded = null;
|
| } else {
|
| @@ -1144,7 +1150,7 @@ class CompileTimeConstantEvaluator extends AbstractVisitor {
|
| List<Constant> arguments =
|
| evaluateArgumentsToConstructor(selector, send.arguments, constructor);
|
| ConstructorEvaluator evaluator =
|
| - new ConstructorEvaluator(constructor, compiler);
|
| + new ConstructorEvaluator(constructor, constantSystem, compiler);
|
| evaluator.evaluateConstructorFieldValues(arguments);
|
| List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
|
|
|
| @@ -1181,8 +1187,10 @@ class CompileTimeConstantEvaluator extends AbstractVisitor {
|
| }
|
|
|
| class TryCompileTimeConstantEvaluator extends CompileTimeConstantEvaluator {
|
| - TryCompileTimeConstantEvaluator(TreeElements elements, Compiler compiler):
|
| - super(elements, compiler, isConst: true);
|
| + TryCompileTimeConstantEvaluator(ConstantSystem constantSystem,
|
| + TreeElements elements,
|
| + Compiler compiler)
|
| + : super(constantSystem, elements, compiler, isConst: true);
|
|
|
| error(Node node) {
|
| // Just fail without reporting it anywhere.
|
| @@ -1196,11 +1204,14 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
|
| final Map<Element, Constant> definitions;
|
| final Map<Element, Constant> fieldValues;
|
|
|
| - ConstructorEvaluator(FunctionElement constructor, Compiler compiler)
|
| + ConstructorEvaluator(FunctionElement constructor,
|
| + ConstantSystem constantSystem,
|
| + Compiler compiler)
|
| : this.constructor = constructor,
|
| this.definitions = new Map<Element, Constant>(),
|
| this.fieldValues = new Map<Element, Constant>(),
|
| - super(compiler.resolver.resolveMethodElement(constructor),
|
| + super(constantSystem,
|
| + compiler.resolver.resolveMethodElement(constructor),
|
| compiler,
|
| isConst: true);
|
|
|
| @@ -1241,8 +1252,8 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
|
| List<Constant> compiledArguments =
|
| evaluateArgumentsToConstructor(selector, arguments, targetConstructor);
|
|
|
| - ConstructorEvaluator evaluator =
|
| - new ConstructorEvaluator(targetConstructor, compiler);
|
| + ConstructorEvaluator evaluator = new ConstructorEvaluator(
|
| + targetConstructor, constantSystem, compiler);
|
| evaluator.evaluateConstructorFieldValues(compiledArguments);
|
| // Copy over the fieldValues from the super/redirect-constructor.
|
| evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
|
|
|