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

Side by Side Diff: dart/lib/compiler/implementation/native_handler.dart

Issue 10441071: Use the typedef arity to know how to invoke a closure given by the dom. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 6 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 #library('native'); 5 #library('native');
6 #import('dart:uri'); 6 #import('dart:uri');
7 #import('leg.dart'); 7 #import('leg.dart');
8 #import('elements/elements.dart'); 8 #import('elements/elements.dart');
9 #import('scanner/scannerlib.dart'); 9 #import('scanner/scannerlib.dart');
10 #import('ssa/ssa.dart'); 10 #import('ssa/ssa.dart');
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 && nativeEmitter.toNativeName(element.enclosingElement) == 'DOMType') { 208 && nativeEmitter.toNativeName(element.enclosingElement) == 'DOMType') {
209 Element methodElement = 209 Element methodElement =
210 compiler.findHelper(const SourceString('getTypeNameOf')); 210 compiler.findHelper(const SourceString('getTypeNameOf'));
211 HStatic method = new HStatic(methodElement); 211 HStatic method = new HStatic(methodElement);
212 builder.add(method); 212 builder.add(method);
213 builder.push(new HInvokeStatic(Selector.INVOCATION_1, 213 builder.push(new HInvokeStatic(Selector.INVOCATION_1,
214 <HInstruction>[method, builder.localsHandler.readThis()])); 214 <HInstruction>[method, builder.localsHandler.readThis()]));
215 return; 215 return;
216 } 216 }
217 217
218 HInstruction convertDartClosure(Element parameter) { 218 HInstruction convertDartClosure(Element parameter, Type type) {
219 HInstruction local = builder.localsHandler.readLocal(parameter); 219 HInstruction local = builder.localsHandler.readLocal(parameter);
220 // TODO(ngeoffray): by better analyzing the function type and 220 // TODO(ngeoffray): For static methods, we could pass a method with a
221 // its formal parameters, we could pass a method with a defined arity. 221 // defined arity.
222 builder.push(new HStatic(builder.interceptors.getClosureConverter())); 222 builder.push(new HStatic(builder.interceptors.getClosureConverter()));
223 List<HInstruction> callInputs = <HInstruction>[builder.pop(), local]; 223 HInstruction arity = builder.graph.addConstantInt(type.computeArity());
224 List<HInstruction> callInputs = <HInstruction>[builder.pop(), local, arity];
224 HInstruction closure = new HInvokeStatic(Selector.INVOCATION_1, callInputs); 225 HInstruction closure = new HInvokeStatic(Selector.INVOCATION_1, callInputs);
225 builder.add(closure); 226 builder.add(closure);
226 return closure; 227 return closure;
227 } 228 }
228 229
229 230
230 // Check which pattern this native method follows: 231 // Check which pattern this native method follows:
231 // 1) foo() native; hasBody = false, isRedirecting = false 232 // 1) foo() native; hasBody = false, isRedirecting = false
232 // 2) foo() native "bar"; hasBody = false, isRedirecting = true 233 // 2) foo() native "bar"; hasBody = false, isRedirecting = true
233 // 3) foo() native "return 42"; hasBody = true, isRedirecting = false 234 // 3) foo() native "return 42"; hasBody = true, isRedirecting = false
(...skipping 24 matching lines...) Expand all
258 List<String> arguments = <String>[]; 259 List<String> arguments = <String>[];
259 List<HInstruction> inputs = <HInstruction>[]; 260 List<HInstruction> inputs = <HInstruction>[];
260 String receiver = ''; 261 String receiver = '';
261 if (element.isInstanceMember()) { 262 if (element.isInstanceMember()) {
262 receiver = '#.'; 263 receiver = '#.';
263 inputs.add(builder.localsHandler.readThis()); 264 inputs.add(builder.localsHandler.readThis());
264 } 265 }
265 parameters.forEachParameter((Element parameter) { 266 parameters.forEachParameter((Element parameter) {
266 Type type = parameter.computeType(compiler); 267 Type type = parameter.computeType(compiler);
267 HInstruction input = builder.localsHandler.readLocal(parameter); 268 HInstruction input = builder.localsHandler.readLocal(parameter);
268 if (type is FunctionType) input = convertDartClosure(parameter); 269 if (type is FunctionType) input = convertDartClosure(parameter, type);
269 inputs.add(input); 270 inputs.add(input);
270 arguments.add('#'); 271 arguments.add('#');
271 }); 272 });
272 273
273 String foreignParameters = Strings.join(arguments, ','); 274 String foreignParameters = Strings.join(arguments, ',');
274 String nativeMethodCall; 275 String nativeMethodCall;
275 if (element.kind == ElementKind.FUNCTION) { 276 if (element.kind == ElementKind.FUNCTION) {
276 nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)'; 277 nativeMethodCall = '$receiver$nativeMethodName($foreignParameters)';
277 } else if (element.kind == ElementKind.GETTER) { 278 } else if (element.kind == ElementKind.GETTER) {
278 nativeMethodCall = '$receiver$nativeMethodName'; 279 nativeMethodCall = '$receiver$nativeMethodName';
(...skipping 10 matching lines...) Expand all
289 } else { 290 } else {
290 // This is JS code written in a Dart file with the construct 291 // This is JS code written in a Dart file with the construct
291 // native """ ... """;. It does not work well with mangling, 292 // native """ ... """;. It does not work well with mangling,
292 // but there should currently be no clash between leg mangling 293 // but there should currently be no clash between leg mangling
293 // and the library where this construct is being used. This 294 // and the library where this construct is being used. This
294 // mangling problem will go away once we switch these libraries 295 // mangling problem will go away once we switch these libraries
295 // to use Leg's 'JS' function. 296 // to use Leg's 'JS' function.
296 parameters.forEachParameter((Element parameter) { 297 parameters.forEachParameter((Element parameter) {
297 Type type = parameter.computeType(compiler); 298 Type type = parameter.computeType(compiler);
298 if (type is FunctionType) { 299 if (type is FunctionType) {
299 HInstruction jsClosure = convertDartClosure(parameter); 300 HInstruction jsClosure = convertDartClosure(parameter, type);
300 // Because the JS code references the argument name directly, 301 // Because the JS code references the argument name directly,
301 // we must keep the name and assign the JS closure to it. 302 // we must keep the name and assign the JS closure to it.
302 builder.add(new HForeign( 303 builder.add(new HForeign(
303 new DartString.literal('${parameter.name.slowToString()} = #'), 304 new DartString.literal('${parameter.name.slowToString()} = #'),
304 const LiteralDartString('void'), 305 const LiteralDartString('void'),
305 <HInstruction>[jsClosure])); 306 <HInstruction>[jsClosure]));
306 } 307 }
307 }); 308 });
308 LiteralString jsCode = node.arguments.head; 309 LiteralString jsCode = node.arguments.head;
309 builder.push(new HForeign(jsCode.dartString, 310 builder.push(new HForeign(jsCode.dartString,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 String parameters) { 350 String parameters) {
350 buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty"); 351 buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty");
351 buffer.add("('$methodName')) {\n"); 352 buffer.add("('$methodName')) {\n");
352 buffer.add(" $code"); 353 buffer.add(" $code");
353 buffer.add(" } else {\n"); 354 buffer.add(" } else {\n");
354 buffer.add(" return Object.prototype.$methodName.call(this"); 355 buffer.add(" return Object.prototype.$methodName.call(this");
355 buffer.add(parameters == '' ? '' : ', $parameters'); 356 buffer.add(parameters == '' ? '' : ', $parameters');
356 buffer.add(");\n"); 357 buffer.add(");\n");
357 buffer.add(" }\n"); 358 buffer.add(" }\n");
358 } 359 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698