| Index: sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
|
| index 465a6c4cfcd4738850851a0b07d9ef693aa32853..d32d460e5881a3a000b2496a9fdac9b400973149 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
|
| @@ -322,12 +322,12 @@ class IrBuilder {
|
| return v;
|
| }
|
|
|
| - ir.Constant makeConst(ConstExp exp, Constant value) {
|
| - return new ir.Constant(exp, value);
|
| + ir.Constant makeConst(ConstExp exp) {
|
| + return new ir.Constant(exp);
|
| }
|
|
|
| ir.Constant makePrimConst(PrimitiveConstant value) {
|
| - return makeConst(new PrimitiveConstExp(value), value);
|
| + return makeConst(new PrimitiveConstExp(value));
|
| }
|
|
|
| // TODO(johnniwinther): Build constants directly through [ConstExp] when these
|
| @@ -465,8 +465,6 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> with IrBuilder {
|
| /// A stack of collectors for continues.
|
| final List<JumpCollector> continueCollectors;
|
|
|
| - ConstExpBuilder constantBuilder;
|
| -
|
| final List<ConstDeclaration> localConstants;
|
|
|
| FunctionElement currentFunction;
|
| @@ -480,7 +478,6 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> with IrBuilder {
|
| closureLocals = new DetectClosureVariables(elements),
|
| super(elements) {
|
| constantSystem = compiler.backend.constantSystem;
|
| - constantBuilder = new ConstExpBuilder(this);
|
| }
|
|
|
| /// Construct a delimited visitor for visiting a subtree.
|
| @@ -494,7 +491,6 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> with IrBuilder {
|
| sourceFile = parent.sourceFile,
|
| breakCollectors = parent.breakCollectors,
|
| continueCollectors = parent.continueCollectors,
|
| - constantBuilder = parent.constantBuilder,
|
| localConstants = parent.localConstants,
|
| currentFunction = parent.currentFunction,
|
| closureLocals = parent.closureLocals,
|
| @@ -517,7 +513,6 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> with IrBuilder {
|
| sourceFile = parent.sourceFile,
|
| breakCollectors = parent.breakCollectors,
|
| continueCollectors = parent.continueCollectors,
|
| - constantBuilder = parent.constantBuilder,
|
| localConstants = parent.localConstants,
|
| currentFunction = parent.currentFunction,
|
| closureLocals = parent.closureLocals,
|
| @@ -556,11 +551,7 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> with IrBuilder {
|
|
|
| List<ConstExp> defaults = new List<ConstExp>();
|
| signature.orderedOptionalParameters.forEach((ParameterElement element) {
|
| - if (element.initializer != null) {
|
| - defaults.add(constantBuilder.visit(element.initializer));
|
| - } else {
|
| - defaults.add(new PrimitiveConstExp(constantSystem.createNull()));
|
| - }
|
| + defaults.add(getConstantForVariable(element));
|
| });
|
|
|
| visit(function.body);
|
| @@ -1161,7 +1152,7 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> with IrBuilder {
|
| assert(!definition.arguments.isEmpty);
|
| assert(definition.arguments.tail.isEmpty);
|
| VariableElement element = elements[definition];
|
| - ConstExp value = constantBuilder.visit(definition.arguments.head);
|
| + ConstExp value = getConstantForVariable(element);
|
| localConstants.add(new ConstDeclaration(element, value));
|
| }
|
| } else {
|
| @@ -1282,14 +1273,22 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> with IrBuilder {
|
| return translateConstant(node);
|
| }
|
|
|
| - Constant getConstantForNode(ast.Node node) {
|
| - Constant constant =
|
| + ConstExp getConstantForNode(ast.Node node) {
|
| + ConstExp constant =
|
| compiler.backend.constantCompilerTask.compileNode(node, elements);
|
| assert(invariant(node, constant != null,
|
| message: 'No constant computed for $node'));
|
| return constant;
|
| }
|
|
|
| + ConstExp getConstantForVariable(VariableElement element) {
|
| + ConstExp constant =
|
| + compiler.backend.constants.getConstantForVariable(element);
|
| + assert(invariant(element, constant != null,
|
| + message: 'No constant computed for $element'));
|
| + return constant;
|
| + }
|
| +
|
| ir.Primitive visitLiteralList(ast.LiteralList node) {
|
| assert(isOpen);
|
| if (node.isConst) {
|
| @@ -1872,12 +1871,12 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> with IrBuilder {
|
| (k) => new ir.ConcatenateStrings(k, arguments));
|
| }
|
|
|
| - ir.Primitive translateConstant(ast.Node node, [Constant value]) {
|
| + ir.Primitive translateConstant(ast.Node node, [ConstExp constant]) {
|
| assert(isOpen);
|
| - if (value == null) {
|
| - value = getConstantForNode(node);
|
| + if (constant == null) {
|
| + constant = getConstantForNode(node);
|
| }
|
| - ir.Primitive primitive = makeConst(constantBuilder.visit(node), value);
|
| + ir.Primitive primitive = makeConst(constant);
|
| add(new ir.LetPrim(primitive));
|
| return primitive;
|
| }
|
| @@ -1931,164 +1930,6 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> with IrBuilder {
|
| }
|
| }
|
|
|
| -/// Translates constant expressions from the AST to the [ConstExp] language.
|
| -class ConstExpBuilder extends ast.Visitor<ConstExp> {
|
| - final IrBuilderVisitor parent;
|
| - final TreeElements elements;
|
| - final ConstantSystem constantSystem;
|
| - final ConstantCompiler constantCompiler;
|
| -
|
| - ConstExpBuilder(IrBuilderVisitor parent)
|
| - : this.parent = parent,
|
| - this.elements = parent.elements,
|
| - this.constantSystem = parent.constantSystem,
|
| - this.constantCompiler = parent.compiler.backend.constantCompilerTask;
|
| -
|
| - Constant computeConstant(ast.Node node) {
|
| - return constantCompiler.compileNode(node, elements);
|
| - }
|
| -
|
| - /// True if the given constant is small enough that inlining it is likely
|
| - /// to be profitable. Always false for non-primitive constants.
|
| - bool isSmallConstant(Constant constant) {
|
| - if (constant is BoolConstant || constant is NullConstant) {
|
| - return true;
|
| - }
|
| - if (constant is IntConstant) {
|
| - return -10 < constant.value && constant.value < 100;
|
| - }
|
| - if (constant is DoubleConstant) {
|
| - return constant.isZero || constant.isOne;
|
| - }
|
| - if (constant is StringConstant) {
|
| - ast.DartString string = constant.value;
|
| - if (string is ast.LiteralDartString) {
|
| - return string.length < 4;
|
| - }
|
| - if (string is ast.SourceBasedDartString) {
|
| - return string.length < 4;
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - ConstExp visit(ast.Node node) => node.accept(this);
|
| -
|
| - ConstExp visitStringJuxtaposition(ast.StringJuxtaposition node) {
|
| - ConstExp first = visit(node.first);
|
| - ConstExp second = visit(node.second);
|
| - return new ConcatenateConstExp([first, second]);
|
| - }
|
| -
|
| - ConstExp visitStringInterpolation(ast.StringInterpolation node) {
|
| - List<ConstExp> arguments = <ConstExp>[];
|
| - arguments.add(visitLiteralString(node.string));
|
| - var it = node.parts.iterator;
|
| - while (it.moveNext()) {
|
| - ast.StringInterpolationPart part = it.current;
|
| - arguments.add(visit(part.expression));
|
| - arguments.add(visitLiteralString(part.string));
|
| - }
|
| - return new ConcatenateConstExp(arguments);
|
| - }
|
| -
|
| - ConstExp visitNewExpression(ast.NewExpression node) {
|
| - FunctionElement element = elements[node.send];
|
| - // The resolver will already have thrown an error if the constructor was
|
| - // unresolved.
|
| - assert(invariant(node, !Elements.isUnresolved(element)));
|
| -
|
| - Selector selector = elements.getSelector(node.send);
|
| - ast.Node selectorNode = node.send.selector;
|
| - GenericType type = elements.getType(node);
|
| - List<ConstExp> args = node.send.arguments.mapToList(visit, growable:false);
|
| - return new ConstructorConstExp(type, element, selector, args);
|
| - }
|
| -
|
| - ConstExp visitNamedArgument(ast.NamedArgument node) {
|
| - return visit(node.expression);
|
| - }
|
| -
|
| - ConstExp visitSend(ast.Send node) {
|
| - Element element = elements[node];
|
| - if (node.isOperator) {
|
| - return new PrimitiveConstExp(computeConstant(node));
|
| - }
|
| - if (Elements.isStaticOrTopLevelFunction(element)) {
|
| - return new FunctionConstExp(element);
|
| - }
|
| - if (Elements.isLocal(element) ||
|
| - Elements.isStaticOrTopLevelField(element)) {
|
| - // If the constant is small, inline it instead of using the declared const
|
| - Constant value = constantCompiler.getConstantForVariable(element);
|
| - if (isSmallConstant(value))
|
| - return new PrimitiveConstExp(value);
|
| - else
|
| - return new VariableConstExp(element);
|
| - }
|
| - DartType type = elements.getTypeLiteralType(node);
|
| - if (type != null) {
|
| - return new TypeConstExp(type);
|
| - }
|
| - throw "Unexpected constant Send: $node";
|
| - }
|
| -
|
| - ConstExp visitParenthesizedExpression(ast.ParenthesizedExpression node) {
|
| - return visit(node.expression);
|
| - }
|
| -
|
| - ConstExp visitLiteralList(ast.LiteralList node) {
|
| - List<ConstExp> values = node.elements.nodes.mapToList(visit);
|
| - GenericType type = elements.getType(node);
|
| - return new ListConstExp(type, values);
|
| - }
|
| -
|
| - ConstExp visitLiteralMap(ast.LiteralMap node) {
|
| - List<ConstExp> keys = new List<ConstExp>();
|
| - List<ConstExp> values = new List<ConstExp>();
|
| - node.entries.nodes.forEach((ast.LiteralMapEntry node) {
|
| - keys.add(visit(node.key));
|
| - values.add(visit(node.value));
|
| - });
|
| - GenericType type = elements.getType(node);
|
| - return new MapConstExp(type, keys, values);
|
| - }
|
| -
|
| - ConstExp visitLiteralSymbol(ast.LiteralSymbol node) {
|
| - return new SymbolConstExp(node.slowNameString);
|
| - }
|
| -
|
| - ConstExp visitLiteralInt(ast.LiteralInt node) {
|
| - return new PrimitiveConstExp(constantSystem.createInt(node.value));
|
| - }
|
| -
|
| - ConstExp visitLiteralDouble(ast.LiteralDouble node) {
|
| - return new PrimitiveConstExp(constantSystem.createDouble(node.value));
|
| - }
|
| -
|
| - ConstExp visitLiteralString(ast.LiteralString node) {
|
| - return new PrimitiveConstExp(constantSystem.createString(node.dartString));
|
| - }
|
| -
|
| - ConstExp visitLiteralBool(ast.LiteralBool node) {
|
| - return new PrimitiveConstExp(constantSystem.createBool(node.value));
|
| - }
|
| -
|
| - ConstExp visitLiteralNull(ast.LiteralNull node) {
|
| - return new PrimitiveConstExp(constantSystem.createNull());
|
| - }
|
| -
|
| - ConstExp visitConditional(ast.Conditional node) {
|
| - BoolConstant condition = computeConstant(node.condition);
|
| - return visit(condition.isTrue ? node.thenExpression : node.elseExpression);
|
| - }
|
| -
|
| - ConstExp visitNode(ast.Node node) {
|
| - throw "Unexpected constant: $node";
|
| - }
|
| -
|
| -}
|
| -
|
| /// Classifies local variables and local functions as 'closure variables'.
|
| /// A closure variable is one that is accessed from an inner function nested
|
| /// one or more levels inside the one that declares it.
|
|
|