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

Unified Diff: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart

Issue 1123413002: dart2js: build metadata-types lazily in the new emitter. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Merged Created 5 years, 7 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 | « pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
index 7d4b2a5f2cd35c09472530a194466914243db05a..a61c38d963c24e7d86c09e87ce503b199713ef84 100644
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
@@ -160,13 +160,21 @@ class ModelEmitter {
return totalSize;
}
- js.LiteralString unparse(Compiler compiler, js.Node value) {
+ /// Unparses the given [value].
+ ///
+ /// Pretty-prints the given [value] and, if [protectForEval] is
+ /// true, wraps the resulting string in parenthesis. The result is escaped
+ /// and returned.
+ js.LiteralString unparse(Compiler compiler, js.Node value,
+ {bool protectForEval: true}) {
String text = js.prettyPrint(value, compiler).getText();
- if (value is js.Fun) text = '($text)';
- if (value is js.LiteralExpression &&
- (value.template.startsWith("function ") ||
- value.template.startsWith("{"))) {
- text = '($text)';
+ if (protectForEval) {
+ if (value is js.Fun) text = '($text)';
+ if (value is js.LiteralExpression &&
+ (value.template.startsWith("function ") ||
+ value.template.startsWith("{"))) {
+ text = '($text)';
+ }
}
return js.js.escapedString(text);
}
@@ -201,6 +209,7 @@ class ModelEmitter {
backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()),
'outputContainsConstantList': program.outputContainsConstantList,
'embeddedGlobals': emitEmbeddedGlobals(program),
+ 'readMetadataTypeFunction': readMetadataTypeFunction,
'staticNonFinals':
emitStaticNonFinalFields(fragment.staticNonFinalFields),
'operatorIsPrefix': js.string(namer.operatorIsPrefix),
@@ -421,6 +430,28 @@ class ModelEmitter {
return new js.Property(js.string(GET_TYPE_FROM_NAME), function);
}
+ static final String readMetadataTypeName = "readMetadataType";
+
+ js.Statement get readMetadataTypeFunction {
+ // Types are non-evaluated and must be compiled at first use.
+ // Compiled strings are guaranteed not to be strings, and it's thus safe
+ // to use a type-test to determine if a type has already been compiled.
+ return js.js.statement('''function $readMetadataTypeName(index) {
+ var type = #typesAccess[index];
+ if (typeof type == 'string') {
+ type = expressionCompile(type);
+ #typesAccess[index] = type;
+ }
+ return type;
+ }''', {"typesAccess": generateEmbeddedGlobalAccess(TYPES)});
+ }
+
+ js.Template get templateForReadType {
+ // TODO(floitsch): make sure that no local variable shadows the access to
+ // the readMetadataType function.
+ return js.js.expressionTemplateFor('$readMetadataTypeName(#)');
+ }
+
List<js.Property> emitMetadata(Program program) {
List<js.Property> metadataGlobals = <js.Property>[];
metadataGlobals.add(new js.Property(
@@ -428,9 +459,11 @@ class ModelEmitter {
List<js.Expression> types =
program.metadataTypes[program.fragments.first.outputUnit];
if (types == null) types = <js.Expression>[];
- metadataGlobals.add(new js.Property(
- js.string(TYPES), new js.ArrayInitializer(types)));
-
+ List<js.LiteralString> unparsedTypes = types
+ .map((type) => unparse(compiler, type, protectForEval: false))
+ .toList();
+ js.ArrayInitializer typesArray = new js.ArrayInitializer(unparsedTypes);
+ metadataGlobals.add(new js.Property(js.string(TYPES), typesArray));
return metadataGlobals;
}
@@ -458,7 +491,7 @@ class ModelEmitter {
js.LiteralString immediateString = unparse(compiler, immediateCode);
- js.Expression deferredTypes = types == null
+ js.Expression deferredTypes = (types == null)
? js.string("[]")
: unparse(compiler, new js.ArrayInitializer(types));
@@ -1156,6 +1189,13 @@ function parseFunctionDescriptor(proto, name, descriptor, typesOffset) {
// Initialize globals.
#embeddedGlobals;
+ function expressionCompile(__s__) {
+ 'use strict';
+ return eval('(' + __s__ + ')');
+ }
+
+ #readMetadataTypeFunction;
+
// TODO(floitsch): this order means that native classes may not be
// referenced from constants. I'm mostly afraid of things like using them as
// generic arguments (which should be fine, but maybe there are other
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698