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

Side by Side Diff: frog/lib/isolate_serialization.dart

Issue 8467034: Isolates in frog - tweaks in existing js code to make things run (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: '' Created 9 years, 1 month 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
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 /**
6 * Abstract visitor for dart objects that can be passed as messages between any
7 * isolates.
Jennifer Messerly 2011/11/08 05:04:35 I'd add a TODO: we should get rid of a lot of this
jimhug 2011/11/08 15:39:01 +1 - But I'm also a little concerned about how we
8 */
5 class MessageTraverser { 9 class MessageTraverser {
6 static bool isPrimitive(x) { 10 static bool isPrimitive(x) {
7 return (x === null) || (x is String) || (x is num) || (x is bool); 11 return (x === null) || (x is String) || (x is num) || (x is bool);
8 } 12 }
9 13
10 MessageTraverser(); 14 MessageTraverser();
11 15
16 /** Visitor's entry point. */
12 traverse(var x) { 17 traverse(var x) {
13 if (isPrimitive(x)) return visitPrimitive(x); 18 if (isPrimitive(x)) return visitPrimitive(x);
14 _taggedObjects = new List(); 19 _taggedObjects = new List();
15 var result; 20 var result;
16 try { 21 try {
17 result = _dispatch(x); 22 result = _dispatch(x);
18 } finally { 23 } finally {
19 _cleanup(); 24 _cleanup();
20 } 25 }
21 return result; 26 return result;
22 } 27 }
23 28
29 /** Remove all information injected in the native objects by this visitor. */
24 void _cleanup() { 30 void _cleanup() {
25 int len = _taggedObjects.length; 31 int len = _taggedObjects.length;
26 for (int i = 0; i < len; i++) { 32 for (int i = 0; i < len; i++) {
27 _clearAttachedInfo(_taggedObjects[i]); 33 _clearAttachedInfo(_taggedObjects[i]);
28 } 34 }
29 _taggedObjects = null; 35 _taggedObjects = null;
30 } 36 }
31 37
38 /** Injects into the native object some information used by the visitor. */
32 void _attachInfo(var o, var info) { 39 void _attachInfo(var o, var info) {
33 _taggedObjects.add(o); 40 _taggedObjects.add(o);
34 _setAttachedInfo(o, info); 41 _setAttachedInfo(o, info);
35 } 42 }
36 43
44 /** Retrieves any information stored in the native object [o]. */
37 _getInfo(var o) { 45 _getInfo(var o) {
38 return _getAttachedInfo(o); 46 return _getAttachedInfo(o);
39 } 47 }
40 48
41 _dispatch(var x) { 49 _dispatch(var x) {
42 if (isPrimitive(x)) return visitPrimitive(x); 50 if (isPrimitive(x)) return visitPrimitive(x);
43 if (x is List) return visitList(x); 51 if (x is List) return visitList(x);
44 if (x is Map) return visitMap(x); 52 if (x is Map) return visitMap(x);
45 if (x is SendPortImpl) return visitSendPort(x); 53 if (x is SendPortImpl) return visitSendPort(x);
46 if (x is ReceivePortImpl) return visitReceivePort(x); 54 if (x is ReceivePortImpl) return visitReceivePort(x);
47 if (x is ReceivePortSingleShotImpl) return visitReceivePortSingleShot(x); 55 if (x is ReceivePortSingleShotImpl) return visitReceivePortSingleShot(x);
48 // TODO(floitsch): make this a real exception. (which one)? 56 // TODO(floitsch): make this a real exception. (which one)?
49 throw "Message serialization: Illegal value $x passed"; 57 throw "Message serialization: Illegal value $x passed";
50 } 58 }
51 59
52 abstract visitPrimitive(x); 60 abstract visitPrimitive(x);
53 abstract visitList(List x); 61 abstract visitList(List x);
54 abstract visitMap(Map x); 62 abstract visitMap(Map x);
55 abstract visitSendPort(SendPortImpl x); 63 abstract visitSendPort(SendPortImpl x);
56 abstract visitReceivePort(ReceivePortImpl x); 64 abstract visitReceivePort(ReceivePortImpl x);
57 abstract visitReceivePortSingleShot(ReceivePortSingleShotImpl x); 65 abstract visitReceivePortSingleShot(ReceivePortSingleShotImpl x);
58 66
59 List _taggedObjects; 67 List _taggedObjects;
60 68
61 _clearAttachedInfo(var obj) native; 69 _clearAttachedInfo(var o) native
62 _setAttachedInfo(var o, var info) native; 70 "o['__MessageTraverser__attached_info__'] = (void 0);";
jimhug 2011/11/08 15:39:01 I'm going to have to get you to explain (void 0) t
Siggi Cherem (dart-lang) 2011/11/08 17:56:42 void is an operator that produces the side effects
63 _getAttachedInfo(var o) native; 71
72 _setAttachedInfo(var o, var info) native
73 "o['__MessageTraverser__attached_info__'] = info;";
74
75 _getAttachedInfo(var o) native
76 "return o['__MessageTraverser__attached_info__'];";
64 } 77 }
65 78
79 /** A visitor that recursively copies a message. */
66 class Copier extends MessageTraverser { 80 class Copier extends MessageTraverser {
67 Copier() : super(); 81 Copier() : super();
68 82
69 visitPrimitive(x) => x; 83 visitPrimitive(x) => x;
70 84
71 List visitList(List list) { 85 List visitList(List list) {
72 List copy = _getInfo(list); 86 List copy = _getInfo(list);
73 if (copy !== null) return copy; 87 if (copy !== null) return copy;
74 88
75 int len = list.length; 89 int len = list.length;
90
76 // TODO(floitsch): we loose the generic type of the List. 91 // TODO(floitsch): we loose the generic type of the List.
77 copy = new List(len); 92 copy = new List(len);
78 _attachInfo(list, copy); 93 _attachInfo(list, copy);
79 for (int i = 0; i < len; i++) { 94 for (int i = 0; i < len; i++) {
80 copy[i] = _dispatch(list[i]); 95 copy[i] = _dispatch(list[i]);
81 } 96 }
82 return copy; 97 return copy;
83 } 98 }
84 99
85 Map visitMap(Map map) { 100 Map visitMap(Map map) {
(...skipping 17 matching lines...) Expand all
103 118
104 SendPort visitReceivePort(ReceivePortImpl port) { 119 SendPort visitReceivePort(ReceivePortImpl port) {
105 return port._toNewSendPort(); 120 return port._toNewSendPort();
106 } 121 }
107 122
108 SendPort visitReceivePortSingleShot(ReceivePortSingleShotImpl port) { 123 SendPort visitReceivePortSingleShot(ReceivePortSingleShotImpl port) {
109 return port._toNewSendPort(); 124 return port._toNewSendPort();
110 } 125 }
111 } 126 }
112 127
128 /** Visitor that serializes a message as a JSON array. */
113 class Serializer extends MessageTraverser { 129 class Serializer extends MessageTraverser {
114 Serializer() : super(); 130 Serializer() : super();
115 131
116 visitPrimitive(x) => x; 132 visitPrimitive(x) => x;
117 133
118 visitList(List list) { 134 visitList(List list) {
119 int copyId = _getInfo(list); 135 int copyId = _getInfo(list);
120 if (copyId !== null) return _makeRef(copyId); 136 if (copyId !== null) return ['ref', copyId];
121 137
122 int id = _nextFreeRefId++; 138 int id = _nextFreeRefId++;
123 _attachInfo(list, id); 139 _attachInfo(list, id);
124 var jsArray = _serializeDartListIntoNewJsArray(list); 140 var jsArray = _serializeList(list);
125 // TODO(floitsch): we are losing the generic type. 141 // TODO(floitsch): we are losing the generic type.
126 return _dartListToJsArrayNoCopy(['list', id, jsArray]); 142 return ['list', id, jsArray];
127 } 143 }
128 144
129 visitMap(Map map) { 145 visitMap(Map map) {
130 int copyId = _getInfo(map); 146 int copyId = _getInfo(map);
131 if (copyId !== null) return _makeRef(copyId); 147 if (copyId !== null) return ['ref', copyId];
132 148
133 int id = _nextFreeRefId++; 149 int id = _nextFreeRefId++;
134 _attachInfo(map, id); 150 _attachInfo(map, id);
135 var keys = _serializeDartListIntoNewJsArray(map.getKeys()); 151 var keys = _serializeList(map.getKeys());
136 var values = _serializeDartListIntoNewJsArray(map.getValues()); 152 var values = _serializeList(map.getValues());
137 // TODO(floitsch): we are losing the generic type. 153 // TODO(floitsch): we are losing the generic type.
138 return _dartListToJsArrayNoCopy(['map', id, keys, values]); 154 return ['map', id, keys, values];
139 } 155 }
140 156
141 visitSendPort(SendPortImpl port) { 157 visitSendPort(SendPortImpl port) {
142 return _dartListToJsArrayNoCopy(['sendport', 158 return ['sendport', port._workerId, port._isolateId, port._receivePortId];
143 port._workerId,
144 port._isolateId,
145 port._receivePortId]);
146 } 159 }
147 160
148 visitReceivePort(ReceivePortImpl port) { 161 visitReceivePort(ReceivePortImpl port) {
149 return visitSendPort(port.toSendPort());; 162 return visitSendPort(port.toSendPort());;
150 } 163 }
151 164
152 visitReceivePortSingleShot(ReceivePortSingleShotImpl port) { 165 visitReceivePortSingleShot(ReceivePortSingleShotImpl port) {
153 return visitSendPort(port.toSendPort()); 166 return visitSendPort(port.toSendPort());
154 } 167 }
155 168
156 _serializeDartListIntoNewJsArray(List list) { 169 _serializeList(List list) {
157 int len = list.length; 170 int len = list.length;
158 var jsArray = _newJsArray(len); 171 var result = new List(len);
159 for (int i = 0; i < len; i++) { 172 for (int i = 0; i < len; i++) {
160 _jsArrayIndexSet(jsArray, i, _dispatch(list[i])); 173 result[i] = _dispatch(list[i]);
161 } 174 }
162 return jsArray; 175 return result;
163 }
164
165 _makeRef(int id) {
166 return _dartListToJsArrayNoCopy(['ref', id]);
167 } 176 }
168 177
169 int _nextFreeRefId = 0; 178 int _nextFreeRefId = 0;
170
171 static _newJsArray(int len) native;
172 static _jsArrayIndexSet(jsArray, int index, val) native;
173 static _dartListToJsArrayNoCopy(List list) native;
174 } 179 }
175 180
181 /** Deserializes arrays created with [Serializer]. */
176 class Deserializer { 182 class Deserializer {
177 Deserializer(); 183 Deserializer();
178 184
179 static bool isPrimitive(x) { 185 static bool isPrimitive(x) {
180 return (x === null) || (x is String) || (x is num) || (x is bool); 186 return (x === null) || (x is String) || (x is num) || (x is bool);
181 } 187 }
182 188
183 deserialize(x) { 189 deserialize(x) {
184 if (isPrimitive(x)) return x; 190 if (isPrimitive(x)) return x;
185 // TODO(floitsch): this should be new HashMap<int, var|Dynamic>() 191 // TODO(floitsch): this should be new HashMap<int, var|Dynamic>()
186 _deserialized = new HashMap(); 192 _deserialized = new HashMap();
187 return _deserializeHelper(x); 193 return _deserializeHelper(x);
188 } 194 }
189 195
190 _deserializeHelper(x) { 196 _deserializeHelper(x) {
191 if (isPrimitive(x)) return x; 197 if (isPrimitive(x)) return x;
192 assert(_isJsArray(x)); 198 assert(x is List);
193 switch (_jsArrayIndex(x, 0)) { 199 switch (x[0]) {
194 case 'ref': return _deserializeRef(x); 200 case 'ref': return _deserializeRef(x);
195 case 'list': return _deserializeList(x); 201 case 'list': return _deserializeList(x);
196 case 'map': return _deserializeMap(x); 202 case 'map': return _deserializeMap(x);
197 case 'sendport': return _deserializeSendPort(x); 203 case 'sendport': return _deserializeSendPort(x);
198 // TODO(floitsch): Use real exception (which one?). 204 // TODO(floitsch): Use real exception (which one?).
199 default: throw "Unexpected serialized object"; 205 default: throw "Unexpected serialized object";
200 } 206 }
201 } 207 }
202 208
203 _deserializeRef(x) { 209 _deserializeRef(List x) {
204 int id = _jsArrayIndex(x, 1); 210 int id = x[1];
205 var result = _deserialized[id]; 211 var result = _deserialized[id];
206 assert(result !== null); 212 assert(result !== null);
207 return result; 213 return result;
208 } 214 }
209 215
210 List _deserializeList(x) { 216 List _deserializeList(List x) {
211 int id = _jsArrayIndex(x, 1); 217 int id = x[1];
212 var jsArray = _jsArrayIndex(x, 2); 218 // We rely on the fact that Dart-lists are directly mapped to Js-arrays.
213 assert(_isJsArray(jsArray)); 219 List dartList = x[2];
214 List dartList = _jsArrayToDartListNoCopy(jsArray);
215 _deserialized[id] = dartList; 220 _deserialized[id] = dartList;
216 int len = dartList.length; 221 int len = dartList.length;
217 for (int i = 0; i < len; i++) { 222 for (int i = 0; i < len; i++) {
218 dartList[i] = _deserializeHelper(dartList[i]); 223 dartList[i] = _deserializeHelper(dartList[i]);
219 } 224 }
220 return dartList; 225 return dartList;
221 } 226 }
222 227
223 Map _deserializeMap(x) { 228 Map _deserializeMap(List x) {
224 Map result = new Map(); 229 Map result = new Map();
225 int id = _jsArrayIndex(x, 1); 230 int id = x[1];
226 _deserialized[id] = result; 231 _deserialized[id] = result;
227 var keys = _jsArrayIndex(x, 2); 232 List keys = x[2];
228 var values = _jsArrayIndex(x, 3); 233 List values = x[3];
229 assert(_isJsArray(keys)); 234 int len = keys.length;
230 assert(_isJsArray(values)); 235 assert(len == values.length);
231 int len = _jsArrayLength(keys);
232 assert(len == _jsArrayLength(values));
233 for (int i = 0; i < len; i++) { 236 for (int i = 0; i < len; i++) {
234 var key = _deserializeHelper(_jsArrayIndex(keys, i)); 237 var key = _deserializeHelper(keys[i]);
235 var value = _deserializeHelper(_jsArrayIndex(values, i)); 238 var value = _deserializeHelper(values[i]);
236 result[key] = value; 239 result[key] = value;
237 } 240 }
238 return result; 241 return result;
239 } 242 }
240 243
241 SendPort _deserializeSendPort(x) { 244 SendPort _deserializeSendPort(List x) {
242 int workerId = _jsArrayIndex(x, 1); 245 int workerId = x[1];
243 int isolateId = _jsArrayIndex(x, 2); 246 int isolateId = x[2];
244 int receivePortId = _jsArrayIndex(x, 3); 247 int receivePortId = x[3];
245 return new SendPortImpl(workerId, isolateId, receivePortId); 248 return new SendPortImpl(workerId, isolateId, receivePortId);
246 } 249 }
247 250
248 List _jsArrayToDartListNoCopy(a) {
249 // We rely on the fact that Dart-lists are directly mapped to Js-arrays.
250 // TODO(floitsch): can we do better here?
251 assert(a is List);
252 return a;
253 }
254
255 // TODO(floitsch): this should by Map<int, var> or Map<int, Dynamic>. 251 // TODO(floitsch): this should by Map<int, var> or Map<int, Dynamic>.
256 Map _deserialized; 252 Map<int, Dynamic> _deserialized;
257
258 static bool _isJsArray(x) native;
259 static _jsArrayIndex(x, int index) native;
260 static int _jsArrayLength(x) native;
261 } 253 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698