Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 /** | 5 /** |
| 6 * Top level generator object for writing code and keeping track of | 6 * Top level generator object for writing code and keeping track of |
| 7 * dependencies. | 7 * dependencies. |
| 8 * | 8 * |
| 9 * Should have two compilation models, but only one implemented so far. | 9 * Should have two compilation models, but only one implemented so far. |
| 10 * | 10 * |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 if (options.compileAll) { | 41 if (options.compileAll) { |
| 42 markLibrariesUsed( | 42 markLibrariesUsed( |
| 43 [world.coreimpl, world.corelib, main.declaringType.library]); | 43 [world.coreimpl, world.corelib, main.declaringType.library]); |
| 44 } else { | 44 } else { |
| 45 // TODO(jimhug): Better way to capture hidden control flow. | 45 // TODO(jimhug): Better way to capture hidden control flow. |
| 46 world.corelib.types['BadNumberFormatException'].markUsed(); | 46 world.corelib.types['BadNumberFormatException'].markUsed(); |
| 47 world.coreimpl.types['NumImplementation'].markUsed(); | 47 world.coreimpl.types['NumImplementation'].markUsed(); |
| 48 world.coreimpl.types['StringImplementation'].markUsed(); | 48 world.coreimpl.types['StringImplementation'].markUsed(); |
| 49 genMethod( | 49 genMethod( |
| 50 world.coreimpl.types['StringImplementation'].getMember('contains')); | 50 world.coreimpl.types['StringImplementation'].getMember('contains')); |
| 51 if (world.corelib.types['String'].isUsed) { | |
|
Jennifer Messerly
2011/12/15 01:13:14
Can you move this annotation to String.split? in o
Siggi Cherem (dart-lang)
2011/12/15 04:35:56
Done. Just checking - is this safe? I thought we s
| |
| 52 // 'String.split' creates a list. | |
| 53 world.coreimpl.types['ListFactory'].markUsed(); | |
| 54 } | |
| 51 } | 55 } |
| 52 | 56 |
| 53 // Only include isolate-specific code if isolates are used. | 57 // Only include isolate-specific code if isolates are used. |
| 54 if (world.corelib.types['Isolate'].isUsed | 58 if (world.corelib.types['Isolate'].isUsed |
| 55 || world.coreimpl.types['ReceivePortImpl'].isUsed) { | 59 || world.coreimpl.types['ReceivePortImpl'].isUsed) { |
| 56 | 60 |
| 57 // Generate callbacks from JS to isolate code if needed | 61 // Generate callbacks from JS to isolate code if needed |
| 58 if (corejs.useWrap0 || corejs.useWrap1) { | 62 if (corejs.useWrap0 || corejs.useWrap1) { |
| 59 genMethod(world.coreimpl.types['IsolateContext'].getMember('eval')); | 63 genMethod(world.coreimpl.types['IsolateContext'].getMember('eval')); |
| 60 genMethod(world.coreimpl.types['EventLoop'].getMember('run')); | 64 genMethod(world.coreimpl.types['EventLoop'].getMember('run')); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 // e.g. window.console.log$1 | 222 // e.g. window.console.log$1 |
| 219 return '${type.jsname}.$name'; | 223 return '${type.jsname}.$name'; |
| 220 } else if (type.isHiddenNativeType) { | 224 } else if (type.isHiddenNativeType) { |
| 221 corejs.ensureDynamicProto(); | 225 corejs.ensureDynamicProto(); |
| 222 return '\$dynamic("$name").${type.jsname}'; | 226 return '\$dynamic("$name").${type.jsname}'; |
| 223 } else { | 227 } else { |
| 224 return '${type.jsname}.prototype.$name'; | 228 return '${type.jsname}.prototype.$name'; |
| 225 } | 229 } |
| 226 } | 230 } |
| 227 | 231 |
| 232 String _boundMethod(Type type, String name) { | |
|
Jennifer Messerly
2011/12/15 01:13:14
nice!
fwiw, I think you could do all of these wit
Siggi Cherem (dart-lang)
2011/12/15 04:35:56
cool, that seems to work. given that it became so
| |
| 233 if (type.isSingletonNative) { | |
| 234 return '${type.jsname}.$name.bind(${type.jsname})'; | |
| 235 } else if (type.isHiddenNativeType) { | |
| 236 return 'Object.getPrototype(this).${type.jsname}.bind(this)'; | |
| 237 } else { | |
| 238 return '${type.jsname}.prototype.$name.bind(this)'; | |
| 239 } | |
| 240 } | |
| 241 | |
| 228 _maybeIsTest(Type onType, Type checkType) { | 242 _maybeIsTest(Type onType, Type checkType) { |
| 229 bool isSubtype = onType.isSubtypeOf(checkType); | 243 bool isSubtype = onType.isSubtypeOf(checkType); |
| 230 if (checkType.isTested) { | 244 if (checkType.isTested) { |
| 231 // TODO(jmesserly): cache these functions? they just return true or false. | 245 // TODO(jmesserly): cache these functions? they just return true or false. |
| 232 writer.writeln(_prototypeOf(onType, 'is\$${checkType.jsname}') | 246 writer.writeln(_prototypeOf(onType, 'is\$${checkType.jsname}') |
| 233 + ' = function(){return $isSubtype};'); | 247 + ' = function(){return $isSubtype};'); |
| 234 } | 248 } |
| 235 | 249 |
| 236 if (checkType.isChecked) { | 250 if (checkType.isChecked) { |
| 237 String body = 'return this'; | 251 String body = 'return this'; |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 459 writer.writeln(property.setter == null ? '' : ','); | 473 writer.writeln(property.setter == null ? '' : ','); |
| 460 } | 474 } |
| 461 if (property.setter != null) { | 475 if (property.setter != null) { |
| 462 writer.writeln( | 476 writer.writeln( |
| 463 'set: ${property.declaringType.jsname}.prototype.${property.setter.jsn ame}'); | 477 'set: ${property.declaringType.jsname}.prototype.${property.setter.jsn ame}'); |
| 464 } | 478 } |
| 465 writer.exitBlock('});'); | 479 writer.exitBlock('});'); |
| 466 } | 480 } |
| 467 } | 481 } |
| 468 | 482 |
| 469 _writeMethod(Member method) { | 483 _writeMethod(Member m) { |
| 470 if (method.generator != null) { | 484 if (m.generator != null) { |
| 471 method.generator.writeDefinition(writer, null); | 485 m.generator.writeDefinition(writer, null); |
| 486 } else if (m is MethodMember && m.isNative | |
| 487 && m.dynamic._providePropertySyntax && !m.dynamic._provideFieldSyntax) { | |
|
Jennifer Messerly
2011/12/15 01:13:14
perhaps put these on member?
Siggi Cherem (dart-lang)
2011/12/15 04:35:56
Done.
| |
| 488 MethodGenerator._maybeGenerateBoundGetter(m, writer); | |
| 472 } | 489 } |
| 473 } | 490 } |
| 474 | 491 |
| 475 writeGlobals() { | 492 writeGlobals() { |
| 476 if (globals.length > 0) { | 493 if (globals.length > 0) { |
| 477 writer.comment('// ********** Globals **************'); | 494 writer.comment('// ********** Globals **************'); |
| 478 var list = globals.getValues(); | 495 var list = globals.getValues(); |
| 479 list.sort((a, b) => a.compareTo(b)); | 496 list.sort((a, b) => a.compareTo(b)); |
| 480 | 497 |
| 481 // put all static field initializations in a method | 498 // put all static field initializations in a method |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 854 } | 871 } |
| 855 if (method.isConstructor && method.constructorName != '') { | 872 if (method.isConstructor && method.constructorName != '') { |
| 856 defWriter.writeln( | 873 defWriter.writeln( |
| 857 '${method.declaringType.jsname}.${method.constructorName}\$ctor.prototyp e = ' + | 874 '${method.declaringType.jsname}.${method.constructorName}\$ctor.prototyp e = ' + |
| 858 '${method.declaringType.jsname}.prototype;'); | 875 '${method.declaringType.jsname}.prototype;'); |
| 859 } | 876 } |
| 860 | 877 |
| 861 _provideOptionalParamInfo(defWriter); | 878 _provideOptionalParamInfo(defWriter); |
| 862 | 879 |
| 863 if (method is MethodMember) { | 880 if (method is MethodMember) { |
| 864 MethodMember m = method; | 881 MethodMember m = method; |
|
Jennifer Messerly
2011/12/15 01:13:14
shouldn't need this line anymore
Siggi Cherem (dart-lang)
2011/12/15 04:35:56
Done.
| |
| 865 if (m._providePropertySyntax) { | 882 _maybeGenerateBoundGetter(m, defWriter); |
| 866 defWriter.enterBlock('${m.declaringType.jsname}.prototype' | 883 } |
| 867 + '.get\$${m.jsname} = function() {'); | 884 } |
| 868 // TODO(jimhug): Bind not available in older Safari, need fallback? | |
| 869 defWriter.writeln('return ${m.declaringType.jsname}.prototype.' | |
| 870 + '${m.jsname}.bind(this);'); | |
| 871 defWriter.exitBlock('}'); | |
| 872 | 885 |
| 873 if (m._provideFieldSyntax) { | 886 static _maybeGenerateBoundGetter(MethodMember m, CodeWriter defWriter) { |
| 874 world.internalError('bound m accessed with field syntax'); | 887 if (m._providePropertySyntax && !m.declaringType.isSingletonNative) { |
|
Jennifer Messerly
2011/12/15 01:13:14
why are singleton natives excluded?
Siggi Cherem (dart-lang)
2011/12/15 04:35:56
nice catch - this was intended to be a temporary c
| |
| 875 } | 888 defWriter.enterBlock( |
| 889 world.gen._prototypeOf(m.declaringType, "get\$" + m.jsname) | |
| 890 + ' = function() {'); | |
| 891 // TODO(jimhug): Bind not available in older Safari, need fallback? | |
| 892 defWriter.writeln('return ' | |
| 893 + world.gen._boundMethod(m.declaringType, m.jsname)); | |
| 894 defWriter.exitBlock('}'); | |
| 895 | |
| 896 if (m._provideFieldSyntax) { | |
| 897 world.internalError('bound "${m.name}" accessed with field syntax', | |
| 898 m.definition.span); | |
| 876 } | 899 } |
| 877 } | 900 } |
| 878 } | 901 } |
| 879 | 902 |
| 880 /** | 903 /** |
| 881 * Generates information about the default/named arguments into the JS code. | 904 * Generates information about the default/named arguments into the JS code. |
| 882 * Only methods that are passed as bound methods to "var" need this. It is | 905 * Only methods that are passed as bound methods to "var" need this. It is |
| 883 * generated to support run time stub creation. | 906 * generated to support run time stub creation. |
| 884 */ | 907 */ |
| 885 _provideOptionalParamInfo(CodeWriter defWriter) { | 908 _provideOptionalParamInfo(CodeWriter defWriter) { |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1452 var item = _scope.create(itemName, itemType, node.item.name.span, isFinal); | 1475 var item = _scope.create(itemName, itemType, node.item.name.span, isFinal); |
| 1453 Value listVar = list; | 1476 Value listVar = list; |
| 1454 if (list.needsTemp) { | 1477 if (list.needsTemp) { |
| 1455 listVar = _scope.create('\$list', list.type, null); | 1478 listVar = _scope.create('\$list', list.type, null); |
| 1456 writer.writeln('var ${listVar.code} = ${list.code};'); | 1479 writer.writeln('var ${listVar.code} = ${list.code};'); |
| 1457 } | 1480 } |
| 1458 | 1481 |
| 1459 // Special path for list for readability and perf optimization. | 1482 // Special path for list for readability and perf optimization. |
| 1460 if (list.type.isList) { | 1483 if (list.type.isList) { |
| 1461 var tmpi = _scope.create('\$i', world.numType, null); | 1484 var tmpi = _scope.create('\$i', world.numType, null); |
| 1485 var listLength = listVar.get_(this, 'length', node.list); | |
|
Jennifer Messerly
2011/12/15 01:13:14
nice fix. old code was nasty :)
Siggi Cherem (dart-lang)
2011/12/15 04:35:56
thx.
| |
| 1462 writer.enterBlock('for (var ${tmpi.code} = 0;' + | 1486 writer.enterBlock('for (var ${tmpi.code} = 0;' + |
| 1463 '${tmpi.code} < ${listVar.code}.length; ${tmpi.code}++) {'); | 1487 '${tmpi.code} < ${listLength.code}; ${tmpi.code}++) {'); |
| 1464 var value = listVar.invoke(this, ':index', node.list, | 1488 var value = listVar.invoke(this, ':index', node.list, |
| 1465 new Arguments(null, [tmpi])); | 1489 new Arguments(null, [tmpi])); |
| 1466 writer.writeln('var ${item.code} = ${value.code};'); | 1490 writer.writeln('var ${item.code} = ${value.code};'); |
| 1467 } else { | 1491 } else { |
| 1468 _pushBlock(); | 1492 _pushBlock(); |
| 1469 var iterator = list.invoke(this, 'iterator', node.list, Arguments.EMPTY); | 1493 var iterator = list.invoke(this, 'iterator', node.list, Arguments.EMPTY); |
| 1470 var tmpi = _scope.create('\$i', iterator.type, null); | 1494 var tmpi = _scope.create('\$i', iterator.type, null); |
| 1471 | 1495 |
| 1472 var hasNext = tmpi.invoke(this, 'hasNext', node.list, Arguments.EMPTY); | 1496 var hasNext = tmpi.invoke(this, 'hasNext', node.list, Arguments.EMPTY); |
| 1473 var next = tmpi.invoke(this, 'next', node.list, Arguments.EMPTY); | 1497 var next = tmpi.invoke(this, 'next', node.list, Arguments.EMPTY); |
| (...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2530 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); | 2554 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); |
| 2531 } | 2555 } |
| 2532 for (int i = bareCount; i < length; i++) { | 2556 for (int i = bareCount; i < length; i++) { |
| 2533 var name = getName(i); | 2557 var name = getName(i); |
| 2534 if (name == null) name = '\$$i'; | 2558 if (name == null) name = '\$$i'; |
| 2535 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); | 2559 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); |
| 2536 } | 2560 } |
| 2537 return new Arguments(nodes, result); | 2561 return new Arguments(nodes, result); |
| 2538 } | 2562 } |
| 2539 } | 2563 } |
| OLD | NEW |