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

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

Issue 12517012: Revert "Revert "Use interceptor convention for methods declared on native classes."" (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 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 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 643 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 DefineStubFunction defineStub, 654 DefineStubFunction defineStub,
655 Set<String> alreadyGenerated) { 655 Set<String> alreadyGenerated) {
656 FunctionSignature parameters = member.computeSignature(compiler); 656 FunctionSignature parameters = member.computeSignature(compiler);
657 int positionalArgumentCount = selector.positionalArgumentCount; 657 int positionalArgumentCount = selector.positionalArgumentCount;
658 if (positionalArgumentCount == parameters.parameterCount) { 658 if (positionalArgumentCount == parameters.parameterCount) {
659 assert(selector.namedArgumentCount == 0); 659 assert(selector.namedArgumentCount == 0);
660 return; 660 return;
661 } 661 }
662 if (parameters.optionalParametersAreNamed 662 if (parameters.optionalParametersAreNamed
663 && selector.namedArgumentCount == parameters.optionalParameterCount) { 663 && selector.namedArgumentCount == parameters.optionalParameterCount) {
664 // If the selector has the same number of named arguments as 664 // If the selector has the same number of named arguments as the element,
665 // the element, we don't need to add a stub. The call site will 665 // we don't need to add a stub. The call site will hit the method
666 // hit the method directly. 666 // directly.
667 return; 667 return;
668 } 668 }
669 ConstantHandler handler = compiler.constantHandler; 669 ConstantHandler handler = compiler.constantHandler;
670 List<SourceString> names = selector.getOrderedNamedArguments(); 670 List<SourceString> names = selector.getOrderedNamedArguments();
671 671
672 String invocationName = namer.invocationName(selector); 672 String invocationName = namer.invocationName(selector);
673 if (alreadyGenerated.contains(invocationName)) return; 673 if (alreadyGenerated.contains(invocationName)) return;
674 alreadyGenerated.add(invocationName); 674 alreadyGenerated.add(invocationName);
675 675
676 bool isInterceptedMethod = backend.isInterceptedMethod(member); 676 bool isInterceptedMethod = backend.isInterceptedMethod(member);
677 677
678 // If the method is intercepted, we need to also pass 678 // If the method is intercepted, we need to also pass the actual receiver.
679 // the actual receiver.
680 int extraArgumentCount = isInterceptedMethod ? 1 : 0; 679 int extraArgumentCount = isInterceptedMethod ? 1 : 0;
681 // Use '$receiver' to avoid clashes with other parameter names. Using 680 // Use '$receiver' to avoid clashes with other parameter names. Using
682 // '$receiver' works because [:namer.safeName:] used for getting parameter 681 // '$receiver' works because [:namer.safeName:] used for getting parameter
683 // names never returns a name beginning with a single '$'. 682 // names never returns a name beginning with a single '$'.
684 String receiverArgumentName = r'$receiver'; 683 String receiverArgumentName = r'$receiver';
685 684
686 // The parameters that this stub takes. 685 // The parameters that this stub takes.
687 List<jsAst.Parameter> parametersBuffer = 686 List<jsAst.Parameter> parametersBuffer =
688 new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount); 687 new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount);
689 // The arguments that will be passed to the real method. 688 // The arguments that will be passed to the real method.
690 List<jsAst.Expression> argumentsBuffer = 689 List<jsAst.Expression> argumentsBuffer =
691 new List<jsAst.Expression>( 690 new List<jsAst.Expression>(
692 parameters.parameterCount + extraArgumentCount); 691 parameters.parameterCount + extraArgumentCount);
693 692
694 int count = 0; 693 int count = 0;
695 if (isInterceptedMethod) { 694 if (isInterceptedMethod) {
696 count++; 695 count++;
697 parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName); 696 parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName);
698 argumentsBuffer[0] = js[receiverArgumentName]; 697 argumentsBuffer[0] = js[receiverArgumentName];
699 } 698 }
700 699
701 int indexOfLastOptionalArgumentInParameters = positionalArgumentCount - 1; 700 int optionalParameterStart = positionalArgumentCount + extraArgumentCount;
701 // Includes extra receiver argument when using interceptor convention
702 int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1;
703
702 TreeElements elements = 704 TreeElements elements =
703 compiler.enqueuer.resolution.getCachedElements(member); 705 compiler.enqueuer.resolution.getCachedElements(member);
704 706
705 parameters.orderedForEachParameter((Element element) { 707 parameters.orderedForEachParameter((Element element) {
706 String jsName = backend.namer.safeName(element.name.slowToString()); 708 String jsName = backend.namer.safeName(element.name.slowToString());
707 assert(jsName != receiverArgumentName); 709 assert(jsName != receiverArgumentName);
708 int optionalParameterStart = positionalArgumentCount + extraArgumentCount;
709 if (count < optionalParameterStart) { 710 if (count < optionalParameterStart) {
710 parametersBuffer[count] = new jsAst.Parameter(jsName); 711 parametersBuffer[count] = new jsAst.Parameter(jsName);
711 argumentsBuffer[count] = js[jsName]; 712 argumentsBuffer[count] = js[jsName];
712 } else { 713 } else {
713 int index = names.indexOf(element.name); 714 int index = names.indexOf(element.name);
714 if (index != -1) { 715 if (index != -1) {
715 indexOfLastOptionalArgumentInParameters = count; 716 indexOfLastOptionalArgumentInParameters = count;
716 // The order of the named arguments is not the same as the 717 // The order of the named arguments is not the same as the
717 // one in the real method (which is in Dart source order). 718 // one in the real method (which is in Dart source order).
718 argumentsBuffer[count] = js[jsName]; 719 argumentsBuffer[count] = js[jsName];
(...skipping 15 matching lines...) Expand all
734 argumentsBuffer[count] = constantReference(value); 735 argumentsBuffer[count] = constantReference(value);
735 } 736 }
736 } 737 }
737 } 738 }
738 count++; 739 count++;
739 }); 740 });
740 741
741 List body; 742 List body;
742 if (member.hasFixedBackendName()) { 743 if (member.hasFixedBackendName()) {
743 body = nativeEmitter.generateParameterStubStatements( 744 body = nativeEmitter.generateParameterStubStatements(
744 member, invocationName, parametersBuffer, argumentsBuffer, 745 member, isInterceptedMethod, invocationName,
746 parametersBuffer, argumentsBuffer,
745 indexOfLastOptionalArgumentInParameters); 747 indexOfLastOptionalArgumentInParameters);
746 } else { 748 } else {
747 body = [js.return_(js['this'][namer.getName(member)](argumentsBuffer))]; 749 body = [js.return_(js['this'][namer.getName(member)](argumentsBuffer))];
748 } 750 }
749 751
750 jsAst.Fun function = js.fun(parametersBuffer, body); 752 jsAst.Fun function = js.fun(parametersBuffer, body);
751 753
752 defineStub(invocationName, function); 754 defineStub(invocationName, function);
753 } 755 }
754 756
(...skipping 1484 matching lines...) Expand 10 before | Expand all | Expand 10 after
2239 cls == backend.jsFixedArrayClass || 2241 cls == backend.jsFixedArrayClass ||
2240 cls == backend.jsExtendableArrayClass) hasArray = true; 2242 cls == backend.jsExtendableArrayClass) hasArray = true;
2241 else if (cls == backend.jsBoolClass) hasBool = true; 2243 else if (cls == backend.jsBoolClass) hasBool = true;
2242 else if (cls == backend.jsDoubleClass) hasDouble = true; 2244 else if (cls == backend.jsDoubleClass) hasDouble = true;
2243 else if (cls == backend.jsFunctionClass) hasFunction = true; 2245 else if (cls == backend.jsFunctionClass) hasFunction = true;
2244 else if (cls == backend.jsIntClass) hasInt = true; 2246 else if (cls == backend.jsIntClass) hasInt = true;
2245 else if (cls == backend.jsNullClass) hasNull = true; 2247 else if (cls == backend.jsNullClass) hasNull = true;
2246 else if (cls == backend.jsNumberClass) hasNumber = true; 2248 else if (cls == backend.jsNumberClass) hasNumber = true;
2247 else if (cls == backend.jsStringClass) hasString = true; 2249 else if (cls == backend.jsStringClass) hasString = true;
2248 else { 2250 else {
2249 assert(cls == compiler.objectClass); 2251 // TODO(sra): The set of classes includes classes mixed-in to
2252 // interceptor classes.
2253 // assert(cls == compiler.objectClass || cls.isNative());
2250 } 2254 }
2251 } 2255 }
2252 if (hasDouble) { 2256 if (hasDouble) {
2253 hasNumber = true; 2257 hasNumber = true;
2254 } 2258 }
2255 if (hasInt) hasNumber = true; 2259 if (hasInt) hasNumber = true;
2256 2260
2257 jsAst.Block block = new jsAst.Block.empty(); 2261 jsAst.Block block = new jsAst.Block.empty();
2258 2262
2259 if (hasNumber) { 2263 if (hasNumber) {
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after
2786 """; 2790 """;
2787 const String HOOKS_API_USAGE = """ 2791 const String HOOKS_API_USAGE = """
2788 // The code supports the following hooks: 2792 // The code supports the following hooks:
2789 // dartPrint(message) - if this function is defined it is called 2793 // dartPrint(message) - if this function is defined it is called
2790 // instead of the Dart [print] method. 2794 // instead of the Dart [print] method.
2791 // dartMainRunner(main) - if this function is defined, the Dart [main] 2795 // dartMainRunner(main) - if this function is defined, the Dart [main]
2792 // method will not be invoked directly. 2796 // method will not be invoked directly.
2793 // Instead, a closure that will invoke [main] is 2797 // Instead, a closure that will invoke [main] is
2794 // passed to [dartMainRunner]. 2798 // passed to [dartMainRunner].
2795 """; 2799 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698