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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | lib/html/dart2js/html_dart2js.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/dart.js
diff --git a/client/dart.js b/client/dart.js
index 711aeee5702478258e964aad47a196e109154701..722cb4bdf16f4187b0fa0d59fddf99a25e25212c 100644
--- a/client/dart.js
+++ b/client/dart.js
@@ -46,31 +46,66 @@ function ReceivePortSync() {
}
(function() {
- // Track proxied functions.
- // TODO: Fix leaks, particularly in dart2js case.
- var functionRefMap = {};
-
- var nextFunctionRefId = 0;
-
- function functionRefDispatch(message) {
- var id = message[0];
- var args = message[1];
- var f = functionRefMap[id];
- // TODO: Should we capture this automatically?
- return f.apply(null, args);
+ function RefTable(name) {
+ // TODO(vsm): Fix leaks, particularly in dart2js case.
+ this.name = name;
+ this.map = {};
+ this.id = 0;
+ this.initialized = false;
+ }
+
+ RefTable.prototype.nextId = function () { return this.id++; }
+
+ RefTable.prototype.makeRef = function (obj) {
+ this.initializeOnce();
+ // TODO(vsm): Cache refs for each obj.
+ var ref = this.name + '-' + this.nextId();
+ this.map[ref] = obj;
+ return ref;
}
- var functionRefPort = null;
-
- function makeFunctionRef(f) {
- if (functionRefPort == null) {
- var port = new ReceivePortSync();
- port.receive(functionRefDispatch);
- functionRefPort = port.toSendPort();
+ RefTable.prototype.initializeOnce = function () {
+ if (!this.initialized) {
+ this.initialize();
}
- var ref = 'func-ref-' + (nextFunctionRefId++);
- functionRefMap[ref] = f;
- return ref;
+ this.initialized = true;
+ }
+
+ // Overridable initialization on first use hook.
+ RefTable.prototype.initialize = function () {}
+
+ RefTable.prototype.get = function (ref) {
+ return this.map[ref];
+ }
+
+ function FunctionRefTable() {}
+
+ FunctionRefTable.prototype = new RefTable('func-ref');
+
+ FunctionRefTable.prototype.initialize = function () {
+ var receivePort = new ReceivePortSync();
+ map = this.map;
+ receivePort.receive(function (message) {
+ var id = message[0];
+ var args = message[1];
+ var f = map[id];
+ // TODO(vsm): Should we capture this automatically?
+ return f.apply(null, args);
+ });
+ this.port = receivePort.toSendPort();
+ }
+
+ var functionRefTable = new FunctionRefTable();
+
+ function JSRefTable() {}
+
+ JSRefTable.prototype = new RefTable('js-ref');
+
+ var jsRefTable = new JSRefTable();
+
+ function DartProxy(id) {
+ // TODO(vsm): Set isolate id.
+ this.id = id;
}
function serialize(message) {
@@ -107,8 +142,14 @@ function ReceivePortSync() {
} else if (message instanceof DartSendPortSync) {
return [ 'sendport', 'dart', message.isolateId, message.portId ];
} else if (message instanceof Function) {
- return [ 'funcref', makeFunctionRef(message),
- doSerialize(functionRefPort) ];
+ return [ 'funcref', functionRefTable.makeRef(message),
+ doSerialize(functionRefTable.port) ];
+ } else if (message instanceof DartProxy) {
+ return [ 'objref', 'dart', message.id ];
+ } else if (message.__proto__ != {}.__proto__) {
+ // TODO(vsm): Is the above portable and what we want?
+ // Proxy non-map Objects.
+ return [ 'objref', 'nativejs', jsRefTable.makeRef(message) ];
} else {
return checkedSerialization(message, function(id) {
var keys = Object.getOwnPropertyNames(message);
@@ -127,27 +168,28 @@ function ReceivePortSync() {
return deserializeHelper(message);
}
- function deserializeHelper(x) {
- if (x == null ||
- typeof(x) == 'string' ||
- typeof(x) == 'number' ||
- typeof(x) == 'boolean') {
- return x;
+ function deserializeHelper(message) {
+ if (message == null ||
+ typeof(message) == 'string' ||
+ typeof(message) == 'number' ||
+ typeof(message) == 'boolean') {
+ return message;
}
- switch (x[0]) {
- case 'map': return deserializeMap(x);
- case 'sendport': return deserializeSendPort(x);
- case 'list': return deserializeList(x);
- case 'funcref': return deserializeFunction(x);
+ switch (message[0]) {
+ case 'map': return deserializeMap(message);
+ case 'sendport': return deserializeSendPort(message);
+ case 'list': return deserializeList(message);
+ case 'funcref': return deserializeFunction(message);
+ case 'objref': return deserializeProxy(message);
default: throw 'unimplemented';
}
}
- function deserializeMap(x) {
+ function deserializeMap(message) {
var result = { };
- var id = x[1];
- var keys = x[2];
- var values = x[3];
+ var id = message[1];
+ var keys = message[2];
+ var values = message[3];
for (var i = 0, length = keys.length; i < length; i++) {
var key = deserializeHelper(keys[i]);
var value = deserializeHelper(values[i]);
@@ -156,23 +198,23 @@ function ReceivePortSync() {
return result;
}
- function deserializeSendPort(x) {
- var tag = x[1];
+ function deserializeSendPort(message) {
+ var tag = message[1];
switch (tag) {
case 'nativejs':
- var id = x[2];
+ var id = message[2];
return new LocalSendPortSync(ReceivePortSync.map[id]);
case 'dart':
- var isolateId = x[2];
- var portId = x[3];
+ var isolateId = message[2];
+ var portId = message[3];
return new DartSendPortSync(isolateId, portId);
default:
throw 'Illegal SendPortSync type: $tag';
}
}
- function deserializeList(x) {
- var values = x[2];
+ function deserializeList(message) {
+ var values = message[2];
var length = values.length;
var result = new Array(length);
for (var i = 0; i < length; i++) {
@@ -181,14 +223,26 @@ function ReceivePortSync() {
return result;
}
- function deserializeFunction(x) {
- var ref = x[1];
- var sendPort = deserializeSendPort(x[2]);
+ function deserializeFunction(message) {
+ var ref = message[1];
+ var sendPort = deserializeSendPort(message[2]);
// Number of arguments is not used as of now
// we cannot find it out for Dart function in pure Dart.
return _makeFunctionFromRef(ref, sendPort);
}
+ function deserializeProxy(message) {
+ var tag = message[1];
+ if (tag == 'nativejs') {
+ var id = message[2];
+ return jsRefTable.map[id];
+ } else if (tag == 'dart') {
+ var id = message[2];
+ return new DartProxy(id);
+ }
+ throw 'Illegal proxy object: ' + message;
+ }
+
window.registerPort = function(name, port) {
var stringified = JSON.stringify(serialize(port));
window.localStorage['dart-port:' + name] = stringified;
@@ -274,7 +328,7 @@ function ReceivePortSync() {
}
// Leaking implementation.
- // TODO: provide proper, backend-specific implementation.
+ // TODO(vsm): provide proper, backend-specific implementation.
function _makeFunctionFromRef(ref, sendPort) {
return function() {
return sendPort.callSync([ref, Array.prototype.slice.call(arguments)]);
« 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