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 js_backend; | 5 part of js_backend; |
6 | 6 |
7 /** | 7 /** |
8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
9 * from the given element. | 9 * from the given element. |
10 */ | 10 */ |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 var newIsolate = new Function(str); | 315 var newIsolate = new Function(str); |
316 newIsolate.prototype = isolatePrototype; | 316 newIsolate.prototype = isolatePrototype; |
317 isolatePrototype.constructor = newIsolate; | 317 isolatePrototype.constructor = newIsolate; |
318 newIsolate.${namer.ISOLATE_PROPERTIES} = isolateProperties; | 318 newIsolate.${namer.ISOLATE_PROPERTIES} = isolateProperties; |
319 return newIsolate; | 319 return newIsolate; |
320 }"""; | 320 }"""; |
321 } | 321 } |
322 | 322 |
323 String get lazyInitializerFunction { | 323 String get lazyInitializerFunction { |
324 String isolate = namer.CURRENT_ISOLATE; | 324 String isolate = namer.CURRENT_ISOLATE; |
| 325 return """ |
| 326 function(prototype, staticName, fieldName, getterName, lazyValue) { |
| 327 var getter = new Function("{ return $isolate." + fieldName + ";}"); |
| 328 $lazyInitializerLogic |
| 329 }"""; |
| 330 } |
| 331 |
| 332 String get lazyInitializerLogic { |
| 333 String isolate = namer.CURRENT_ISOLATE; |
325 JavaScriptBackend backend = compiler.backend; | 334 JavaScriptBackend backend = compiler.backend; |
326 String cyclicThrow = namer.isolateAccess(backend.cyclicThrowHelper); | 335 String cyclicThrow = namer.isolateAccess(backend.cyclicThrowHelper); |
327 return """ | 336 return """ |
328 function(prototype, staticName, fieldName, getterName, lazyValue) { | |
329 var sentinelUndefined = {}; | 337 var sentinelUndefined = {}; |
330 var sentinelInProgress = {}; | 338 var sentinelInProgress = {}; |
331 prototype[fieldName] = sentinelUndefined; | 339 prototype[fieldName] = sentinelUndefined; |
332 var getter = new Function("{ return $isolate." + fieldName + ";}"); | |
333 prototype[getterName] = function() { | 340 prototype[getterName] = function() { |
334 var result = $isolate[fieldName]; | 341 var result = $isolate[fieldName]; |
335 try { | 342 try { |
336 if (result === sentinelUndefined) { | 343 if (result === sentinelUndefined) { |
337 $isolate[fieldName] = sentinelInProgress; | 344 $isolate[fieldName] = sentinelInProgress; |
338 try { | 345 try { |
339 result = $isolate[fieldName] = lazyValue(); | 346 result = $isolate[fieldName] = lazyValue(); |
340 } catch (e) { | 347 } catch (e) { |
341 if ($isolate[fieldName] === sentinelInProgress) { | 348 if ($isolate[fieldName] === sentinelInProgress) { |
342 $isolate[fieldName] = null; | 349 $isolate[fieldName] = null; |
343 } | 350 } |
344 throw e; | 351 throw e; |
345 } | 352 } |
346 } else if (result === sentinelInProgress) { | 353 } else if (result === sentinelInProgress) { |
347 $cyclicThrow(staticName); | 354 $cyclicThrow(staticName); |
348 } | 355 } |
349 return result; | 356 return result; |
350 } finally { | 357 } finally { |
351 $isolate[getterName] = getter; | 358 $isolate[getterName] = getter; |
352 } | 359 } |
353 }; | 360 };"""; |
354 }"""; | |
355 } | 361 } |
356 | 362 |
357 void addDefineClassAndFinishClassFunctionsIfNecessary(CodeBuffer buffer) { | 363 void addDefineClassAndFinishClassFunctionsIfNecessary(CodeBuffer buffer) { |
358 if (needsDefineClass) { | 364 if (needsDefineClass) { |
359 buffer.add("$defineClassName = $defineClassFunction;\n"); | 365 buffer.add("$defineClassName = $defineClassFunction;\n"); |
360 buffer.add(protoSupportCheck); | 366 buffer.add(protoSupportCheck); |
361 buffer.add("$pendingClassesName = {};\n"); | 367 buffer.add("$pendingClassesName = {};\n"); |
362 buffer.add("$finishClassesName = $finishClassesFunction;\n"); | 368 buffer.add("$finishClassesName = $finishClassesFunction;\n"); |
363 } | 369 } |
364 } | 370 } |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1329 buffer.add("$lazyInitializerName("); | 1335 buffer.add("$lazyInitializerName("); |
1330 buffer.add(isolateProperties); | 1336 buffer.add(isolateProperties); |
1331 buffer.add(", '"); | 1337 buffer.add(", '"); |
1332 buffer.add(element.name.slowToString()); | 1338 buffer.add(element.name.slowToString()); |
1333 buffer.add("', '"); | 1339 buffer.add("', '"); |
1334 buffer.add(namer.getName(element)); | 1340 buffer.add(namer.getName(element)); |
1335 buffer.add("', '"); | 1341 buffer.add("', '"); |
1336 buffer.add(namer.getLazyInitializerName(element)); | 1342 buffer.add(namer.getLazyInitializerName(element)); |
1337 buffer.add("', "); | 1343 buffer.add("', "); |
1338 buffer.add(code); | 1344 buffer.add(code); |
| 1345 emitLazyInitializedGetter(element, buffer); |
1339 buffer.add(");\n"); | 1346 buffer.add(");\n"); |
1340 } | 1347 } |
1341 } | 1348 } |
1342 } | 1349 } |
1343 | 1350 |
| 1351 void emitLazyInitializedGetter(VariableElement element, CodeBuffer buffer) { |
| 1352 // Nothing to do, the 'lazy' function will create the getter. |
| 1353 } |
| 1354 |
1344 void emitCompileTimeConstants(CodeBuffer buffer) { | 1355 void emitCompileTimeConstants(CodeBuffer buffer) { |
1345 ConstantHandler handler = compiler.constantHandler; | 1356 ConstantHandler handler = compiler.constantHandler; |
1346 List<Constant> constants = handler.getConstantsForEmission(); | 1357 List<Constant> constants = handler.getConstantsForEmission(); |
1347 bool addedMakeConstantList = false; | 1358 bool addedMakeConstantList = false; |
1348 for (Constant constant in constants) { | 1359 for (Constant constant in constants) { |
1349 // No need to emit functions. We already did that. | 1360 // No need to emit functions. We already did that. |
1350 if (constant.isFunction()) continue; | 1361 if (constant.isFunction()) continue; |
1351 // Numbers, strings and booleans are currently always inlined. | 1362 // Numbers, strings and booleans are currently always inlined. |
1352 if (constant.isPrimitive()) continue; | 1363 if (constant.isPrimitive()) continue; |
1353 | 1364 |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1734 const String HOOKS_API_USAGE = """ | 1745 const String HOOKS_API_USAGE = """ |
1735 // Generated by dart2js, the Dart to JavaScript compiler. | 1746 // Generated by dart2js, the Dart to JavaScript compiler. |
1736 // The code supports the following hooks: | 1747 // The code supports the following hooks: |
1737 // dartPrint(message) - if this function is defined it is called | 1748 // dartPrint(message) - if this function is defined it is called |
1738 // instead of the Dart [print] method. | 1749 // instead of the Dart [print] method. |
1739 // dartMainRunner(main) - if this function is defined, the Dart [main] | 1750 // dartMainRunner(main) - if this function is defined, the Dart [main] |
1740 // method will not be invoked directly. | 1751 // method will not be invoked directly. |
1741 // Instead, a closure that will invoke [main] is | 1752 // Instead, a closure that will invoke [main] is |
1742 // passed to [dartMainRunner]. | 1753 // passed to [dartMainRunner]. |
1743 """; | 1754 """; |
OLD | NEW |