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

Side by Side Diff: frog/leg/native_handler.dart

Issue 9537007: Implement native getters and setters and move supported tests to 'native'. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
« no previous file with comments | « no previous file | frog/tests/frog/frog.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #library('native'); 5 #library('native');
6 #import('leg.dart'); 6 #import('leg.dart');
7 #import('elements/elements.dart'); 7 #import('elements/elements.dart');
8 #import('scanner/scannerlib.dart'); 8 #import('scanner/scannerlib.dart');
9 #import('ssa/ssa.dart'); 9 #import('ssa/ssa.dart');
10 #import('tree/tree.dart'); 10 #import('tree/tree.dart');
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 i++; 121 i++;
122 inputs.add(builder.localsHandler.readThis()); 122 inputs.add(builder.localsHandler.readThis());
123 } 123 }
124 parameters.forEachParameter((Element parameter) { 124 parameters.forEachParameter((Element parameter) {
125 arguments.add('\$$i'); 125 arguments.add('\$$i');
126 inputs.add(builder.localsHandler.readLocal(parameter)); 126 inputs.add(builder.localsHandler.readLocal(parameter));
127 i++; 127 i++;
128 }); 128 });
129 String foreignParameters = Strings.join(arguments, ','); 129 String foreignParameters = Strings.join(arguments, ',');
130 130
131 String methodName = builder.compiler.namer.instanceMethodName( 131 String dartMethodName;
kasperl 2012/02/29 10:16:38 I guess this almost calls for an abstraction with
ngeoffray 2012/02/29 10:19:19 We have the element, but I'm not sure I want to po
132 element.name, parameters.parameterCount); 132 String nativeMethodName = element.name.slowToString();
133 String nativeMethodCall;
134
135 if (element.kind == ElementKind.FUNCTION) {
136 dartMethodName = builder.compiler.namer.instanceMethodName(
137 element.name, parameters.parameterCount);
138 nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)';
139 } else if (element.kind == ElementKind.GETTER) {
140 dartMethodName = builder.compiler.namer.getterName(element.name);
141 nativeMethodCall = '$receiver$nativeMethodName';
142 } else if (element.kind == ElementKind.SETTER) {
143 dartMethodName = builder.compiler.namer.setterName(element.name);
144 nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters';
145 } else {
146 builder.compiler.internalError('unexpected kind: "${element.kind}"',
147 element: element);
148 }
133 149
134 HInstruction thenInstruction; 150 HInstruction thenInstruction;
135 void visitThen() { 151 void visitThen() {
136 SourceString jsCode = new SourceString( 152 SourceString jsCode = new SourceString(nativeMethodCall);
137 '$receiver${element.name.slowToString()}($foreignParameters)');
138 thenInstruction = 153 thenInstruction =
139 new HForeign(jsCode, const SourceString('Object'), inputs); 154 new HForeign(jsCode, const SourceString('Object'), inputs);
140 builder.add(thenInstruction); 155 builder.add(thenInstruction);
141 } 156 }
142 157
143 if (!element.isInstanceMember()) { 158 if (!element.isInstanceMember()) {
144 // If the method is a non-instance method, we just generate a direct 159 // If the method is a non-instance method, we just generate a direct
145 // call to the native method. 160 // call to the native method.
146 visitThen(); 161 visitThen();
147 builder.stack.add(thenInstruction); 162 builder.stack.add(thenInstruction);
148 } else { 163 } else {
149 // If the method is an instance method, we generate the following code: 164 // If the method is an instance method, we generate the following code:
150 // function(params) { 165 // function(params) {
151 // return Object.getPrototypeOf(this).hasOwnProperty(methodName)) 166 // return Object.getPrototypeOf(this).hasOwnProperty(dartMethodName))
152 // ? this.methodName(params) 167 // ? this.methodName(params)
153 // : Object.prototype.methodName.call(this, params); 168 // : Object.prototype.methodName.call(this, params);
154 // } 169 // }
155 // 170 //
156 // The property check at the beginning is to make sure we won't 171 // The property check at the beginning is to make sure we won't
157 // call the method from the super class, in case the prototype of 172 // call the method from the super class, in case the prototype of
158 // 'this' does not have the method yet. 173 // 'this' does not have the method yet.
159 // 174 //
160 // TODO(ngeoffray): We can avoid this if we know the class of this 175 // TODO(ngeoffray): We can avoid this if we know the class of this
161 // method does not have subclasses. 176 // method does not have subclasses.
162 HInstruction elseInstruction; 177 HInstruction elseInstruction;
163 void visitElse() { 178 void visitElse() {
164 SourceString jsCode = new SourceString('Object.prototype.$methodName'); 179 SourceString jsCode =
180 new SourceString('Object.prototype.$dartMethodName');
165 HInstruction instruction = 181 HInstruction instruction =
166 new HForeign(jsCode, const SourceString('Object'), []); 182 new HForeign(jsCode, const SourceString('Object'), []);
167 builder.add(instruction); 183 builder.add(instruction);
168 List<HInstruction> elseInputs = new List<HInstruction>.from(inputs); 184 List<HInstruction> elseInputs = new List<HInstruction>.from(inputs);
169 elseInputs.add(instruction); 185 elseInputs.add(instruction);
170 String params = arguments.isEmpty() ? '' : ', $foreignParameters'; 186 String params = arguments.isEmpty() ? '' : ', $foreignParameters';
171 jsCode = new SourceString('\$${i}.call(\$0$params)'); 187 jsCode = new SourceString('\$${i}.call(\$0$params)');
172 elseInstruction = 188 elseInstruction =
173 new HForeign(jsCode, const SourceString('Object'), elseInputs); 189 new HForeign(jsCode, const SourceString('Object'), elseInputs);
174 builder.add(elseInstruction); 190 builder.add(elseInstruction);
175 } 191 }
176 192
177 HLiteral literal = builder.graph.addNewLiteralString( 193 HLiteral literal = builder.graph.addNewLiteralString(
178 new DartString.literal('$methodName')); 194 new DartString.literal('$dartMethodName'));
179 SourceString jsCode = new SourceString( 195 SourceString jsCode = new SourceString(
180 'Object.getPrototypeOf(\$0).hasOwnProperty(\$1)'); 196 'Object.getPrototypeOf(\$0).hasOwnProperty(\$1)');
181 builder.push(new HForeign( 197 builder.push(new HForeign(
182 jsCode, const SourceString('Object'), 198 jsCode, const SourceString('Object'),
183 <HInstruction>[builder.localsHandler.readThis(), literal])); 199 <HInstruction>[builder.localsHandler.readThis(), literal]));
184 200
185 builder.handleIf(visitThen, visitElse); 201 builder.handleIf(visitThen, visitElse);
186 202
187 HPhi phi = new HPhi.manyInputs( 203 HPhi phi = new HPhi.manyInputs(
188 null, <HInstruction>[thenInstruction, elseInstruction]); 204 null, <HInstruction>[thenInstruction, elseInstruction]);
189 builder.current.addPhi(phi); 205 builder.current.addPhi(phi);
190 builder.stack.add(phi); 206 builder.stack.add(phi);
191 } 207 }
192 208
193 } else if (!node.arguments.tail.isEmpty()) { 209 } else if (!node.arguments.tail.isEmpty()) {
194 builder.compiler.cancel('More than one argument to native'); 210 builder.compiler.cancel('More than one argument to native');
195 } else { 211 } else {
196 LiteralString jsCode = node.arguments.head; 212 LiteralString jsCode = node.arguments.head;
197 int start = jsCode.value.slowToString()[0] === '@' ? 1 : 0; 213 int start = jsCode.value.slowToString()[0] === '@' ? 1 : 0;
198 builder.push(new HForeign(builder.unquote(jsCode, start), 214 builder.push(new HForeign(builder.unquote(jsCode, start),
199 const SourceString('Object'), 215 const SourceString('Object'),
200 <HInstruction>[])); 216 <HInstruction>[]));
201 } 217 }
202 } 218 }
OLDNEW
« no previous file with comments | « no previous file | frog/tests/frog/frog.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698