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

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
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
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
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
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
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 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698