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

Side by Side Diff: client/dart.js

Issue 10827462: Support proxying of objects between JS and Dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix html.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 | « no previous file | lib/html/dart2js/html_dart2js.dart » ('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 // Bootstrap support for Dart scripts on the page as this script. 5 // Bootstrap support for Dart scripts on the page as this script.
6 if (navigator.webkitStartDart) { 6 if (navigator.webkitStartDart) {
7 if (!navigator.webkitStartDart()) { 7 if (!navigator.webkitStartDart()) {
8 document.body.innerHTML = 'This build has expired. Please download a new Da rtium at http://www.dartlang.org/dartium/index.html'; 8 document.body.innerHTML = 'This build has expired. Please download a new Da rtium at http://www.dartlang.org/dartium/index.html';
9 } 9 }
10 } else { 10 } else {
(...skipping 28 matching lines...) Expand all
39 // --------------------------------------------------------------------------- 39 // ---------------------------------------------------------------------------
40 function SendPortSync() { 40 function SendPortSync() {
41 } 41 }
42 42
43 function ReceivePortSync() { 43 function ReceivePortSync() {
44 this.id = ReceivePortSync.id++; 44 this.id = ReceivePortSync.id++;
45 ReceivePortSync.map[this.id] = this; 45 ReceivePortSync.map[this.id] = this;
46 } 46 }
47 47
48 (function() { 48 (function() {
49 // Track proxied functions. 49 function RefTable(name) {
50 // TODO: Fix leaks, particularly in dart2js case. 50 // TODO(vsm): Fix leaks, particularly in dart2js case.
51 var functionRefMap = {}; 51 this.name = name;
52 this.map = {};
53 this.id = 0;
54 this.initialized = false;
55 }
56
57 RefTable.prototype.nextId = function () { return this.id++; }
52 58
53 var nextFunctionRefId = 0; 59 RefTable.prototype.makeRef = function (obj) {
54 60 this.initializeOnce();
55 function functionRefDispatch(message) { 61 // TODO(vsm): Cache refs for each obj.
56 var id = message[0]; 62 var ref = this.name + '-' + this.nextId();
57 var args = message[1]; 63 this.map[ref] = obj;
58 var f = functionRefMap[id];
59 // TODO: Should we capture this automatically?
60 return f.apply(null, args);
61 }
62
63 var functionRefPort = null;
64
65 function makeFunctionRef(f) {
66 if (functionRefPort == null) {
67 var port = new ReceivePortSync();
68 port.receive(functionRefDispatch);
69 functionRefPort = port.toSendPort();
70 }
71 var ref = 'func-ref-' + (nextFunctionRefId++);
72 functionRefMap[ref] = f;
73 return ref; 64 return ref;
74 } 65 }
75 66
67 RefTable.prototype.initializeOnce = function () {
68 if (!this.initialized) {
69 this.initialize();
70 }
71 this.initialized = true;
72 }
73
74 // Overridable initialization on first use hook.
75 RefTable.prototype.initialize = function () {}
76
77 RefTable.prototype.get = function (ref) {
78 return this.map[ref];
79 }
80
81 function FunctionRefTable() {}
82
83 FunctionRefTable.prototype = new RefTable('func-ref');
84
85 FunctionRefTable.prototype.initialize = function () {
86 var receivePort = new ReceivePortSync();
87 map = this.map;
88 receivePort.receive(function (message) {
89 var id = message[0];
90 var args = message[1];
91 var f = map[id];
92 // TODO(vsm): Should we capture this automatically?
93 return f.apply(null, args);
94 });
95 this.port = receivePort.toSendPort();
96 }
97
98 var functionRefTable = new FunctionRefTable();
99
100 function JSRefTable() {}
101
102 JSRefTable.prototype = new RefTable('js-ref');
103
104 var jsRefTable = new JSRefTable();
105
106 function DartProxy(id) {
107 // TODO(vsm): Set isolate id.
108 this.id = id;
109 }
110
76 function serialize(message) { 111 function serialize(message) {
77 var visited = []; 112 var visited = [];
78 function checkedSerialization(obj, serializer) { 113 function checkedSerialization(obj, serializer) {
79 // Implementation detail: for now use linear search. 114 // Implementation detail: for now use linear search.
80 // Another option is expando, but it may prohibit 115 // Another option is expando, but it may prohibit
81 // VM optimizations (like putting object into slow mode 116 // VM optimizations (like putting object into slow mode
82 // on property deletion.) 117 // on property deletion.)
83 var id = visited.indexOf(obj); 118 var id = visited.indexOf(obj);
84 if (id != -1) return [ 'ref', id ]; 119 if (id != -1) return [ 'ref', id ];
85 var id = visited.length; 120 var id = visited.length;
(...skipping 14 matching lines...) Expand all
100 for (var i = 0; i < message.length; i++) { 135 for (var i = 0; i < message.length; i++) {
101 values[i] = doSerialize(message[i]); 136 values[i] = doSerialize(message[i]);
102 } 137 }
103 return [ 'list', id, values ]; 138 return [ 'list', id, values ];
104 }); 139 });
105 } else if (message instanceof LocalSendPortSync) { 140 } else if (message instanceof LocalSendPortSync) {
106 return [ 'sendport', 'nativejs', message.receivePort.id ]; 141 return [ 'sendport', 'nativejs', message.receivePort.id ];
107 } else if (message instanceof DartSendPortSync) { 142 } else if (message instanceof DartSendPortSync) {
108 return [ 'sendport', 'dart', message.isolateId, message.portId ]; 143 return [ 'sendport', 'dart', message.isolateId, message.portId ];
109 } else if (message instanceof Function) { 144 } else if (message instanceof Function) {
110 return [ 'funcref', makeFunctionRef(message), 145 return [ 'funcref', functionRefTable.makeRef(message),
111 doSerialize(functionRefPort) ]; 146 doSerialize(functionRefTable.port) ];
147 } else if (message instanceof DartProxy) {
148 return [ 'objref', 'dart', message.id ];
149 } else if (message.__proto__ != {}.__proto__) {
150 // TODO(vsm): Is the above portable and what we want?
151 // Proxy non-map Objects.
152 return [ 'objref', 'nativejs', jsRefTable.makeRef(message) ];
112 } else { 153 } else {
113 return checkedSerialization(message, function(id) { 154 return checkedSerialization(message, function(id) {
114 var keys = Object.getOwnPropertyNames(message); 155 var keys = Object.getOwnPropertyNames(message);
115 var values = new Array(keys.length); 156 var values = new Array(keys.length);
116 for (var i = 0; i < keys.length; i++) { 157 for (var i = 0; i < keys.length; i++) {
117 values[i] = doSerialize(message[keys[i]]); 158 values[i] = doSerialize(message[keys[i]]);
118 } 159 }
119 return [ 'map', id, keys, values ]; 160 return [ 'map', id, keys, values ];
120 }); 161 });
121 } 162 }
122 } 163 }
123 return doSerialize(message); 164 return doSerialize(message);
124 } 165 }
125 166
126 function deserialize(message) { 167 function deserialize(message) {
127 return deserializeHelper(message); 168 return deserializeHelper(message);
128 } 169 }
129 170
130 function deserializeHelper(x) { 171 function deserializeHelper(message) {
131 if (x == null || 172 if (message == null ||
132 typeof(x) == 'string' || 173 typeof(message) == 'string' ||
133 typeof(x) == 'number' || 174 typeof(message) == 'number' ||
134 typeof(x) == 'boolean') { 175 typeof(message) == 'boolean') {
135 return x; 176 return message;
136 } 177 }
137 switch (x[0]) { 178 switch (message[0]) {
138 case 'map': return deserializeMap(x); 179 case 'map': return deserializeMap(message);
139 case 'sendport': return deserializeSendPort(x); 180 case 'sendport': return deserializeSendPort(message);
140 case 'list': return deserializeList(x); 181 case 'list': return deserializeList(message);
141 case 'funcref': return deserializeFunction(x); 182 case 'funcref': return deserializeFunction(message);
183 case 'objref': return deserializeProxy(message);
142 default: throw 'unimplemented'; 184 default: throw 'unimplemented';
143 } 185 }
144 } 186 }
145 187
146 function deserializeMap(x) { 188 function deserializeMap(message) {
147 var result = { }; 189 var result = { };
148 var id = x[1]; 190 var id = message[1];
149 var keys = x[2]; 191 var keys = message[2];
150 var values = x[3]; 192 var values = message[3];
151 for (var i = 0, length = keys.length; i < length; i++) { 193 for (var i = 0, length = keys.length; i < length; i++) {
152 var key = deserializeHelper(keys[i]); 194 var key = deserializeHelper(keys[i]);
153 var value = deserializeHelper(values[i]); 195 var value = deserializeHelper(values[i]);
154 result[key] = value; 196 result[key] = value;
155 } 197 }
156 return result; 198 return result;
157 } 199 }
158 200
159 function deserializeSendPort(x) { 201 function deserializeSendPort(message) {
160 var tag = x[1]; 202 var tag = message[1];
161 switch (tag) { 203 switch (tag) {
162 case 'nativejs': 204 case 'nativejs':
163 var id = x[2]; 205 var id = message[2];
164 return new LocalSendPortSync(ReceivePortSync.map[id]); 206 return new LocalSendPortSync(ReceivePortSync.map[id]);
165 case 'dart': 207 case 'dart':
166 var isolateId = x[2]; 208 var isolateId = message[2];
167 var portId = x[3]; 209 var portId = message[3];
168 return new DartSendPortSync(isolateId, portId); 210 return new DartSendPortSync(isolateId, portId);
169 default: 211 default:
170 throw 'Illegal SendPortSync type: $tag'; 212 throw 'Illegal SendPortSync type: $tag';
171 } 213 }
172 } 214 }
173 215
174 function deserializeList(x) { 216 function deserializeList(message) {
175 var values = x[2]; 217 var values = message[2];
176 var length = values.length; 218 var length = values.length;
177 var result = new Array(length); 219 var result = new Array(length);
178 for (var i = 0; i < length; i++) { 220 for (var i = 0; i < length; i++) {
179 result[i] = deserializeHelper(values[i]); 221 result[i] = deserializeHelper(values[i]);
180 } 222 }
181 return result; 223 return result;
182 } 224 }
183 225
184 function deserializeFunction(x) { 226 function deserializeFunction(message) {
185 var ref = x[1]; 227 var ref = message[1];
186 var sendPort = deserializeSendPort(x[2]); 228 var sendPort = deserializeSendPort(message[2]);
187 // Number of arguments is not used as of now 229 // Number of arguments is not used as of now
188 // we cannot find it out for Dart function in pure Dart. 230 // we cannot find it out for Dart function in pure Dart.
189 return _makeFunctionFromRef(ref, sendPort); 231 return _makeFunctionFromRef(ref, sendPort);
190 } 232 }
191 233
234 function deserializeProxy(message) {
235 var tag = message[1];
236 if (tag == 'nativejs') {
237 var id = message[2];
238 return jsRefTable.map[id];
239 } else if (tag == 'dart') {
240 var id = message[2];
241 return new DartProxy(id);
242 }
243 throw 'Illegal proxy object: ' + message;
244 }
245
192 window.registerPort = function(name, port) { 246 window.registerPort = function(name, port) {
193 var stringified = JSON.stringify(serialize(port)); 247 var stringified = JSON.stringify(serialize(port));
194 window.localStorage['dart-port:' + name] = stringified; 248 window.localStorage['dart-port:' + name] = stringified;
195 }; 249 };
196 250
197 window.lookupPort = function(name) { 251 window.lookupPort = function(name) {
198 var stringified = window.localStorage['dart-port:' + name]; 252 var stringified = window.localStorage['dart-port:' + name];
199 return deserialize(JSON.parse(stringified)); 253 return deserialize(JSON.parse(stringified));
200 }; 254 };
201 255
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 var listener = function (e) { 321 var listener = function (e) {
268 result = JSON.parse(e.data); 322 result = JSON.parse(e.data);
269 }; 323 };
270 window.addEventListener(source, listener, false); 324 window.addEventListener(source, listener, false);
271 dispatchEvent(target, [source, serialized]); 325 dispatchEvent(target, [source, serialized]);
272 window.removeEventListener(source, listener, false); 326 window.removeEventListener(source, listener, false);
273 return deserialize(result); 327 return deserialize(result);
274 } 328 }
275 329
276 // Leaking implementation. 330 // Leaking implementation.
277 // TODO: provide proper, backend-specific implementation. 331 // TODO(vsm): provide proper, backend-specific implementation.
278 function _makeFunctionFromRef(ref, sendPort) { 332 function _makeFunctionFromRef(ref, sendPort) {
279 return function() { 333 return function() {
280 return sendPort.callSync([ref, Array.prototype.slice.call(arguments)]); 334 return sendPort.callSync([ref, Array.prototype.slice.call(arguments)]);
281 } 335 }
282 } 336 }
283 })(); 337 })();
OLDNEW
« no previous file with comments | « no previous file | lib/html/dart2js/html_dart2js.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698