OLD | NEW |
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 _serialize(var message) { | 5 _serialize(var message) { |
6 return new _JsSerializer().traverse(message); | 6 return new _JsSerializer().traverse(message); |
7 } | 7 } |
8 | 8 |
9 class JsProxy { | 9 class JsProxy { |
10 SendPortSync _port; | 10 SendPortSync _port; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 if (x is JsProxy) return visitJsProxy(x); | 71 if (x is JsProxy) return visitJsProxy(x); |
72 if (x is Element) return visitElement(x); | 72 if (x is Element) return visitElement(x); |
73 | 73 |
74 // TODO: Handle DOM elements and proxy other objects. | 74 // TODO: Handle DOM elements and proxy other objects. |
75 var proxyId = _dartProxyRegistry._add(x); | 75 var proxyId = _dartProxyRegistry._add(x); |
76 return [ 'objref', proxyId, | 76 return [ 'objref', proxyId, |
77 visitSendPortSync(_dartProxyRegistry._sendPort) ]; | 77 visitSendPortSync(_dartProxyRegistry._sendPort) ]; |
78 } | 78 } |
79 | 79 |
80 visitFunction(Function func) { | 80 visitFunction(Function func) { |
| 81 // Look for a cached serialization first. The cached version |
| 82 // should point to the original port. |
| 83 var serialized = _deserializedFunctionTable.find(func); |
| 84 if (serialized != null) return serialized; |
| 85 // Create a new serialization forwarding to this port. |
81 return [ 'funcref', | 86 return [ 'funcref', |
82 _functionRegistry._add(func), | 87 _functionRegistry._add(func), |
83 visitSendPortSync(_functionRegistry._sendPort), null ]; | 88 visitSendPortSync(_functionRegistry._sendPort), null ]; |
84 } | 89 } |
85 | 90 |
86 visitJsProxy(JsProxy proxy) { | 91 visitJsProxy(JsProxy proxy) { |
87 return [ 'objref', proxy._id, visitSendPortSync(proxy._port) ]; | 92 return [ 'objref', proxy._id, visitSendPortSync(proxy._port) ]; |
88 } | 93 } |
89 | 94 |
90 visitElement(Element element) { | 95 visitElement(Element element) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 } | 172 } |
168 return __dartProxyRegistry; | 173 return __dartProxyRegistry; |
169 } | 174 } |
170 | 175 |
171 /// End of object proxy implementation. | 176 /// End of object proxy implementation. |
172 | 177 |
173 _deserialize(var message) { | 178 _deserialize(var message) { |
174 return new _JsDeserializer().deserialize(message); | 179 return new _JsDeserializer().deserialize(message); |
175 } | 180 } |
176 | 181 |
| 182 // TODO(vsm): Replace this with a hash map once functions are |
| 183 // hashable. |
| 184 class _DeserializedFunctionTable { |
| 185 List data; |
| 186 _DeserializedFunctionTable() { |
| 187 data = []; |
| 188 } |
| 189 |
| 190 find(Function f) { |
| 191 for (var item in data) { |
| 192 if (f == item[0]) return item[1]; |
| 193 } |
| 194 return null; |
| 195 } |
| 196 |
| 197 add(Function f, x) { |
| 198 data.add([f, x]); |
| 199 } |
| 200 } |
| 201 |
| 202 _DeserializedFunctionTable __deserializedFunctionTable = null; |
| 203 get _deserializedFunctionTable { |
| 204 if (__deserializedFunctionTable == null) { |
| 205 __deserializedFunctionTable = new _DeserializedFunctionTable(); |
| 206 } |
| 207 return __deserializedFunctionTable; |
| 208 } |
| 209 |
177 class _JsDeserializer extends _Deserializer { | 210 class _JsDeserializer extends _Deserializer { |
178 | 211 |
179 static const _UNSPECIFIED = const Object(); | 212 static const _UNSPECIFIED = const Object(); |
180 | 213 |
181 deserializeSendPort(List x) { | 214 deserializeSendPort(List x) { |
182 String tag = x[1]; | 215 String tag = x[1]; |
183 switch (tag) { | 216 switch (tag) { |
184 case 'nativejs': | 217 case 'nativejs': |
185 num id = x[2]; | 218 num id = x[2]; |
186 return new _JsSendPortSync(id); | 219 return new _JsSendPortSync(id); |
(...skipping 11 matching lines...) Expand all Loading... |
198 switch (tag) { | 231 switch (tag) { |
199 case 'funcref': return deserializeFunction(x); | 232 case 'funcref': return deserializeFunction(x); |
200 case 'objref': return deserializeProxy(x); | 233 case 'objref': return deserializeProxy(x); |
201 case 'element': return deserializeElement(x); | 234 case 'element': return deserializeElement(x); |
202 default: throw 'Illegal object type: $x'; | 235 default: throw 'Illegal object type: $x'; |
203 } | 236 } |
204 } | 237 } |
205 | 238 |
206 deserializeFunction(List x) { | 239 deserializeFunction(List x) { |
207 var id = x[1]; | 240 var id = x[1]; |
| 241 // If the sendPort is local, just return the underlying function. |
| 242 // Otherwise, create a new function that forwards to the remote |
| 243 // port. |
208 SendPortSync port = deserializeSendPort(x[2]); | 244 SendPortSync port = deserializeSendPort(x[2]); |
| 245 if (port is _LocalSendPortSync) { |
| 246 return _functionRegistry._get(id); |
| 247 } |
209 // TODO: Support varargs when there is support in the language. | 248 // TODO: Support varargs when there is support in the language. |
210 return ([arg0 = _UNSPECIFIED, arg1 = _UNSPECIFIED, | 249 var f = ([arg0 = _UNSPECIFIED, arg1 = _UNSPECIFIED, |
211 arg2 = _UNSPECIFIED, arg3 = _UNSPECIFIED]) { | 250 arg2 = _UNSPECIFIED, arg3 = _UNSPECIFIED]) { |
212 var args = [arg0, arg1, arg2, arg3]; | 251 var args = [arg0, arg1, arg2, arg3]; |
213 var last = args.indexOf(_UNSPECIFIED); | 252 var last = args.indexOf(_UNSPECIFIED); |
214 if (last >= 0) args = args.getRange(0, last); | 253 if (last >= 0) args = args.getRange(0, last); |
215 var message = [id, args]; | 254 var message = [id, args]; |
216 return port.callSync(message); | 255 return port.callSync(message); |
217 }; | 256 }; |
| 257 _deserializedFunctionTable.add(f, x); |
| 258 return f; |
218 } | 259 } |
219 | 260 |
220 deserializeProxy(x) { | 261 deserializeProxy(x) { |
221 var id = x[1]; | 262 var id = x[1]; |
222 var port = deserializeSendPort(x[2]); | 263 var port = deserializeSendPort(x[2]); |
223 if (port is _JsSendPortSync) return new JsProxy._internal(port, id); | 264 if (port is _JsSendPortSync) return new JsProxy._internal(port, id); |
224 if (port is _LocalSendPortSync) return _dartProxyRegistry._get(id); | 265 if (port is _LocalSendPortSync) return _dartProxyRegistry._get(id); |
225 // TODO(vsm): Support this case. | 266 // TODO(vsm): Support this case. |
226 if (port is _RemoteSendPortSync) throw 'Remote Dart proxies unsupported'; | 267 if (port is _RemoteSendPortSync) throw 'Remote Dart proxies unsupported'; |
227 throw 'Illegal proxy: $port'; | 268 throw 'Illegal proxy: $port'; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 } | 409 } |
369 } | 410 } |
370 | 411 |
371 get _isolateId => ReceivePortSync._isolateId; | 412 get _isolateId => ReceivePortSync._isolateId; |
372 | 413 |
373 void _dispatchEvent(String receiver, var message) { | 414 void _dispatchEvent(String receiver, var message) { |
374 var event = document.$dom_createEvent('TextEvent'); | 415 var event = document.$dom_createEvent('TextEvent'); |
375 event.initTextEvent(receiver, false, false, window, JSON.stringify(message)); | 416 event.initTextEvent(receiver, false, false, window, JSON.stringify(message)); |
376 window.$dom_dispatchEvent(event); | 417 window.$dom_dispatchEvent(event); |
377 } | 418 } |
OLD | NEW |