Chromium Code Reviews| 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 /** | 5 /** |
| 6 * A function element that represents a closure call. The signature is copied | 6 * A function element that represents a closure call. The signature is copied |
| 7 * from the given element. | 7 * from the given element. |
| 8 */ | 8 */ |
| 9 class ClosureInvocationElement extends FunctionElement { | 9 class ClosureInvocationElement extends FunctionElement { |
| 10 ClosureInvocationElement(SourceString name, | 10 ClosureInvocationElement(SourceString name, |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 342 */ | 342 */ |
| 343 void addParameterStub(FunctionElement member, | 343 void addParameterStub(FunctionElement member, |
| 344 Selector selector, | 344 Selector selector, |
| 345 DefineMemberFunction defineInstanceMember) { | 345 DefineMemberFunction defineInstanceMember) { |
| 346 FunctionSignature parameters = member.computeSignature(compiler); | 346 FunctionSignature parameters = member.computeSignature(compiler); |
| 347 int positionalArgumentCount = selector.positionalArgumentCount; | 347 int positionalArgumentCount = selector.positionalArgumentCount; |
| 348 if (positionalArgumentCount == parameters.parameterCount) { | 348 if (positionalArgumentCount == parameters.parameterCount) { |
| 349 assert(selector.namedArgumentCount == 0); | 349 assert(selector.namedArgumentCount == 0); |
| 350 return; | 350 return; |
| 351 } | 351 } |
| 352 if (parameters.optionalParametersAreNamed | |
| 353 && selector.namedArgumentCount == parameters.optionalParameterCount) { | |
| 354 // If the selector has the same number of named arguments than | |
|
ahe
2012/09/13 14:29:10
than -> as
ngeoffray
2012/09/17 12:21:01
Done.
| |
| 355 // the element, we don't need to add a stub. The call site will | |
| 356 // hit the method directly. | |
| 357 return; | |
| 358 } | |
| 352 ConstantHandler handler = compiler.constantHandler; | 359 ConstantHandler handler = compiler.constantHandler; |
| 353 List<SourceString> names = selector.getOrderedNamedArguments(); | 360 List<SourceString> names = selector.getOrderedNamedArguments(); |
| 354 | 361 |
| 355 String invocationName = | 362 String invocationName = |
| 356 namer.instanceMethodInvocationName(member.getLibrary(), member.name, | 363 namer.instanceMethodInvocationName(member.getLibrary(), member.name, |
| 357 selector); | 364 selector); |
| 358 CodeBuffer buffer = new CodeBuffer(); | 365 CodeBuffer buffer = new CodeBuffer(); |
| 359 buffer.add('function('); | 366 buffer.add('function('); |
| 360 | 367 |
| 361 // The parameters that this stub takes. | 368 // The parameters that this stub takes. |
| 362 List<String> parametersBuffer = new List<String>(selector.argumentCount); | 369 List<String> parametersBuffer = new List<String>(selector.argumentCount); |
| 363 // The arguments that will be passed to the real method. | 370 // The arguments that will be passed to the real method. |
| 364 List<String> argumentsBuffer = new List<String>(parameters.parameterCount); | 371 List<String> argumentsBuffer = new List<String>(parameters.parameterCount); |
| 365 | 372 |
| 373 // TODO(5074): Update this comment once we remove support for | |
| 374 // the deprecated parameter specification. | |
|
ahe
2012/09/13 14:29:10
Actually, I think this comment should be moved to
ngeoffray
2012/09/17 12:21:01
Done.
| |
| 366 // We fill the lists depending on the selector. For example, | 375 // We fill the lists depending on the selector. For example, |
| 367 // take method foo: | 376 // take method foo: |
| 368 // foo(a, b, [c, d]); | 377 // foo(a, b, [c, d]); |
| 369 // | 378 // |
| 370 // We may have multiple ways of calling foo: | 379 // We may have multiple ways of calling foo: |
| 371 // (1) foo(1, 2, 3, 4) | 380 // (1) foo(1, 2, 3, 4) |
| 372 // (2) foo(1, 2); | 381 // (2) foo(1, 2); |
| 373 // (3) foo(1, 2, 3); | 382 // (3) foo(1, 2, 3); |
| 374 // (4) foo(1, 2, c: 3); | 383 // (4) foo(1, 2, c: 3); |
| 375 // (5) foo(1, 2, d: 4); | 384 // (5) foo(1, 2, d: 4); |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 Set<FunctionElement> functionsNeedingGetter = | 812 Set<FunctionElement> functionsNeedingGetter = |
| 804 compiler.codegenWorld.staticFunctionsNeedingGetter; | 813 compiler.codegenWorld.staticFunctionsNeedingGetter; |
| 805 for (FunctionElement element in functionsNeedingGetter) { | 814 for (FunctionElement element in functionsNeedingGetter) { |
| 806 // The static function does not have the correct name. Since | 815 // The static function does not have the correct name. Since |
| 807 // [addParameterStubs] use the name to create its stubs we simply | 816 // [addParameterStubs] use the name to create its stubs we simply |
| 808 // create a fake element with the correct name. | 817 // create a fake element with the correct name. |
| 809 // Note: the callElement will not have any enclosingElement. | 818 // Note: the callElement will not have any enclosingElement. |
| 810 FunctionElement callElement = | 819 FunctionElement callElement = |
| 811 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element); | 820 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element); |
| 812 String staticName = namer.getName(element); | 821 String staticName = namer.getName(element); |
| 813 int parameterCount = element.parameterCount(compiler); | 822 String invocationName = namer.instanceMethodName(callElement); |
| 814 String invocationName = | |
| 815 namer.instanceMethodName(element.getLibrary(), callElement.name, | |
| 816 parameterCount); | |
| 817 String fieldAccess = '$isolateProperties.$staticName'; | 823 String fieldAccess = '$isolateProperties.$staticName'; |
| 818 buffer.add("$fieldAccess.$invocationName = $fieldAccess;\n"); | 824 buffer.add("$fieldAccess.$invocationName = $fieldAccess;\n"); |
| 819 addParameterStubs(callElement, (String name, CodeBuffer value) { | 825 addParameterStubs(callElement, (String name, CodeBuffer value) { |
| 820 buffer.add('$fieldAccess.$name = $value;\n'); | 826 buffer.add('$fieldAccess.$name = $value;\n'); |
| 821 }); | 827 }); |
| 822 // If a static function is used as a closure we need to add its name | 828 // If a static function is used as a closure we need to add its name |
| 823 // in case it is used in spawnFunction. | 829 // in case it is used in spawnFunction. |
| 824 String fieldName = namer.STATIC_CLOSURE_NAME_NAME; | 830 String fieldName = namer.STATIC_CLOSURE_NAME_NAME; |
| 825 buffer.add('$fieldAccess.$fieldName = "$staticName";\n'); | 831 buffer.add('$fieldAccess.$fieldName = "$staticName";\n'); |
| 826 } | 832 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 871 ['self', 'target'], | 877 ['self', 'target'], |
| 872 'super': '$superName', | 878 'super': '$superName', |
| 873 """); | 879 """); |
| 874 // Now add the methods on the closure class. The instance method does not | 880 // Now add the methods on the closure class. The instance method does not |
| 875 // have the correct name. Since [addParameterStubs] use the name to create | 881 // have the correct name. Since [addParameterStubs] use the name to create |
| 876 // its stubs we simply create a fake element with the correct name. | 882 // its stubs we simply create a fake element with the correct name. |
| 877 // Note: the callElement will not have any enclosingElement. | 883 // Note: the callElement will not have any enclosingElement. |
| 878 FunctionElement callElement = | 884 FunctionElement callElement = |
| 879 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member); | 885 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member); |
| 880 | 886 |
| 881 String invocationName = | 887 String invocationName = namer.instanceMethodName(callElement); |
| 882 namer.instanceMethodName(member.getLibrary(), | |
| 883 callElement.name, parameterCount); | |
| 884 List<String> arguments = new List<String>(parameterCount); | 888 List<String> arguments = new List<String>(parameterCount); |
| 885 for (int i = 0; i < parameterCount; i++) { | 889 for (int i = 0; i < parameterCount; i++) { |
| 886 arguments[i] = "p$i"; | 890 arguments[i] = "p$i"; |
| 887 } | 891 } |
| 888 String joinedArgs = Strings.join(arguments, ", "); | 892 String joinedArgs = Strings.join(arguments, ", "); |
| 889 boundClosureBuffer.add( | 893 boundClosureBuffer.add( |
| 890 "$invocationName: function($joinedArgs) {"); | 894 "$invocationName: function($joinedArgs) {"); |
| 891 boundClosureBuffer.add(" return this.self[this.target]($joinedArgs);"); | 895 boundClosureBuffer.add(" return this.self[this.target]($joinedArgs);"); |
| 892 boundClosureBuffer.add(" }"); | 896 boundClosureBuffer.add(" }"); |
| 893 addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) { | 897 addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) { |
| 894 boundClosureBuffer.add(',\n $stubName: $memberValue'); | 898 boundClosureBuffer.add(',\n $stubName: $memberValue'); |
| 895 }); | 899 }); |
| 896 boundClosureBuffer.add("\n};\n"); | 900 boundClosureBuffer.add("\n};\n"); |
| 897 | 901 |
| 898 closureClass = namer.isolateAccess(closureClassElement); | 902 closureClass = namer.isolateAccess(closureClassElement); |
| 899 | 903 |
| 900 // Cache it. | 904 // Cache it. |
| 901 if (!hasOptionalParameters) { | 905 if (!hasOptionalParameters) { |
| 902 boundClosureCache[parameterCount] = closureClass; | 906 boundClosureCache[parameterCount] = closureClass; |
| 903 } | 907 } |
| 904 } | 908 } |
| 905 | 909 |
| 906 // And finally the getter. | 910 // And finally the getter. |
| 907 String getterName = namer.getterName(member.getLibrary(), member.name); | 911 String getterName = namer.getterName(member.getLibrary(), member.name); |
| 908 String targetName = namer.instanceMethodName(member.getLibrary(), | 912 String targetName = namer.instanceMethodName(member); |
| 909 member.name, parameterCount); | |
| 910 CodeBuffer getterBuffer = new CodeBuffer(); | 913 CodeBuffer getterBuffer = new CodeBuffer(); |
| 911 getterBuffer.add( | 914 getterBuffer.add( |
| 912 "function() { return new $closureClass(this, '$targetName'); }"); | 915 "function() { return new $closureClass(this, '$targetName'); }"); |
| 913 defineInstanceMember(getterName, getterBuffer); | 916 defineInstanceMember(getterName, getterBuffer); |
| 914 } | 917 } |
| 915 | 918 |
| 916 void emitCallStubForGetter(Element member, | 919 void emitCallStubForGetter(Element member, |
| 917 Set<Selector> selectors, | 920 Set<Selector> selectors, |
| 918 DefineMemberFunction defineInstanceMember) { | 921 DefineMemberFunction defineInstanceMember) { |
| 919 String getter; | 922 String getter; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1034 emitDynamicFunctionGetter(member, defineInstanceMember); | 1037 emitDynamicFunctionGetter(member, defineInstanceMember); |
| 1035 } | 1038 } |
| 1036 } | 1039 } |
| 1037 } | 1040 } |
| 1038 | 1041 |
| 1039 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { | 1042 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { |
| 1040 // Do not generate no such method handlers if there is no class. | 1043 // Do not generate no such method handlers if there is no class. |
| 1041 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return; | 1044 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return; |
| 1042 | 1045 |
| 1043 String noSuchMethodName = | 1046 String noSuchMethodName = |
| 1044 namer.instanceMethodName(null, Compiler.NO_SUCH_METHOD, 2); | 1047 namer.instanceMethodNameByArity(Compiler.NO_SUCH_METHOD, 2); |
| 1045 | 1048 |
| 1046 // Keep track of the JavaScript names we've already added so we | 1049 // Keep track of the JavaScript names we've already added so we |
| 1047 // do not introduce duplicates (bad for code size). | 1050 // do not introduce duplicates (bad for code size). |
| 1048 Set<String> addedJsNames = new Set<String>(); | 1051 Set<String> addedJsNames = new Set<String>(); |
| 1049 | 1052 |
| 1050 // Keep track of the noSuchMethod holders for each possible | 1053 // Keep track of the noSuchMethod holders for each possible |
| 1051 // receiver type. | 1054 // receiver type. |
| 1052 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = | 1055 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = |
| 1053 new Map<ClassElement, Set<ClassElement>>(); | 1056 new Map<ClassElement, Set<ClassElement>>(); |
| 1054 Set<ClassElement> noSuchMethodHoldersFor(DartType type) { | 1057 Set<ClassElement> noSuchMethodHoldersFor(DartType type) { |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1347 const String HOOKS_API_USAGE = """ | 1350 const String HOOKS_API_USAGE = """ |
| 1348 // Generated by dart2js, the Dart to JavaScript compiler. | 1351 // Generated by dart2js, the Dart to JavaScript compiler. |
| 1349 // The code supports the following hooks: | 1352 // The code supports the following hooks: |
| 1350 // dartPrint(message) - if this function is defined it is called | 1353 // dartPrint(message) - if this function is defined it is called |
| 1351 // instead of the Dart [print] method. | 1354 // instead of the Dart [print] method. |
| 1352 // dartMainRunner(main) - if this function is defined, the Dart [main] | 1355 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 1353 // method will not be invoked directly. | 1356 // method will not be invoked directly. |
| 1354 // Instead, a closure that will invoke [main] is | 1357 // Instead, a closure that will invoke [main] is |
| 1355 // passed to [dartMainRunner]. | 1358 // passed to [dartMainRunner]. |
| 1356 """; | 1359 """; |
| OLD | NEW |