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 // VM-specific implementation of the dart:mirrors library. | 5 // VM-specific implementation of the dart:mirrors library. |
6 | 6 |
7 class _IsolateMirrorImpl implements IsolateMirror { | 7 // These values are allowed to be passed directly over the wire. |
8 _IsolateMirrorImpl(this.port, this.debugName) {} | 8 bool isSimpleValue(var value) { |
| 9 return (value === null || value is num || value is String || value is bool); |
| 10 } |
9 | 11 |
10 final SendPort port; | 12 abstract class _LocalMirrorImpl implements Mirror { |
| 13 // Local mirrors always return the same IsolateMirror. This field |
| 14 // is more interesting once we implement remote mirrors. |
| 15 IsolateMirror get isolate() { return Mirrors.localIsolateMirror(); } |
| 16 } |
| 17 |
| 18 class _LocalIsolateMirrorImpl extends _LocalMirrorImpl |
| 19 implements IsolateMirror { |
| 20 _LocalIsolateMirrorImpl(this.debugName, this.rootLibrary, this.libraries) {} |
| 21 |
11 final String debugName; | 22 final String debugName; |
| 23 final LibraryMirror rootLibrary; |
| 24 final Map<String, LibraryMirror> libraries; |
| 25 } |
12 | 26 |
13 static _make(SendPort port, String debugName) { | 27 // A VMReference is used to hold a reference to a VM-internal object, |
14 return new _IsolateMirrorImpl(port, debugName); | 28 // which can include things like libraries, classes, etc. |
| 29 class VMReference extends NativeFieldWrapperClass1 { |
| 30 } |
| 31 |
| 32 abstract class _LocalVMObjectMirrorImpl extends _LocalMirrorImpl { |
| 33 _LocalVMObjectMirrorImpl(this._reference) {} |
| 34 |
| 35 // For now, all VMObjects hold a VMReference. We could consider |
| 36 // storing the Object reference itself here if the object is a Dart |
| 37 // language objects (except for objects of type VMReference, of |
| 38 // course). |
| 39 VMReference _reference; |
| 40 } |
| 41 |
| 42 abstract class _LocalObjectMirrorImpl extends _LocalVMObjectMirrorImpl |
| 43 implements ObjectMirror { |
| 44 _LocalObjectMirrorImpl(ref) : super(ref) {} |
| 45 |
| 46 Future<InstanceMirror> invoke(String memberName, |
| 47 List<Object> positionalArguments, |
| 48 [Map<String,Object> namedArguments]) { |
| 49 if (namedArguments !== null) { |
| 50 throw new NotImplementedException('named arguments not implemented'); |
| 51 } |
| 52 // Walk the arguments and make sure they are legal. |
| 53 for (int i = 0; i < positionalArguments.length; i++) { |
| 54 var arg = positionalArguments[i]; |
| 55 if (arg is Mirror) { |
| 56 throw new MirrorException( |
| 57 'positional argument $i ($arg) was not an InstanceMirror'); |
| 58 } |
| 59 if (!isSimpleValue(arg)) { |
| 60 throw new MirrorException( |
| 61 'positional argument $i ($arg) was not a simple value'); |
| 62 } |
| 63 } |
| 64 Completer<InstanceMirror> completer = new Completer<InstanceMirror>(); |
| 65 completer.complete( |
| 66 _invoke(this, memberName, positionalArguments)); |
| 67 return completer.future; |
15 } | 68 } |
| 69 |
| 70 static _invoke(ref, memberName, positionalArguments) |
| 71 native 'LocalObjectMirrorImpl_invoke'; |
| 72 } |
| 73 |
| 74 class _LocalInstanceMirrorImpl extends _LocalObjectMirrorImpl |
| 75 implements InstanceMirror { |
| 76 _LocalInstanceMirrorImpl(ref, this.simpleValue) : super(ref) {} |
| 77 |
| 78 final simpleValue; |
| 79 } |
| 80 |
| 81 class _LocalLibraryMirrorImpl extends _LocalObjectMirrorImpl |
| 82 implements LibraryMirror { |
| 83 _LocalLibraryMirrorImpl(ref, this.simpleName, this.url) : super(ref) {} |
| 84 |
| 85 final String simpleName; |
| 86 final String url; |
16 } | 87 } |
17 | 88 |
18 class _Mirrors { | 89 class _Mirrors { |
| 90 // Does a port refer to our local isolate? |
| 91 static bool isLocalPort(SendPort port) native 'Mirrors_isLocalPort'; |
| 92 |
| 93 static IsolateMirror _localIsolateMirror; |
| 94 |
| 95 // The IsolateMirror for the current isolate. |
| 96 static IsolateMirror localIsolateMirror() { |
| 97 if (_localIsolateMirror === null) { |
| 98 _localIsolateMirror = makeLocalIsolateMirror(); |
| 99 } |
| 100 return _localIsolateMirror; |
| 101 } |
| 102 |
| 103 // Creates a new local IsolateMirror. |
| 104 static bool makeLocalIsolateMirror() |
| 105 native 'Mirrors_makeLocalIsolateMirror'; |
| 106 |
19 static Future<IsolateMirror> isolateMirrorOf(SendPort port) { | 107 static Future<IsolateMirror> isolateMirrorOf(SendPort port) { |
20 Completer<IsolateMirror> completer = new Completer<IsolateMirror>(); | 108 Completer<IsolateMirror> completer = new Completer<IsolateMirror>(); |
21 String request = '{ "command": "isolateMirrorOf" }'; | 109 if (isLocalPort(port)) { |
22 ReceivePort rp = new ReceivePort(); | 110 // Make a local isolate mirror. |
23 if (!send(port, request, rp.toSendPort())) { | 111 completer.complete(localIsolateMirror()); |
24 throw new Exception("Unable to send mirror request to port $port"); | 112 } else { |
| 113 // Make a remote isolate mirror. |
| 114 throw new NotImplementedException('Remote mirrors not yet implemented'); |
25 } | 115 } |
26 rp.receive((message, _) { | |
27 rp.close(); | |
28 completer.complete(_Mirrors.processResponse( | |
29 port, "isolateMirrorOf", message)); | |
30 }); | |
31 return completer.future; | 116 return completer.future; |
32 } | 117 } |
33 | |
34 static bool send(SendPort port, String request, SendPort replyTo) | |
35 native "Mirrors_send"; | |
36 | |
37 static processResponse(SendPort port, String command, String response) | |
38 native "Mirrors_processResponse"; | |
39 } | 118 } |
OLD | NEW |