| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 * Generates the code for all used classes in the program. Static fields (even | 8 * Generates the code for all used classes in the program. Static fields (even |
| 9 * in classes) are ignored, since they can be treated as non-class elements. | 9 * in classes) are ignored, since they can be treated as non-class elements. |
| 10 * | 10 * |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 Isolate.$finishClassesProperty = oldIsolate.$finishClassesProperty; | 540 Isolate.$finishClassesProperty = oldIsolate.$finishClassesProperty; |
| 541 if (#) | 541 if (#) |
| 542 Isolate.makeConstantList = oldIsolate.makeConstantList; | 542 Isolate.makeConstantList = oldIsolate.makeConstantList; |
| 543 return Isolate; | 543 return Isolate; |
| 544 }''', | 544 }''', |
| 545 [ needsDefineClass, hasMakeConstantList ]); | 545 [ needsDefineClass, hasMakeConstantList ]); |
| 546 } | 546 } |
| 547 | 547 |
| 548 jsAst.Fun get lazyInitializerFunction { | 548 jsAst.Fun get lazyInitializerFunction { |
| 549 String isolate = namer.currentIsolate; | 549 String isolate = namer.currentIsolate; |
| 550 String cyclicThrow = namer.isolateAccess(backend.getCyclicThrowHelper()); | 550 jsAst.Expression cyclicThrow = |
| 551 namer.elementAccess(backend.getCyclicThrowHelper()); |
| 551 | 552 |
| 552 return js(''' | 553 return js(''' |
| 553 function (prototype, staticName, fieldName, getterName, lazyValue) { | 554 function (prototype, staticName, fieldName, getterName, lazyValue) { |
| 554 if (#) { | 555 if (#) { |
| 555 if (!init.lazies) init.lazies = {}; | 556 if (!init.lazies) init.lazies = {}; |
| 556 init.lazies[fieldName] = getterName; | 557 init.lazies[fieldName] = getterName; |
| 557 } | 558 } |
| 558 | 559 |
| 559 var sentinelUndefined = {}; | 560 var sentinelUndefined = {}; |
| 560 var sentinelInProgress = {}; | 561 var sentinelInProgress = {}; |
| 561 prototype[fieldName] = sentinelUndefined; | 562 prototype[fieldName] = sentinelUndefined; |
| 562 | 563 |
| 563 prototype[getterName] = function () { | 564 prototype[getterName] = function () { |
| 564 var result = $isolate[fieldName]; | 565 var result = $isolate[fieldName]; |
| 565 try { | 566 try { |
| 566 if (result === sentinelUndefined) { | 567 if (result === sentinelUndefined) { |
| 567 $isolate[fieldName] = sentinelInProgress; | 568 $isolate[fieldName] = sentinelInProgress; |
| 568 | 569 |
| 569 try { | 570 try { |
| 570 result = $isolate[fieldName] = lazyValue(); | 571 result = $isolate[fieldName] = lazyValue(); |
| 571 } finally { | 572 } finally { |
| 572 // Use try-finally, not try-catch/throw as it destroys the | 573 // Use try-finally, not try-catch/throw as it destroys the |
| 573 // stack trace. | 574 // stack trace. |
| 574 if (result === sentinelUndefined) | 575 if (result === sentinelUndefined) |
| 575 if ($isolate[fieldName] === sentinelInProgress) | 576 if ($isolate[fieldName] === sentinelInProgress) |
| 576 $isolate[fieldName] = null; | 577 $isolate[fieldName] = null; |
| 577 } | 578 } |
| 578 } else { | 579 } else { |
| 579 if (result === sentinelInProgress) | 580 if (result === sentinelInProgress) |
| 580 $cyclicThrow(staticName); | 581 #(staticName); |
| 581 } | 582 } |
| 582 | 583 |
| 583 return result; | 584 return result; |
| 584 } finally { | 585 } finally { |
| 585 $isolate[getterName] = function() { return this[fieldName]; }; | 586 $isolate[getterName] = function() { return this[fieldName]; }; |
| 586 } | 587 } |
| 587 } | 588 } |
| 588 } | 589 } |
| 589 ''', [backend.rememberLazies]); | 590 ''', [backend.rememberLazies, cyclicThrow]); |
| 590 } | 591 } |
| 591 | 592 |
| 592 List buildDefineClassAndFinishClassFunctionsIfNecessary() { | 593 List buildDefineClassAndFinishClassFunctionsIfNecessary() { |
| 593 if (!needsDefineClass) return []; | 594 if (!needsDefineClass) return []; |
| 594 return defineClassFunction | 595 return defineClassFunction |
| 595 ..addAll(buildInheritFrom()) | 596 ..addAll(buildInheritFrom()) |
| 596 ..addAll([ | 597 ..addAll([ |
| 597 js('$finishClassesName = #', finishClassesFunction) | 598 js('$finishClassesName = #', finishClassesFunction) |
| 598 ]); | 599 ]); |
| 599 } | 600 } |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 return list; | 952 return list; |
| 952 }; | 953 }; |
| 953 '''); | 954 '''); |
| 954 } | 955 } |
| 955 | 956 |
| 956 /// Returns the code equivalent to: | 957 /// Returns the code equivalent to: |
| 957 /// `function(args) { $.startRootIsolate(X.main$closure(), args); }` | 958 /// `function(args) { $.startRootIsolate(X.main$closure(), args); }` |
| 958 String buildIsolateSetupClosure(CodeBuffer buffer, | 959 String buildIsolateSetupClosure(CodeBuffer buffer, |
| 959 Element appMain, | 960 Element appMain, |
| 960 Element isolateMain) { | 961 Element isolateMain) { |
| 961 String mainAccess = "${namer.isolateStaticClosureAccess(appMain)}"; | 962 jsAst.Expression mainAccess = namer.isolateStaticClosureAccess(appMain); |
| 962 // Since we pass the closurized version of the main method to | 963 // Since we pass the closurized version of the main method to |
| 963 // the isolate method, we must make sure that it exists. | 964 // the isolate method, we must make sure that it exists. |
| 964 return "(function(a){${namer.isolateAccess(isolateMain)}($mainAccess,a)})"; | 965 jsAst.Expression setup = js('function(a){ #(#, a); }', |
| 966 [namer.elementAccess(isolateMain), mainAccess]); |
| 967 |
| 968 return jsAst.prettyPrint(setup, compiler).getText(); |
| 965 } | 969 } |
| 966 | 970 |
| 967 /** | 971 /** |
| 968 * Emits code that sets `init.isolateTag` to a unique string. | 972 * Emits code that sets `init.isolateTag` to a unique string. |
| 969 */ | 973 */ |
| 970 jsAst.Expression generateIsolateAffinityTagInitialization() { | 974 jsAst.Expression generateIsolateAffinityTagInitialization() { |
| 971 return js(''' | 975 return js(''' |
| 972 !function() { | 976 !function() { |
| 973 // On V8, the 'intern' function converts a string to a symbol, which | 977 // On V8, the 'intern' function converts a string to a symbol, which |
| 974 // makes property access much faster. | 978 // makes property access much faster. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 | 1018 |
| 1015 emitMain(CodeBuffer buffer) { | 1019 emitMain(CodeBuffer buffer) { |
| 1016 if (compiler.isMockCompilation) return; | 1020 if (compiler.isMockCompilation) return; |
| 1017 Element main = compiler.mainFunction; | 1021 Element main = compiler.mainFunction; |
| 1018 String mainCallClosure = null; | 1022 String mainCallClosure = null; |
| 1019 if (compiler.hasIsolateSupport()) { | 1023 if (compiler.hasIsolateSupport()) { |
| 1020 Element isolateMain = | 1024 Element isolateMain = |
| 1021 compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE); | 1025 compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE); |
| 1022 mainCallClosure = buildIsolateSetupClosure(buffer, main, isolateMain); | 1026 mainCallClosure = buildIsolateSetupClosure(buffer, main, isolateMain); |
| 1023 } else { | 1027 } else { |
| 1028 // TODO(sra): Replace with AST. |
| 1024 mainCallClosure = '${namer.isolateAccess(main)}'; | 1029 mainCallClosure = '${namer.isolateAccess(main)}'; |
| 1025 } | 1030 } |
| 1026 | 1031 |
| 1027 if (backend.needToInitializeIsolateAffinityTag) { | 1032 if (backend.needToInitializeIsolateAffinityTag) { |
| 1028 buffer.write( | 1033 buffer.write( |
| 1029 jsAst.prettyPrint(generateIsolateAffinityTagInitialization(), | 1034 jsAst.prettyPrint(generateIsolateAffinityTagInitialization(), |
| 1030 compiler)); | 1035 compiler)); |
| 1031 buffer.write(N); | 1036 buffer.write(N); |
| 1032 } | 1037 } |
| 1033 if (backend.needToInitializeDispatchProperty) { | 1038 if (backend.needToInitializeDispatchProperty) { |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1185 function MyClass() {}; | 1190 function MyClass() {}; |
| 1186 MyClass.prototype = properties; | 1191 MyClass.prototype = properties; |
| 1187 new MyClass(); | 1192 new MyClass(); |
| 1188 '''); | 1193 '''); |
| 1189 if (DEBUG_FAST_OBJECTS) { | 1194 if (DEBUG_FAST_OBJECTS) { |
| 1190 ClassElement primitives = | 1195 ClassElement primitives = |
| 1191 compiler.findHelper('Primitives'); | 1196 compiler.findHelper('Primitives'); |
| 1192 FunctionElement printHelper = | 1197 FunctionElement printHelper = |
| 1193 compiler.lookupElementIn( | 1198 compiler.lookupElementIn( |
| 1194 primitives, 'printString'); | 1199 primitives, 'printString'); |
| 1200 // TODO(sra): Replace with AST. |
| 1195 String printHelperName = namer.isolateAccess(printHelper); | 1201 String printHelperName = namer.isolateAccess(printHelper); |
| 1196 mainBuffer.add(''' | 1202 mainBuffer.add(''' |
| 1197 // The following only works on V8 when run with option "--allow-natives-syntax". | 1203 // The following only works on V8 when run with option "--allow-natives-syntax". |
| 1198 if (typeof $printHelperName === "function") { | 1204 if (typeof $printHelperName === "function") { |
| 1199 $printHelperName("Size of global object: " | 1205 $printHelperName("Size of global object: " |
| 1200 + String(Object.getOwnPropertyNames(properties).length) | 1206 + String(Object.getOwnPropertyNames(properties).length) |
| 1201 + ", fast properties " + %HasFastProperties(properties)); | 1207 + ", fast properties " + %HasFastProperties(properties)); |
| 1202 } | 1208 } |
| 1203 '''); | 1209 '''); |
| 1204 } | 1210 } |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1471 emitConvertToFastObjectFunction(); | 1477 emitConvertToFastObjectFunction(); |
| 1472 for (String globalObject in Namer.reservedGlobalObjectNames) { | 1478 for (String globalObject in Namer.reservedGlobalObjectNames) { |
| 1473 mainBuffer.add('$globalObject = convertToFastObject($globalObject)$N'); | 1479 mainBuffer.add('$globalObject = convertToFastObject($globalObject)$N'); |
| 1474 } | 1480 } |
| 1475 if (DEBUG_FAST_OBJECTS) { | 1481 if (DEBUG_FAST_OBJECTS) { |
| 1476 ClassElement primitives = | 1482 ClassElement primitives = |
| 1477 compiler.findHelper('Primitives'); | 1483 compiler.findHelper('Primitives'); |
| 1478 FunctionElement printHelper = | 1484 FunctionElement printHelper = |
| 1479 compiler.lookupElementIn( | 1485 compiler.lookupElementIn( |
| 1480 primitives, 'printString'); | 1486 primitives, 'printString'); |
| 1487 // TODO(sra): Replace with AST. |
| 1481 String printHelperName = namer.isolateAccess(printHelper); | 1488 String printHelperName = namer.isolateAccess(printHelper); |
| 1482 | 1489 |
| 1483 mainBuffer.add(''' | 1490 mainBuffer.add(''' |
| 1484 // The following only works on V8 when run with option "--allow-natives-syntax". | 1491 // The following only works on V8 when run with option "--allow-natives-syntax". |
| 1485 if (typeof $printHelperName === "function") { | 1492 if (typeof $printHelperName === "function") { |
| 1486 $printHelperName("Size of global helper object: " | 1493 $printHelperName("Size of global helper object: " |
| 1487 + String(Object.getOwnPropertyNames(H).length) | 1494 + String(Object.getOwnPropertyNames(H).length) |
| 1488 + ", fast properties " + %HasFastProperties(H)); | 1495 + ", fast properties " + %HasFastProperties(H)); |
| 1489 $printHelperName("Size of global platform object: " | 1496 $printHelperName("Size of global platform object: " |
| 1490 + String(Object.getOwnPropertyNames(P).length) | 1497 + String(Object.getOwnPropertyNames(P).length) |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1700 String sourceMap = sourceMapBuilder.build(); | 1707 String sourceMap = sourceMapBuilder.build(); |
| 1701 compiler.outputProvider(name, 'js.map') | 1708 compiler.outputProvider(name, 'js.map') |
| 1702 ..add(sourceMap) | 1709 ..add(sourceMap) |
| 1703 ..close(); | 1710 ..close(); |
| 1704 } | 1711 } |
| 1705 | 1712 |
| 1706 void registerReadTypeVariable(TypeVariableElement element) { | 1713 void registerReadTypeVariable(TypeVariableElement element) { |
| 1707 readTypeVariables.add(element); | 1714 readTypeVariables.add(element); |
| 1708 } | 1715 } |
| 1709 } | 1716 } |
| OLD | NEW |