| 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('js_backend/js_backend.dart'); | 9 #import('js_backend/js_backend.dart'); |
| 10 #import('scanner/scannerlib.dart'); | 10 #import('scanner/scannerlib.dart'); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 element.setNative(); | 184 element.setNative(); |
| 185 NativeEmitter nativeEmitter = builder.emitter.nativeEmitter; | 185 NativeEmitter nativeEmitter = builder.emitter.nativeEmitter; |
| 186 // If what we're compiling is a getter named 'typeName' and the native | 186 // If what we're compiling is a getter named 'typeName' and the native |
| 187 // class is named 'DOMType', we generate a call to the typeNameOf | 187 // class is named 'DOMType', we generate a call to the typeNameOf |
| 188 // function attached on the isolate. | 188 // function attached on the isolate. |
| 189 // The DOM classes assume that their 'typeName' property, which is | 189 // The DOM classes assume that their 'typeName' property, which is |
| 190 // not a JS property on the DOM types, returns the type name. | 190 // not a JS property on the DOM types, returns the type name. |
| 191 if (element.name == const SourceString('typeName') | 191 if (element.name == const SourceString('typeName') |
| 192 && element.isGetter() | 192 && element.isGetter() |
| 193 && nativeEmitter.toNativeName(element.getEnclosingClass()) == 'DOMType') { | 193 && nativeEmitter.toNativeName(element.getEnclosingClass()) == 'DOMType') { |
| 194 Element methodElement = | 194 Element helper = |
| 195 compiler.findHelper(const SourceString('getTypeNameOf')); | 195 compiler.findHelper(const SourceString('getTypeNameOf')); |
| 196 HStatic method = new HStatic(methodElement); | 196 builder.pushInvokeHelper1(helper, builder.localsHandler.readThis()); |
| 197 builder.add(method); | |
| 198 builder.push(new HInvokeStatic(Selector.INVOCATION_1, | |
| 199 <HInstruction>[method, builder.localsHandler.readThis()])); | |
| 200 builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit); | 197 builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit); |
| 201 } | 198 } |
| 202 | 199 |
| 203 HInstruction convertDartClosure(Element parameter, FunctionType type) { | 200 HInstruction convertDartClosure(Element parameter, FunctionType type) { |
| 204 HInstruction local = builder.localsHandler.readLocal(parameter); | 201 HInstruction local = builder.localsHandler.readLocal(parameter); |
| 202 HInstruction arity = builder.graph.addConstantInt(type.computeArity()); |
| 205 // TODO(ngeoffray): For static methods, we could pass a method with a | 203 // TODO(ngeoffray): For static methods, we could pass a method with a |
| 206 // defined arity. | 204 // defined arity. |
| 207 builder.push(new HStatic(builder.interceptors.getClosureConverter())); | 205 Element helper = builder.interceptors.getClosureConverter(); |
| 208 HInstruction arity = builder.graph.addConstantInt(type.computeArity()); | 206 builder.pushInvokeHelper2(helper, local, arity); |
| 209 List<HInstruction> callInputs = <HInstruction>[builder.pop(), local, arity]; | 207 HInstruction closure = builder.pop(); |
| 210 HInstruction closure = new HInvokeStatic(Selector.INVOCATION_1, callInputs); | |
| 211 builder.add(closure); | |
| 212 return closure; | 208 return closure; |
| 213 } | 209 } |
| 214 | 210 |
| 215 // Check which pattern this native method follows: | 211 // Check which pattern this native method follows: |
| 216 // 1) foo() native; hasBody = false, isRedirecting = false | 212 // 1) foo() native; hasBody = false, isRedirecting = false |
| 217 // 2) foo() native "bar"; hasBody = false, isRedirecting = true | 213 // 2) foo() native "bar"; hasBody = false, isRedirecting = true |
| 218 // 3) foo() native "return 42"; hasBody = true, isRedirecting = false | 214 // 3) foo() native "return 42"; hasBody = true, isRedirecting = false |
| 219 RegExp nativeRedirectionRegExp = const RegExp(@'^[a-zA-Z][a-zA-Z_$0-9]*$'); | 215 RegExp nativeRedirectionRegExp = const RegExp(@'^[a-zA-Z][a-zA-Z_$0-9]*$'); |
| 220 bool hasBody = false; | 216 bool hasBody = false; |
| 221 bool isRedirecting = false; | 217 bool isRedirecting = false; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 String parameters) { | 327 String parameters) { |
| 332 buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty"); | 328 buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty"); |
| 333 buffer.add("('$methodName')) {\n"); | 329 buffer.add("('$methodName')) {\n"); |
| 334 buffer.add(" $code"); | 330 buffer.add(" $code"); |
| 335 buffer.add(" } else {\n"); | 331 buffer.add(" } else {\n"); |
| 336 buffer.add(" return Object.prototype.$methodName.call(this"); | 332 buffer.add(" return Object.prototype.$methodName.call(this"); |
| 337 buffer.add(parameters == '' ? '' : ', $parameters'); | 333 buffer.add(parameters == '' ? '' : ', $parameters'); |
| 338 buffer.add(");\n"); | 334 buffer.add(");\n"); |
| 339 buffer.add(" }\n"); | 335 buffer.add(" }\n"); |
| 340 } | 336 } |
| OLD | NEW |