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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart2js.new_js_emitter.model_emitter; 5 library dart2js.new_js_emitter.model_emitter;
6 6
7 import '../../constants/values.dart' show ConstantValue, FunctionConstantValue; 7 import '../../constants/values.dart' show ConstantValue, FunctionConstantValue;
8 import '../../dart2jslib.dart' show Compiler; 8 import '../../dart2jslib.dart' show Compiler;
9 import '../../dart_types.dart' show DartType; 9 import '../../dart_types.dart' show DartType;
10 import '../../elements/elements.dart' show ClassElement, FunctionElement; 10 import '../../elements/elements.dart' show ClassElement, FunctionElement;
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 String mainCode = js.prettyPrint(mainAst, compiler).getText(); 153 String mainCode = js.prettyPrint(mainAst, compiler).getText();
154 compiler.outputProvider(mainFragment.outputFileName, 'js') 154 compiler.outputProvider(mainFragment.outputFileName, 'js')
155 ..add(buildGeneratedBy(compiler)) 155 ..add(buildGeneratedBy(compiler))
156 ..add(mainCode) 156 ..add(mainCode)
157 ..close(); 157 ..close();
158 totalSize += mainCode.length; 158 totalSize += mainCode.length;
159 159
160 return totalSize; 160 return totalSize;
161 } 161 }
162 162
163 js.LiteralString unparse(Compiler compiler, js.Node value) { 163 /// Unparses the given [value].
164 ///
165 /// Pretty-prints the given [value] and, if [protectForEval] is
166 /// true, wraps the resulting string in parenthesis. The result is escaped
167 /// and returned.
168 js.LiteralString unparse(Compiler compiler, js.Node value,
169 {bool protectForEval: true}) {
164 String text = js.prettyPrint(value, compiler).getText(); 170 String text = js.prettyPrint(value, compiler).getText();
165 if (value is js.Fun) text = '($text)'; 171 if (protectForEval) {
166 if (value is js.LiteralExpression && 172 if (value is js.Fun) text = '($text)';
167 (value.template.startsWith("function ") || 173 if (value is js.LiteralExpression &&
168 value.template.startsWith("{"))) { 174 (value.template.startsWith("function ") ||
169 text = '($text)'; 175 value.template.startsWith("{"))) {
176 text = '($text)';
177 }
170 } 178 }
171 return js.js.escapedString(text); 179 return js.js.escapedString(text);
172 } 180 }
173 181
174 String buildGeneratedBy(compiler) { 182 String buildGeneratedBy(compiler) {
175 var suffix = ''; 183 var suffix = '';
176 if (compiler.hasBuildId) suffix = ' version: ${compiler.buildId}'; 184 if (compiler.hasBuildId) suffix = ' version: ${compiler.buildId}';
177 return '// Generated by dart2js, the Dart to JavaScript compiler$suffix.\n'; 185 return '// Generated by dart2js, the Dart to JavaScript compiler$suffix.\n';
178 } 186 }
179 187
(...skipping 14 matching lines...) Expand all
194 'parseFunctionDescriptor': 202 'parseFunctionDescriptor':
195 js.js.statement(parseFunctionDescriptorBoilerplate, 203 js.js.statement(parseFunctionDescriptorBoilerplate,
196 {'argumentCount': js.string(namer.requiredParameterField), 204 {'argumentCount': js.string(namer.requiredParameterField),
197 'defaultArgumentValues': js.string(namer.defaultValuesField), 205 'defaultArgumentValues': js.string(namer.defaultValuesField),
198 'callName': js.string(namer.callNameField)}), 206 'callName': js.string(namer.callNameField)}),
199 207
200 'cyclicThrow': 208 'cyclicThrow':
201 backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()), 209 backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()),
202 'outputContainsConstantList': program.outputContainsConstantList, 210 'outputContainsConstantList': program.outputContainsConstantList,
203 'embeddedGlobals': emitEmbeddedGlobals(program), 211 'embeddedGlobals': emitEmbeddedGlobals(program),
212 'readMetadataTypeFunction': readMetadataTypeFunction,
204 'staticNonFinals': 213 'staticNonFinals':
205 emitStaticNonFinalFields(fragment.staticNonFinalFields), 214 emitStaticNonFinalFields(fragment.staticNonFinalFields),
206 'operatorIsPrefix': js.string(namer.operatorIsPrefix), 215 'operatorIsPrefix': js.string(namer.operatorIsPrefix),
207 'callName': js.string(namer.callNameField), 216 'callName': js.string(namer.callNameField),
208 'argumentCount': js.string(namer.requiredParameterField), 217 'argumentCount': js.string(namer.requiredParameterField),
209 'defaultArgumentValues': js.string(namer.defaultValuesField), 218 'defaultArgumentValues': js.string(namer.defaultValuesField),
210 'eagerClasses': emitEagerClassInitializations(fragment.libraries), 219 'eagerClasses': emitEagerClassInitializations(fragment.libraries),
211 'invokeMain': fragment.invokeMain, 220 'invokeMain': fragment.invokeMain,
212 'code': code}; 221 'code': code};
213 222
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 } 423 }
415 424
416 js.Property emitGetTypeFromName() { 425 js.Property emitGetTypeFromName() {
417 js.Expression function = 426 js.Expression function =
418 js.js( """function(name) { 427 js.js( """function(name) {
419 return holdersMap[name][name].ensureResolved(); 428 return holdersMap[name][name].ensureResolved();
420 }"""); 429 }""");
421 return new js.Property(js.string(GET_TYPE_FROM_NAME), function); 430 return new js.Property(js.string(GET_TYPE_FROM_NAME), function);
422 } 431 }
423 432
433 static final String readMetadataTypeName = "readMetadataType";
434
435 js.Statement get readMetadataTypeFunction {
436 // Types are non-evaluated and must be compiled at first use.
437 // Compiled strings are guaranteed not to be strings, and it's thus safe
438 // to use a type-test to determine if a type has already been compiled.
439 return js.js.statement('''function $readMetadataTypeName(index) {
440 var type = #typesAccess[index];
441 if (typeof type == 'string') {
442 type = expressionCompile(type);
443 #typesAccess[index] = type;
444 }
445 return type;
446 }''', {"typesAccess": generateEmbeddedGlobalAccess(TYPES)});
447 }
448
449 js.Template get templateForReadType {
450 // TODO(floitsch): make sure that no local variable shadows the access to
451 // the readMetadataType function.
452 return js.js.expressionTemplateFor('$readMetadataTypeName(#)');
453 }
454
424 List<js.Property> emitMetadata(Program program) { 455 List<js.Property> emitMetadata(Program program) {
425 List<js.Property> metadataGlobals = <js.Property>[]; 456 List<js.Property> metadataGlobals = <js.Property>[];
426 metadataGlobals.add(new js.Property( 457 metadataGlobals.add(new js.Property(
427 js.string(METADATA), new js.ArrayInitializer(program.metadata))); 458 js.string(METADATA), new js.ArrayInitializer(program.metadata)));
428 List<js.Expression> types = 459 List<js.Expression> types =
429 program.metadataTypes[program.fragments.first.outputUnit]; 460 program.metadataTypes[program.fragments.first.outputUnit];
430 if (types == null) types = <js.Expression>[]; 461 if (types == null) types = <js.Expression>[];
431 metadataGlobals.add(new js.Property( 462 List<js.LiteralString> unparsedTypes = types
432 js.string(TYPES), new js.ArrayInitializer(types))); 463 .map((type) => unparse(compiler, type, protectForEval: false))
433 464 .toList();
465 js.ArrayInitializer typesArray = new js.ArrayInitializer(unparsedTypes);
466 metadataGlobals.add(new js.Property(js.string(TYPES), typesArray));
434 return metadataGlobals; 467 return metadataGlobals;
435 } 468 }
436 469
437 js.Expression emitDeferredFragment(List<js.Expression> types, 470 js.Expression emitDeferredFragment(List<js.Expression> types,
438 DeferredFragment fragment, 471 DeferredFragment fragment,
439 List<Holder> holders) { 472 List<Holder> holders) {
440 // TODO(floitsch): initialize eager classes. 473 // TODO(floitsch): initialize eager classes.
441 // TODO(floitsch): the hash must depend on the output. 474 // TODO(floitsch): the hash must depend on the output.
442 int hash = fragment.hashCode; 475 int hash = fragment.hashCode;
443 476
444 List<js.Expression> deferredCode = 477 List<js.Expression> deferredCode =
445 fragment.libraries.map(emitLibrary).toList(); 478 fragment.libraries.map(emitLibrary).toList();
446 479
447 deferredCode.add( 480 deferredCode.add(
448 emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields)); 481 emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
449 482
450 deferredCode.add(emitConstants(fragment.constants)); 483 deferredCode.add(emitConstants(fragment.constants));
451 484
452 js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode); 485 js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode);
453 486
454 // This is the code that must be evaluated after all deferred classes have 487 // This is the code that must be evaluated after all deferred classes have
455 // been setup. 488 // been setup.
456 js.Statement immediateCode = 489 js.Statement immediateCode =
457 emitEagerClassInitializations(fragment.libraries); 490 emitEagerClassInitializations(fragment.libraries);
458 491
459 js.LiteralString immediateString = unparse(compiler, immediateCode); 492 js.LiteralString immediateString = unparse(compiler, immediateCode);
460 493
461 js.Expression deferredTypes = types == null 494 js.Expression deferredTypes = (types == null)
462 ? js.string("[]") 495 ? js.string("[]")
463 : unparse(compiler, new js.ArrayInitializer(types)); 496 : unparse(compiler, new js.ArrayInitializer(types));
464 497
465 js.ArrayInitializer hunk = 498 js.ArrayInitializer hunk =
466 new js.ArrayInitializer([deferredArray, immediateString, 499 new js.ArrayInitializer([deferredArray, immediateString,
467 deferredTypes]); 500 deferredTypes]);
468 501
469 return js.js("$deferredInitializersGlobal[$hash] = #", hunk); 502 return js.js("$deferredInitializersGlobal[$hash] = #", hunk);
470 } 503 }
471 504
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 #nativeInfoHandler; 1182 #nativeInfoHandler;
1150 } 1183 }
1151 } 1184 }
1152 } 1185 }
1153 1186
1154 $setupProgramName(program, 0); 1187 $setupProgramName(program, 0);
1155 1188
1156 // Initialize globals. 1189 // Initialize globals.
1157 #embeddedGlobals; 1190 #embeddedGlobals;
1158 1191
1192 function expressionCompile(__s__) {
1193 'use strict';
1194 return eval('(' + __s__ + ')');
1195 }
1196
1197 #readMetadataTypeFunction;
1198
1159 // TODO(floitsch): this order means that native classes may not be 1199 // TODO(floitsch): this order means that native classes may not be
1160 // referenced from constants. I'm mostly afraid of things like using them as 1200 // referenced from constants. I'm mostly afraid of things like using them as
1161 // generic arguments (which should be fine, but maybe there are other 1201 // generic arguments (which should be fine, but maybe there are other
1162 // similar things). 1202 // similar things).
1163 // Initialize natives. 1203 // Initialize natives.
1164 if (#needsNativeSupport) handleNativeClassInfos(); 1204 if (#needsNativeSupport) handleNativeClassInfos();
1165 1205
1166 // Initialize static non-final fields. 1206 // Initialize static non-final fields.
1167 #staticNonFinals; 1207 #staticNonFinals;
1168 1208
1169 // Add native boilerplate code. 1209 // Add native boilerplate code.
1170 #nativeIsolateAffinityTagInitialization; 1210 #nativeIsolateAffinityTagInitialization;
1171 1211
1172 // Initialize eager classes. 1212 // Initialize eager classes.
1173 #eagerClasses; 1213 #eagerClasses;
1174 1214
1175 var end = Date.now(); 1215 var end = Date.now();
1176 // print('Setup: ' + (end - start) + ' ms.'); 1216 // print('Setup: ' + (end - start) + ' ms.');
1177 1217
1178 #invokeMain; // Start main. 1218 #invokeMain; // Start main.
1179 1219
1180 }(Date.now(), #code) 1220 }(Date.now(), #code)
1181 }"""; 1221 }""";
1182 1222
1183 } 1223 }
OLDNEW
« 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