Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1301)

Side by Side Diff: lib/html/src/Isolates.dart

Issue 10914129: Remove proxying support from dart:html (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Regen dart:html Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/html/dartium/html_dartium.dart ('k') | tests/html/html.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 SendPortSync _port;
11 final _id;
12
13 JsProxy._internal(this._port, this._id);
14
15 noSuchMethod(method, args) {
16 var result = _port.callSync([_id, method, args]);
17 switch (result[0]) {
18 case 'return': return result[1];
19 case 'exception': throw result[1];
20 case 'none': throw new NoSuchMethodException(this, method, args);
21 default: throw 'Invalid return value';
22 }
23 }
24 }
25
26 int _localNextElementId = 0;
27
28 const _DART_ID = 'data-dart_id';
29
30 _elementId(Element e) {
31 if (e.attributes.containsKey(_DART_ID)) return e.attributes[_DART_ID];
32 var id = '$_isolateId-${_localNextElementId++}';
33 e.attributes[_DART_ID] = id;
34 return id;
35 }
36
37 Element _getElement(var id) {
38 var list = queryAll('[$_DART_ID="$id"]');
39 if (list.length > 1) throw 'Non unique ID: $id';
40 if (list.length == 0) {
41 throw 'Only elements attached to document can be serialized: $id';
42 }
43 return list[0];
44 }
45
46 class _JsSerializer extends _Serializer { 9 class _JsSerializer extends _Serializer {
47 10
48 visitSendPortSync(SendPortSync x) { 11 visitSendPortSync(SendPortSync x) {
49 if (x is _JsSendPortSync) return visitJsSendPortSync(x); 12 if (x is _JsSendPortSync) return visitJsSendPortSync(x);
50 if (x is _LocalSendPortSync) return visitLocalSendPortSync(x); 13 if (x is _LocalSendPortSync) return visitLocalSendPortSync(x);
51 if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x); 14 if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x);
52 throw "Unknown port type $x"; 15 throw "Unknown port type $x";
53 } 16 }
54 17
55 visitJsSendPortSync(_JsSendPortSync x) { 18 visitJsSendPortSync(_JsSendPortSync x) {
56 return [ 'sendport', 'nativejs', x._id ]; 19 return [ 'sendport', 'nativejs', x._id ];
57 } 20 }
58 21
59 visitLocalSendPortSync(_LocalSendPortSync x) { 22 visitLocalSendPortSync(_LocalSendPortSync x) {
60 return [ 'sendport', 'dart', 23 return [ 'sendport', 'dart',
61 ReceivePortSync._isolateId, x._receivePort._portId ]; 24 ReceivePortSync._isolateId, x._receivePort._portId ];
62 } 25 }
63 26
64 visitRemoteSendPortSync(_RemoteSendPortSync x) { 27 visitRemoteSendPortSync(_RemoteSendPortSync x) {
65 return [ 'sendport', 'dart', 28 return [ 'sendport', 'dart',
66 x._receivePort._isolateId, x._receivePort._portId ]; 29 x._receivePort._isolateId, x._receivePort._portId ];
67 } 30 }
68
69 visitObject(Object x) {
70 if (x is Function) return visitFunction(x);
71 if (x is JsProxy) return visitJsProxy(x);
72 if (x is Element) return visitElement(x);
73
74 // TODO: Handle DOM elements and proxy other objects.
75 var proxyId = _dartProxyRegistry._add(x);
76 return [ 'objref', proxyId,
77 visitSendPortSync(_dartProxyRegistry._sendPort) ];
78 }
79
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.
86 return [ 'funcref',
87 _functionRegistry._add(func),
88 visitSendPortSync(_functionRegistry._sendPort), null ];
89 }
90
91 visitJsProxy(JsProxy proxy) {
92 return [ 'objref', proxy._id, visitSendPortSync(proxy._port) ];
93 }
94
95 visitElement(Element element) {
96 var id = _elementId(element);
97 // Verify that the element is connected to the document.
98 // Otherwise, we will not be able to find it on the other side.
99 _getElement(id);
100 return [ 'element', id ];
101 }
102 } 31 }
103 32
104 // Leaking implementation. Later will be backend specific and hopefully
105 // not leaking (at least in most of the cases.)
106 // TODO: provide better, backend specific implementation.
107 class _Registry<T> {
108 final String _name;
109 int _nextId;
110 final Map<String, T> _registry;
111 final ReceivePortSync _port;
112
113 _Registry(this._name) :
114 _nextId = 0,
115 _registry = <T>{},
116 _port = new ReceivePortSync();
117
118 String _add(T x) {
119 // TODO(vsm): Cache x and reuse id.
120 final id = '$_name-${_nextId++}';
121 _registry[id] = x;
122 return id;
123 }
124
125 T _get(String id) {
126 return _registry[id];
127 }
128
129 get _sendPort => _port.toSendPort();
130 }
131
132 class _FunctionRegistry extends _Registry<Function> {
133 _FunctionRegistry() : super('func-ref') {
134 _port.receive((msg) {
135 final id = msg[0];
136 final args = msg[1];
137 final f = _registry[id];
138 switch (args.length) {
139 case 0: return f();
140 case 1: return f(args[0]);
141 case 2: return f(args[0], args[1]);
142 case 3: return f(args[0], args[1], args[2]);
143 case 4: return f(args[0], args[1], args[2], args[3]);
144 default: throw 'Unsupported number of arguments.';
145 }
146 });
147 }
148 }
149
150 _FunctionRegistry __functionRegistry;
151 get _functionRegistry {
152 if (__functionRegistry === null) __functionRegistry = new _FunctionRegistry();
153 return __functionRegistry;
154 }
155 /// End of function serialization implementation.
156
157 /// Object proxy implementation.
158
159 class _DartProxyRegistry extends _Registry<Object> {
160 _DartProxyRegistry() : super('dart-ref') {
161 _port.receive((msg) {
162 // TODO(vsm): Support a mechanism to register a handler here.
163 throw 'Invocation unsupported on Dart proxies';
164 });
165 }
166 }
167
168 _DartProxyRegistry __dartProxyRegistry;
169 get _dartProxyRegistry {
170 if (__dartProxyRegistry === null) {
171 __dartProxyRegistry = new _DartProxyRegistry();
172 }
173 return __dartProxyRegistry;
174 }
175
176 /// End of object proxy implementation.
177
178 _deserialize(var message) { 33 _deserialize(var message) {
179 return new _JsDeserializer().deserialize(message); 34 return new _JsDeserializer().deserialize(message);
180 } 35 }
181 36
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 37
210 class _JsDeserializer extends _Deserializer { 38 class _JsDeserializer extends _Deserializer {
211 39
212 static const _UNSPECIFIED = const Object(); 40 static const _UNSPECIFIED = const Object();
213 41
214 deserializeSendPort(List x) { 42 deserializeSendPort(List x) {
215 String tag = x[1]; 43 String tag = x[1];
216 switch (tag) { 44 switch (tag) {
217 case 'nativejs': 45 case 'nativejs':
218 num id = x[2]; 46 num id = x[2];
219 return new _JsSendPortSync(id); 47 return new _JsSendPortSync(id);
220 case 'dart': 48 case 'dart':
221 num isolateId = x[2]; 49 num isolateId = x[2];
222 num portId = x[3]; 50 num portId = x[3];
223 return ReceivePortSync._lookup(isolateId, portId); 51 return ReceivePortSync._lookup(isolateId, portId);
224 default: 52 default:
225 throw 'Illegal SendPortSync type: $tag'; 53 throw 'Illegal SendPortSync type: $tag';
226 } 54 }
227 } 55 }
228
229 deserializeObject(List x) {
230 String tag = x[0];
231 switch (tag) {
232 case 'funcref': return deserializeFunction(x);
233 case 'objref': return deserializeProxy(x);
234 case 'element': return deserializeElement(x);
235 default: throw 'Illegal object type: $x';
236 }
237 }
238
239 deserializeFunction(List x) {
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.
244 SendPortSync port = deserializeSendPort(x[2]);
245 if (port is _LocalSendPortSync) {
246 return _functionRegistry._get(id);
247 }
248 // TODO: Support varargs when there is support in the language.
249 var f = ([arg0 = _UNSPECIFIED, arg1 = _UNSPECIFIED,
250 arg2 = _UNSPECIFIED, arg3 = _UNSPECIFIED]) {
251 var args = [arg0, arg1, arg2, arg3];
252 var last = args.indexOf(_UNSPECIFIED);
253 if (last >= 0) args = args.getRange(0, last);
254 var message = [id, args];
255 return port.callSync(message);
256 };
257 _deserializedFunctionTable.add(f, x);
258 return f;
259 }
260
261 deserializeProxy(x) {
262 var id = x[1];
263 var port = deserializeSendPort(x[2]);
264 if (port is _JsSendPortSync) return new JsProxy._internal(port, id);
265 if (port is _LocalSendPortSync) return _dartProxyRegistry._get(id);
266 // TODO(vsm): Support this case.
267 if (port is _RemoteSendPortSync) throw 'Remote Dart proxies unsupported';
268 throw 'Illegal proxy: $port';
269 }
270
271 deserializeElement(x) {
272 var id = x[1];
273 return _getElement(id);
274 }
275 } 56 }
276 57
277 // The receiver is JS. 58 // The receiver is JS.
278 class _JsSendPortSync implements SendPortSync { 59 class _JsSendPortSync implements SendPortSync {
279 60
280 num _id; 61 num _id;
281 _JsSendPortSync(this._id); 62 _JsSendPortSync(this._id);
282 63
283 callSync(var message) { 64 callSync(var message) {
284 var serialized = _serialize(message); 65 var serialized = _serialize(message);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 } 190 }
410 } 191 }
411 192
412 get _isolateId => ReceivePortSync._isolateId; 193 get _isolateId => ReceivePortSync._isolateId;
413 194
414 void _dispatchEvent(String receiver, var message) { 195 void _dispatchEvent(String receiver, var message) {
415 var event = document.$dom_createEvent('TextEvent'); 196 var event = document.$dom_createEvent('TextEvent');
416 event.initTextEvent(receiver, false, false, window, JSON.stringify(message)); 197 event.initTextEvent(receiver, false, false, window, JSON.stringify(message));
417 window.$dom_dispatchEvent(event); 198 window.$dom_dispatchEvent(event);
418 } 199 }
OLDNEW
« no previous file with comments | « lib/html/dartium/html_dartium.dart ('k') | tests/html/html.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698