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

Unified Diff: client/dart.js

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 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 722cb4bdf16f4187b0fa0d59fddf99a25e25212c..6d80aa4fc3a24617d63c0daa383369f31538278e 100644
--- a/client/dart.js
+++ b/client/dart.js
@@ -46,68 +46,12 @@ function ReceivePortSync() {
}
(function() {
- 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;
- }
-
- RefTable.prototype.initializeOnce = function () {
- if (!this.initialized) {
- this.initialize();
- }
- 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;
- }
-
+ // Serialize:
+ // - primitives / null: unchanged
+ // - lists: [ 'list', id, list of recursively serialized elements ]
+ // - maps: [ 'map', id, map of keys and recursively serialized values ]
+ // - functions: [ 'funcref', function-proxy-id, function-proxy-send-port ]
+ // - objects: [ 'objref', object-proxy-id, object-proxy-send-port ]
function serialize(message) {
var visited = [];
function checkedSerialization(obj, serializer) {
@@ -143,13 +87,14 @@ function ReceivePortSync() {
return [ 'sendport', 'dart', message.isolateId, message.portId ];
} else if (message instanceof Function) {
return [ 'funcref', functionRefTable.makeRef(message),
- doSerialize(functionRefTable.port) ];
+ doSerialize(functionRefTable.sendPort) ];
} else if (message instanceof DartProxy) {
- return [ 'objref', 'dart', message.id ];
+ return [ 'objref', message._id, doSerialize(message._port) ];
} 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) ];
+ return [ 'objref', jsRefTable.makeRef(message),
+ doSerialize(jsRefTable.sendPort) ];
} else {
return checkedSerialization(message, function(id) {
var keys = Object.getOwnPropertyNames(message);
@@ -232,13 +177,12 @@ function ReceivePortSync() {
}
function deserializeProxy(message) {
- var tag = message[1];
- if (tag == 'nativejs') {
- var id = message[2];
+ var id = message[1];
+ var port = deserializeSendPort(message[2]);
+ if (port instanceof LocalSendPortSync) {
return jsRefTable.map[id];
- } else if (tag == 'dart') {
- var id = message[2];
- return new DartProxy(id);
+ } else if (port instanceof DartSendPortSync) {
+ return new DartProxy(port, id);
}
throw 'Illegal proxy object: ' + message;
}
@@ -327,6 +271,104 @@ function ReceivePortSync() {
return deserialize(result);
}
+ // Proxy support
+
+ function RefTable(name) {
+ // TODO(vsm): Fix leaks, particularly in dart2js case.
+ this.name = name;
+ this.map = {};
+ this.id = 0;
+ this.initialized = false;
+ this.port = new ReceivePortSync();
+ this.sendPort = this.port.toSendPort();
+ }
+
+ 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;
+ }
+
+ RefTable.prototype.initializeOnce = function () {
+ if (!this.initialized) {
+ this.initialize();
+ }
+ 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 () {
+ map = this.map;
+ this.port.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);
+ });
+ }
+
+ var functionRefTable = new FunctionRefTable();
+
+ function JSRefTable() {}
+
+ JSRefTable.prototype = new RefTable('js-ref');
+
+ JSRefTable.prototype.initialize = function () {
+ map = this.map;
+ this.port.receive(function (message) {
+ // TODO(vsm): Support a mechanism to register a handler here.
+ var receiver = map[message[0]];
+ var method = message[1];
+ var args = message[2];
+ if (method.indexOf("get:") == 0) {
+ // Getter.
+ var field = method.substring(4);
+ if (field in receiver && args.length == 0) {
+ return [ 'return', receiver[field] ];
+ }
+ } else if (method.indexOf("set:") == 0) {
+ // Setter.
+ var field = method.substring(4);
+ if (field in receiver && args.length == 1) {
+ return [ 'return', receiver[field] = args[0] ];
+ }
+ } else {
+ var f = receiver[method];
+ if (f) {
+ try {
+ var result = f.apply(receiver, args);
+ return [ 'return', result ];
+ } catch (e) {
+ return [ 'exception', e ];
+ }
+ }
+ }
+ return [ 'none' ];
+ });
+ }
+
+ var jsRefTable = new JSRefTable();
+
+ function DartProxy(port, id) {
+ this._port = port;
+ this._id = id;
+ }
+
// Leaking implementation.
// TODO(vsm): provide proper, backend-specific implementation.
function _makeFunctionFromRef(ref, sendPort) {
« 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