Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 |
|
kasperl
2012/05/29 12:16:24
for -> For
ngeoffray
2012/05/29 12:31:01
Done.
| |
| 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.arity()); |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |