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

Side by Side Diff: client/dart.js

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 | « 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 // Serialize: 49 // Serialize the following types as follows:
50 // - primitives / null: unchanged 50 // - primitives / null: unchanged
51 // - lists: [ 'list', id, list of recursively serialized elements ] 51 // - lists: [ 'list', internal id, list of recursively serialized elements ]
52 // - maps: [ 'map', id, map of keys and recursively serialized values ] 52 // - maps: [ 'map', internal id, map of keys and recursively serialized value s ]
53 // - functions: [ 'funcref', function-proxy-id, function-proxy-send-port ] 53 // - send ports: [ 'sendport', type, isolate id, port id ]
54 // - objects: [ 'objref', object-proxy-id, object-proxy-send-port ] 54 //
55 // Note, internal id's are for cycle detection.
55 function serialize(message) { 56 function serialize(message) {
56 var visited = []; 57 var visited = [];
57 function checkedSerialization(obj, serializer) { 58 function checkedSerialization(obj, serializer) {
58 // Implementation detail: for now use linear search. 59 // Implementation detail: for now use linear search.
59 // Another option is expando, but it may prohibit 60 // Another option is expando, but it may prohibit
60 // VM optimizations (like putting object into slow mode 61 // VM optimizations (like putting object into slow mode
61 // on property deletion.) 62 // on property deletion.)
62 var id = visited.indexOf(obj); 63 var id = visited.indexOf(obj);
63 if (id != -1) return [ 'ref', id ]; 64 if (id != -1) return [ 'ref', id ];
64 var id = visited.length; 65 var id = visited.length;
(...skipping 13 matching lines...) Expand all
78 var values = new Array(message.length); 79 var values = new Array(message.length);
79 for (var i = 0; i < message.length; i++) { 80 for (var i = 0; i < message.length; i++) {
80 values[i] = doSerialize(message[i]); 81 values[i] = doSerialize(message[i]);
81 } 82 }
82 return [ 'list', id, values ]; 83 return [ 'list', id, values ];
83 }); 84 });
84 } else if (message instanceof LocalSendPortSync) { 85 } else if (message instanceof LocalSendPortSync) {
85 return [ 'sendport', 'nativejs', message.receivePort.id ]; 86 return [ 'sendport', 'nativejs', message.receivePort.id ];
86 } else if (message instanceof DartSendPortSync) { 87 } else if (message instanceof DartSendPortSync) {
87 return [ 'sendport', 'dart', message.isolateId, message.portId ]; 88 return [ 'sendport', 'dart', message.isolateId, message.portId ];
88 } else if (message instanceof Function) {
89 // In case we are reserializing a previously serialized
90 // function, use a cached value.
91 if (message._dart_serialized) return message._dart_serialized;
92 message._dart_serialized = [ 'funcref',
93 functionRefTable.makeRef(message),
94 doSerialize(functionRefTable.sendPort) ];
95 return message._dart_serialized;
96 } else if (message instanceof HTMLElement) {
97 var id = elementId(message);
98 // Verify that the element is connected to the document.
99 // Otherwise, we will not be able to find it on the other side.
100 getElement(id);
101 return [ 'element', id ];
102 } else if (message instanceof DartProxy) {
103 return [ 'objref', message._id, doSerialize(message._port) ];
104 } else if (message.__proto__ != {}.__proto__) {
105 // TODO(vsm): Is the above portable and what we want?
106 // Proxy non-map Objects.
107 return [ 'objref', jsRefTable.makeRef(message),
108 doSerialize(jsRefTable.sendPort) ];
109 } else { 89 } else {
110 return checkedSerialization(message, function(id) { 90 return checkedSerialization(message, function(id) {
111 var keys = Object.getOwnPropertyNames(message); 91 var keys = Object.getOwnPropertyNames(message);
112 var values = new Array(keys.length); 92 var values = new Array(keys.length);
113 for (var i = 0; i < keys.length; i++) { 93 for (var i = 0; i < keys.length; i++) {
114 values[i] = doSerialize(message[keys[i]]); 94 values[i] = doSerialize(message[keys[i]]);
115 } 95 }
116 return [ 'map', id, keys, values ]; 96 return [ 'map', id, keys, values ];
117 }); 97 });
118 } 98 }
119 } 99 }
120 return doSerialize(message); 100 return doSerialize(message);
121 } 101 }
122 102
123 function deserialize(message) { 103 function deserialize(message) {
124 return deserializeHelper(message); 104 return deserializeHelper(message);
125 } 105 }
126 106
127 function deserializeHelper(message) { 107 function deserializeHelper(message) {
128 if (message == null || 108 if (message == null ||
129 typeof(message) == 'string' || 109 typeof(message) == 'string' ||
130 typeof(message) == 'number' || 110 typeof(message) == 'number' ||
131 typeof(message) == 'boolean') { 111 typeof(message) == 'boolean') {
132 return message; 112 return message;
133 } 113 }
134 switch (message[0]) { 114 switch (message[0]) {
135 case 'map': return deserializeMap(message); 115 case 'map': return deserializeMap(message);
136 case 'sendport': return deserializeSendPort(message); 116 case 'sendport': return deserializeSendPort(message);
137 case 'list': return deserializeList(message); 117 case 'list': return deserializeList(message);
138 case 'funcref': return deserializeFunction(message);
139 case 'objref': return deserializeProxy(message);
140 case 'element': return deserializeElement(message);
141 default: throw 'unimplemented'; 118 default: throw 'unimplemented';
142 } 119 }
143 } 120 }
144 121
145 function deserializeMap(message) { 122 function deserializeMap(message) {
146 var result = { }; 123 var result = { };
147 var id = message[1]; 124 var id = message[1];
148 var keys = message[2]; 125 var keys = message[2];
149 var values = message[3]; 126 var values = message[3];
150 for (var i = 0, length = keys.length; i < length; i++) { 127 for (var i = 0, length = keys.length; i < length; i++) {
(...skipping 22 matching lines...) Expand all
173 function deserializeList(message) { 150 function deserializeList(message) {
174 var values = message[2]; 151 var values = message[2];
175 var length = values.length; 152 var length = values.length;
176 var result = new Array(length); 153 var result = new Array(length);
177 for (var i = 0; i < length; i++) { 154 for (var i = 0; i < length; i++) {
178 result[i] = deserializeHelper(values[i]); 155 result[i] = deserializeHelper(values[i]);
179 } 156 }
180 return result; 157 return result;
181 } 158 }
182 159
183 function deserializeFunction(message) {
184 var ref = message[1];
185 var sendPort = deserializeSendPort(message[2]);
186 // Number of arguments is not used as of now
187 // we cannot find it out for Dart function in pure Dart.
188 var result = _makeFunctionFromRef(ref, sendPort);
189 // Cache the serialized form in case we resend this.
190 result._dart_serialized = message;
191 return result;
192 }
193
194 function deserializeProxy(message) {
195 var id = message[1];
196 var port = deserializeSendPort(message[2]);
197 if (port instanceof LocalSendPortSync) {
198 return jsRefTable.map[id];
199 } else if (port instanceof DartSendPortSync) {
200 return new DartProxy(port, id);
201 }
202 throw 'Illegal proxy object: ' + message;
203 }
204
205 function deserializeElement(message) {
206 var id = message[1];
207 return getElement(id);
208 }
209
210 window.registerPort = function(name, port) { 160 window.registerPort = function(name, port) {
211 var stringified = JSON.stringify(serialize(port)); 161 var stringified = JSON.stringify(serialize(port));
212 window.localStorage['dart-port:' + name] = stringified; 162 window.localStorage['dart-port:' + name] = stringified;
213 }; 163 };
214 164
215 window.lookupPort = function(name) { 165 window.lookupPort = function(name) {
216 var stringified = window.localStorage['dart-port:' + name]; 166 var stringified = window.localStorage['dart-port:' + name];
217 return deserialize(JSON.parse(stringified)); 167 return deserialize(JSON.parse(stringified));
218 }; 168 };
219 169
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 var source = target + '-result'; 233 var source = target + '-result';
284 var result = null; 234 var result = null;
285 var listener = function (e) { 235 var listener = function (e) {
286 result = JSON.parse(e.data); 236 result = JSON.parse(e.data);
287 }; 237 };
288 window.addEventListener(source, listener, false); 238 window.addEventListener(source, listener, false);
289 dispatchEvent(target, [source, serialized]); 239 dispatchEvent(target, [source, serialized]);
290 window.removeEventListener(source, listener, false); 240 window.removeEventListener(source, listener, false);
291 return deserialize(result); 241 return deserialize(result);
292 } 242 }
293
294 // Proxy support
295
296 function RefTable(name) {
297 // TODO(vsm): Fix leaks, particularly in dart2js case.
298 this.name = name;
299 this.map = {};
300 this.id = 0;
301 this.initialized = false;
302 this.port = new ReceivePortSync();
303 this.sendPort = this.port.toSendPort();
304 }
305
306 RefTable.prototype.nextId = function () { return this.id++; }
307
308 RefTable.prototype.makeRef = function (obj) {
309 this.initializeOnce();
310 // TODO(vsm): Cache refs for each obj.
311 var ref = this.name + '-' + this.nextId();
312 this.map[ref] = obj;
313 return ref;
314 }
315
316 RefTable.prototype.initializeOnce = function () {
317 if (!this.initialized) {
318 this.initialize();
319 }
320 this.initialized = true;
321 }
322
323 // Overridable initialization on first use hook.
324 RefTable.prototype.initialize = function () {}
325
326 RefTable.prototype.get = function (ref) {
327 return this.map[ref];
328 }
329
330 function FunctionRefTable() {}
331
332 FunctionRefTable.prototype = new RefTable('func-ref');
333
334 FunctionRefTable.prototype.initialize = function () {
335 var map = this.map;
336 this.port.receive(function (message) {
337 var id = message[0];
338 var args = message[1];
339 var f = map[id];
340 // TODO(vsm): Should we capture this automatically?
341 return f.apply(null, args);
342 });
343 }
344
345 var functionRefTable = new FunctionRefTable();
346
347 function JSRefTable() {}
348
349 JSRefTable.prototype = new RefTable('js-ref');
350
351 JSRefTable.prototype.initialize = function () {
352 var map = this.map;
353 this.port.receive(function (message) {
354 // TODO(vsm): Support a mechanism to register a handler here.
355 var receiver = map[message[0]];
356 var method = message[1];
357 var args = message[2];
358 if (method.indexOf("get:") == 0) {
359 // Getter.
360 var field = method.substring(4);
361 if (field in receiver && args.length == 0) {
362 return [ 'return', receiver[field] ];
363 }
364 } else if (method.indexOf("set:") == 0) {
365 // Setter.
366 var field = method.substring(4);
367 if (field in receiver && args.length == 1) {
368 return [ 'return', receiver[field] = args[0] ];
369 }
370 } else {
371 var f = receiver[method];
372 if (f) {
373 try {
374 var result = f.apply(receiver, args);
375 return [ 'return', result ];
376 } catch (e) {
377 return [ 'exception', e ];
378 }
379 }
380 }
381 return [ 'none' ];
382 });
383 }
384
385 var jsRefTable = new JSRefTable();
386
387 function DartProxy(port, id) {
388 this._port = port;
389 this._id = id;
390 }
391
392 // Leaking implementation.
393 // TODO(vsm): provide proper, backend-specific implementation.
394 function _makeFunctionFromRef(ref, sendPort) {
395 // If the sendPort is local, just return the underlying function.
396 // Otherwise, create a new function that forwards to the remote
397 // port.
398 if (sendPort instanceof LocalSendPortSync) {
399 return functionRefTable.map[ref];
400 }
401 return function() {
402 return sendPort.callSync([ref, Array.prototype.slice.call(arguments)]);
403 };
404 }
405
406 var localNextElementId = 0;
407 var _DART_ID = 'data-dart_id';
408
409 function elementId(e) {
410 if (e.hasAttribute(_DART_ID)) return e.getAttribute(_DART_ID);
411 var id = (localNextElementId++).toString();
412 e.setAttribute(_DART_ID, id);
413 return id;
414 }
415
416 function getElement(id) {
417 var list = document.querySelectorAll('[' + _DART_ID + '="' + id + '"]');
418
419 if (list.length > 1) throw 'Non unique ID: ' + id;
420 if (list.length == 0) {
421 throw 'Element must be attached to the document: ' + id;
422 }
423 return list[0];
424 }
425 })(); 243 })();
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