| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 // Defines message visitors, serialization, and deserialization. |
| 6 |
| 7 /** Serialize [message] (or simulate serialization). */ |
| 8 _serializeMessage(message) { |
| 9 if (_globalState.needSerialization) { |
| 10 return new _JsSerializer().traverse(message); |
| 11 } else { |
| 12 return new _JsCopier().traverse(message); |
| 13 } |
| 14 } |
| 15 |
| 16 /** Deserialize [message] (or simulate deserialization). */ |
| 17 _deserializeMessage(message) { |
| 18 if (_globalState.needSerialization) { |
| 19 return new _JsDeserializer().deserialize(message); |
| 20 } else { |
| 21 // Nothing more to do. |
| 22 return message; |
| 23 } |
| 24 } |
| 25 |
| 26 class _JsSerializer extends _Serializer { |
| 27 |
| 28 _JsSerializer() : super() { _visited = new _JsVisitedMap(); } |
| 29 |
| 30 visitSendPort(SendPort x) { |
| 31 if (x is _NativeJsSendPort) return visitNativeJsSendPort(x); |
| 32 if (x is _WorkerSendPort) return visitWorkerSendPort(x); |
| 33 if (x is _BufferingSendPort) return visitBufferingSendPort(x); |
| 34 throw "Illegal underlying port $x"; |
| 35 } |
| 36 |
| 37 visitNativeJsSendPort(_NativeJsSendPort port) { |
| 38 return ['sendport', _globalState.currentManagerId, |
| 39 port._isolateId, port._receivePort._id]; |
| 40 } |
| 41 |
| 42 visitWorkerSendPort(_WorkerSendPort port) { |
| 43 return ['sendport', port._workerId, port._isolateId, port._receivePortId]; |
| 44 } |
| 45 |
| 46 visitBufferingSendPort(_BufferingSendPort port) { |
| 47 if (port._port != null) { |
| 48 return visitSendPort(port._port); |
| 49 } else { |
| 50 // TODO(floitsch): Use real exception (which one?). |
| 51 throw |
| 52 "internal error: must call _waitForPendingPorts to ensure all" |
| 53 " ports are resolved at this point."; |
| 54 } |
| 55 } |
| 56 |
| 57 } |
| 58 |
| 59 |
| 60 class _JsCopier extends _Copier { |
| 61 |
| 62 _JsCopier() : super() { _visited = new _JsVisitedMap(); } |
| 63 |
| 64 visitSendPort(SendPort x) { |
| 65 if (x is _NativeJsSendPort) return visitNativeJsSendPort(x); |
| 66 if (x is _WorkerSendPort) return visitWorkerSendPort(x); |
| 67 if (x is _BufferingSendPort) return visitBufferingSendPort(x); |
| 68 throw "Illegal underlying port $p"; |
| 69 } |
| 70 |
| 71 SendPort visitNativeJsSendPort(_NativeJsSendPort port) { |
| 72 return new _NativeJsSendPort(port._receivePort, port._isolateId); |
| 73 } |
| 74 |
| 75 SendPort visitWorkerSendPort(_WorkerSendPort port) { |
| 76 return new _WorkerSendPort( |
| 77 port._workerId, port._isolateId, port._receivePortId); |
| 78 } |
| 79 |
| 80 SendPort visitBufferingSendPort(_BufferingSendPort port) { |
| 81 if (port._port != null) { |
| 82 return visitSendPort(port._port); |
| 83 } else { |
| 84 // TODO(floitsch): Use real exception (which one?). |
| 85 throw |
| 86 "internal error: must call _waitForPendingPorts to ensure all" |
| 87 " ports are resolved at this point."; |
| 88 } |
| 89 } |
| 90 |
| 91 } |
| 92 |
| 93 class _JsDeserializer extends _Deserializer { |
| 94 |
| 95 SendPort deserializeSendPort(List x) { |
| 96 int managerId = x[1]; |
| 97 int isolateId = x[2]; |
| 98 int receivePortId = x[3]; |
| 99 // If two isolates are in the same manager, we use NativeJsSendPorts to |
| 100 // deliver messages directly without using postMessage. |
| 101 if (managerId == _globalState.currentManagerId) { |
| 102 var isolate = _globalState.isolates[isolateId]; |
| 103 if (isolate == null) return null; // Isolate has been closed. |
| 104 var receivePort = isolate.lookup(receivePortId); |
| 105 return new _NativeJsSendPort(receivePort, isolateId); |
| 106 } else { |
| 107 return new _WorkerSendPort(managerId, isolateId, receivePortId); |
| 108 } |
| 109 } |
| 110 |
| 111 } |
| 112 |
| 113 class _JsVisitedMap implements _MessageTraverserVisitedMap { |
| 114 List tagged; |
| 115 |
| 116 /** Retrieves any information stored in the native object [object]. */ |
| 117 operator[](var object) { |
| 118 return _getAttachedInfo(object); |
| 119 } |
| 120 |
| 121 /** Injects some information into the native [object]. */ |
| 122 void operator[]=(var object, var info) { |
| 123 tagged.add(object); |
| 124 _setAttachedInfo(object, info); |
| 125 } |
| 126 |
| 127 /** Get ready to rumble. */ |
| 128 void reset() { |
| 129 assert(tagged == null); |
| 130 tagged = new List(); |
| 131 } |
| 132 |
| 133 /** Remove all information injected in the native objects. */ |
| 134 cleanup() { |
| 135 for (int i = 0, length = tagged.length; i < length; i++) { |
| 136 _clearAttachedInfo(tagged[i]); |
| 137 } |
| 138 tagged = null; |
| 139 } |
| 140 |
| 141 _clearAttachedInfo(var o) native |
| 142 "o['__MessageTraverser__attached_info__'] = (void 0);"; |
| 143 |
| 144 _setAttachedInfo(var o, var info) native |
| 145 "o['__MessageTraverser__attached_info__'] = info;"; |
| 146 |
| 147 _getAttachedInfo(var o) native |
| 148 "return o['__MessageTraverser__attached_info__'];"; |
| 149 } |
| 150 |
| 151 // only visible for testing purposes |
| 152 // TODO(sigmund): remove once we can disable privacy for testing (bug #1882) |
| 153 class TestingOnly { |
| 154 static copy(x) { |
| 155 return new _JsCopier().traverse(x); |
| 156 } |
| 157 |
| 158 // only visible for testing purposes |
| 159 static serialize(x) { |
| 160 _Serializer serializer = new _JsSerializer(); |
| 161 _Deserializer deserializer = new _JsDeserializer(); |
| 162 return deserializer.deserialize(serializer.traverse(x)); |
| 163 } |
| 164 } |
| OLD | NEW |