Chromium Code Reviews| Index: frog/lib/isolate_serialization.dart |
| diff --git a/frog/lib/isolate_serialization.dart b/frog/lib/isolate_serialization.dart |
| index 52e978f5dd8bda75e8c9cea55fd65c95ff34f5ae..d836e2f0a5d66ea88e848be7bf125948c8396382 100644 |
| --- a/frog/lib/isolate_serialization.dart |
| +++ b/frog/lib/isolate_serialization.dart |
| @@ -2,6 +2,10 @@ |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| +/** |
| + * Abstract visitor for dart objects that can be passed as messages between any |
| + * 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
|
| + */ |
| class MessageTraverser { |
| static bool isPrimitive(x) { |
| return (x === null) || (x is String) || (x is num) || (x is bool); |
| @@ -9,6 +13,7 @@ class MessageTraverser { |
| MessageTraverser(); |
| + /** Visitor's entry point. */ |
| traverse(var x) { |
| if (isPrimitive(x)) return visitPrimitive(x); |
| _taggedObjects = new List(); |
| @@ -21,6 +26,7 @@ class MessageTraverser { |
| return result; |
| } |
| + /** Remove all information injected in the native objects by this visitor. */ |
| void _cleanup() { |
| int len = _taggedObjects.length; |
| for (int i = 0; i < len; i++) { |
| @@ -29,11 +35,13 @@ class MessageTraverser { |
| _taggedObjects = null; |
| } |
| + /** Injects into the native object some information used by the visitor. */ |
| void _attachInfo(var o, var info) { |
| _taggedObjects.add(o); |
| _setAttachedInfo(o, info); |
| } |
| + /** Retrieves any information stored in the native object [o]. */ |
| _getInfo(var o) { |
| return _getAttachedInfo(o); |
| } |
| @@ -58,11 +66,17 @@ class MessageTraverser { |
| List _taggedObjects; |
| - _clearAttachedInfo(var obj) native; |
| - _setAttachedInfo(var o, var info) native; |
| - _getAttachedInfo(var o) native; |
| + _clearAttachedInfo(var o) native |
| + "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
|
| + |
| + _setAttachedInfo(var o, var info) native |
| + "o['__MessageTraverser__attached_info__'] = info;"; |
| + |
| + _getAttachedInfo(var o) native |
| + "return o['__MessageTraverser__attached_info__'];"; |
| } |
| +/** A visitor that recursively copies a message. */ |
| class Copier extends MessageTraverser { |
| Copier() : super(); |
| @@ -73,6 +87,7 @@ class Copier extends MessageTraverser { |
| if (copy !== null) return copy; |
| int len = list.length; |
| + |
| // TODO(floitsch): we loose the generic type of the List. |
| copy = new List(len); |
| _attachInfo(list, copy); |
| @@ -110,6 +125,7 @@ class Copier extends MessageTraverser { |
| } |
| } |
| +/** Visitor that serializes a message as a JSON array. */ |
| class Serializer extends MessageTraverser { |
| Serializer() : super(); |
| @@ -117,32 +133,29 @@ class Serializer extends MessageTraverser { |
| visitList(List list) { |
| int copyId = _getInfo(list); |
| - if (copyId !== null) return _makeRef(copyId); |
| + if (copyId !== null) return ['ref', copyId]; |
| int id = _nextFreeRefId++; |
| _attachInfo(list, id); |
| - var jsArray = _serializeDartListIntoNewJsArray(list); |
| + var jsArray = _serializeList(list); |
| // TODO(floitsch): we are losing the generic type. |
| - return _dartListToJsArrayNoCopy(['list', id, jsArray]); |
| + return ['list', id, jsArray]; |
| } |
| visitMap(Map map) { |
| int copyId = _getInfo(map); |
| - if (copyId !== null) return _makeRef(copyId); |
| + if (copyId !== null) return ['ref', copyId]; |
| int id = _nextFreeRefId++; |
| _attachInfo(map, id); |
| - var keys = _serializeDartListIntoNewJsArray(map.getKeys()); |
| - var values = _serializeDartListIntoNewJsArray(map.getValues()); |
| + var keys = _serializeList(map.getKeys()); |
| + var values = _serializeList(map.getValues()); |
| // TODO(floitsch): we are losing the generic type. |
| - return _dartListToJsArrayNoCopy(['map', id, keys, values]); |
| + return ['map', id, keys, values]; |
| } |
| visitSendPort(SendPortImpl port) { |
| - return _dartListToJsArrayNoCopy(['sendport', |
| - port._workerId, |
| - port._isolateId, |
| - port._receivePortId]); |
| + return ['sendport', port._workerId, port._isolateId, port._receivePortId]; |
| } |
| visitReceivePort(ReceivePortImpl port) { |
| @@ -153,26 +166,19 @@ class Serializer extends MessageTraverser { |
| return visitSendPort(port.toSendPort()); |
| } |
| - _serializeDartListIntoNewJsArray(List list) { |
| + _serializeList(List list) { |
| int len = list.length; |
| - var jsArray = _newJsArray(len); |
| + var result = new List(len); |
| for (int i = 0; i < len; i++) { |
| - _jsArrayIndexSet(jsArray, i, _dispatch(list[i])); |
| + result[i] = _dispatch(list[i]); |
| } |
| - return jsArray; |
| - } |
| - |
| - _makeRef(int id) { |
| - return _dartListToJsArrayNoCopy(['ref', id]); |
| + return result; |
| } |
| int _nextFreeRefId = 0; |
| - |
| - static _newJsArray(int len) native; |
| - static _jsArrayIndexSet(jsArray, int index, val) native; |
| - static _dartListToJsArrayNoCopy(List list) native; |
| } |
| +/** Deserializes arrays created with [Serializer]. */ |
| class Deserializer { |
| Deserializer(); |
| @@ -189,8 +195,8 @@ class Deserializer { |
| _deserializeHelper(x) { |
| if (isPrimitive(x)) return x; |
| - assert(_isJsArray(x)); |
| - switch (_jsArrayIndex(x, 0)) { |
| + assert(x is List); |
| + switch (x[0]) { |
| case 'ref': return _deserializeRef(x); |
| case 'list': return _deserializeList(x); |
| case 'map': return _deserializeMap(x); |
| @@ -200,18 +206,17 @@ class Deserializer { |
| } |
| } |
| - _deserializeRef(x) { |
| - int id = _jsArrayIndex(x, 1); |
| + _deserializeRef(List x) { |
| + int id = x[1]; |
| var result = _deserialized[id]; |
| assert(result !== null); |
| return result; |
| } |
| - List _deserializeList(x) { |
| - int id = _jsArrayIndex(x, 1); |
| - var jsArray = _jsArrayIndex(x, 2); |
| - assert(_isJsArray(jsArray)); |
| - List dartList = _jsArrayToDartListNoCopy(jsArray); |
| + List _deserializeList(List x) { |
| + int id = x[1]; |
| + // We rely on the fact that Dart-lists are directly mapped to Js-arrays. |
| + List dartList = x[2]; |
| _deserialized[id] = dartList; |
| int len = dartList.length; |
| for (int i = 0; i < len; i++) { |
| @@ -220,42 +225,29 @@ class Deserializer { |
| return dartList; |
| } |
| - Map _deserializeMap(x) { |
| + Map _deserializeMap(List x) { |
| Map result = new Map(); |
| - int id = _jsArrayIndex(x, 1); |
| + int id = x[1]; |
| _deserialized[id] = result; |
| - var keys = _jsArrayIndex(x, 2); |
| - var values = _jsArrayIndex(x, 3); |
| - assert(_isJsArray(keys)); |
| - assert(_isJsArray(values)); |
| - int len = _jsArrayLength(keys); |
| - assert(len == _jsArrayLength(values)); |
| + List keys = x[2]; |
| + List values = x[3]; |
| + int len = keys.length; |
| + assert(len == values.length); |
| for (int i = 0; i < len; i++) { |
| - var key = _deserializeHelper(_jsArrayIndex(keys, i)); |
| - var value = _deserializeHelper(_jsArrayIndex(values, i)); |
| + var key = _deserializeHelper(keys[i]); |
| + var value = _deserializeHelper(values[i]); |
| result[key] = value; |
| } |
| return result; |
| } |
| - SendPort _deserializeSendPort(x) { |
| - int workerId = _jsArrayIndex(x, 1); |
| - int isolateId = _jsArrayIndex(x, 2); |
| - int receivePortId = _jsArrayIndex(x, 3); |
| + SendPort _deserializeSendPort(List x) { |
| + int workerId = x[1]; |
| + int isolateId = x[2]; |
| + int receivePortId = x[3]; |
| return new SendPortImpl(workerId, isolateId, receivePortId); |
| } |
| - List _jsArrayToDartListNoCopy(a) { |
| - // We rely on the fact that Dart-lists are directly mapped to Js-arrays. |
| - // TODO(floitsch): can we do better here? |
| - assert(a is List); |
| - return a; |
| - } |
| - |
| // TODO(floitsch): this should by Map<int, var> or Map<int, Dynamic>. |
| - Map _deserialized; |
| - |
| - static bool _isJsArray(x) native; |
| - static _jsArrayIndex(x, int index) native; |
| - static int _jsArrayLength(x) native; |
| + Map<int, Dynamic> _deserialized; |
| } |