| 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:collection' show Queue; | 7 import 'dart:collection' show Queue; |
| 8 import 'dart:uri'; | 8 import 'dart:uri'; |
| 9 import 'dart2jslib.dart' hide SourceString; | 9 import 'dart2jslib.dart' hide SourceString; |
| 10 import 'dart_types.dart'; | 10 import 'dart_types.dart'; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 * Records matched constraints ([SpecialType] or [DartType]). Once a type | 84 * Records matched constraints ([SpecialType] or [DartType]). Once a type |
| 85 * constraint has been matched, there is no need to match it again. | 85 * constraint has been matched, there is no need to match it again. |
| 86 */ | 86 */ |
| 87 final Set matchedTypeConstraints = new Set(); | 87 final Set matchedTypeConstraints = new Set(); |
| 88 | 88 |
| 89 /// Pending actions. Classes in [pendingClasses] have action thunks in | 89 /// Pending actions. Classes in [pendingClasses] have action thunks in |
| 90 /// [queue] to register the class. | 90 /// [queue] to register the class. |
| 91 final queue = new Queue(); | 91 final queue = new Queue(); |
| 92 bool flushing = false; | 92 bool flushing = false; |
| 93 | 93 |
| 94 /// Maps JS foreign calls to their computed native behavior. |
| 95 final Map<Node, NativeBehavior> nativeBehaviors = |
| 96 new Map<Node, NativeBehavior>(); |
| 94 | 97 |
| 95 final Enqueuer world; | 98 final Enqueuer world; |
| 96 final Compiler compiler; | 99 final Compiler compiler; |
| 97 final bool enableLiveTypeAnalysis; | 100 final bool enableLiveTypeAnalysis; |
| 98 | 101 |
| 99 ClassElement _annotationCreatesClass; | 102 ClassElement _annotationCreatesClass; |
| 100 ClassElement _annotationReturnsClass; | 103 ClassElement _annotationReturnsClass; |
| 101 ClassElement _annotationJsNameClass; | 104 ClassElement _annotationJsNameClass; |
| 102 | 105 |
| 103 /// Subclasses of [NativeEnqueuerBase] are constructed by the backend. | 106 /// Subclasses of [NativeEnqueuerBase] are constructed by the backend. |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 } | 298 } |
| 296 | 299 |
| 297 void registerFieldStore(Element field) { | 300 void registerFieldStore(Element field) { |
| 298 processNativeBehavior( | 301 processNativeBehavior( |
| 299 NativeBehavior.ofFieldStore(field, compiler), | 302 NativeBehavior.ofFieldStore(field, compiler), |
| 300 field); | 303 field); |
| 301 flushQueue(); | 304 flushQueue(); |
| 302 } | 305 } |
| 303 | 306 |
| 304 void registerJsCall(Send node, ResolverVisitor resolver) { | 307 void registerJsCall(Send node, ResolverVisitor resolver) { |
| 305 processNativeBehavior( | 308 NativeBehavior behavior = NativeBehavior.ofJsCall(node, compiler, resolver); |
| 306 NativeBehavior.ofJsCall(node, compiler, resolver), | 309 processNativeBehavior(behavior, node); |
| 307 node); | 310 nativeBehaviors[node] = behavior; |
| 308 flushQueue(); | 311 flushQueue(); |
| 309 } | 312 } |
| 310 | 313 |
| 314 NativeBehavior getNativeBehaviorOf(Send node) => nativeBehaviors[node]; |
| 315 |
| 311 processNativeBehavior(NativeBehavior behavior, cause) { | 316 processNativeBehavior(NativeBehavior behavior, cause) { |
| 312 bool allUsedBefore = unusedClasses.isEmpty; | 317 bool allUsedBefore = unusedClasses.isEmpty; |
| 313 for (var type in behavior.typesInstantiated) { | 318 for (var type in behavior.typesInstantiated) { |
| 314 if (matchedTypeConstraints.contains(type)) continue; | 319 if (matchedTypeConstraints.contains(type)) continue; |
| 315 matchedTypeConstraints.add(type); | 320 matchedTypeConstraints.add(type); |
| 316 if (type is SpecialType) { | 321 if (type is SpecialType) { |
| 317 if (type == SpecialType.JsArray) { | 322 if (type == SpecialType.JsArray) { |
| 318 world.registerInstantiatedClass(compiler.listClass); | 323 world.registerInstantiatedClass(compiler.listClass); |
| 319 } else if (type == SpecialType.JsObject) { | 324 } else if (type == SpecialType.JsObject) { |
| 320 world.registerInstantiatedClass(compiler.objectClass); | 325 world.registerInstantiatedClass(compiler.objectClass); |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 } else if (element.kind == ElementKind.GETTER) { | 879 } else if (element.kind == ElementKind.GETTER) { |
| 875 nativeMethodCall = '$receiver$nativeMethodName'; | 880 nativeMethodCall = '$receiver$nativeMethodName'; |
| 876 } else if (element.kind == ElementKind.SETTER) { | 881 } else if (element.kind == ElementKind.SETTER) { |
| 877 nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters'; | 882 nativeMethodCall = '$receiver$nativeMethodName = $foreignParameters'; |
| 878 } else { | 883 } else { |
| 879 builder.compiler.internalError('unexpected kind: "${element.kind}"', | 884 builder.compiler.internalError('unexpected kind: "${element.kind}"', |
| 880 element: element); | 885 element: element); |
| 881 } | 886 } |
| 882 | 887 |
| 883 DartString jsCode = new DartString.literal(nativeMethodCall); | 888 DartString jsCode = new DartString.literal(nativeMethodCall); |
| 884 builder.push( | 889 builder.push(new HForeign(jsCode, HType.UNKNOWN, inputs)); |
| 885 new HForeign(jsCode, const LiteralDartString('Object'), inputs)); | |
| 886 builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit); | 890 builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit); |
| 887 } else { | 891 } else { |
| 888 if (parameters.parameterCount != 0) { | 892 if (parameters.parameterCount != 0) { |
| 889 compiler.cancel( | 893 compiler.cancel( |
| 890 'native "..." syntax is restricted to functions with zero parameters', | 894 'native "..." syntax is restricted to functions with zero parameters', |
| 891 node: nativeBody); | 895 node: nativeBody); |
| 892 } | 896 } |
| 893 LiteralString jsCode = nativeBody.asLiteralString(); | 897 LiteralString jsCode = nativeBody.asLiteralString(); |
| 894 builder.push(new HForeign.statement(jsCode.dartString, <HInstruction>[])); | 898 builder.push(new HForeign.statement(jsCode.dartString, <HInstruction>[])); |
| 895 } | 899 } |
| 896 } | 900 } |
| OLD | NEW |