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

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

Issue 10876008: Remove most superfluous getter arguments from dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 4 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 30 matching lines...) Expand all
41 : namer = compiler.namer, 41 : namer = compiler.namer,
42 boundClosureBuffer = new CodeBuffer(), 42 boundClosureBuffer = new CodeBuffer(),
43 mainBuffer = new CodeBuffer(), 43 mainBuffer = new CodeBuffer(),
44 boundClosureCache = new Map<int, String>(), 44 boundClosureCache = new Map<int, String>(),
45 generateSourceMap = generateSourceMap, 45 generateSourceMap = generateSourceMap,
46 sourceMapBuilder = new SourceMapBuilder(), 46 sourceMapBuilder = new SourceMapBuilder(),
47 super(compiler) { 47 super(compiler) {
48 nativeEmitter = new NativeEmitter(this); 48 nativeEmitter = new NativeEmitter(this);
49 } 49 }
50 50
51 String get name() => 'CodeEmitter'; 51 String get name => 'CodeEmitter';
52 52
53 String get defineClassName() 53 String get defineClassName
54 => '${namer.ISOLATE}.\$defineClass'; 54 => '${namer.ISOLATE}.\$defineClass';
55 String get finishClassesName() 55 String get finishClassesName
56 => '${namer.ISOLATE}.\$finishClasses'; 56 => '${namer.ISOLATE}.\$finishClasses';
57 String get finishIsolateConstructorName() 57 String get finishIsolateConstructorName
58 => '${namer.ISOLATE}.\$finishIsolateConstructor'; 58 => '${namer.ISOLATE}.\$finishIsolateConstructor';
59 String get pendingClassesName() 59 String get pendingClassesName
60 => '${namer.ISOLATE}.\$pendingClasses'; 60 => '${namer.ISOLATE}.\$pendingClasses';
61 String get isolatePropertiesName() 61 String get isolatePropertiesName
62 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}'; 62 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}';
63 String get supportsProtoName() 63 String get supportsProtoName
64 => 'supportsProto'; 64 => 'supportsProto';
65 65
66 final String GETTER_SUFFIX = "?"; 66 final String GETTER_SUFFIX = "?";
67 final String SETTER_SUFFIX = "!"; 67 final String SETTER_SUFFIX = "!";
68 final String GETTER_SETTER_SUFFIX = "="; 68 final String GETTER_SETTER_SUFFIX = "=";
69 69
70 String get generateGetterSetterFunction() { 70 String get generateGetterSetterFunction {
71 return """ 71 return """
72 function(field, prototype) { 72 function(field, prototype) {
73 var len = field.length; 73 var len = field.length;
74 var lastChar = field[len - 1]; 74 var lastChar = field[len - 1];
75 var needsGetter = lastChar == '$GETTER_SUFFIX' || lastChar == '$GETTER_SETTER_ SUFFIX'; 75 var needsGetter = lastChar == '$GETTER_SUFFIX' || lastChar == '$GETTER_SETTER_ SUFFIX';
76 var needsSetter = lastChar == '$SETTER_SUFFIX' || lastChar == '$GETTER_SETTER_ SUFFIX'; 76 var needsSetter = lastChar == '$SETTER_SUFFIX' || lastChar == '$GETTER_SETTER_ SUFFIX';
77 if (needsGetter || needsSetter) field = field.substring(0, len - 1); 77 if (needsGetter || needsSetter) field = field.substring(0, len - 1);
78 if (needsGetter) { 78 if (needsGetter) {
79 var getterString = "return this." + field + ";"; 79 var getterString = "return this." + field + ";";
80 """ /* The supportsProtoCheck below depends on the getter/setter convention. 80 """ /* The supportsProtoCheck below depends on the getter/setter convention.
81 When changing here, update the protoCheck too. */ """ 81 When changing here, update the protoCheck too. */ """
82 prototype["get\$" + field] = new Function(getterString); 82 prototype["get\$" + field] = new Function(getterString);
83 } 83 }
84 if (needsSetter) { 84 if (needsSetter) {
85 var setterString = "this." + field + " = v;"; 85 var setterString = "this." + field + " = v;";
86 prototype["set\$" + field] = new Function("v", setterString); 86 prototype["set\$" + field] = new Function("v", setterString);
87 } 87 }
88 return field; 88 return field;
89 }"""; 89 }""";
90 } 90 }
91 91
92 String get defineClassFunction() { 92 String get defineClassFunction {
93 // First the class name, then the super class name, followed by the fields 93 // First the class name, then the super class name, followed by the fields
94 // (in an array) and the members (inside an Object literal). 94 // (in an array) and the members (inside an Object literal).
95 // The caller can also pass in the constructor as a function if needed. 95 // The caller can also pass in the constructor as a function if needed.
96 // 96 //
97 // Example: 97 // Example:
98 // defineClass("A", "B", ["x", "y"], { 98 // defineClass("A", "B", ["x", "y"], {
99 // foo$1: function(y) { 99 // foo$1: function(y) {
100 // print(this.x + y); 100 // print(this.x + y);
101 // }, 101 // },
102 // bar$2: function(t, v) { 102 // bar$2: function(t, v) {
(...skipping 19 matching lines...) Expand all
122 str += ") {" + body + "}\\n"; 122 str += ") {" + body + "}\\n";
123 str += "return " + cls + ";"; 123 str += "return " + cls + ";";
124 constructor = new Function(str)(); 124 constructor = new Function(str)();
125 } 125 }
126 constructor.prototype = prototype; 126 constructor.prototype = prototype;
127 return constructor; 127 return constructor;
128 }"""; 128 }""";
129 } 129 }
130 130
131 /** Needs defineClass to be defined. */ 131 /** Needs defineClass to be defined. */
132 String get protoSupportCheck() { 132 String get protoSupportCheck {
133 // On Firefox and Webkit browsers we can manipulate the __proto__ 133 // On Firefox and Webkit browsers we can manipulate the __proto__
134 // directly. Opera claims to have __proto__ support, but it is buggy. 134 // directly. Opera claims to have __proto__ support, but it is buggy.
135 // So we have to do more checks. 135 // So we have to do more checks.
136 // If the browser does not support __proto__ we need to instantiate an 136 // If the browser does not support __proto__ we need to instantiate an
137 // object with the correct (internal) prototype set up correctly, and then 137 // object with the correct (internal) prototype set up correctly, and then
138 // copy the members. 138 // copy the members.
139 139
140 return ''' 140 return '''
141 var $supportsProtoName = false; 141 var $supportsProtoName = false;
142 var tmp = $defineClassName('c', ['f?'], {}).prototype; 142 var tmp = $defineClassName('c', ['f?'], {}).prototype;
143 if (tmp.__proto__) { 143 if (tmp.__proto__) {
144 tmp.__proto__ = {}; 144 tmp.__proto__ = {};
145 if (typeof tmp.get\$f !== "undefined") $supportsProtoName = true; 145 if (typeof tmp.get\$f !== "undefined") $supportsProtoName = true;
146 } 146 }
147 '''; 147 ''';
148 } 148 }
149 149
150 String get finishClassesFunction() { 150 String get finishClassesFunction {
151 // 'defineClass' does not require the classes to be constructed in order. 151 // 'defineClass' does not require the classes to be constructed in order.
152 // Classes are initially just stored in the 'pendingClasses' field. 152 // Classes are initially just stored in the 'pendingClasses' field.
153 // 'finishClasses' takes all pending classes and sets up the prototype. 153 // 'finishClasses' takes all pending classes and sets up the prototype.
154 // Once set up, the constructors prototype field satisfy: 154 // Once set up, the constructors prototype field satisfy:
155 // - it contains all (local) members. 155 // - it contains all (local) members.
156 // - its internal prototype (__proto__) points to the superclass' 156 // - its internal prototype (__proto__) points to the superclass'
157 // prototype field. 157 // prototype field.
158 // - the prototype's constructor field points to the JavaScript 158 // - the prototype's constructor field points to the JavaScript
159 // constructor. 159 // constructor.
160 // For engines where we have access to the '__proto__' we can manipulate 160 // For engines where we have access to the '__proto__' we can manipulate
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 if (hasOwnProperty.call(prototype, member)) { 201 if (hasOwnProperty.call(prototype, member)) {
202 newPrototype[member] = prototype[member]; 202 newPrototype[member] = prototype[member];
203 } 203 }
204 } 204 }
205 } 205 }
206 } 206 }
207 for (var cls in pendingClasses) finishClass(cls); 207 for (var cls in pendingClasses) finishClass(cls);
208 }'''; 208 }''';
209 } 209 }
210 210
211 String get finishIsolateConstructorFunction() { 211 String get finishIsolateConstructorFunction {
212 String isolate = namer.ISOLATE; 212 String isolate = namer.ISOLATE;
213 // We replace the old Isolate function with a new one that initializes 213 // We replace the old Isolate function with a new one that initializes
214 // all its field with the initial (and often final) value of all globals. 214 // all its field with the initial (and often final) value of all globals.
215 // This has two advantages: 215 // This has two advantages:
216 // 1. the properties are in the object itself (thus avoiding to go through 216 // 1. the properties are in the object itself (thus avoiding to go through
217 // the prototype when looking up globals. 217 // the prototype when looking up globals.
218 // 2. a new isolate goes through a (usually well optimized) constructor 218 // 2. a new isolate goes through a (usually well optimized) constructor
219 // function of the form: "function() { this.x = ...; this.y = ...; }". 219 // function of the form: "function() { this.x = ...; this.y = ...; }".
220 // 220 //
221 // Example: If [isolateProperties] is an object containing: x = 3 and 221 // Example: If [isolateProperties] is an object containing: x = 3 and
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 705
706 void emitDynamicFunctionGetter(FunctionElement member, 706 void emitDynamicFunctionGetter(FunctionElement member,
707 DefineMemberFunction defineInstanceMember) { 707 DefineMemberFunction defineInstanceMember) {
708 // For every method that has the same name as a property-get we create a 708 // For every method that has the same name as a property-get we create a
709 // getter that returns a bound closure. Say we have a class 'A' with method 709 // getter that returns a bound closure. Say we have a class 'A' with method
710 // 'foo' and somewhere in the code there is a dynamic property get of 710 // 'foo' and somewhere in the code there is a dynamic property get of
711 // 'foo'. Then we generate the following code (in pseudo Dart/JavaScript): 711 // 'foo'. Then we generate the following code (in pseudo Dart/JavaScript):
712 // 712 //
713 // class A { 713 // class A {
714 // foo(x, y, z) { ... } // Original function. 714 // foo(x, y, z) { ... } // Original function.
715 // get foo() { return new BoundClosure499(this, "foo"); } 715 // get foo { return new BoundClosure499(this, "foo"); }
716 // } 716 // }
717 // class BoundClosure499 extends Closure { 717 // class BoundClosure499 extends Closure {
718 // var self; 718 // var self;
719 // BoundClosure499(this.self, this.name); 719 // BoundClosure499(this.self, this.name);
720 // $call3(x, y, z) { return self[name](x, y, z); } 720 // $call3(x, y, z) { return self[name](x, y, z); }
721 // } 721 // }
722 722
723 // TODO(floitsch): share the closure classes with other classes 723 // TODO(floitsch): share the closure classes with other classes
724 // if they share methods with the same signature. Currently we do this only 724 // if they share methods with the same signature. Currently we do this only
725 // if there are no optional parameters. Closures with optional parameters 725 // if there are no optional parameters. Closures with optional parameters
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 sourceName = token.slowToString(); 1167 sourceName = token.slowToString();
1168 } 1168 }
1169 int totalOffset = bufferOffset + offset; 1169 int totalOffset = bufferOffset + offset;
1170 sourceMapBuilder.addMapping( 1170 sourceMapBuilder.addMapping(
1171 sourceFile, token.charOffset, sourceName, totalOffset); 1171 sourceFile, token.charOffset, sourceName, totalOffset);
1172 }); 1172 });
1173 } 1173 }
1174 } 1174 }
1175 1175
1176 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition); 1176 typedef void DefineMemberFunction(String invocationName, CodeBuffer definition);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698