Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: lib/compiler/implementation/js_backend/emitter.dart

Issue 10911211: Runtime support for the new parameter specification. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
kasperl 2012/09/12 11:34:48 Add a comment that explains what this does.
ngeoffray 2012/09/12 11:40:06 Done.
353 && selector.namedArgumentCount == parameters.optionalParameterCount) {
354 return;
355 }
352 ConstantHandler handler = compiler.constantHandler; 356 ConstantHandler handler = compiler.constantHandler;
353 List<SourceString> names = selector.getOrderedNamedArguments(); 357 List<SourceString> names = selector.getOrderedNamedArguments();
354 358
355 String invocationName = 359 String invocationName =
356 namer.instanceMethodInvocationName(member.getLibrary(), member.name, 360 namer.instanceMethodInvocationName(member.getLibrary(), member.name,
357 selector); 361 selector);
358 CodeBuffer buffer = new CodeBuffer(); 362 CodeBuffer buffer = new CodeBuffer();
359 buffer.add('function('); 363 buffer.add('function(');
360 364
361 // The parameters that this stub takes. 365 // The parameters that this stub takes.
362 List<String> parametersBuffer = new List<String>(selector.argumentCount); 366 List<String> parametersBuffer = new List<String>(selector.argumentCount);
363 // The arguments that will be passed to the real method. 367 // The arguments that will be passed to the real method.
364 List<String> argumentsBuffer = new List<String>(parameters.parameterCount); 368 List<String> argumentsBuffer = new List<String>(parameters.parameterCount);
365 369
370 // TODO(5074): Update this comment once we remove support for
371 // the deprecated parameter specification.
366 // We fill the lists depending on the selector. For example, 372 // We fill the lists depending on the selector. For example,
367 // take method foo: 373 // take method foo:
368 // foo(a, b, [c, d]); 374 // foo(a, b, [c, d]);
369 // 375 //
370 // We may have multiple ways of calling foo: 376 // We may have multiple ways of calling foo:
371 // (1) foo(1, 2, 3, 4) 377 // (1) foo(1, 2, 3, 4)
372 // (2) foo(1, 2); 378 // (2) foo(1, 2);
373 // (3) foo(1, 2, 3); 379 // (3) foo(1, 2, 3);
374 // (4) foo(1, 2, c: 3); 380 // (4) foo(1, 2, c: 3);
375 // (5) foo(1, 2, d: 4); 381 // (5) foo(1, 2, d: 4);
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 Set<FunctionElement> functionsNeedingGetter = 809 Set<FunctionElement> functionsNeedingGetter =
804 compiler.codegenWorld.staticFunctionsNeedingGetter; 810 compiler.codegenWorld.staticFunctionsNeedingGetter;
805 for (FunctionElement element in functionsNeedingGetter) { 811 for (FunctionElement element in functionsNeedingGetter) {
806 // The static function does not have the correct name. Since 812 // The static function does not have the correct name. Since
807 // [addParameterStubs] use the name to create its stubs we simply 813 // [addParameterStubs] use the name to create its stubs we simply
808 // create a fake element with the correct name. 814 // create a fake element with the correct name.
809 // Note: the callElement will not have any enclosingElement. 815 // Note: the callElement will not have any enclosingElement.
810 FunctionElement callElement = 816 FunctionElement callElement =
811 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element); 817 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element);
812 String staticName = namer.getName(element); 818 String staticName = namer.getName(element);
813 int parameterCount = element.parameterCount(compiler); 819 String invocationName = namer.instanceMethodName(callElement);
814 String invocationName =
815 namer.instanceMethodName(element.getLibrary(), callElement.name,
816 parameterCount);
817 String fieldAccess = '$isolateProperties.$staticName'; 820 String fieldAccess = '$isolateProperties.$staticName';
818 buffer.add("$fieldAccess.$invocationName = $fieldAccess;\n"); 821 buffer.add("$fieldAccess.$invocationName = $fieldAccess;\n");
819 addParameterStubs(callElement, (String name, CodeBuffer value) { 822 addParameterStubs(callElement, (String name, CodeBuffer value) {
820 buffer.add('$fieldAccess.$name = $value;\n'); 823 buffer.add('$fieldAccess.$name = $value;\n');
821 }); 824 });
822 // If a static function is used as a closure we need to add its name 825 // If a static function is used as a closure we need to add its name
823 // in case it is used in spawnFunction. 826 // in case it is used in spawnFunction.
824 String fieldName = namer.STATIC_CLOSURE_NAME_NAME; 827 String fieldName = namer.STATIC_CLOSURE_NAME_NAME;
825 buffer.add('$fieldAccess.$fieldName = "$staticName";\n'); 828 buffer.add('$fieldAccess.$fieldName = "$staticName";\n');
826 } 829 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 ['self', 'target'], 874 ['self', 'target'],
872 'super': '$superName', 875 'super': '$superName',
873 """); 876 """);
874 // Now add the methods on the closure class. The instance method does not 877 // 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 878 // have the correct name. Since [addParameterStubs] use the name to create
876 // its stubs we simply create a fake element with the correct name. 879 // its stubs we simply create a fake element with the correct name.
877 // Note: the callElement will not have any enclosingElement. 880 // Note: the callElement will not have any enclosingElement.
878 FunctionElement callElement = 881 FunctionElement callElement =
879 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member); 882 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member);
880 883
881 String invocationName = 884 String invocationName = namer.instanceMethodName(callElement);
882 namer.instanceMethodName(member.getLibrary(),
883 callElement.name, parameterCount);
884 List<String> arguments = new List<String>(parameterCount); 885 List<String> arguments = new List<String>(parameterCount);
885 for (int i = 0; i < parameterCount; i++) { 886 for (int i = 0; i < parameterCount; i++) {
886 arguments[i] = "p$i"; 887 arguments[i] = "p$i";
887 } 888 }
888 String joinedArgs = Strings.join(arguments, ", "); 889 String joinedArgs = Strings.join(arguments, ", ");
889 boundClosureBuffer.add( 890 boundClosureBuffer.add(
890 "$invocationName: function($joinedArgs) {"); 891 "$invocationName: function($joinedArgs) {");
891 boundClosureBuffer.add(" return this.self[this.target]($joinedArgs);"); 892 boundClosureBuffer.add(" return this.self[this.target]($joinedArgs);");
892 boundClosureBuffer.add(" }"); 893 boundClosureBuffer.add(" }");
893 addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) { 894 addParameterStubs(callElement, (String stubName, CodeBuffer memberValue) {
894 boundClosureBuffer.add(',\n $stubName: $memberValue'); 895 boundClosureBuffer.add(',\n $stubName: $memberValue');
895 }); 896 });
896 boundClosureBuffer.add("\n};\n"); 897 boundClosureBuffer.add("\n};\n");
897 898
898 closureClass = namer.isolateAccess(closureClassElement); 899 closureClass = namer.isolateAccess(closureClassElement);
899 900
900 // Cache it. 901 // Cache it.
901 if (!hasOptionalParameters) { 902 if (!hasOptionalParameters) {
902 boundClosureCache[parameterCount] = closureClass; 903 boundClosureCache[parameterCount] = closureClass;
903 } 904 }
904 } 905 }
905 906
906 // And finally the getter. 907 // And finally the getter.
907 String getterName = namer.getterName(member.getLibrary(), member.name); 908 String getterName = namer.getterName(member.getLibrary(), member.name);
908 String targetName = namer.instanceMethodName(member.getLibrary(), 909 String targetName = namer.instanceMethodName(member);
909 member.name, parameterCount);
910 CodeBuffer getterBuffer = new CodeBuffer(); 910 CodeBuffer getterBuffer = new CodeBuffer();
911 getterBuffer.add( 911 getterBuffer.add(
912 "function() { return new $closureClass(this, '$targetName'); }"); 912 "function() { return new $closureClass(this, '$targetName'); }");
913 defineInstanceMember(getterName, getterBuffer); 913 defineInstanceMember(getterName, getterBuffer);
914 } 914 }
915 915
916 void emitCallStubForGetter(Element member, 916 void emitCallStubForGetter(Element member,
917 Set<Selector> selectors, 917 Set<Selector> selectors,
918 DefineMemberFunction defineInstanceMember) { 918 DefineMemberFunction defineInstanceMember) {
919 String getter; 919 String getter;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 emitDynamicFunctionGetter(member, defineInstanceMember); 1034 emitDynamicFunctionGetter(member, defineInstanceMember);
1035 } 1035 }
1036 } 1036 }
1037 } 1037 }
1038 1038
1039 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { 1039 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) {
1040 // Do not generate no such method handlers if there is no class. 1040 // Do not generate no such method handlers if there is no class.
1041 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return; 1041 if (compiler.codegenWorld.instantiatedClasses.isEmpty()) return;
1042 1042
1043 String noSuchMethodName = 1043 String noSuchMethodName =
1044 namer.instanceMethodName(null, Compiler.NO_SUCH_METHOD, 2); 1044 namer.instanceMethodNameByArity(Compiler.NO_SUCH_METHOD, 2);
1045 1045
1046 // Keep track of the JavaScript names we've already added so we 1046 // Keep track of the JavaScript names we've already added so we
1047 // do not introduce duplicates (bad for code size). 1047 // do not introduce duplicates (bad for code size).
1048 Set<String> addedJsNames = new Set<String>(); 1048 Set<String> addedJsNames = new Set<String>();
1049 1049
1050 // Keep track of the noSuchMethod holders for each possible 1050 // Keep track of the noSuchMethod holders for each possible
1051 // receiver type. 1051 // receiver type.
1052 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = 1052 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders =
1053 new Map<ClassElement, Set<ClassElement>>(); 1053 new Map<ClassElement, Set<ClassElement>>();
1054 Set<ClassElement> noSuchMethodHoldersFor(DartType type) { 1054 Set<ClassElement> noSuchMethodHoldersFor(DartType type) {
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 const String HOOKS_API_USAGE = """ 1347 const String HOOKS_API_USAGE = """
1348 // Generated by dart2js, the Dart to JavaScript compiler. 1348 // Generated by dart2js, the Dart to JavaScript compiler.
1349 // The code supports the following hooks: 1349 // The code supports the following hooks:
1350 // dartPrint(message) - if this function is defined it is called 1350 // dartPrint(message) - if this function is defined it is called
1351 // instead of the Dart [print] method. 1351 // instead of the Dart [print] method.
1352 // dartMainRunner(main) - if this function is defined, the Dart [main] 1352 // dartMainRunner(main) - if this function is defined, the Dart [main]
1353 // method will not be invoked directly. 1353 // method will not be invoked directly.
1354 // Instead, a closure that will invoke [main] is 1354 // Instead, a closure that will invoke [main] is
1355 // passed to [dartMainRunner]. 1355 // passed to [dartMainRunner].
1356 """; 1356 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698