| 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 | 7 |
| 8 class OldEmitter implements Emitter { | 8 class OldEmitter implements Emitter { |
| 9 final Compiler compiler; | 9 final Compiler compiler; |
| 10 final CodeEmitterTask task; | 10 final CodeEmitterTask task; |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); | 450 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); |
| 451 jsAst.Expression interceptorsByTagAccess = | 451 jsAst.Expression interceptorsByTagAccess = |
| 452 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); | 452 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); |
| 453 jsAst.Expression leafTagsAccess = | 453 jsAst.Expression leafTagsAccess = |
| 454 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); | 454 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); |
| 455 jsAst.Expression finishedClassesAccess = | 455 jsAst.Expression finishedClassesAccess = |
| 456 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); | 456 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); |
| 457 | 457 |
| 458 return js(''' | 458 return js(''' |
| 459 (function(){ | 459 (function(){ |
| 460 # = Object.create(null); // embedded allClasses. | 460 #allClasses = Object.create(null); |
| 461 # = Object.create(null); // embedded interceptorsByTag. | 461 #interceptorsByTag = Object.create(null); |
| 462 # = Object.create(null); // embedded leafTags. | 462 #leafTags = Object.create(null); |
| 463 # = Object.create(null); // embedded finishedClasses | 463 #finishedClasses = Object.create(null); |
| 464 })() | 464 })() |
| 465 ''', [allClassesAccess, | 465 ''', {'allClasses': allClassesAccess, |
| 466 interceptorsByTagAccess, | 466 'interceptorsByTag': interceptorsByTagAccess, |
| 467 leafTagsAccess, | 467 'leafTags': leafTagsAccess, |
| 468 finishedClassesAccess]); | 468 'finishedClasses': finishedClassesAccess}); |
| 469 } | 469 } |
| 470 | 470 |
| 471 jsAst.Fun get finishClassesFunction { | 471 jsAst.Fun get finishClassesFunction { |
| 472 // Class descriptions are collected in a JS object. | 472 // Class descriptions are collected in a JS object. |
| 473 // 'finishClasses' takes all collected descriptions and sets up | 473 // 'finishClasses' takes all collected descriptions and sets up |
| 474 // the prototype. | 474 // the prototype. |
| 475 // Once set up, the constructors prototype field satisfy: | 475 // Once set up, the constructors prototype field satisfy: |
| 476 // - it contains all (local) members. | 476 // - it contains all (local) members. |
| 477 // - its internal prototype (__proto__) points to the superclass' | 477 // - its internal prototype (__proto__) points to the superclass' |
| 478 // prototype field. | 478 // prototype field. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 'debugFastObjects': DEBUG_FAST_OBJECTS, | 586 'debugFastObjects': DEBUG_FAST_OBJECTS, |
| 587 'hasRetainedMetadata': backend.hasRetainedMetadata, | 587 'hasRetainedMetadata': backend.hasRetainedMetadata, |
| 588 'metadata': metadataAccess, | 588 'metadata': metadataAccess, |
| 589 'isTreeShakingDisabled': backend.isTreeShakingDisabled, | 589 'isTreeShakingDisabled': backend.isTreeShakingDisabled, |
| 590 'finishClassFunction': buildFinishClass(), | 590 'finishClassFunction': buildFinishClass(), |
| 591 'trivialNsmHandlers': nsmEmitter.buildTrivialNsmHandlers(), | 591 'trivialNsmHandlers': nsmEmitter.buildTrivialNsmHandlers(), |
| 592 'inCspMode': compiler.useContentSecurityPolicy, | 592 'inCspMode': compiler.useContentSecurityPolicy, |
| 593 'notInCspMode': !compiler.useContentSecurityPolicy}); | 593 'notInCspMode': !compiler.useContentSecurityPolicy}); |
| 594 } | 594 } |
| 595 | 595 |
| 596 jsAst.Node optional(bool condition, jsAst.Node node) { | |
| 597 return condition ? node : new jsAst.EmptyStatement(); | |
| 598 } | |
| 599 | |
| 600 jsAst.Statement buildFinishClass() { | 596 jsAst.Statement buildFinishClass() { |
| 601 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" | 597 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" |
| 602 | 598 |
| 603 jsAst.Expression finishedClassesAccess = | 599 jsAst.Expression finishedClassesAccess = |
| 604 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); | 600 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); |
| 605 jsAst.Expression interceptorsByTagAccess = | 601 jsAst.Expression interceptorsByTagAccess = |
| 606 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); | 602 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); |
| 607 jsAst.Expression leafTagsAccess = | 603 jsAst.Expression leafTagsAccess = |
| 608 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); | 604 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); |
| 609 | 605 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 | 775 |
| 780 jsAst.Fun get lazyInitializerFunction { | 776 jsAst.Fun get lazyInitializerFunction { |
| 781 String isolate = namer.currentIsolate; | 777 String isolate = namer.currentIsolate; |
| 782 jsAst.Expression cyclicThrow = | 778 jsAst.Expression cyclicThrow = |
| 783 staticFunctionAccess(backend.getCyclicThrowHelper()); | 779 staticFunctionAccess(backend.getCyclicThrowHelper()); |
| 784 jsAst.Expression laziesAccess = | 780 jsAst.Expression laziesAccess = |
| 785 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); | 781 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); |
| 786 | 782 |
| 787 return js(''' | 783 return js(''' |
| 788 function (prototype, staticName, fieldName, getterName, lazyValue) { | 784 function (prototype, staticName, fieldName, getterName, lazyValue) { |
| 789 if (!#) # = Object.create(null); | 785 if (!#lazies) #lazies = Object.create(null); |
| 790 #[fieldName] = getterName; | 786 #lazies[fieldName] = getterName; |
| 791 | 787 |
| 792 var sentinelUndefined = {}; | 788 var sentinelUndefined = {}; |
| 793 var sentinelInProgress = {}; | 789 var sentinelInProgress = {}; |
| 794 prototype[fieldName] = sentinelUndefined; | 790 prototype[fieldName] = sentinelUndefined; |
| 795 | 791 |
| 796 prototype[getterName] = function () { | 792 prototype[getterName] = function () { |
| 797 var result = $isolate[fieldName]; | 793 var result = $isolate[fieldName]; |
| 798 try { | 794 try { |
| 799 if (result === sentinelUndefined) { | 795 if (result === sentinelUndefined) { |
| 800 $isolate[fieldName] = sentinelInProgress; | 796 $isolate[fieldName] = sentinelInProgress; |
| 801 | 797 |
| 802 try { | 798 try { |
| 803 result = $isolate[fieldName] = lazyValue(); | 799 result = $isolate[fieldName] = lazyValue(); |
| 804 } finally { | 800 } finally { |
| 805 // Use try-finally, not try-catch/throw as it destroys the | 801 // Use try-finally, not try-catch/throw as it destroys the |
| 806 // stack trace. | 802 // stack trace. |
| 807 if (result === sentinelUndefined) | 803 if (result === sentinelUndefined) |
| 808 $isolate[fieldName] = null; | 804 $isolate[fieldName] = null; |
| 809 } | 805 } |
| 810 } else { | 806 } else { |
| 811 if (result === sentinelInProgress) | 807 if (result === sentinelInProgress) |
| 812 #(staticName); | 808 #cyclicThrow(staticName); |
| 813 } | 809 } |
| 814 | 810 |
| 815 return result; | 811 return result; |
| 816 } finally { | 812 } finally { |
| 817 $isolate[getterName] = function() { return this[fieldName]; }; | 813 $isolate[getterName] = function() { return this[fieldName]; }; |
| 818 } | 814 } |
| 819 } | 815 } |
| 820 } | 816 } |
| 821 ''', [laziesAccess, laziesAccess, | 817 ''', {'lazies': laziesAccess, 'cyclicThrow': cyclicThrow}); |
| 822 laziesAccess, | |
| 823 cyclicThrow]); | |
| 824 } | 818 } |
| 825 | 819 |
| 826 List buildDefineClassAndFinishClassFunctionsIfNecessary() { | 820 List buildDefineClassAndFinishClassFunctionsIfNecessary() { |
| 827 if (!needsDefineClass) return []; | 821 if (!needsDefineClass) return []; |
| 828 return defineClassFunction | 822 return defineClassFunction |
| 829 ..add(buildInheritFrom()) | 823 ..add(buildInheritFrom()) |
| 830 ..add(js('$finishClassesName = #', finishClassesFunction)) | 824 ..add(js('$finishClassesName = #', finishClassesFunction)) |
| 831 ..add(initFinishClasses); | 825 ..add(initFinishClasses); |
| 832 } | 826 } |
| 833 | 827 |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1218 return js(''' | 1212 return js(''' |
| 1219 !function() { | 1213 !function() { |
| 1220 // On V8, the 'intern' function converts a string to a symbol, which | 1214 // On V8, the 'intern' function converts a string to a symbol, which |
| 1221 // makes property access much faster. | 1215 // makes property access much faster. |
| 1222 function intern(s) { | 1216 function intern(s) { |
| 1223 var o = {}; | 1217 var o = {}; |
| 1224 o[s] = 1; | 1218 o[s] = 1; |
| 1225 return Object.keys(convertToFastObject(o))[0]; | 1219 return Object.keys(convertToFastObject(o))[0]; |
| 1226 } | 1220 } |
| 1227 | 1221 |
| 1228 # = function(name) { // embedded getIsolateTag | 1222 #getIsolateTag = function(name) { |
| 1229 return intern("___dart_" + name + #); // embedded isolateTag | 1223 return intern("___dart_" + name + #isolateTag); |
| 1230 }; | 1224 }; |
| 1231 | 1225 |
| 1232 // To ensure that different programs loaded into the same context (page) | 1226 // To ensure that different programs loaded into the same context (page) |
| 1233 // use distinct dispatch properies, we place an object on `Object` to | 1227 // use distinct dispatch properies, we place an object on `Object` to |
| 1234 // contain the names already in use. | 1228 // contain the names already in use. |
| 1235 var tableProperty = "___dart_isolate_tags_"; | 1229 var tableProperty = "___dart_isolate_tags_"; |
| 1236 var usedProperties = Object[tableProperty] || | 1230 var usedProperties = Object[tableProperty] || |
| 1237 (Object[tableProperty] = Object.create(null)); | 1231 (Object[tableProperty] = Object.create(null)); |
| 1238 | 1232 |
| 1239 var rootProperty = "_${generateIsolateTagRoot()}"; | 1233 var rootProperty = "_${generateIsolateTagRoot()}"; |
| 1240 for (var i = 0; ; i++) { | 1234 for (var i = 0; ; i++) { |
| 1241 var property = intern(rootProperty + "_" + i + "_"); | 1235 var property = intern(rootProperty + "_" + i + "_"); |
| 1242 if (!(property in usedProperties)) { | 1236 if (!(property in usedProperties)) { |
| 1243 usedProperties[property] = 1; | 1237 usedProperties[property] = 1; |
| 1244 # = property; // embedded isolateTag | 1238 #isolateTag = property; |
| 1245 break; | 1239 break; |
| 1246 } | 1240 } |
| 1247 } | 1241 } |
| 1248 }() | 1242 }() |
| 1249 ''', [getIsolateTagAccess, | 1243 ''', |
| 1250 isolateTagAccess, | 1244 {'getIsolateTag': getIsolateTagAccess, 'isolateTag': isolateTagAccess}); |
| 1251 isolateTagAccess]); | |
| 1252 } | 1245 } |
| 1253 | 1246 |
| 1254 jsAst.Expression generateDispatchPropertyNameInitialization() { | 1247 jsAst.Expression generateDispatchPropertyNameInitialization() { |
| 1255 jsAst.Expression dispatchPropertyNameAccess = | 1248 jsAst.Expression dispatchPropertyNameAccess = |
| 1256 generateEmbeddedGlobalAccess(embeddedNames.DISPATCH_PROPERTY_NAME); | 1249 generateEmbeddedGlobalAccess(embeddedNames.DISPATCH_PROPERTY_NAME); |
| 1257 jsAst.Expression getIsolateTagAccess = | 1250 jsAst.Expression getIsolateTagAccess = |
| 1258 generateEmbeddedGlobalAccess(embeddedNames.GET_ISOLATE_TAG); | 1251 generateEmbeddedGlobalAccess(embeddedNames.GET_ISOLATE_TAG); |
| 1259 return js('# = #("dispatch_record")', | 1252 return js('# = #("dispatch_record")', |
| 1260 [dispatchPropertyNameAccess, | 1253 [dispatchPropertyNameAccess, |
| 1261 getIsolateTagAccess]); | 1254 getIsolateTagAccess]); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1319 function onLoad(event) { | 1312 function onLoad(event) { |
| 1320 for (var i = 0; i < scripts.length; ++i) { | 1313 for (var i = 0; i < scripts.length; ++i) { |
| 1321 scripts[i].removeEventListener("load", onLoad, false); | 1314 scripts[i].removeEventListener("load", onLoad, false); |
| 1322 } | 1315 } |
| 1323 callback(event.target); | 1316 callback(event.target); |
| 1324 } | 1317 } |
| 1325 for (var i = 0; i < scripts.length; ++i) { | 1318 for (var i = 0; i < scripts.length; ++i) { |
| 1326 scripts[i].addEventListener("load", onLoad, false); | 1319 scripts[i].addEventListener("load", onLoad, false); |
| 1327 } | 1320 } |
| 1328 })(function(currentScript) { | 1321 })(function(currentScript) { |
| 1329 # = currentScript; // embedded currentScript. | 1322 #currentScript = currentScript; |
| 1330 | 1323 |
| 1331 if (typeof dartMainRunner === "function") { | 1324 if (typeof dartMainRunner === "function") { |
| 1332 dartMainRunner(#, []); // mainCallClosure. | 1325 dartMainRunner(#mainCallClosure, []); |
| 1333 } else { | 1326 } else { |
| 1334 #([]); // mainCallClosure. | 1327 #mainCallClosure([]); |
| 1335 } | 1328 } |
| 1336 })$N''', [currentScriptAccess, | 1329 })''', {'currentScript': currentScriptAccess, |
| 1337 mainCallClosure, | 1330 'mainCallClosure': mainCallClosure}); |
| 1338 mainCallClosure]); | |
| 1339 | 1331 |
| 1340 buffer.write(';'); | 1332 buffer.write(';'); |
| 1341 buffer.write(jsAst.prettyPrint(invokeMain, | 1333 buffer.write(jsAst.prettyPrint(invokeMain, |
| 1342 compiler, monitor: compiler.dumpInfoTask)); | 1334 compiler, monitor: compiler.dumpInfoTask)); |
| 1343 buffer.write(N); | 1335 buffer.write(N); |
| 1344 addComment('END invoke [main].', buffer); | 1336 addComment('END invoke [main].', buffer); |
| 1345 } | 1337 } |
| 1346 | 1338 |
| 1347 void emitInitFunction(CodeBuffer buffer) { | 1339 void emitInitFunction(CodeBuffer buffer) { |
| 1348 jsAst.FunctionDeclaration decl = js.statement(''' | 1340 jsAst.FunctionDeclaration decl = js.statement(''' |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1678 if (needsDefineClass || | 1670 if (needsDefineClass || |
| 1679 !(nativeClasses.isEmpty && | 1671 !(nativeClasses.isEmpty && |
| 1680 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty && | 1672 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty && |
| 1681 outputClassLists.values.every((classList) => classList.isEmpty) && | 1673 outputClassLists.values.every((classList) => classList.isEmpty) && |
| 1682 typedefsNeededForReflection.isEmpty)) { | 1674 typedefsNeededForReflection.isEmpty)) { |
| 1683 // Shorten the code by using "$$" as temporary. | 1675 // Shorten the code by using "$$" as temporary. |
| 1684 classesCollector = r"$$"; | 1676 classesCollector = r"$$"; |
| 1685 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n'); | 1677 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n'); |
| 1686 } | 1678 } |
| 1687 | 1679 |
| 1688 if (!nativeClasses.isEmpty) { | |
| 1689 addComment('Native classes', mainBuffer); | |
| 1690 } | |
| 1691 | |
| 1692 List<ClassElement> classes = task.outputClassLists[mainOutputUnit]; | 1680 List<ClassElement> classes = task.outputClassLists[mainOutputUnit]; |
| 1693 if (classes != null) { | 1681 if (classes != null) { |
| 1694 for (ClassElement element in classes) { | 1682 for (ClassElement element in classes) { |
| 1695 generateClass(element, getElementDescriptor(element)); | 1683 generateClass(element, getElementDescriptor(element)); |
| 1696 } | 1684 } |
| 1697 } | 1685 } |
| 1698 | 1686 |
| 1699 if (compiler.enableMinification) { | 1687 if (compiler.enableMinification) { |
| 1700 mainBuffer.write(';'); | 1688 mainBuffer.write(';'); |
| 1701 } | 1689 } |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2288 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2276 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 2289 if (element.isInstanceMember) { | 2277 if (element.isInstanceMember) { |
| 2290 cachedClassBuilders.remove(element.enclosingClass); | 2278 cachedClassBuilders.remove(element.enclosingClass); |
| 2291 | 2279 |
| 2292 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2280 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 2293 | 2281 |
| 2294 } | 2282 } |
| 2295 } | 2283 } |
| 2296 } | 2284 } |
| 2297 } | 2285 } |
| OLD | NEW |