Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Side by Side Diff: lib/isolate/frog/messages.dart

Issue 9422019: isolates refactor: this change introduces 'dart:isolate' as a library. This is a (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: '' Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/isolate/frog/isolateimpl.dart ('k') | lib/isolate/frog/natives.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /** 5 // Defines message visitors, serialization, and deserialization.
6 * Abstract visitor for dart objects that can be passed as messages between any 6
7 * isolates. 7 /** Serialize [message] (or simulate serialization). */
8 */ 8 _serializeMessage(message) {
9 class MessageTraverser { 9 if (globalState.needSerialization) {
10 static bool isPrimitive(x) { 10 return new _Serializer().traverse(message);
11 return (x === null) || (x is String) || (x is num) || (x is bool); 11 } else {
12 return new _Copier().traverse(message);
12 } 13 }
14 }
13 15
14 MessageTraverser(); 16 /** Deserialize [message] (or simulate deserialization). */
17 _deserializeMessage(message) {
18 if (globalState.needSerialization) {
19 return new _Deserializer().deserialize(message);
20 } else {
21 // Nothing more to do.
22 return message;
23 }
24 }
25
26 /** Abstract visitor for dart objects that can be sent as isolate messages. */
27 class _MessageTraverser {
28
29 List _taggedObjects;
30
31 _MessageTraverser();
15 32
16 /** Visitor's entry point. */ 33 /** Visitor's entry point. */
17 traverse(var x) { 34 traverse(var x) {
18 if (isPrimitive(x)) return visitPrimitive(x); 35 if (isPrimitive(x)) return visitPrimitive(x);
19 _taggedObjects = new List(); 36 _taggedObjects = new List();
20 var result; 37 var result;
21 try { 38 try {
22 result = _dispatch(x); 39 result = _dispatch(x);
23 } finally { 40 } finally {
24 _cleanup(); 41 _cleanup();
(...skipping 18 matching lines...) Expand all
43 60
44 /** Retrieves any information stored in the native object [o]. */ 61 /** Retrieves any information stored in the native object [o]. */
45 _getInfo(var o) { 62 _getInfo(var o) {
46 return _getAttachedInfo(o); 63 return _getAttachedInfo(o);
47 } 64 }
48 65
49 _dispatch(var x) { 66 _dispatch(var x) {
50 if (isPrimitive(x)) return visitPrimitive(x); 67 if (isPrimitive(x)) return visitPrimitive(x);
51 if (x is List) return visitList(x); 68 if (x is List) return visitList(x);
52 if (x is Map) return visitMap(x); 69 if (x is Map) return visitMap(x);
53 if (x is NativeJsSendPort) return visitNativeJsSendPort(x); 70 if (x is _NativeJsSendPort) return visitNativeJsSendPort(x);
54 if (x is WorkerSendPort) return visitWorkerSendPort(x); 71 if (x is _WorkerSendPort) return visitWorkerSendPort(x);
55 if (x is BufferingSendPort) return visitBufferingSendPort(x); 72 if (x is _BufferingSendPort) return visitBufferingSendPort(x);
56 if (x is ReceivePortImpl) return visitReceivePort(x); 73 if (x is _ReceivePortImpl) return visitReceivePort(x);
57 if (x is ReceivePortSingleShotImpl) return visitReceivePortSingleShot(x); 74 if (x is _ReceivePortSingleShotImpl) return visitReceivePortSingleShot(x);
58 // TODO(floitsch): make this a real exception. (which one)? 75 // TODO(floitsch): make this a real exception. (which one)?
59 throw "Message serialization: Illegal value $x passed"; 76 throw "Message serialization: Illegal value $x passed";
60 } 77 }
61 78
62 abstract visitPrimitive(x); 79 abstract visitPrimitive(x);
63 abstract visitList(List x); 80 abstract visitList(List x);
64 abstract visitMap(Map x); 81 abstract visitMap(Map x);
65 abstract visitNativeJsSendPort(NativeJsSendPort x); 82 abstract visitNativeJsSendPort(_NativeJsSendPort x);
66 abstract visitWorkerSendPort(WorkerSendPort x); 83 abstract visitWorkerSendPort(_WorkerSendPort x);
67 abstract visitBufferingSendPort(BufferingSendPort x); 84 abstract visitBufferingSendPort(_BufferingSendPort x);
68 abstract visitReceivePort(ReceivePortImpl x); 85 abstract visitReceivePort(_ReceivePortImpl x);
69 abstract visitReceivePortSingleShot(ReceivePortSingleShotImpl x); 86 abstract visitReceivePortSingleShot(_ReceivePortSingleShotImpl x);
70
71 List _taggedObjects;
72 87
73 _clearAttachedInfo(var o) native 88 _clearAttachedInfo(var o) native
74 "o['__MessageTraverser__attached_info__'] = (void 0);"; 89 "o['__MessageTraverser__attached_info__'] = (void 0);";
75 90
76 _setAttachedInfo(var o, var info) native 91 _setAttachedInfo(var o, var info) native
77 "o['__MessageTraverser__attached_info__'] = info;"; 92 "o['__MessageTraverser__attached_info__'] = info;";
78 93
79 _getAttachedInfo(var o) native 94 _getAttachedInfo(var o) native
80 "return o['__MessageTraverser__attached_info__'];"; 95 "return o['__MessageTraverser__attached_info__'];";
81 96
82 _visitNativeOrWorkerPort(SendPort p) { 97 _visitNativeOrWorkerPort(SendPort p) {
83 if (p is NativeJsSendPort) return visitNativeJsSendPort(p); 98 if (p is _NativeJsSendPort) return visitNativeJsSendPort(p);
84 if (p is WorkerSendPort) return visitWorkerSendPort(p); 99 if (p is _WorkerSendPort) return visitWorkerSendPort(p);
85 throw "Illegal underlying port $p"; 100 throw "Illegal underlying port $p";
86 } 101 }
102
103 static bool isPrimitive(x) {
104 return (x === null) || (x is String) || (x is num) || (x is bool);
105 }
87 } 106 }
88 107
108
89 /** A visitor that recursively copies a message. */ 109 /** A visitor that recursively copies a message. */
90 class Copier extends MessageTraverser { 110 class _Copier extends _MessageTraverser {
91 Copier() : super(); 111 _Copier() : super();
92 112
93 visitPrimitive(x) => x; 113 visitPrimitive(x) => x;
94 114
95 List visitList(List list) { 115 List visitList(List list) {
96 List copy = _getInfo(list); 116 List copy = _getInfo(list);
97 if (copy !== null) return copy; 117 if (copy !== null) return copy;
98 118
99 int len = list.length; 119 int len = list.length;
100 120
101 // TODO(floitsch): we loose the generic type of the List. 121 // TODO(floitsch): we loose the generic type of the List.
(...skipping 11 matching lines...) Expand all
113 133
114 // TODO(floitsch): we loose the generic type of the map. 134 // TODO(floitsch): we loose the generic type of the map.
115 copy = new Map(); 135 copy = new Map();
116 _attachInfo(map, copy); 136 _attachInfo(map, copy);
117 map.forEach((key, val) { 137 map.forEach((key, val) {
118 copy[_dispatch(key)] = _dispatch(val); 138 copy[_dispatch(key)] = _dispatch(val);
119 }); 139 });
120 return copy; 140 return copy;
121 } 141 }
122 142
123 SendPort visitNativeJsSendPort(NativeJsSendPort port) { 143 SendPort visitNativeJsSendPort(_NativeJsSendPort port) {
124 return new NativeJsSendPort(port._receivePort, port._isolateId); 144 return new _NativeJsSendPort(port._receivePort, port._isolateId);
125 } 145 }
126 146
127 SendPort visitWorkerSendPort(WorkerSendPort port) { 147 SendPort visitWorkerSendPort(_WorkerSendPort port) {
128 return new WorkerSendPort( 148 return new _WorkerSendPort(
129 port._workerId, port._isolateId, port._receivePortId); 149 port._workerId, port._isolateId, port._receivePortId);
130 } 150 }
131 151
132 SendPort visitBufferingSendPort(BufferingSendPort port) { 152 SendPort visitBufferingSendPort(_BufferingSendPort port) {
133 if (port._port != null) { 153 if (port._port != null) {
134 return _visitNativeOrWorkerPort(port._port); 154 return _visitNativeOrWorkerPort(port._port);
135 } else { 155 } else {
136 // TODO(floitsch): Use real exception (which one?). 156 // TODO(floitsch): Use real exception (which one?).
137 throw "internal error: must call _waitForPendingPorts to ensure all" 157 throw "internal error: must call _waitForPendingPorts to ensure all"
138 + " ports are resolved at this point."; 158 + " ports are resolved at this point.";
139 } 159 }
140 } 160 }
141 161
142 SendPort visitReceivePort(ReceivePortImpl port) { 162 SendPort visitReceivePort(_ReceivePortImpl port) {
143 return port.toSendPort(); 163 return port.toSendPort();
144 } 164 }
145 165
146 SendPort visitReceivePortSingleShot(ReceivePortSingleShotImpl port) { 166 SendPort visitReceivePortSingleShot(_ReceivePortSingleShotImpl port) {
147 return port.toSendPort(); 167 return port.toSendPort();
148 } 168 }
149 } 169 }
150 170
151 /** Visitor that serializes a message as a JSON array. */ 171 /** Visitor that serializes a message as a JSON array. */
152 class Serializer extends MessageTraverser { 172 class _Serializer extends _MessageTraverser {
153 Serializer() : super(); 173 int _nextFreeRefId = 0;
174
175 _Serializer() : super();
154 176
155 visitPrimitive(x) => x; 177 visitPrimitive(x) => x;
156 178
157 visitList(List list) { 179 visitList(List list) {
158 int copyId = _getInfo(list); 180 int copyId = _getInfo(list);
159 if (copyId !== null) return ['ref', copyId]; 181 if (copyId !== null) return ['ref', copyId];
160 182
161 int id = _nextFreeRefId++; 183 int id = _nextFreeRefId++;
162 _attachInfo(list, id); 184 _attachInfo(list, id);
163 var jsArray = _serializeList(list); 185 var jsArray = _serializeList(list);
164 // TODO(floitsch): we are losing the generic type. 186 // TODO(floitsch): we are losing the generic type.
165 return ['list', id, jsArray]; 187 return ['list', id, jsArray];
166 } 188 }
167 189
168 visitMap(Map map) { 190 visitMap(Map map) {
169 int copyId = _getInfo(map); 191 int copyId = _getInfo(map);
170 if (copyId !== null) return ['ref', copyId]; 192 if (copyId !== null) return ['ref', copyId];
171 193
172 int id = _nextFreeRefId++; 194 int id = _nextFreeRefId++;
173 _attachInfo(map, id); 195 _attachInfo(map, id);
174 var keys = _serializeList(map.getKeys()); 196 var keys = _serializeList(map.getKeys());
175 var values = _serializeList(map.getValues()); 197 var values = _serializeList(map.getValues());
176 // TODO(floitsch): we are losing the generic type. 198 // TODO(floitsch): we are losing the generic type.
177 return ['map', id, keys, values]; 199 return ['map', id, keys, values];
178 } 200 }
179 201
180 visitNativeJsSendPort(NativeJsSendPort port) { 202 visitNativeJsSendPort(_NativeJsSendPort port) {
181 return ['sendport', _globalState.currentWorkerId, 203 return ['sendport', globalState.currentWorkerId,
182 port._isolateId, port._receivePort._id]; 204 port._isolateId, port._receivePort._id];
183 } 205 }
184 206
185 visitWorkerSendPort(WorkerSendPort port) { 207 visitWorkerSendPort(_WorkerSendPort port) {
186 return ['sendport', port._workerId, port._isolateId, port._receivePortId]; 208 return ['sendport', port._workerId, port._isolateId, port._receivePortId];
187 } 209 }
188 210
189 visitBufferingSendPort(BufferingSendPort port) { 211 visitBufferingSendPort(_BufferingSendPort port) {
190 if (port._port != null) { 212 if (port._port != null) {
191 return _visitNativeOrWorkerPort(port._port); 213 return _visitNativeOrWorkerPort(port._port);
192 } else { 214 } else {
193 // TODO(floitsch): Use real exception (which one?). 215 // TODO(floitsch): Use real exception (which one?).
194 throw "internal error: must call _waitForPendingPorts to ensure all" 216 throw "internal error: must call _waitForPendingPorts to ensure all"
195 + " ports are resolved at this point."; 217 + " ports are resolved at this point.";
196 } 218 }
197 } 219 }
198 220
199 visitReceivePort(ReceivePortImpl port) { 221 visitReceivePort(_ReceivePortImpl port) {
200 return visitNativeJsSendPort(port.toSendPort());; 222 return visitNativeJsSendPort(port.toSendPort());;
201 } 223 }
202 224
203 visitReceivePortSingleShot(ReceivePortSingleShotImpl port) { 225 visitReceivePortSingleShot(_ReceivePortSingleShotImpl port) {
204 return visitNativeJsSendPort(port.toSendPort()); 226 return visitNativeJsSendPort(port.toSendPort());
205 } 227 }
206 228
207 _serializeList(List list) { 229 _serializeList(List list) {
208 int len = list.length; 230 int len = list.length;
209 var result = new List(len); 231 var result = new List(len);
210 for (int i = 0; i < len; i++) { 232 for (int i = 0; i < len; i++) {
211 result[i] = _dispatch(list[i]); 233 result[i] = _dispatch(list[i]);
212 } 234 }
213 return result; 235 return result;
214 } 236 }
215
216 int _nextFreeRefId = 0;
217 } 237 }
218 238
219 /** Visitor that finds all unresolved [SendPort]s in a message. */ 239 /** Deserializes arrays created with [_Serializer]. */
220 class PendingSendPortFinder extends MessageTraverser { 240 class _Deserializer {
221 List<Future<SendPort>> ports; 241 Map<int, Dynamic> _deserialized;
222 PendingSendPortFinder() : super(), ports = [];
223 242
224 visitPrimitive(x) {} 243 _Deserializer();
225 visitNativeJsSendPort(NativeJsSendPort port) {}
226 visitWorkerSendPort(WorkerSendPort port) {}
227 visitReceivePort(ReceivePortImpl port) {}
228 visitReceivePortSingleShot(ReceivePortSingleShotImpl port) {}
229
230 visitList(List list) {
231 final visited = _getInfo(list);
232 if (visited !== null) return;
233 _attachInfo(list, true);
234 // TODO(sigmund): replace with the following: (bug #1660)
235 // list.forEach(_dispatch);
236 list.forEach((e) => _dispatch(e));
237 }
238
239 visitMap(Map map) {
240 final visited = _getInfo(map);
241 if (visited !== null) return;
242
243 _attachInfo(map, true);
244 // TODO(sigmund): replace with the following: (bug #1660)
245 // map.getValues().forEach(_dispatch);
246 map.getValues().forEach((e) => _dispatch(e));
247 }
248
249 visitBufferingSendPort(BufferingSendPort port) {
250 if (port._port == null) {
251 ports.add(port._futurePort);
252 }
253 }
254 }
255
256
257 /** Deserializes arrays created with [Serializer]. */
258 class Deserializer {
259 Deserializer();
260 244
261 static bool isPrimitive(x) { 245 static bool isPrimitive(x) {
262 return (x === null) || (x is String) || (x is num) || (x is bool); 246 return (x === null) || (x is String) || (x is num) || (x is bool);
263 } 247 }
264 248
265 deserialize(x) { 249 deserialize(x) {
266 if (isPrimitive(x)) return x; 250 if (isPrimitive(x)) return x;
267 // TODO(floitsch): this should be new HashMap<int, var|Dynamic>() 251 // TODO(floitsch): this should be new HashMap<int, var|Dynamic>()
268 _deserialized = new HashMap(); 252 _deserialized = new HashMap();
269 return _deserializeHelper(x); 253 return _deserializeHelper(x);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 } 300 }
317 return result; 301 return result;
318 } 302 }
319 303
320 SendPort _deserializeSendPort(List x) { 304 SendPort _deserializeSendPort(List x) {
321 int workerId = x[1]; 305 int workerId = x[1];
322 int isolateId = x[2]; 306 int isolateId = x[2];
323 int receivePortId = x[3]; 307 int receivePortId = x[3];
324 // If two isolates are in the same worker, we use NativeJsSendPorts to 308 // If two isolates are in the same worker, we use NativeJsSendPorts to
325 // deliver messages directly without using postMessage. 309 // deliver messages directly without using postMessage.
326 if (workerId == _globalState.currentWorkerId) { 310 if (workerId == globalState.currentWorkerId) {
327 var isolate = _globalState.isolates[isolateId]; 311 var isolate = globalState.isolates[isolateId];
328 if (isolate == null) return null; // Isolate has been closed. 312 if (isolate == null) return null; // Isolate has been closed.
329 var receivePort = isolate.lookup(receivePortId); 313 var receivePort = isolate.lookup(receivePortId);
330 return new NativeJsSendPort(receivePort, isolateId); 314 return new _NativeJsSendPort(receivePort, isolateId);
331 } else { 315 } else {
332 return new WorkerSendPort(workerId, isolateId, receivePortId); 316 return new _WorkerSendPort(workerId, isolateId, receivePortId);
333 } 317 }
334 } 318 }
319 }
335 320
336 Map<int, Dynamic> _deserialized; 321 // only visible for testing purposes
322 // TODO(sigmund): remove once we can disable privacy for testing (bug #1882)
323 class TestingOnly {
324 static copy(x) {
325 return new _Copier().traverse(x);
326 }
327
328 // only visible for testing purposes
329 static serialize(x) {
330 _Serializer serializer = new _Serializer();
331 _Deserializer deserializer = new _Deserializer();
332 return deserializer.deserialize(serializer.traverse(x));
333 }
337 } 334 }
OLDNEW
« no previous file with comments | « lib/isolate/frog/isolateimpl.dart ('k') | lib/isolate/frog/natives.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698