| 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 |