Chromium Code Reviews| 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); |
|
floitsch
2014/12/29 18:09:12
Ok with change, but we could have just removed the
zarah
2014/12/30 10:29:25
Done, in another cl.
| |
| 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) { | 596 jsAst.Node optional(bool condition, jsAst.Node node) { |
|
floitsch
2014/12/29 18:09:12
Since you are doing cleanups: I believe this funct
zarah
2014/12/30 10:29:26
Done.
| |
| 597 return condition ? node : new jsAst.EmptyStatement(); | 597 return condition ? node : new jsAst.EmptyStatement(); |
| 598 } | 598 } |
| 599 | 599 |
| 600 jsAst.Statement buildFinishClass() { | 600 jsAst.Statement buildFinishClass() { |
| 601 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" | 601 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" |
| 602 | 602 |
| 603 jsAst.Expression finishedClassesAccess = | 603 jsAst.Expression finishedClassesAccess = |
| 604 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); | 604 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); |
| 605 jsAst.Expression interceptorsByTagAccess = | 605 jsAst.Expression interceptorsByTagAccess = |
| 606 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); | 606 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 779 | 779 |
| 780 jsAst.Fun get lazyInitializerFunction { | 780 jsAst.Fun get lazyInitializerFunction { |
| 781 String isolate = namer.currentIsolate; | 781 String isolate = namer.currentIsolate; |
| 782 jsAst.Expression cyclicThrow = | 782 jsAst.Expression cyclicThrow = |
| 783 staticFunctionAccess(backend.getCyclicThrowHelper()); | 783 staticFunctionAccess(backend.getCyclicThrowHelper()); |
| 784 jsAst.Expression laziesAccess = | 784 jsAst.Expression laziesAccess = |
| 785 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); | 785 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); |
| 786 | 786 |
| 787 return js(''' | 787 return js(''' |
| 788 function (prototype, staticName, fieldName, getterName, lazyValue) { | 788 function (prototype, staticName, fieldName, getterName, lazyValue) { |
| 789 if (!#) # = Object.create(null); | 789 if (!#lazies) #lazies = Object.create(null); |
| 790 #[fieldName] = getterName; | 790 #lazies[fieldName] = getterName; |
| 791 | 791 |
| 792 var sentinelUndefined = {}; | 792 var sentinelUndefined = {}; |
| 793 var sentinelInProgress = {}; | 793 var sentinelInProgress = {}; |
| 794 prototype[fieldName] = sentinelUndefined; | 794 prototype[fieldName] = sentinelUndefined; |
| 795 | 795 |
| 796 prototype[getterName] = function () { | 796 prototype[getterName] = function () { |
| 797 var result = $isolate[fieldName]; | 797 var result = $isolate[fieldName]; |
| 798 try { | 798 try { |
| 799 if (result === sentinelUndefined) { | 799 if (result === sentinelUndefined) { |
| 800 $isolate[fieldName] = sentinelInProgress; | 800 $isolate[fieldName] = sentinelInProgress; |
| 801 | 801 |
| 802 try { | 802 try { |
| 803 result = $isolate[fieldName] = lazyValue(); | 803 result = $isolate[fieldName] = lazyValue(); |
| 804 } finally { | 804 } finally { |
| 805 // Use try-finally, not try-catch/throw as it destroys the | 805 // Use try-finally, not try-catch/throw as it destroys the |
| 806 // stack trace. | 806 // stack trace. |
| 807 if (result === sentinelUndefined) | 807 if (result === sentinelUndefined) |
| 808 $isolate[fieldName] = null; | 808 $isolate[fieldName] = null; |
| 809 } | 809 } |
| 810 } else { | 810 } else { |
| 811 if (result === sentinelInProgress) | 811 if (result === sentinelInProgress) |
| 812 #(staticName); | 812 #cyclicThrow(staticName); |
| 813 } | 813 } |
| 814 | 814 |
| 815 return result; | 815 return result; |
| 816 } finally { | 816 } finally { |
| 817 $isolate[getterName] = function() { return this[fieldName]; }; | 817 $isolate[getterName] = function() { return this[fieldName]; }; |
| 818 } | 818 } |
| 819 } | 819 } |
| 820 } | 820 } |
| 821 ''', [laziesAccess, laziesAccess, | 821 ''', {'lazies': laziesAccess, 'cyclicThrow': cyclicThrow}); |
| 822 laziesAccess, | |
| 823 cyclicThrow]); | |
| 824 } | 822 } |
| 825 | 823 |
| 826 List buildDefineClassAndFinishClassFunctionsIfNecessary() { | 824 List buildDefineClassAndFinishClassFunctionsIfNecessary() { |
| 827 if (!needsDefineClass) return []; | 825 if (!needsDefineClass) return []; |
| 828 return defineClassFunction | 826 return defineClassFunction |
| 829 ..add(buildInheritFrom()) | 827 ..add(buildInheritFrom()) |
| 830 ..add(js('$finishClassesName = #', finishClassesFunction)) | 828 ..add(js('$finishClassesName = #', finishClassesFunction)) |
| 831 ..add(initFinishClasses); | 829 ..add(initFinishClasses); |
| 832 } | 830 } |
| 833 | 831 |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1218 return js(''' | 1216 return js(''' |
| 1219 !function() { | 1217 !function() { |
| 1220 // On V8, the 'intern' function converts a string to a symbol, which | 1218 // On V8, the 'intern' function converts a string to a symbol, which |
| 1221 // makes property access much faster. | 1219 // makes property access much faster. |
| 1222 function intern(s) { | 1220 function intern(s) { |
| 1223 var o = {}; | 1221 var o = {}; |
| 1224 o[s] = 1; | 1222 o[s] = 1; |
| 1225 return Object.keys(convertToFastObject(o))[0]; | 1223 return Object.keys(convertToFastObject(o))[0]; |
| 1226 } | 1224 } |
| 1227 | 1225 |
| 1228 # = function(name) { // embedded getIsolateTag | 1226 #getIsolateTag = function(name) { |
| 1229 return intern("___dart_" + name + #); // embedded isolateTag | 1227 return intern("___dart_" + name + #isolateTag); |
| 1230 }; | 1228 }; |
| 1231 | 1229 |
| 1232 // To ensure that different programs loaded into the same context (page) | 1230 // To ensure that different programs loaded into the same context (page) |
| 1233 // use distinct dispatch properies, we place an object on `Object` to | 1231 // use distinct dispatch properies, we place an object on `Object` to |
| 1234 // contain the names already in use. | 1232 // contain the names already in use. |
| 1235 var tableProperty = "___dart_isolate_tags_"; | 1233 var tableProperty = "___dart_isolate_tags_"; |
| 1236 var usedProperties = Object[tableProperty] || | 1234 var usedProperties = Object[tableProperty] || |
| 1237 (Object[tableProperty] = Object.create(null)); | 1235 (Object[tableProperty] = Object.create(null)); |
| 1238 | 1236 |
| 1239 var rootProperty = "_${generateIsolateTagRoot()}"; | 1237 var rootProperty = "_${generateIsolateTagRoot()}"; |
| 1240 for (var i = 0; ; i++) { | 1238 for (var i = 0; ; i++) { |
| 1241 var property = intern(rootProperty + "_" + i + "_"); | 1239 var property = intern(rootProperty + "_" + i + "_"); |
| 1242 if (!(property in usedProperties)) { | 1240 if (!(property in usedProperties)) { |
| 1243 usedProperties[property] = 1; | 1241 usedProperties[property] = 1; |
| 1244 # = property; // embedded isolateTag | 1242 #isolateTag = property; |
| 1245 break; | 1243 break; |
| 1246 } | 1244 } |
| 1247 } | 1245 } |
| 1248 }() | 1246 }() |
| 1249 ''', [getIsolateTagAccess, | 1247 ''', |
| 1250 isolateTagAccess, | 1248 {'getIsolateTag': getIsolateTagAccess, 'isolateTag': isolateTagAccess}); |
| 1251 isolateTagAccess]); | |
| 1252 } | 1249 } |
| 1253 | 1250 |
| 1254 jsAst.Expression generateDispatchPropertyNameInitialization() { | 1251 jsAst.Expression generateDispatchPropertyNameInitialization() { |
| 1255 jsAst.Expression dispatchPropertyNameAccess = | 1252 jsAst.Expression dispatchPropertyNameAccess = |
| 1256 generateEmbeddedGlobalAccess(embeddedNames.DISPATCH_PROPERTY_NAME); | 1253 generateEmbeddedGlobalAccess(embeddedNames.DISPATCH_PROPERTY_NAME); |
| 1257 jsAst.Expression getIsolateTagAccess = | 1254 jsAst.Expression getIsolateTagAccess = |
| 1258 generateEmbeddedGlobalAccess(embeddedNames.GET_ISOLATE_TAG); | 1255 generateEmbeddedGlobalAccess(embeddedNames.GET_ISOLATE_TAG); |
| 1259 return js('# = #("dispatch_record")', | 1256 return js('# = #("dispatch_record")', |
| 1260 [dispatchPropertyNameAccess, | 1257 [dispatchPropertyNameAccess, |
| 1261 getIsolateTagAccess]); | 1258 getIsolateTagAccess]); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1319 function onLoad(event) { | 1316 function onLoad(event) { |
| 1320 for (var i = 0; i < scripts.length; ++i) { | 1317 for (var i = 0; i < scripts.length; ++i) { |
| 1321 scripts[i].removeEventListener("load", onLoad, false); | 1318 scripts[i].removeEventListener("load", onLoad, false); |
| 1322 } | 1319 } |
| 1323 callback(event.target); | 1320 callback(event.target); |
| 1324 } | 1321 } |
| 1325 for (var i = 0; i < scripts.length; ++i) { | 1322 for (var i = 0; i < scripts.length; ++i) { |
| 1326 scripts[i].addEventListener("load", onLoad, false); | 1323 scripts[i].addEventListener("load", onLoad, false); |
| 1327 } | 1324 } |
| 1328 })(function(currentScript) { | 1325 })(function(currentScript) { |
| 1329 # = currentScript; // embedded currentScript. | 1326 #currentScript = currentScript; |
| 1330 | 1327 |
| 1331 if (typeof dartMainRunner === "function") { | 1328 if (typeof dartMainRunner === "function") { |
| 1332 dartMainRunner(#, []); // mainCallClosure. | 1329 dartMainRunner(#mainCallClosure, []); |
| 1333 } else { | 1330 } else { |
| 1334 #([]); // mainCallClosure. | 1331 #mainCallClosure([]); |
| 1335 } | 1332 } |
| 1336 })$N''', [currentScriptAccess, | 1333 })$N''', {'currentScript': currentScriptAccess, |
|
floitsch
2014/12/29 18:09:12
I could be wrong, but I believe that the "$N" here
zarah
2014/12/30 10:29:26
I agree.
| |
| 1337 mainCallClosure, | 1334 'mainCallClosure': mainCallClosure}); |
| 1338 mainCallClosure]); | |
| 1339 | 1335 |
| 1340 buffer.write(';'); | 1336 buffer.write(';'); |
| 1341 buffer.write(jsAst.prettyPrint(invokeMain, | 1337 buffer.write(jsAst.prettyPrint(invokeMain, |
| 1342 compiler, monitor: compiler.dumpInfoTask)); | 1338 compiler, monitor: compiler.dumpInfoTask)); |
| 1343 buffer.write(N); | 1339 buffer.write(N); |
| 1344 addComment('END invoke [main].', buffer); | 1340 addComment('END invoke [main].', buffer); |
| 1345 } | 1341 } |
| 1346 | 1342 |
| 1347 void emitInitFunction(CodeBuffer buffer) { | 1343 void emitInitFunction(CodeBuffer buffer) { |
| 1348 jsAst.FunctionDeclaration decl = js.statement(''' | 1344 jsAst.FunctionDeclaration decl = js.statement(''' |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1678 if (needsDefineClass || | 1674 if (needsDefineClass || |
| 1679 !(nativeClasses.isEmpty && | 1675 !(nativeClasses.isEmpty && |
| 1680 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty && | 1676 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty && |
| 1681 outputClassLists.values.every((classList) => classList.isEmpty) && | 1677 outputClassLists.values.every((classList) => classList.isEmpty) && |
| 1682 typedefsNeededForReflection.isEmpty)) { | 1678 typedefsNeededForReflection.isEmpty)) { |
| 1683 // Shorten the code by using "$$" as temporary. | 1679 // Shorten the code by using "$$" as temporary. |
| 1684 classesCollector = r"$$"; | 1680 classesCollector = r"$$"; |
| 1685 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n'); | 1681 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n'); |
| 1686 } | 1682 } |
| 1687 | 1683 |
| 1688 if (!nativeClasses.isEmpty) { | |
| 1689 addComment('Native classes', mainBuffer); | |
| 1690 } | |
| 1691 | |
| 1692 List<ClassElement> classes = task.outputClassLists[mainOutputUnit]; | 1684 List<ClassElement> classes = task.outputClassLists[mainOutputUnit]; |
| 1693 if (classes != null) { | 1685 if (classes != null) { |
| 1694 for (ClassElement element in classes) { | 1686 for (ClassElement element in classes) { |
| 1695 generateClass(element, getElementDescriptor(element)); | 1687 generateClass(element, getElementDescriptor(element)); |
| 1696 } | 1688 } |
| 1697 } | 1689 } |
| 1698 | 1690 |
| 1699 if (compiler.enableMinification) { | 1691 if (compiler.enableMinification) { |
| 1700 mainBuffer.write(';'); | 1692 mainBuffer.write(';'); |
| 1701 } | 1693 } |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2288 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2280 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 2289 if (element.isInstanceMember) { | 2281 if (element.isInstanceMember) { |
| 2290 cachedClassBuilders.remove(element.enclosingClass); | 2282 cachedClassBuilders.remove(element.enclosingClass); |
| 2291 | 2283 |
| 2292 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2284 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 2293 | 2285 |
| 2294 } | 2286 } |
| 2295 } | 2287 } |
| 2296 } | 2288 } |
| 2297 } | 2289 } |
| OLD | NEW |