OLD | NEW |
---|---|
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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
193 'parseFunctionDescriptor': | 193 'parseFunctionDescriptor': |
194 js.js.statement(parseFunctionDescriptorBoilerplate, | 194 js.js.statement(parseFunctionDescriptorBoilerplate, |
195 {'argumentCount': js.string(namer.requiredParameterField), | 195 {'argumentCount': js.string(namer.requiredParameterField), |
196 'defaultArgumentValues': js.string(namer.defaultValuesField), | 196 'defaultArgumentValues': js.string(namer.defaultValuesField), |
197 'callName': js.string(namer.callNameField)}), | 197 'callName': js.string(namer.callNameField)}), |
198 | 198 |
199 'cyclicThrow': | 199 'cyclicThrow': |
200 backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()), | 200 backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()), |
201 'outputContainsConstantList': program.outputContainsConstantList, | 201 'outputContainsConstantList': program.outputContainsConstantList, |
202 'embeddedGlobals': emitEmbeddedGlobals(program), | 202 'embeddedGlobals': emitEmbeddedGlobals(program), |
203 'readMetadataTypeFunction': readMetadataTypeFunction, | |
203 'staticNonFinals': | 204 'staticNonFinals': |
204 emitStaticNonFinalFields(fragment.staticNonFinalFields), | 205 emitStaticNonFinalFields(fragment.staticNonFinalFields), |
205 'operatorIsPrefix': js.string(namer.operatorIsPrefix), | 206 'operatorIsPrefix': js.string(namer.operatorIsPrefix), |
206 'callName': js.string(namer.callNameField), | 207 'callName': js.string(namer.callNameField), |
207 'argumentCount': js.string(namer.requiredParameterField), | 208 'argumentCount': js.string(namer.requiredParameterField), |
208 'defaultArgumentValues': js.string(namer.defaultValuesField), | 209 'defaultArgumentValues': js.string(namer.defaultValuesField), |
209 'eagerClasses': emitEagerClassInitializations(fragment.libraries), | 210 'eagerClasses': emitEagerClassInitializations(fragment.libraries), |
210 'invokeMain': fragment.invokeMain, | 211 'invokeMain': fragment.invokeMain, |
211 'code': code}; | 212 'code': code}; |
212 | 213 |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
413 } | 414 } |
414 | 415 |
415 js.Property emitGetTypeFromName() { | 416 js.Property emitGetTypeFromName() { |
416 js.Expression function = | 417 js.Expression function = |
417 js.js( """function(name) { | 418 js.js( """function(name) { |
418 return holdersMap[name][name].ensureResolved(); | 419 return holdersMap[name][name].ensureResolved(); |
419 }"""); | 420 }"""); |
420 return new js.Property(js.string(GET_TYPE_FROM_NAME), function); | 421 return new js.Property(js.string(GET_TYPE_FROM_NAME), function); |
421 } | 422 } |
422 | 423 |
424 static final metadataTypeComment = | |
425 "Types are non-evaluated and must be compiled at first use. " | |
426 "Compiled strings are guaranteed not to be strings, and it's thus safe " | |
427 "to use a type-test to determine if a type has already been compiled."; | |
428 | |
429 static final String readMetadataTypeName = "readMetadataType"; | |
430 | |
431 js.Statement get readMetadataTypeFunction { | |
432 return js.js.statement('''function $readMetadataTypeName(index) { | |
433 // $metadataTypeComment. | |
sra1
2015/05/07 03:39:30
Just put the comment here.
floitsch
2015/05/07 04:08:59
Done.
| |
434 var type = #typesAccess[index]; | |
435 if (typeof type == 'string') { | |
436 type = expressionCompile(type); | |
437 #typesAccess[index] = type; | |
438 } | |
439 return type; | |
440 }''', {"typesAccess": generateEmbeddedGlobalAccess(TYPES)}); | |
441 } | |
442 | |
443 js.Template get templateForReadType { | |
444 // TODO(floitsch): make sure that no local variable shadows the access to | |
445 // the readMetadataType function. | |
446 return js.js.expressionTemplateFor('$readMetadataTypeName(#)'); | |
447 } | |
448 | |
423 List<js.Property> emitMetadata(Program program) { | 449 List<js.Property> emitMetadata(Program program) { |
424 | 450 |
425 List<js.Property> metadataGlobals = <js.Property>[]; | 451 List<js.Property> metadataGlobals = <js.Property>[]; |
426 | 452 |
427 js.Property createGlobal(List<String> list, String global) { | 453 js.Property createGlobal(List<String> list, String global) { |
428 String listAsString = "[${list.join(",")}]"; | 454 String listAsString = "[${list.join(",")}]"; |
429 js.Expression metadata = | 455 js.Expression metadata = |
430 js.js.uncachedExpressionTemplate(listAsString).instantiate([]); | 456 js.js.uncachedExpressionTemplate(listAsString).instantiate([]); |
431 return new js.Property(js.string(global), metadata); | 457 return new js.Property(js.string(global), metadata); |
432 } | 458 } |
433 | 459 |
434 metadataGlobals.add(createGlobal(program.metadata, METADATA)); | 460 metadataGlobals.add(createGlobal(program.metadata, METADATA)); |
435 List<String> types = | 461 List<String> types = |
436 program.metadataTypes[program.fragments.first.outputUnit]; | 462 program.metadataTypes[program.fragments.first.outputUnit]; |
437 if (types == null) types = <String>[]; | 463 if (types == null) types = <String>[]; |
438 metadataGlobals.add(createGlobal(types, TYPES)); | 464 // The strings in the array are already pretty-printed JS expressions. |
465 js.Expression unparsedTypes = js.stringArray(types); | |
466 metadataGlobals.add(new js.Property(js.string(TYPES), unparsedTypes)); | |
439 | 467 |
440 return metadataGlobals; | 468 return metadataGlobals; |
441 } | 469 } |
442 | 470 |
443 js.Expression emitDeferredFragment(List<String> types, | 471 js.Expression emitDeferredFragment(List<String> types, |
444 DeferredFragment fragment, | 472 DeferredFragment fragment, |
445 List<Holder> holders) { | 473 List<Holder> holders) { |
446 // TODO(floitsch): initialize eager classes. | 474 // TODO(floitsch): initialize eager classes. |
447 // TODO(floitsch): the hash must depend on the output. | 475 // TODO(floitsch): the hash must depend on the output. |
448 int hash = fragment.hashCode; | 476 int hash = fragment.hashCode; |
449 | 477 |
450 List<js.Expression> deferredCode = | 478 List<js.Expression> deferredCode = |
451 fragment.libraries.map(emitLibrary).toList(); | 479 fragment.libraries.map(emitLibrary).toList(); |
452 | 480 |
453 deferredCode.add( | 481 deferredCode.add( |
454 emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields)); | 482 emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields)); |
455 | 483 |
456 deferredCode.add(emitConstants(fragment.constants)); | 484 deferredCode.add(emitConstants(fragment.constants)); |
457 | 485 |
458 js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode); | 486 js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode); |
459 | 487 |
460 // This is the code that must be evaluated after all deferred classes have | 488 // This is the code that must be evaluated after all deferred classes have |
461 // been setup. | 489 // been setup. |
462 js.Statement immediateCode = | 490 js.Statement immediateCode = |
463 emitEagerClassInitializations(fragment.libraries); | 491 emitEagerClassInitializations(fragment.libraries); |
464 | 492 |
465 js.LiteralString immediateString = unparse(compiler, immediateCode); | 493 js.LiteralString immediateString = unparse(compiler, immediateCode); |
466 | 494 |
467 js.Expression deferredTypes = types == null | 495 js.Expression deferredTypes = (types == null) |
468 ? js.string("[]") | 496 ? js.string("[]") |
469 : js.string("[${types.join(",")}]"); | 497 : js.string("[${types.join(",")}]"); |
470 | 498 |
471 js.ArrayInitializer hunk = | 499 js.ArrayInitializer hunk = |
472 new js.ArrayInitializer([deferredArray, immediateString, | 500 new js.ArrayInitializer([deferredArray, immediateString, |
473 deferredTypes]); | 501 deferredTypes]); |
474 | 502 |
475 return js.js("$deferredInitializersGlobal[$hash] = #", hunk); | 503 return js.js("$deferredInitializersGlobal[$hash] = #", hunk); |
476 } | 504 } |
477 | 505 |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1155 #nativeInfoHandler; | 1183 #nativeInfoHandler; |
1156 } | 1184 } |
1157 } | 1185 } |
1158 } | 1186 } |
1159 | 1187 |
1160 $setupProgramName(program, 0); | 1188 $setupProgramName(program, 0); |
1161 | 1189 |
1162 // Initialize globals. | 1190 // Initialize globals. |
1163 #embeddedGlobals; | 1191 #embeddedGlobals; |
1164 | 1192 |
1193 function expressionCompile(__s__) { | |
1194 'use strict'; | |
1195 return eval('(' + __s__ + ')'); | |
1196 } | |
1197 | |
1198 #readMetadataTypeFunction; | |
1199 | |
1165 // TODO(floitsch): this order means that native classes may not be | 1200 // TODO(floitsch): this order means that native classes may not be |
1166 // referenced from constants. I'm mostly afraid of things like using them as | 1201 // referenced from constants. I'm mostly afraid of things like using them as |
1167 // generic arguments (which should be fine, but maybe there are other | 1202 // generic arguments (which should be fine, but maybe there are other |
1168 // similar things). | 1203 // similar things). |
1169 // Initialize natives. | 1204 // Initialize natives. |
1170 if (#needsNativeSupport) handleNativeClassInfos(); | 1205 if (#needsNativeSupport) handleNativeClassInfos(); |
1171 | 1206 |
1172 // Initialize static non-final fields. | 1207 // Initialize static non-final fields. |
1173 #staticNonFinals; | 1208 #staticNonFinals; |
1174 | 1209 |
1175 // Add native boilerplate code. | 1210 // Add native boilerplate code. |
1176 #nativeIsolateAffinityTagInitialization; | 1211 #nativeIsolateAffinityTagInitialization; |
1177 | 1212 |
1178 // Initialize eager classes. | 1213 // Initialize eager classes. |
1179 #eagerClasses; | 1214 #eagerClasses; |
1180 | 1215 |
1181 var end = Date.now(); | 1216 var end = Date.now(); |
1182 // print('Setup: ' + (end - start) + ' ms.'); | 1217 // print('Setup: ' + (end - start) + ' ms.'); |
1183 | 1218 |
1184 #invokeMain; // Start main. | 1219 #invokeMain; // Start main. |
1185 | 1220 |
1186 }(Date.now(), #code) | 1221 }(Date.now(), #code) |
1187 }"""; | 1222 }"""; |
1188 | 1223 |
1189 } | 1224 } |
OLD | NEW |