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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart

Issue 928203003: Implement Function.apply in the new emitter. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library dart2js.new_js_emitter.model_emitter; 5 library dart2js.new_js_emitter.model_emitter;
6 6
7 import '../../constants/values.dart' show ConstantValue;
7 import '../../dart2jslib.dart' show Compiler; 8 import '../../dart2jslib.dart' show Compiler;
8 import '../../dart_types.dart' show DartType; 9 import '../../dart_types.dart' show DartType;
9 import '../../elements/elements.dart' show ClassElement; 10 import '../../elements/elements.dart' show ClassElement;
10 import '../../js/js.dart' as js; 11 import '../../js/js.dart' as js;
11 import '../../js_backend/js_backend.dart' show 12 import '../../js_backend/js_backend.dart' show
12 JavaScriptBackend, 13 JavaScriptBackend,
13 Namer, 14 Namer,
14 ConstantEmitter; 15 ConstantEmitter;
15 16
16 import '../js_emitter.dart' show 17 import '../js_emitter.dart' show
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 elements.add( 107 elements.add(
107 emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields)); 108 emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
108 109
109 js.Expression code = new js.ArrayInitializer(elements); 110 js.Expression code = new js.ArrayInitializer(elements);
110 111
111 Map<String, dynamic> holes = 112 Map<String, dynamic> holes =
112 {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap), 113 {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap),
113 'holders': emitHolders(program.holders), 114 'holders': emitHolders(program.holders),
114 'tearOff': buildTearOffCode(backend), 115 'tearOff': buildTearOffCode(backend),
115 'parseFunctionDescriptor': 116 'parseFunctionDescriptor':
116 js.js.statement(parseFunctionDescriptorBoilerplate), 117 js.js.statement(parseFunctionDescriptorBoilerplate,
118 {'argCnt': js.string(namer.requiredParameterField),
119 'defArgValues': js.string(namer.defaultValuesField)}),
120
117 'cyclicThrow': 121 'cyclicThrow':
118 backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()), 122 backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()),
119 'outputContainsConstantList': program.outputContainsConstantList, 123 'outputContainsConstantList': program.outputContainsConstantList,
120 'embeddedGlobals': emitEmbeddedGlobals(program), 124 'embeddedGlobals': emitEmbeddedGlobals(program),
121 'constants': emitConstants(fragment.constants), 125 'constants': emitConstants(fragment.constants),
122 'staticNonFinals': 126 'staticNonFinals':
123 emitStaticNonFinalFields(fragment.staticNonFinalFields), 127 emitStaticNonFinalFields(fragment.staticNonFinalFields),
124 'operatorIsPrefix': js.string(namer.operatorIsPrefix), 128 'operatorIsPrefix': js.string(namer.operatorIsPrefix),
125 'eagerClasses': emitEagerClassInitializations(fragment.libraries), 129 'eagerClasses': emitEagerClassInitializations(fragment.libraries),
126 'invokeMain': fragment.invokeMain, 130 'invokeMain': fragment.invokeMain,
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 assert(field.isLazy); 549 assert(field.isLazy);
546 return unparse(compiler, field.code); 550 return unparse(compiler, field.code);
547 } 551 }
548 552
549 /// JavaScript code template that implements parsing of a function descriptor. 553 /// JavaScript code template that implements parsing of a function descriptor.
550 /// Descriptors are used in place of the actual JavaScript function 554 /// Descriptors are used in place of the actual JavaScript function
551 /// definition in the output if additional information needs to be passed to 555 /// definition in the output if additional information needs to be passed to
552 /// facilitate the generation of tearOffs at runtime. The format is an array 556 /// facilitate the generation of tearOffs at runtime. The format is an array
553 /// with the following fields: 557 /// with the following fields:
554 /// 558 ///
555 /// [InstanceMethod.aliasName] (optional). 559 /// [InstanceMethod.aliasName] (optional).
floitsch 2015/02/16 15:26:03 Since this is dartdoc, writing the fields line per
herhut 2015/02/17 10:25:39 Done.
556 /// [Method.code] 560 /// [Method.code]
557 /// [DartMethod.callName] 561 /// [DartMethod.callName]
558 /// isInterceptedMethod (optional, present if [DartMethod.needsTearOff]). 562 /// isInterceptedMethod (optional, present if [DartMethod.needsTearOff]).
559 /// [DartMethod.tearOffName] (optional, present if [DartMethod.needsTearOff]). 563 /// [DartMethod.tearOffName] (optional, present if [DartMethod.needsTearOff]).
560 /// functionType (optional, present if [DartMethod.needsTearOff]). 564 /// functionType (optional, present if [DartMethod.needsTearOff]).
561 /// 565 ///
562 /// followed by 566 /// followed by
563 /// 567 ///
564 /// [ParameterStubMethod.name] 568 /// [ParameterStubMethod.name]
565 /// [ParameterStubMethod.code] 569 /// [ParameterStubMethod.code]
floitsch 2015/02/16 15:26:03 Something seems to be missing here.
herhut 2015/02/17 10:25:39 [ParameterStubMethod.callName] was missing. Fixed.
566 /// 570 ///
567 /// for each stub in [DartMethod.parameterStubs]. 571 /// for each stub in [DartMethod.parameterStubs]. If [DartMethod.canBeApplied]
floitsch 2015/02/16 15:26:03 Start a new paragraph. If the closure could be us
herhut 2015/02/17 10:25:39 Done.
572 /// is true
573 ///
574 /// [DartMethod.requiredParameterCount]
575 /// [DartMethod.optionalParameterDefaultValues]
576 ///
577 /// is also appended.
568 578
569 static final String parseFunctionDescriptorBoilerplate = r""" 579 static final String parseFunctionDescriptorBoilerplate = r"""
570 function parseFunctionDescriptor(proto, name, descriptor) { 580 function parseFunctionDescriptor(proto, name, descriptor) {
571 if (descriptor instanceof Array) { 581 if (descriptor instanceof Array) {
572 // 'pos' points to the last read entry. 582 // 'pos' points to the last read entry.
573 var f, pos = -1; 583 var f, pos = -1;
574 var aliasOrFunction = descriptor[++pos]; 584 var aliasOrFunction = descriptor[++pos];
575 if (typeof aliasOrFunction == "string") { 585 if (typeof aliasOrFunction == "string") {
576 // Install the alias for super calls on the prototype chain. 586 // Install the alias for super calls on the prototype chain.
577 proto[aliasOrFunction] = f = descriptor[++pos]; 587 proto[aliasOrFunction] = f = descriptor[++pos];
578 } else { 588 } else {
579 f = aliasOrFunction; 589 f = aliasOrFunction;
580 } 590 }
581 591
582 proto[name] = f; 592 proto[name] = f;
583 var funs = [f]; 593 var funs = [f];
584 f.$callName = descriptor[++pos]; 594 f.$callName = descriptor[++pos];
585 595
586 var isInterceptedOrParameterStubName = descriptor[pos + 1]; 596 var isInterceptedOrParameterStubName = descriptor[pos + 1];
587 var isIntercepted, tearOffName, reflectionInfo; 597 var isIntercepted, tearOffName, reflectionInfo;
588 if (typeof isInterceptedOrParameterStubName == "boolean") { 598 if (typeof isInterceptedOrParameterStubName == "boolean") {
589 isIntercepted = descriptor[++pos]; 599 isIntercepted = descriptor[++pos];
590 tearOffName = descriptor[++pos]; 600 tearOffName = descriptor[++pos];
591 reflectionInfo = descriptor[++pos]; 601 reflectionInfo = descriptor[++pos];
592 } 602 }
593 603
594 for (++pos; pos < descriptor.length; pos += 3) { 604 for (++pos; pos < descriptor.length - 2; pos += 3) {
floitsch 2015/02/16 15:26:03 add a comment why the "2".
herhut 2015/02/17 10:25:39 Done.
595 var stub = descriptor[pos + 2]; 605 var stub = descriptor[pos + 2];
596 stub.$callName = descriptor[pos + 1]; 606 stub.$callName = descriptor[pos + 1];
floitsch 2015/02/16 15:26:03 This should be a shared variable. (the "$callName"
herhut 2015/02/17 10:25:39 Done.
597 proto[descriptor[pos]] = stub; 607 proto[descriptor[pos]] = stub;
598 funs.push(stub); 608 funs.push(stub);
599 } 609 }
600 610
601 if (tearOffName) { 611 if (tearOffName) {
602 proto[tearOffName] = 612 proto[tearOffName] =
603 tearOff(funs, reflectionInfo, false, name, isIntercepted); 613 tearOff(funs, reflectionInfo, false, name, isIntercepted);
604 } 614 }
605 615 if (descriptor[pos] != null) {
616 f[#argCnt] = descriptor[pos];
617 f[#defArgValues] = descriptor[pos + 1];
618 }
606 } else { 619 } else {
607 proto[name] = descriptor; 620 proto[name] = descriptor;
608 } 621 }
609 } 622 }
610 """; 623 """;
611 624
612 js.Expression _generateFunctionType(DartType memberType) { 625 js.Expression _generateFunctionType(DartType memberType) {
613 if (memberType.containsTypeVariables) { 626 if (memberType.containsTypeVariables) {
614 js.Expression thisAccess = js.js(r'this.$receiver'); 627 js.Expression thisAccess = js.js(r'this.$receiver');
615 return backend.rti.getSignatureEncoding(memberType, thisAccess); 628 return backend.rti.getSignatureEncoding(memberType, thisAccess);
616 } else { 629 } else {
617 return js.number(backend.emitter.metadataCollector.reifyType(memberType)); 630 return js.number(backend.emitter.metadataCollector.reifyType(memberType));
618 } 631 }
619 } 632 }
620 633
634 js.Expression _encodeOptionalParameterDefaultValues(DartMethod method) {
635 js.Expression result;
636 // TODO(herhut): Replace [js.LiteralNull] with [js.ArrayHole].
637 if (method.optionalParameterDefaultValues is List) {
638 List<ConstantValue> defs = method.optionalParameterDefaultValues;
639 Iterable<js.Expression> elements = defs.map(constantEmitter.reference);
640 return new js.ArrayInitializer(elements.toList());
641 } else {
642 Map<String, ConstantValue> defs = method.optionalParameterDefaultValues;
643 List<js.Property> properties = <js.Property>[];
644 defs.forEach((String name, ConstantValue value) {
645 properties.add(new js.Property(js.string(name),
646 constantEmitter.reference(value)));
647 });
648 return new js.ObjectInitializer(properties);
649 }
650 }
651
621 Iterable<js.Expression> emitInstanceMethod(Method method) { 652 Iterable<js.Expression> emitInstanceMethod(Method method) {
622 653
623 List<js.Expression> makeNameCodePair(Method method) { 654 List<js.Expression> makeNameCodePair(Method method) {
624 return [js.string(method.name), method.code]; 655 return [js.string(method.name), method.code];
625 } 656 }
626 657
627 List<js.Expression> makeNameCallNameCodeTriplet(ParameterStubMethod stub) { 658 List<js.Expression> makeNameCallNameCodeTriplet(ParameterStubMethod stub) {
628 js.Expression callName = stub.callName == null 659 js.Expression callName = stub.callName == null
629 ? new js.LiteralNull() 660 ? new js.LiteralNull()
630 : js.string(stub.callName); 661 : js.string(stub.callName);
(...skipping 14 matching lines...) Expand all
645 data.add(js.string(method.callName)); 676 data.add(js.string(method.callName));
646 677
647 if (method.needsTearOff) { 678 if (method.needsTearOff) {
648 bool isIntercepted = backend.isInterceptedMethod(method.element); 679 bool isIntercepted = backend.isInterceptedMethod(method.element);
649 data.add(new js.LiteralBool(isIntercepted)); 680 data.add(new js.LiteralBool(isIntercepted));
650 data.add(js.string(method.tearOffName)); 681 data.add(js.string(method.tearOffName));
651 data.add(_generateFunctionType(method.type)); 682 data.add(_generateFunctionType(method.type));
652 } 683 }
653 684
654 data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet)); 685 data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet));
686 if (method.canBeApplied) {
687 data.add(js.number(method.requiredParameterCount));
688 data.add(_encodeOptionalParameterDefaultValues(method));
689 }
655 return [js.string(method.name), new js.ArrayInitializer(data)]; 690 return [js.string(method.name), new js.ArrayInitializer(data)];
656 } else { 691 } else {
657 // TODO(floitsch): not the most efficient way... 692 // TODO(floitsch): not the most efficient way...
658 return ([method]..addAll(method.parameterStubs)) 693 return ([method]..addAll(method.parameterStubs))
659 .expand(makeNameCodePair); 694 .expand(makeNameCodePair);
660 } 695 }
661 } else { 696 } else {
662 return makeNameCodePair(method); 697 return makeNameCodePair(method);
663 } 698 }
664 } 699 }
(...skipping 23 matching lines...) Expand all
688 /// The format emitted is the same as for the parser specified at 723 /// The format emitted is the same as for the parser specified at
689 /// [parseFunctionDescriptorBoilerplate] except for the missing 724 /// [parseFunctionDescriptorBoilerplate] except for the missing
690 /// field whether the method is intercepted. 725 /// field whether the method is intercepted.
691 // [name, [function, callName, tearOffName, functionType, 726 // [name, [function, callName, tearOffName, functionType,
692 // stub1_name, stub1_callName, stub1_code, ...] 727 // stub1_name, stub1_callName, stub1_code, ...]
693 var data = [unparse(compiler, method.code)]; 728 var data = [unparse(compiler, method.code)];
694 data.add(js.string(method.callName)); 729 data.add(js.string(method.callName));
695 data.add(js.string(method.tearOffName)); 730 data.add(js.string(method.tearOffName));
696 data.add(_generateFunctionType(method.type)); 731 data.add(_generateFunctionType(method.type));
697 data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet)); 732 data.addAll(method.parameterStubs.expand(makeNameCallNameCodeTriplet));
733 if (method.canBeApplied) {
734 data.add(js.number(method.requiredParameterCount));
735 data.add(_encodeOptionalParameterDefaultValues(method));
736 }
698 return [js.string(method.name), holderIndex, 737 return [js.string(method.name), holderIndex,
699 new js.ArrayInitializer(data)]; 738 new js.ArrayInitializer(data)];
700 } else { 739 } else {
701 method.parameterStubs.forEach(_addMethod); 740 method.parameterStubs.forEach(_addMethod);
702 } 741 }
703 } 742 }
704 return output; 743 return output;
705 } 744 }
706 745
707 static final String setupProgramName = "setupProgram"; 746 static final String setupProgramName = "setupProgram";
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 1017
979 var end = Date.now(); 1018 var end = Date.now();
980 // print('Setup: ' + (end - start) + ' ms.'); 1019 // print('Setup: ' + (end - start) + ' ms.');
981 1020
982 #invokeMain; // Start main. 1021 #invokeMain; // Start main.
983 1022
984 }(Date.now(), #code) 1023 }(Date.now(), #code)
985 }"""; 1024 }""";
986 1025
987 } 1026 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698