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 | 6 |
| 7 import 'dart:uri'; | 7 import 'dart:uri'; |
| 8 import 'dart2jslib.dart' hide SourceString; | 8 import 'dart2jslib.dart' hide SourceString; |
| 9 import 'elements/elements.dart'; | 9 import 'elements/elements.dart'; |
| 10 import 'js_backend/js_backend.dart'; | 10 import 'js_backend/js_backend.dart'; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 49 /** | 49 /** |
| 50 * Handles JS-calls, which can be an instantiation point for types. | 50 * Handles JS-calls, which can be an instantiation point for types. |
| 51 * | 51 * |
| 52 * For example, the following code instantiates and returns native classes | 52 * For example, the following code instantiates and returns native classes |
| 53 * that are `_DOMWindowImpl` or a subtype. | 53 * that are `_DOMWindowImpl` or a subtype. |
| 54 * | 54 * |
| 55 * JS('_DOMWindowImpl', 'window') | 55 * JS('_DOMWindowImpl', 'window') |
| 56 * | 56 * |
| 57 */ | 57 */ |
| 58 // TODO(sra): The entry from codegen will not have a resolver. | 58 // TODO(sra): The entry from codegen will not have a resolver. |
| 59 void registerJsCall(Send node, ResolverVisitor resolver) {} | 59 void registerJsCall(Send node, Enqueuer enqueuer, ResolverVisitor resolver) {} |
|
sra1
2012/11/29 16:45:50
enqueuer already available in implementations as t
| |
| 60 | 60 |
| 61 /// Emits a summary information using the [log] function. | 61 /// Emits a summary information using the [log] function. |
| 62 void logSummary(log(message)) {} | 62 void logSummary(log(message)) {} |
| 63 } | 63 } |
| 64 | 64 |
| 65 | 65 |
| 66 abstract class NativeEnqueuerBase implements NativeEnqueuer { | 66 abstract class NativeEnqueuerBase implements NativeEnqueuer { |
| 67 | 67 |
| 68 /** | 68 /** |
| 69 * The set of all native classes. Each native class is in [nativeClasses] and | 69 * The set of all native classes. Each native class is in [nativeClasses] and |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 flushQueue(); | 211 flushQueue(); |
| 212 } | 212 } |
| 213 | 213 |
| 214 void registerFieldStore(Element field) { | 214 void registerFieldStore(Element field) { |
| 215 processNativeBehavior( | 215 processNativeBehavior( |
| 216 NativeBehavior.ofFieldStore(field, compiler), | 216 NativeBehavior.ofFieldStore(field, compiler), |
| 217 field); | 217 field); |
| 218 flushQueue(); | 218 flushQueue(); |
| 219 } | 219 } |
| 220 | 220 |
| 221 void registerJsCall(Send node, ResolverVisitor resolver) { | 221 void registerJsCall(Send node, Enqueuer enqueuer, ResolverVisitor resolver) { |
| 222 processNativeBehavior( | 222 processNativeBehavior( |
| 223 NativeBehavior.ofJsCall(node, compiler, resolver), | 223 NativeBehavior.ofJsCall(node, compiler, enqueuer, resolver), |
| 224 node); | 224 node); |
| 225 flushQueue(); | 225 flushQueue(); |
| 226 } | 226 } |
| 227 | 227 |
| 228 processNativeBehavior(NativeBehavior behavior, cause) { | 228 processNativeBehavior(NativeBehavior behavior, cause) { |
| 229 bool allUsedBefore = unusedClasses.isEmpty; | 229 bool allUsedBefore = unusedClasses.isEmpty; |
| 230 for (var type in behavior.typesInstantiated) { | 230 for (var type in behavior.typesInstantiated) { |
| 231 if (matchedTypeConstraints.contains(type)) continue; | 231 if (matchedTypeConstraints.contains(type)) continue; |
| 232 matchedTypeConstraints.add(type); | 232 matchedTypeConstraints.add(type); |
| 233 if (type is SpecialType) { | 233 if (type is SpecialType) { |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 /// [DartType]s or [SpecialType]s returned or yielded by the native element. | 394 /// [DartType]s or [SpecialType]s returned or yielded by the native element. |
| 395 final List typesReturned = []; | 395 final List typesReturned = []; |
| 396 | 396 |
| 397 /// [DartType]s or [SpecialType]s instantiated by the native element. | 397 /// [DartType]s or [SpecialType]s instantiated by the native element. |
| 398 final List typesInstantiated = []; | 398 final List typesInstantiated = []; |
| 399 | 399 |
| 400 static final NativeBehavior NONE = new NativeBehavior(); | 400 static final NativeBehavior NONE = new NativeBehavior(); |
| 401 | 401 |
| 402 //NativeBehavior(); | 402 //NativeBehavior(); |
| 403 | 403 |
| 404 static NativeBehavior ofJsCall(Send jsCall, Compiler compiler, resolver) { | 404 static NativeBehavior ofJsCall( |
| 405 Send jsCall, Compiler compiler, Enqueuer enqueuer, resolver) { | |
| 405 // The first argument of a JS-call is a string encoding various attributes | 406 // The first argument of a JS-call is a string encoding various attributes |
| 406 // of the code. | 407 // of the code. |
| 407 // | 408 // |
| 408 // 'Type1|Type2'. A union type. | 409 // 'Type1|Type2'. A union type. |
| 409 // '=Object'. A JavaScript Object, no subtype. | 410 // '=Object'. A JavaScript Object, no subtype. |
| 410 // '=List'. A JavaScript Array, no subtype. | 411 // '=List'. A JavaScript Array, no subtype. |
|
ahe
2012/11/29 14:48:43
This has *nothing* to do with legacy support for n
ngeoffray
2012/11/30 11:30:00
Yes, as discussed, native_handler got mixed into l
| |
| 411 | 412 |
| 412 var argNodes = jsCall.arguments; | 413 var argNodes = jsCall.arguments; |
| 413 if (argNodes.isEmpty) { | 414 if (argNodes.isEmpty) { |
| 414 compiler.cancel("JS expression has no type", node: jsCall); | 415 compiler.cancel("JS expression has no type", node: jsCall); |
| 415 } | 416 } |
| 416 | 417 |
| 417 var firstArg = argNodes.head; | 418 var firstArg = argNodes.head; |
| 418 LiteralString specLiteral = firstArg.asLiteralString(); | 419 LiteralString specLiteral = firstArg.asLiteralString(); |
| 419 if (specLiteral != null) { | 420 if (specLiteral != null) { |
| 420 String specString = specLiteral.dartString.slowToString(); | 421 String specString = specLiteral.dartString.slowToString(); |
| 421 // Various things that are not in fact types. | 422 // Various things that are not in fact types. |
| 422 if (specString == 'void') return NativeBehavior.NONE; | 423 if (specString == 'void') return NativeBehavior.NONE; |
| 423 if (specString == '' || specString == 'var') { | 424 if (specString == '' || specString == 'var') { |
| 424 var behavior = new NativeBehavior(); | 425 var behavior = new NativeBehavior(); |
| 425 behavior.typesReturned.add(compiler.objectClass.computeType(compiler)); | 426 behavior.typesReturned.add(compiler.objectClass.computeType(compiler)); |
| 426 return behavior; | 427 return behavior; |
| 427 } | 428 } |
| 428 var behavior = new NativeBehavior(); | 429 var behavior = new NativeBehavior(); |
| 429 for (final typeString in specString.split('|')) { | 430 for (final typeString in specString.split('|')) { |
| 430 var type = _parseType(typeString, compiler, | 431 var type = _parseType(typeString, compiler, |
| 431 (name) => resolver.resolveTypeFromString(name), | 432 (name) => resolver.resolveTypeFromString(name), |
| 432 jsCall); | 433 jsCall); |
| 434 if (type == SpecialType.JsArray) { | |
| 435 enqueuer.registerInstantiatedClass(compiler.listClass); | |
|
sra1
2012/11/29 16:45:50
NativeBehavior is data. There should be no side e
ngeoffray
2012/11/30 11:30:00
Done.
| |
| 436 } else if (type == SpecialType.JsObject) { | |
| 437 enqueuer.registerInstantiatedClass(compiler.objectClass); | |
| 438 } else if (type is InterfaceType) { | |
| 439 enqueuer.registerInstantiatedClass(type.element); | |
|
sra1
2012/11/29 16:45:50
I assume this is how 'int' gets instantiated.
Is
ngeoffray
2012/11/30 11:30:00
Yeah, just unconditionally registering will lead t
| |
| 440 } | |
| 433 behavior.typesInstantiated.add(type); | 441 behavior.typesInstantiated.add(type); |
| 434 behavior.typesReturned.add(type); | 442 behavior.typesReturned.add(type); |
| 435 } | 443 } |
| 436 return behavior; | 444 return behavior; |
| 437 } | 445 } |
| 438 | 446 |
| 439 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It | 447 // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2'). It |
| 440 // is not very satisfactory because it does not work for void, dynamic. | 448 // is not very satisfactory because it does not work for void, dynamic. |
| 441 | 449 |
| 442 compiler.cancel("Unexpected JS first argument", node: firstArg); | 450 compiler.cancel("Unexpected JS first argument", node: firstArg); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 845 String parameters) { | 853 String parameters) { |
| 846 buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty"); | 854 buffer.add(" if (Object.getPrototypeOf(this).hasOwnProperty"); |
| 847 buffer.add("('$methodName')) {\n"); | 855 buffer.add("('$methodName')) {\n"); |
| 848 buffer.add(" $code"); | 856 buffer.add(" $code"); |
| 849 buffer.add(" } else {\n"); | 857 buffer.add(" } else {\n"); |
| 850 buffer.add(" return Object.prototype.$methodName.call(this"); | 858 buffer.add(" return Object.prototype.$methodName.call(this"); |
| 851 buffer.add(parameters == '' ? '' : ', $parameters'); | 859 buffer.add(parameters == '' ? '' : ', $parameters'); |
| 852 buffer.add(");\n"); | 860 buffer.add(");\n"); |
| 853 buffer.add(" }\n"); | 861 buffer.add(" }\n"); |
| 854 } | 862 } |
| OLD | NEW |