Chromium Code Reviews| 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 d70bd83f3b5126ab021a1ee99ea2982f923a6bde..b934540239bf18cacf8da79d556a2b057ca60822 100644 |
| --- a/lib/compiler/implementation/compile_time_constants.dart |
| +++ b/lib/compiler/implementation/compile_time_constants.dart |
| @@ -22,6 +22,7 @@ class Constant implements Hashable { |
| bool isObject() => false; |
| bool isNaN() => false; |
| + bool isMinusZero() => false; |
| abstract void _writeJsCode(CodeBuffer buffer, ConstantHandler handler); |
| /** |
| @@ -140,6 +141,7 @@ class DoubleConstant extends NumConstant { |
| const DoubleConstant._internal(this.value); |
| bool isDouble() => true; |
| bool isNaN() => value.isNaN(); |
| + bool isMinusZero() => value == 0.0 && value.isNegative(); |
|
ngeoffray
2012/08/17 08:32:59
Please add a comment why -0.0 doesn't work.
floitsch
2012/09/03 14:34:52
Done.
|
| void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| if (value.isNaN()) { |
| @@ -177,11 +179,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(); |
| } |
| @@ -481,6 +478,7 @@ class ConstructedConstant extends ObjectConstant { |
| * optional parameters. |
| */ |
| class ConstantHandler extends CompilerTask { |
| + final FoldingOperations foldingOperations; |
| // Contains the initial value of fields. Must contain all static and global |
| // initializations of used fields. May contain caches for instance fields. |
| final Map<VariableElement, Constant> initialVariableValues; |
| @@ -491,7 +489,7 @@ class ConstantHandler extends CompilerTask { |
| // The set of variable elements that are in the process of being computed. |
| final Set<VariableElement> pendingVariables; |
| - ConstantHandler(Compiler compiler) |
| + ConstantHandler(Compiler compiler, this.foldingOperations) |
| : initialVariableValues = new Map<VariableElement, Dynamic>(), |
| compiledConstants = new Map<Constant, String>(), |
| pendingVariables = new Set<VariableElement>(), |
| @@ -564,8 +562,8 @@ class ConstantHandler extends CompilerTask { |
| Constant compileNodeWithDefinitions(Node node, TreeElements definitions) { |
| return measure(() { |
| assert(node !== null); |
| - CompileTimeConstantEvaluator evaluator = |
| - new CompileTimeConstantEvaluator(definitions, compiler); |
| + CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator( |
| + foldingOperations, definitions, compiler); |
| return evaluator.evaluate(node); |
| }); |
| } |
| @@ -576,7 +574,9 @@ class ConstantHandler extends CompilerTask { |
| assert(node !== null); |
| try { |
| TryCompileTimeConstantEvaluator evaluator = |
| - new TryCompileTimeConstantEvaluator(definitions, compiler); |
| + new TryCompileTimeConstantEvaluator(foldingOperations, |
| + definitions, |
| + compiler); |
| return evaluator.evaluate(node); |
| } catch (CompileTimeConstantError exn) { |
| return null; |
| @@ -713,10 +713,13 @@ class ConstantHandler extends CompilerTask { |
| } |
| class CompileTimeConstantEvaluator extends AbstractVisitor { |
| + final FoldingOperations foldingOperations; |
| final TreeElements elements; |
| final Compiler compiler; |
| - CompileTimeConstantEvaluator(this.elements, this.compiler); |
| + CompileTimeConstantEvaluator(this.foldingOperations, |
| + this.elements, |
| + this.compiler); |
| Constant evaluate(Node node) { |
| return node.accept(this); |
| @@ -850,13 +853,13 @@ class CompileTimeConstantEvaluator extends AbstractVisitor { |
| Constant folded; |
| switch (op.source.stringValue) { |
| case "!": |
| - folded = const NotOperation().fold(receiverConstant); |
| + folded = foldingOperations.not.fold(receiverConstant); |
| break; |
| case "-": |
| - folded = const NegateOperation().fold(receiverConstant); |
| + folded = foldingOperations.negate.fold(receiverConstant); |
| break; |
| case "~": |
| - folded = const BitNotOperation().fold(receiverConstant); |
| + folded = foldingOperations.bitNot.fold(receiverConstant); |
| break; |
| default: |
| compiler.internalError("Unexpected operator.", node: op); |
| @@ -872,69 +875,69 @@ class CompileTimeConstantEvaluator extends AbstractVisitor { |
| Constant folded = null; |
| switch (op.source.stringValue) { |
| case "+": |
| - folded = const AddOperation().fold(left, right); |
| + folded = foldingOperations.add.fold(left, right); |
| break; |
| case "-": |
| - folded = const SubtractOperation().fold(left, right); |
| + folded = foldingOperations.subtract.fold(left, right); |
| break; |
| case "*": |
| - folded = const MultiplyOperation().fold(left, right); |
| + folded = foldingOperations.multiply.fold(left, right); |
| break; |
| case "/": |
| - folded = const DivideOperation().fold(left, right); |
| + folded = foldingOperations.divide.fold(left, right); |
| break; |
| case "%": |
| - folded = const ModuloOperation().fold(left, right); |
| + folded = foldingOperations.modulo.fold(left, right); |
| break; |
| case "~/": |
| - folded = const TruncatingDivideOperation().fold(left, right); |
| + folded = foldingOperations.truncatingDivide.fold(left, right); |
| break; |
| case "|": |
| - folded = const BitOrOperation().fold(left, right); |
| + folded = foldingOperations.bitOr.fold(left, right); |
| break; |
| case "&": |
| - folded = const BitAndOperation().fold(left, right); |
| + folded = foldingOperations.bitAnd.fold(left, right); |
| break; |
| case "^": |
| - folded = const BitXorOperation().fold(left, right); |
| + folded = foldingOperations.bitXor.fold(left, right); |
| break; |
| case "||": |
| - folded = const BooleanOr().fold(left, right); |
| + folded = foldingOperations.booleanOr.fold(left, right); |
| break; |
| case "&&": |
| - folded = const BooleanAnd().fold(left, right); |
| + folded = foldingOperations.booleanAnd.fold(left, right); |
| break; |
| case "<<": |
| - folded = const ShiftLeftOperation().fold(left, right); |
| + folded = foldingOperations.shiftLeft.fold(left, right); |
| break; |
| case ">>": |
| - folded = const ShiftRightOperation().fold(left, right); |
| + folded = foldingOperations.shiftRight.fold(left, right); |
| break; |
| case "<": |
| - folded = const LessOperation().fold(left, right); |
| + folded = foldingOperations.less.fold(left, right); |
| break; |
| case "<=": |
| - folded = const LessEqualOperation().fold(left, right); |
| + folded = foldingOperations.lessEqual.fold(left, right); |
| break; |
| case ">": |
| - folded = const GreaterOperation().fold(left, right); |
| + folded = foldingOperations.greater.fold(left, right); |
| break; |
| case ">=": |
| - folded = const GreaterEqualOperation().fold(left, right); |
| + folded = foldingOperations.greaterEqual.fold(left, right); |
| break; |
| case "==": |
| if (left.isPrimitive() && right.isPrimitive()) { |
| - folded = const EqualsOperation().fold(left, right); |
| + folded = foldingOperations.equal.fold(left, right); |
| } |
| break; |
| case "===": |
| if (left.isPrimitive() && right.isPrimitive()) { |
| - folded = const IdentityOperation().fold(left, right); |
| + folded = foldingOperations.identity.fold(left, right); |
| } |
| break; |
| case "!=": |
| if (left.isPrimitive() && right.isPrimitive()) { |
| - BoolConstant areEquals = const EqualsOperation().fold(left, right); |
| + BoolConstant areEquals = foldingOperations.equal.fold(left, right); |
| if (areEquals === null) { |
| folded = null; |
| } else { |
| @@ -945,7 +948,7 @@ class CompileTimeConstantEvaluator extends AbstractVisitor { |
| case "!==": |
| if (left.isPrimitive() && right.isPrimitive()) { |
| BoolConstant areIdentical = |
| - const IdentityOperation().fold(left, right); |
| + foldingOperations.identity.fold(left, right); |
| if (areIdentical === null) { |
| folded = null; |
| } else { |
| @@ -998,7 +1001,7 @@ class CompileTimeConstantEvaluator extends AbstractVisitor { |
| List<Constant> arguments = |
| evaluateArgumentsToConstructor(selector, send.arguments, constructor); |
| ConstructorEvaluator evaluator = |
| - new ConstructorEvaluator(constructor, compiler); |
| + new ConstructorEvaluator(constructor, foldingOperations, compiler); |
| evaluator.evaluateConstructorFieldValues(arguments); |
| List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); |
| @@ -1023,8 +1026,10 @@ class CompileTimeConstantEvaluator extends AbstractVisitor { |
| } |
| class TryCompileTimeConstantEvaluator extends CompileTimeConstantEvaluator { |
| - TryCompileTimeConstantEvaluator(TreeElements elements, Compiler compiler): |
| - super(elements, compiler); |
| + TryCompileTimeConstantEvaluator(FoldingOperations foldingOperations, |
| + TreeElements elements, |
| + Compiler compiler): |
| + super(foldingOperations, elements, compiler); |
| error(Node node) { |
| // Just fail without reporting it anywhere. |
| @@ -1038,11 +1043,14 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator { |
| final Map<Element, Constant> definitions; |
| final Map<Element, Constant> fieldValues; |
| - ConstructorEvaluator(FunctionElement constructor, Compiler compiler) |
| + ConstructorEvaluator(FunctionElement constructor, |
| + FoldingOperations foldingOperations, |
| + Compiler compiler) |
| : this.constructor = constructor, |
| this.definitions = new Map<Element, Constant>(), |
| this.fieldValues = new Map<Element, Constant>(), |
| - super(compiler.resolver.resolveMethodElement(constructor), |
| + super(foldingOperations, |
| + compiler.resolver.resolveMethodElement(constructor), |
| compiler); |
| Constant visitSend(Send send) { |
| @@ -1082,8 +1090,8 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator { |
| List<Constant> compiledArguments = |
| evaluateArgumentsToConstructor(selector, arguments, targetConstructor); |
| - ConstructorEvaluator evaluator = |
| - new ConstructorEvaluator(targetConstructor, compiler); |
| + ConstructorEvaluator evaluator = new ConstructorEvaluator( |
| + targetConstructor, foldingOperations, compiler); |
| evaluator.evaluateConstructorFieldValues(compiledArguments); |
| // Copy over the fieldValues from the super/redirect-constructor. |
| evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); |