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

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

Issue 10873037: Support methods, getters, and setters on JS proxies. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix status Created 8 years, 4 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 { 9 class JsProxy {
10 SendPortSync _port;
10 final _id; 11 final _id;
11 12
12 JsProxy._internal(this._id); 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 }
13 } 24 }
14 25
15 class _JsSerializer extends _Serializer { 26 class _JsSerializer extends _Serializer {
16 27
17 visitSendPortSync(SendPortSync x) { 28 visitSendPortSync(SendPortSync x) {
18 if (x is _JsSendPortSync) return visitJsSendPortSync(x); 29 if (x is _JsSendPortSync) return visitJsSendPortSync(x);
19 if (x is _LocalSendPortSync) return visitLocalSendPortSync(x); 30 if (x is _LocalSendPortSync) return visitLocalSendPortSync(x);
20 if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x); 31 if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x);
21 throw "Illegal underlying port $x"; 32 throw "Unknown port type $x";
22 } 33 }
23 34
24 visitJsSendPortSync(_JsSendPortSync x) { 35 visitJsSendPortSync(_JsSendPortSync x) {
25 return [ 'sendport', 'nativejs', x._id ]; 36 return [ 'sendport', 'nativejs', x._id ];
26 } 37 }
27 38
28 visitLocalSendPortSync(_LocalSendPortSync x) { 39 visitLocalSendPortSync(_LocalSendPortSync x) {
29 return [ 'sendport', 'dart', 40 return [ 'sendport', 'dart',
30 ReceivePortSync._isolateId, x._receivePort._portId ]; 41 ReceivePortSync._isolateId, x._receivePort._portId ];
31 } 42 }
32 43
33 visitRemoteSendPortSync(_RemoteSendPortSync x) { 44 visitRemoteSendPortSync(_RemoteSendPortSync x) {
34 return [ 'sendport', 'dart', 45 return [ 'sendport', 'dart',
35 x._receivePort._isolateId, x._receivePort._portId ]; 46 x._receivePort._isolateId, x._receivePort._portId ];
36 } 47 }
37 48
38 visitObject(Object x) { 49 visitObject(Object x) {
39 if (x is Function) return visitFunction(x); 50 if (x is Function) return visitFunction(x);
40 if (x is JsProxy) return visitJsProxy(x); 51 if (x is JsProxy) return visitJsProxy(x);
41 52
42 // TODO: Handle DOM elements and proxy other objects. 53 // TODO: Handle DOM elements and proxy other objects.
43 var proxyId = _makeDartProxyRef(x); 54 var proxyId = _dartProxyRegistry._add(x);
44 return [ 'objref', 'dart', proxyId ]; 55 return [ 'objref', proxyId,
56 visitSendPortSync(_dartProxyRegistry._sendPort) ];
45 } 57 }
46 58
47 visitFunction(Function func) { 59 visitFunction(Function func) {
48 return [ 'funcref', 60 return [ 'funcref',
49 _makeFunctionRef(func), visitSendPortSync(_sendPort()), null ]; 61 _functionRegistry._add(func),
62 visitSendPortSync(_functionRegistry._sendPort), null ];
50 } 63 }
51 64
52 visitJsProxy(JsProxy proxy) { 65 visitJsProxy(JsProxy proxy) {
53 return [ 'objref', 'nativejs', proxy._id ]; 66 return [ 'objref', proxy._id, visitSendPortSync(proxy._port) ];
54 } 67 }
55 } 68 }
56 69
57 // Leaking implementation. Later will be backend specific and hopefully 70 // Leaking implementation. Later will be backend specific and hopefully
58 // not leaking (at least in most of the cases.) 71 // not leaking (at least in most of the cases.)
59 // TODO: provide better, backend specific implementation. 72 // TODO: provide better, backend specific implementation.
60 class _Registry<T> { 73 class _Registry<T> {
61 final String _name; 74 final String _name;
62 int _nextId; 75 int _nextId;
63 final Map<String, T> _registry; 76 final Map<String, T> _registry;
77 final ReceivePortSync _port;
64 78
65 _Registry(this._name) : _nextId = 0, _registry = <T>{}; 79 _Registry(this._name) :
80 _nextId = 0,
81 _registry = <T>{},
82 _port = new ReceivePortSync();
66 83
67 String _add(T x) { 84 String _add(T x) {
68 // TODO(vsm): Cache x and reuse id. 85 // TODO(vsm): Cache x and reuse id.
69 final id = '$_name-${_nextId++}'; 86 final id = '$_name-${_nextId++}';
70 _registry[id] = x; 87 _registry[id] = x;
71 return id; 88 return id;
72 } 89 }
73 90
74 T _get(String id) { 91 T _get(String id) {
75 return _registry[id]; 92 return _registry[id];
76 } 93 }
94
95 get _sendPort => _port.toSendPort();
77 } 96 }
78 97
79 class _FunctionRegistry extends _Registry<Function> { 98 class _FunctionRegistry extends _Registry<Function> {
80 final ReceivePortSync _port; 99 _FunctionRegistry() : super('func-ref') {
81
82 _FunctionRegistry() :
83 super('func-ref'),
84 _port = new ReceivePortSync() {
85 _port.receive((msg) { 100 _port.receive((msg) {
86 final id = msg[0]; 101 final id = msg[0];
87 final args = msg[1]; 102 final args = msg[1];
88 final f = _registry[id]; 103 final f = _registry[id];
89 switch (args.length) { 104 switch (args.length) {
90 case 0: return f(); 105 case 0: return f();
91 case 1: return f(args[0]); 106 case 1: return f(args[0]);
92 case 2: return f(args[0], args[1]); 107 case 2: return f(args[0], args[1]);
93 case 3: return f(args[0], args[1], args[2]); 108 case 3: return f(args[0], args[1], args[2]);
94 case 4: return f(args[0], args[1], args[2], args[3]); 109 case 4: return f(args[0], args[1], args[2], args[3]);
95 default: throw 'Unsupported number of arguments.'; 110 default: throw 'Unsupported number of arguments.';
96 } 111 }
97 }); 112 });
98 } 113 }
99
100 get _sendPort => _port.toSendPort();
101 } 114 }
102 115
103 _FunctionRegistry __functionRegistry; 116 _FunctionRegistry __functionRegistry;
104 get _functionRegistry { 117 get _functionRegistry {
105 if (__functionRegistry === null) __functionRegistry = new _FunctionRegistry(); 118 if (__functionRegistry === null) __functionRegistry = new _FunctionRegistry();
106 return __functionRegistry; 119 return __functionRegistry;
107 } 120 }
108
109 _makeFunctionRef(f) => _functionRegistry._add(f);
110 _sendPort() => _functionRegistry._sendPort;
111 /// End of function serialization implementation. 121 /// End of function serialization implementation.
112 122
113 /// Object proxy implementation. 123 /// Object proxy implementation.
114 124
115 class _DartProxyRegistry extends _Registry<Object> { 125 class _DartProxyRegistry extends _Registry<Object> {
116 _DartProxyRegistry() : super('dart-ref'); 126 _DartProxyRegistry() : super('dart-ref') {
127 _port.receive((msg) {
128 // TODO(vsm): Support a mechanism to register a handler here.
129 throw 'Invocation unsupported on Dart proxies';
130 });
131 }
117 } 132 }
118 133
119 _DartProxyRegistry __dartProxyRegistry; 134 _DartProxyRegistry __dartProxyRegistry;
120 get _dartProxyRegistry { 135 get _dartProxyRegistry {
121 if (__dartProxyRegistry === null) { 136 if (__dartProxyRegistry === null) {
122 __dartProxyRegistry = new _DartProxyRegistry(); 137 __dartProxyRegistry = new _DartProxyRegistry();
123 } 138 }
124 return __dartProxyRegistry; 139 return __dartProxyRegistry;
125 } 140 }
126 141
127 _makeDartProxyRef(f) => _dartProxyRegistry._add(f);
128 _getDartProxyObj(id) => _dartProxyRegistry._get(id);
129
130 /// End of object proxy implementation. 142 /// End of object proxy implementation.
131 143
132 _deserialize(var message) { 144 _deserialize(var message) {
133 return new _JsDeserializer().deserialize(message); 145 return new _JsDeserializer().deserialize(message);
134 } 146 }
135 147
136 class _JsDeserializer extends _Deserializer { 148 class _JsDeserializer extends _Deserializer {
137 149
138 static final _UNSPECIFIED = const Object(); 150 static final _UNSPECIFIED = const Object();
139 151
(...skipping 29 matching lines...) Expand all
169 arg2 = _UNSPECIFIED, arg3 = _UNSPECIFIED]) { 181 arg2 = _UNSPECIFIED, arg3 = _UNSPECIFIED]) {
170 var args = [arg0, arg1, arg2, arg3]; 182 var args = [arg0, arg1, arg2, arg3];
171 var last = args.indexOf(_UNSPECIFIED); 183 var last = args.indexOf(_UNSPECIFIED);
172 if (last >= 0) args = args.getRange(0, last); 184 if (last >= 0) args = args.getRange(0, last);
173 var message = [id, args]; 185 var message = [id, args];
174 return port.callSync(message); 186 return port.callSync(message);
175 }; 187 };
176 } 188 }
177 189
178 deserializeProxy(x) { 190 deserializeProxy(x) {
179 String tag = x[1]; 191 var id = x[1];
180 switch (tag) { 192 var port = deserializeSendPort(x[2]);
181 case 'nativejs': 193 if (port is _JsSendPortSync) return new JsProxy._internal(port, id);
182 var id = x[2]; 194 if (port is _LocalSendPortSync) return _dartProxyRegistry._get(id);
183 return new JsProxy._internal(id); 195 // TODO(vsm): Support this case.
184 case 'dart': 196 if (port is _RemoteSendPortSync) throw 'Remote Dart proxies unsupported';
185 var id = x[2]; 197 throw 'Illegal proxy: $port';
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 } 198 }
192 } 199 }
193 200
194 // The receiver is JS. 201 // The receiver is JS.
195 class _JsSendPortSync implements SendPortSync { 202 class _JsSendPortSync implements SendPortSync {
196 203
197 num _id; 204 num _id;
198 _JsSendPortSync(this._id); 205 _JsSendPortSync(this._id);
199 206
200 callSync(var message) { 207 callSync(var message) {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 return new _RemoteSendPortSync(isolateId, portId); 331 return new _RemoteSendPortSync(isolateId, portId);
325 } 332 }
326 } 333 }
327 } 334 }
328 335
329 void _dispatchEvent(String receiver, var message) { 336 void _dispatchEvent(String receiver, var message) {
330 var event = document.$dom_createEvent('TextEvent'); 337 var event = document.$dom_createEvent('TextEvent');
331 event.initTextEvent(receiver, false, false, window, JSON.stringify(message)); 338 event.initTextEvent(receiver, false, false, window, JSON.stringify(message));
332 window.$dom_dispatchEvent(event); 339 window.$dom_dispatchEvent(event);
333 } 340 }
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