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

Unified Diff: pkg/compiler/lib/src/js_backend/constant_emitter.dart

Issue 947333004: dart2js: simplify constant expression generation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix long line. Created 5 years, 10 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_emitter/code_emitter_task.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js_backend/constant_emitter.dart
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 234e2a01615904554a52c282c033e7ad507e039e..1a008819fa4e81928db8f304ec39e33d8125a14e 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -4,165 +4,16 @@
part of js_backend;
-class ConstantEmitter {
- ConstantReferenceEmitter _referenceEmitter;
- ConstantLiteralEmitter _literalEmitter;
-
- ConstantEmitter(Compiler compiler,
- Namer namer,
- jsAst.Template makeConstantListTemplate) {
- _literalEmitter = new ConstantLiteralEmitter(
- compiler, namer, makeConstantListTemplate, this);
- _referenceEmitter = new ConstantReferenceEmitter(compiler, namer, this);
- }
-
- /**
- * Constructs an expression that is a reference to the constant. Uses a
- * canonical name unless the constant can be emitted multiple times (as for
- * numbers and strings).
- */
- jsAst.Expression reference(ConstantValue constant) {
- return _referenceEmitter.generate(constant);
- }
-
- /**
- * Constructs a literal expression that evaluates to the constant. Uses a
- * canonical name unless the constant can be emitted multiple times (as for
- * numbers and strings).
- */
- jsAst.Expression literal(ConstantValue constant) {
- return _literalEmitter.generate(constant);
- }
-
- /**
- * Constructs an expression like [reference], but the expression is valid
- * during isolate initialization.
- */
- jsAst.Expression referenceInInitializationContext(ConstantValue constant) {
- return _referenceEmitter.generate(constant);
- }
-
- /**
- * Constructs an expression used to initialize a canonicalized constant.
- */
- jsAst.Expression initializationExpression(ConstantValue constant) {
- return _literalEmitter.generate(constant);
- }
-}
+typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant);
/**
- * Visitor for generating JavaScript expressions to refer to [ConstantValue]s.
- * Do not use directly, use methods from [ConstantEmitter].
+ * Generates the JavaScript expressions for constants.
+ *
+ * It uses a given [constantReferenceGenerator] to reference nested constants
+ * (if there are some). It is hence up to that function to decide which
+ * constants should be inlined or not.
*/
-class ConstantReferenceEmitter
- implements ConstantValueVisitor<jsAst.Expression, Null> {
- final Compiler compiler;
- final Namer namer;
-
- final ConstantEmitter constantEmitter;
-
- ConstantReferenceEmitter(this.compiler, this.namer, this.constantEmitter);
-
- JavaScriptBackend get backend => compiler.backend;
-
- jsAst.Expression generate(ConstantValue constant) {
- return _visit(constant);
- }
-
- jsAst.Expression _visit(ConstantValue constant) {
- return constant.accept(this, null);
- }
-
- jsAst.Expression emitCanonicalVersion(ConstantValue constant) {
- String name = namer.constantName(constant);
- return new jsAst.PropertyAccess.field(
- new jsAst.VariableUse(namer.globalObjectForConstant(constant)), name);
- }
-
- jsAst.Expression literal(ConstantValue constant) {
- return constantEmitter.literal(constant);
- }
-
- @override
- jsAst.Expression visitFunction(FunctionConstantValue constant, [_]) {
- return backend.emitter.isolateStaticClosureAccess(constant.element);
- }
-
- @override
- jsAst.Expression visitNull(NullConstantValue constant, [_]) {
- return literal(constant);
- }
-
- @override
- jsAst.Expression visitInt(IntConstantValue constant, [_]) {
- return literal(constant);
- }
-
- @override
- jsAst.Expression visitDouble(DoubleConstantValue constant, [_]) {
- return literal(constant);
- }
-
- @override
- jsAst.Expression visitBool(BoolConstantValue constant, [_]) {
- return literal(constant);
- }
-
- /**
- * Write the contents of the quoted string to a [CodeBuffer] in
- * a form that is valid as JavaScript string literal content.
- * The string is assumed quoted by double quote characters.
- */
- @override
- jsAst.Expression visitString(StringConstantValue constant, [_]) {
- // TODO(sra): If the string is long *and repeated* (and not on a hot path)
- // then it should be assigned to a name. We don't have reference counts (or
- // profile information) here, so this is the wrong place.
- return literal(constant);
- }
-
- @override
- jsAst.Expression visitList(ListConstantValue constant, [_]) {
- return emitCanonicalVersion(constant);
- }
-
- @override
- jsAst.Expression visitMap(MapConstantValue constant, [_]) {
- return emitCanonicalVersion(constant);
- }
-
- @override
- jsAst.Expression visitType(TypeConstantValue constant, [_]) {
- return emitCanonicalVersion(constant);
- }
-
- @override
- jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) {
- return emitCanonicalVersion(constant);
- }
-
- @override
- jsAst.Expression visitInterceptor(InterceptorConstantValue constant, [_]) {
- return emitCanonicalVersion(constant);
- }
-
- @override
- jsAst.Expression visitDummy(DummyConstantValue constant, [_]) {
- return literal(constant);
- }
-
- @override
- jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) {
- return emitCanonicalVersion(constant);
- }
-}
-
-/**
- * Visitor for generating JavaScript expressions that litterally represent
- * [ConstantValue]s. These can be used for inlining constants or in
- * initializers. Do not use directly, use methods from [ConstantEmitter].
- */
-class ConstantLiteralEmitter
+class ConstantEmitter
implements ConstantValueVisitor<jsAst.Expression, Null> {
// Matches blank lines, comment lines and trailing comments that can't be part
@@ -172,14 +23,25 @@ class ConstantLiteralEmitter
final Compiler compiler;
final Namer namer;
+ final _ConstantReferenceGenerator constantReferenceGenerator;
final jsAst.Template makeConstantListTemplate;
- final ConstantEmitter constantEmitter;
- ConstantLiteralEmitter(this.compiler,
- this.namer,
- this.makeConstantListTemplate,
- this.constantEmitter);
+ /**
+ * The given [constantReferenceGenerator] function must, when invoked with a
+ * constant, either return a reference or return its literal expression if it
+ * can be inlined.
+ */
+ ConstantEmitter(
+ this.compiler,
+ this.namer,
+ jsAst.Expression this.constantReferenceGenerator(ConstantValue constant),
+ this.makeConstantListTemplate);
+ /**
+ * Constructs a literal expression that evaluates to the constant. Uses a
+ * canonical name unless the constant can be emitted multiple times (as for
+ * numbers and strings).
+ */
jsAst.Expression generate(ConstantValue constant) {
return _visit(constant);
}
@@ -294,7 +156,9 @@ class ConstantLiteralEmitter
@override
jsAst.Expression visitList(ListConstantValue constant, [_]) {
- List<jsAst.Expression> elements = _array(constant.entries);
+ List<jsAst.Expression> elements = constant.entries
+ .map(constantReferenceGenerator)
+ .toList(growable: false);
jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(elements);
jsAst.Expression value = makeConstantListTemplate.instantiate([array]);
return maybeAddTypeArguments(constant.type, value);
@@ -313,7 +177,7 @@ class ConstantLiteralEmitter
// Keys in literal maps must be emitted in place.
jsAst.Literal keyExpression = _visit(key);
jsAst.Expression valueExpression =
- constantEmitter.reference(constant.values[i]);
+ constantReferenceGenerator(constant.values[i]);
properties.add(new jsAst.Property(keyExpression, valueExpression));
}
return new jsAst.ObjectInitializer(properties);
@@ -322,10 +186,9 @@ class ConstantLiteralEmitter
jsAst.Expression jsGeneralMap() {
List<jsAst.Expression> data = <jsAst.Expression>[];
for (int i = 0; i < constant.keys.length; i++) {
- jsAst.Expression keyExpression =
- constantEmitter.reference(constant.keys[i]);
+ jsAst.Expression keyExpression = constantReferenceGenerator(constant.keys[i]);
jsAst.Expression valueExpression =
- constantEmitter.reference(constant.values[i]);
+ constantReferenceGenerator(constant.values[i]);
data.add(keyExpression);
data.add(valueExpression);
}
@@ -348,10 +211,10 @@ class ConstantLiteralEmitter
} else if (field.name == JavaScriptMapConstant.JS_OBJECT_NAME) {
arguments.add(jsMap());
} else if (field.name == JavaScriptMapConstant.KEYS_NAME) {
- arguments.add(constantEmitter.reference(constant.keyList));
+ arguments.add(constantReferenceGenerator(constant.keyList));
} else if (field.name == JavaScriptMapConstant.PROTO_VALUE) {
assert(constant.protoValue != null);
- arguments.add(constantEmitter.reference(constant.protoValue));
+ arguments.add(constantReferenceGenerator(constant.protoValue));
} else if (field.name == JavaScriptMapConstant.JS_DATA_NAME) {
arguments.add(jsGeneralMap());
} else {
@@ -415,8 +278,9 @@ class ConstantLiteralEmitter
}
jsAst.Expression constructor =
backend.emitter.constructorAccess(constant.type.element);
- jsAst.New instantiation =
- new jsAst.New(constructor, _array(constant.fields));
+ List<jsAst.Expression> fields =
+ constant.fields.map(constantReferenceGenerator).toList(growable: false);
+ jsAst.New instantiation = new jsAst.New(constructor, fields);
return maybeAddTypeArguments(constant.type, instantiation);
}
@@ -424,10 +288,6 @@ class ConstantLiteralEmitter
return rawJavaScript.replaceAll(COMMENT_RE, '');
}
- List<jsAst.Expression> _array(List<ConstantValue> values) {
- return values.map(constantEmitter.reference).toList(growable: false);
- }
-
jsAst.Expression maybeAddTypeArguments(InterfaceType type,
jsAst.Expression value) {
if (type is InterfaceType &&
@@ -448,6 +308,6 @@ class ConstantLiteralEmitter
@override
jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) {
- return constantEmitter.reference(constant.referenced);
+ return constantReferenceGenerator(constant.referenced);
}
}
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_emitter/code_emitter_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698