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 { | |
10 final int _id; | |
11 | |
12 JsProxy._internal(this._id); | |
13 } | |
14 | |
9 class _JsSerializer extends _Serializer { | 15 class _JsSerializer extends _Serializer { |
10 | 16 |
11 visitSendPortSync(SendPortSync x) { | 17 visitSendPortSync(SendPortSync x) { |
12 if (x is _JsSendPortSync) return visitJsSendPortSync(x); | 18 if (x is _JsSendPortSync) return visitJsSendPortSync(x); |
13 if (x is _LocalSendPortSync) return visitLocalSendPortSync(x); | 19 if (x is _LocalSendPortSync) return visitLocalSendPortSync(x); |
14 if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x); | 20 if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x); |
15 throw "Illegal underlying port $x"; | 21 throw "Illegal underlying port $x"; |
16 } | 22 } |
17 | 23 |
18 visitJsSendPortSync(_JsSendPortSync x) { | 24 visitJsSendPortSync(_JsSendPortSync x) { |
19 return [ 'sendport', 'nativejs', x._id ]; | 25 return [ 'sendport', 'nativejs', x._id ]; |
20 } | 26 } |
21 | 27 |
22 visitLocalSendPortSync(_LocalSendPortSync x) { | 28 visitLocalSendPortSync(_LocalSendPortSync x) { |
23 return [ 'sendport', 'dart', | 29 return [ 'sendport', 'dart', |
24 ReceivePortSync._isolateId, x._receivePort._portId ]; | 30 ReceivePortSync._isolateId, x._receivePort._portId ]; |
25 } | 31 } |
26 | 32 |
27 visitRemoteSendPortSync(_RemoteSendPortSync x) { | 33 visitRemoteSendPortSync(_RemoteSendPortSync x) { |
28 return [ 'sendport', 'dart', | 34 return [ 'sendport', 'dart', |
29 x._receivePort._isolateId, x._receivePort._portId ]; | 35 x._receivePort._isolateId, x._receivePort._portId ]; |
30 } | 36 } |
31 | 37 |
32 visitObject(Object x) { | 38 visitObject(Object x) { |
33 if (x is Function) return visitFunction(x); | 39 if (x is Function) return visitFunction(x); |
40 if (x is JsProxy) return visitJsProxy(x); | |
41 | |
34 // TODO: Handle DOM elements and proxy other objects. | 42 // TODO: Handle DOM elements and proxy other objects. |
35 throw "Unserializable object $x"; | 43 var proxyId = _makeDartProxyRef(x); |
44 return [ 'objref', 'dart', proxyId ]; | |
36 } | 45 } |
37 | 46 |
38 visitFunction(Function func) { | 47 visitFunction(Function func) { |
39 return [ 'funcref', | 48 return [ 'funcref', |
40 _makeFunctionRef(func), visitSendPortSync(_sendPort()), null ]; | 49 _makeFunctionRef(func), visitSendPortSync(_sendPort()), null ]; |
41 } | 50 } |
51 | |
52 visitJsProxy(JsProxy proxy) { | |
53 return [ 'objref', 'nativejs', proxy._id ]; | |
54 } | |
42 } | 55 } |
43 | 56 |
44 // Leaking implementation. Later will be backend specific and hopefully | 57 // Leaking implementation. Later will be backend specific and hopefully |
45 // not leaking (at least in most of the cases.) | 58 // not leaking (at least in most of the cases.) |
46 // TODO: provide better, backend specific implementation. | 59 // TODO: provide better, backend specific implementation. |
47 class _FunctionRegistry { | 60 class _Registry<T> { |
61 final String _name; | |
62 final int _nextId; | |
63 final Map<String, T> _registry; | |
64 | |
65 _Registry(this._name) : | |
66 _nextId = 0, | |
Emily Fortuna
2012/08/21 23:39:56
lines 66 and 67 could be up on line 65, right?
vsm
2012/08/22 00:04:28
Done.
| |
67 _registry = <T>{}; | |
68 | |
69 String _add(T x) { | |
70 // TODO(vsm): Cache x and reuse id. | |
71 final id = '$_name-${_nextId++}'; | |
72 _registry[id] = x; | |
73 return id; | |
74 } | |
75 | |
76 T _get(String id) { | |
77 return _registry[id]; | |
78 } | |
79 } | |
80 | |
81 class _FunctionRegistry extends _Registry<Function> { | |
48 final ReceivePortSync _port; | 82 final ReceivePortSync _port; |
49 int _nextId; | |
50 final Map<String, Function> _registry; | |
51 | 83 |
52 _FunctionRegistry() : | 84 _FunctionRegistry() : |
53 _port = new ReceivePortSync(), | 85 super('func-ref'), |
54 _nextId = 0, | 86 _port = new ReceivePortSync() { |
55 _registry = <Function>{} { | |
56 _port.receive((msg) { | 87 _port.receive((msg) { |
57 final id = msg[0]; | 88 final id = msg[0]; |
58 final args = msg[1]; | 89 final args = msg[1]; |
59 final f = _registry[id]; | 90 final f = _registry[id]; |
60 switch (args.length) { | 91 switch (args.length) { |
61 case 0: return f(); | 92 case 0: return f(); |
62 case 1: return f(args[0]); | 93 case 1: return f(args[0]); |
63 case 2: return f(args[0], args[1]); | 94 case 2: return f(args[0], args[1]); |
64 case 3: return f(args[0], args[1], args[2]); | 95 case 3: return f(args[0], args[1], args[2]); |
65 case 4: return f(args[0], args[1], args[2], args[3]); | 96 case 4: return f(args[0], args[1], args[2], args[3]); |
66 default: throw 'Unsupported number of arguments.'; | 97 default: throw 'Unsupported number of arguments.'; |
67 } | 98 } |
68 }); | 99 }); |
69 } | 100 } |
70 | 101 |
71 String _add(Function f) { | |
72 final id = 'func-ref-${_nextId++}'; | |
73 _registry[id] = f; | |
74 return id; | |
75 } | |
76 | |
77 get _sendPort() => _port.toSendPort(); | 102 get _sendPort() => _port.toSendPort(); |
78 } | 103 } |
79 | 104 |
80 _FunctionRegistry __functionRegistry; | 105 _FunctionRegistry __functionRegistry; |
81 get _functionRegistry() { | 106 get _functionRegistry() { |
82 if (__functionRegistry === null) __functionRegistry = new _FunctionRegistry(); | 107 if (__functionRegistry === null) __functionRegistry = new _FunctionRegistry(); |
83 return __functionRegistry; | 108 return __functionRegistry; |
84 } | 109 } |
85 | 110 |
86 _makeFunctionRef(f) => _functionRegistry._add(f); | 111 _makeFunctionRef(f) => _functionRegistry._add(f); |
87 _sendPort() => _functionRegistry._sendPort; | 112 _sendPort() => _functionRegistry._sendPort; |
88 /// End of function serialization implementation. | 113 /// End of function serialization implementation. |
89 | 114 |
115 /// Object proxy implementation. | |
116 | |
117 class _DartProxyRegistry extends _Registry<Object> { | |
118 _DartProxyRegistry() : super('dart-ref'); | |
119 } | |
120 | |
121 _DartProxyRegistry __dartProxyRegistry; | |
122 get _dartProxyRegistry() { | |
Emily Fortuna
2012/08/21 23:39:56
use new getter syntax:
get _dartProxyRegistry {
vsm
2012/08/22 00:04:28
Done.
| |
123 if (__dartProxyRegistry === null) __dartProxyRegistry = new _DartProxyRegistry (); | |
Emily Fortuna
2012/08/21 23:39:56
80 char
vsm
2012/08/22 00:04:28
Done.
| |
124 return __dartProxyRegistry; | |
125 } | |
126 | |
127 _makeDartProxyRef(f) => _dartProxyRegistry._add(f); | |
128 _getDartProxyObj(id) => _dartProxyRegistry._get(id); | |
129 | |
130 /// End of object proxy implementation. | |
131 | |
90 _deserialize(var message) { | 132 _deserialize(var message) { |
91 return new _JsDeserializer().deserialize(message); | 133 return new _JsDeserializer().deserialize(message); |
92 } | 134 } |
93 | 135 |
94 class _JsDeserializer extends _Deserializer { | 136 class _JsDeserializer extends _Deserializer { |
95 | 137 |
96 static final _UNSPECIFIED = const Object(); | 138 static final _UNSPECIFIED = const Object(); |
97 | 139 |
98 deserializeSendPort(List x) { | 140 deserializeSendPort(List x) { |
99 String tag = x[1]; | 141 String tag = x[1]; |
100 switch (tag) { | 142 switch (tag) { |
101 case 'nativejs': | 143 case 'nativejs': |
102 num id = x[2]; | 144 num id = x[2]; |
103 return new _JsSendPortSync(id); | 145 return new _JsSendPortSync(id); |
104 case 'dart': | 146 case 'dart': |
105 num isolateId = x[2]; | 147 num isolateId = x[2]; |
106 num portId = x[3]; | 148 num portId = x[3]; |
107 return ReceivePortSync._lookup(isolateId, portId); | 149 return ReceivePortSync._lookup(isolateId, portId); |
108 default: | 150 default: |
109 throw 'Illegal SendPortSync type: $tag'; | 151 throw 'Illegal SendPortSync type: $tag'; |
110 } | 152 } |
111 } | 153 } |
112 | 154 |
113 deserializeObject(List x) { | 155 deserializeObject(List x) { |
114 String tag = x[0]; | 156 String tag = x[0]; |
115 switch (tag) { | 157 switch (tag) { |
116 case 'funcref': return deserializeFunction(x); | 158 case 'funcref': return deserializeFunction(x); |
159 case 'objref': return deserializeProxy(x); | |
117 default: throw 'Illegal object type: $x'; | 160 default: throw 'Illegal object type: $x'; |
118 } | 161 } |
119 } | 162 } |
120 | 163 |
121 deserializeFunction(List x) { | 164 deserializeFunction(List x) { |
122 var id = x[1]; | 165 var id = x[1]; |
123 SendPortSync port = deserializeSendPort(x[2]); | 166 SendPortSync port = deserializeSendPort(x[2]); |
124 // TODO: Support varargs when there is support in the language. | 167 // TODO: Support varargs when there is support in the language. |
125 return ([arg0 = _UNSPECIFIED, arg1 = _UNSPECIFIED, | 168 return ([arg0 = _UNSPECIFIED, arg1 = _UNSPECIFIED, |
126 arg2 = _UNSPECIFIED, arg3 = _UNSPECIFIED]) { | 169 arg2 = _UNSPECIFIED, arg3 = _UNSPECIFIED]) { |
127 var args = [arg0, arg1, arg2, arg3]; | 170 var args = [arg0, arg1, arg2, arg3]; |
128 var last = args.indexOf(_UNSPECIFIED); | 171 var last = args.indexOf(_UNSPECIFIED); |
129 if (last >= 0) args = args.getRange(0, last); | 172 if (last >= 0) args = args.getRange(0, last); |
130 var message = [id, args]; | 173 var message = [id, args]; |
131 return port.callSync(message); | 174 return port.callSync(message); |
132 }; | 175 }; |
133 } | 176 } |
177 | |
178 deserializeProxy(x) { | |
179 String tag = x[1]; | |
180 switch (tag) { | |
181 case 'nativejs': | |
182 int id = x[2]; | |
183 return new JsProxy._internal(id); | |
184 case 'dart': | |
185 int id = x[2]; | |
186 // TODO(vsm): Check for isolate id. If the isolate isn't the | |
187 // current isolate, return a DartProxy. | |
188 return _getDartProxyObj(id); | |
189 default: throw 'Illegal proxy: $x'; | |
190 } | |
191 } | |
134 } | 192 } |
135 | 193 |
136 // The receiver is JS. | 194 // The receiver is JS. |
137 class _JsSendPortSync implements SendPortSync { | 195 class _JsSendPortSync implements SendPortSync { |
138 | 196 |
139 num _id; | 197 num _id; |
140 _JsSendPortSync(this._id); | 198 _JsSendPortSync(this._id); |
141 | 199 |
142 callSync(var message) { | 200 callSync(var message) { |
143 var serialized = _serialize(message); | 201 var serialized = _serialize(message); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 return new _RemoteSendPortSync(isolateId, portId); | 324 return new _RemoteSendPortSync(isolateId, portId); |
267 } | 325 } |
268 } | 326 } |
269 } | 327 } |
270 | 328 |
271 void _dispatchEvent(String receiver, var message) { | 329 void _dispatchEvent(String receiver, var message) { |
272 var event = document.$dom_createEvent('TextEvent'); | 330 var event = document.$dom_createEvent('TextEvent'); |
273 event.initTextEvent(receiver, false, false, window, JSON.stringify(message)); | 331 event.initTextEvent(receiver, false, false, window, JSON.stringify(message)); |
274 window.$dom_dispatchEvent(event); | 332 window.$dom_dispatchEvent(event); |
275 } | 333 } |
OLD | NEW |