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

Side by Side Diff: lib/dart_interop.js

Issue 12457030: [js-interop] Fix function binding and avoid noSuchMethod when using map notation (Closed) Base URL: https://github.com/dart-lang/js-interop.git@master
Patch Set: Fix for constructors plus cleanup Created 7 years, 8 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
« no previous file with comments | « no previous file | lib/js.dart » ('j') | lib/js.dart » ('J')
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 // THIS FILE IS AUTO GENERATED. PLEASE DO NOT EDIT. 5 // THIS FILE IS AUTO GENERATED. PLEASE DO NOT EDIT.
6 6
7 // TODO(vsm): Move this file once we determine where assets should go. See 7 // TODO(vsm): Move this file once we determine where assets should go. See
8 // http://dartbug.com/6101. 8 // http://dartbug.com/6101.
9 9
10 (function() { 10 (function() {
11 // Proxy support for js.dart. 11 // Proxy support for js.dart.
12 12
13 var globalContext = window; 13 var globalContext = window;
14 14
15 // Support for binding the receiver (this) in proxied functions.
16 function bindIfFunction(f, _this) {
17 if (typeof(f) != "function") {
18 return f;
19 } else {
20 return new BoundFunction(_this, f);
21 }
22 }
23
24 function unbind(obj) {
25 if (obj instanceof BoundFunction) {
26 return obj.object;
27 } else {
28 return obj;
29 }
30 }
31
32 function getBoundThis(obj) {
33 if (obj instanceof BoundFunction) {
34 return obj._this;
35 } else {
36 return globalContext;
37 }
38 }
39
40 function BoundFunction(_this, object) {
41 this._this = _this;
42 this.object = object;
43 }
44
15 // Table for local objects and functions that are proxied. 45 // Table for local objects and functions that are proxied.
16 function ProxiedObjectTable() { 46 function ProxiedObjectTable() {
17 // Name for debugging. 47 // Name for debugging.
18 this.name = 'js-ref'; 48 this.name = 'js-ref';
19 49
20 // Table from IDs to JS objects. 50 // Table from IDs to JS objects.
21 this.map = {}; 51 this.map = {};
22 52
23 // Generator for new IDs. 53 // Generator for new IDs.
24 this._nextId = 0; 54 this._nextId = 0;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 } 150 }
121 151
122 ProxiedObjectTable.prototype._initialize = function () { 152 ProxiedObjectTable.prototype._initialize = function () {
123 // Configure this table's port to forward methods, getters, and setters 153 // Configure this table's port to forward methods, getters, and setters
124 // from the remote proxy to the local object. 154 // from the remote proxy to the local object.
125 var table = this; 155 var table = this;
126 156
127 this.port.receive(function (message) { 157 this.port.receive(function (message) {
128 // TODO(vsm): Support a mechanism to register a handler here. 158 // TODO(vsm): Support a mechanism to register a handler here.
129 try { 159 try {
130 var receiver = table.get(message[0]); 160 var object = table.get(message[0]);
161 var receiver = unbind(object);
131 var member = message[1]; 162 var member = message[1];
132 var kind = message[2]; 163 var kind = message[2];
133 var args = message[3].map(deserialize); 164 var args = message[3].map(deserialize);
134 if (kind == 'get') { 165 if (kind == 'get') {
135 // Getter. 166 // Getter.
136 var field = member; 167 var field = member;
137 if (field in receiver && args.length == 0) { 168 if (field in receiver && args.length == 0) {
138 return [ 'return', serialize(receiver[field]) ]; 169 var result = bindIfFunction(receiver[field], receiver);
170 return [ 'return', serialize(result) ];
139 } 171 }
140 } else if (kind == 'set') { 172 } else if (kind == 'set') {
141 // Setter. 173 // Setter.
142 var field = member; 174 var field = member;
143 if (args.length == 1) { 175 if (args.length == 1) {
144 return [ 'return', serialize(receiver[field] = args[0]) ]; 176 return [ 'return', serialize(receiver[field] = args[0]) ];
145 } 177 }
146 } else if (kind == 'apply') { 178 } else if (kind == 'apply') {
147 // Direct function invocation. 179 // Direct function invocation.
148 // TODO(vsm): Should we capture _this_ automatically? 180 var _this = getBoundThis(object);
149 return [ 'return', serialize(receiver.apply(null, args)) ]; 181 return [ 'return', serialize(receiver.apply(_this, args)) ];
150 } else if (member == '[]' && args.length == 1) { 182 } else if (member == '[]' && args.length == 1) {
151 // Index getter. 183 // Index getter.
152 return [ 'return', serialize(receiver[args[0]]) ]; 184 var result = bindIfFunction(receiver[args[0]], receiver);
185 return [ 'return', serialize(result) ];
153 } else if (member == '[]=' && args.length == 2) { 186 } else if (member == '[]=' && args.length == 2) {
154 // Index setter. 187 // Index setter.
155 return [ 'return', serialize(receiver[args[0]] = args[1]) ]; 188 return [ 'return', serialize(receiver[args[0]] = args[1]) ];
156 } else { 189 } else {
190 // Member function invocation.
157 var f = receiver[member]; 191 var f = receiver[member];
158 if (f) { 192 if (f) {
159 var result = f.apply(receiver, args); 193 var result = f.apply(receiver, args);
160 return [ 'return', serialize(result) ]; 194 return [ 'return', serialize(result) ];
161 } 195 }
162 } 196 }
163 return [ 'none' ]; 197 return [ 'none' ];
164 } catch (e) { 198 } catch (e) {
165 return [ 'throws', e.toString() ]; 199 return [ 'throws', e.toString() ];
166 } 200 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 typeof(message) == 'number' || 303 typeof(message) == 'number' ||
270 typeof(message) == 'boolean') { 304 typeof(message) == 'boolean') {
271 // Primitives are passed directly through. 305 // Primitives are passed directly through.
272 return message; 306 return message;
273 } else if (message instanceof SendPortSync) { 307 } else if (message instanceof SendPortSync) {
274 // Non-proxied objects are serialized. 308 // Non-proxied objects are serialized.
275 return message; 309 return message;
276 } else if (message instanceof Element && 310 } else if (message instanceof Element &&
277 (message.ownerDocument == null || message.ownerDocument == document)) { 311 (message.ownerDocument == null || message.ownerDocument == document)) {
278 return [ 'domref', serializeElement(message) ]; 312 return [ 'domref', serializeElement(message) ];
313 } else if (message instanceof BoundFunction &&
314 typeof(message.object) == 'function') {
315 // Local function proxy.
316 return [ 'funcref',
317 proxiedObjectTable.add(message),
318 proxiedObjectTable.sendPort ];
279 } else if (typeof(message) == 'function') { 319 } else if (typeof(message) == 'function') {
280 if ('_dart_id' in message) { 320 if ('_dart_id' in message) {
281 // Remote function proxy. 321 // Remote function proxy.
282 var remoteId = message._dart_id; 322 var remoteId = message._dart_id;
283 var remoteSendPort = message._dart_port; 323 var remoteSendPort = message._dart_port;
284 return [ 'funcref', remoteId, remoteSendPort ]; 324 return [ 'funcref', remoteId, remoteSendPort ];
285 } else { 325 } else {
286 // Local function proxy. 326 // Local function proxy.
287 return [ 'funcref', 327 return [ 'funcref',
288 proxiedObjectTable.add(message), 328 proxiedObjectTable.add(message),
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 } else { 399 } else {
360 // Remote object. 400 // Remote object.
361 return new DartProxy(id, port); 401 return new DartProxy(id, port);
362 } 402 }
363 } 403 }
364 404
365 // Remote handler to construct a new JavaScript object given its 405 // Remote handler to construct a new JavaScript object given its
366 // serialized constructor and arguments. 406 // serialized constructor and arguments.
367 function construct(args) { 407 function construct(args) {
368 args = args.map(deserialize); 408 args = args.map(deserialize);
369 var constructor = args[0]; 409 var constructor = unbind(args[0]);
370 args = Array.prototype.slice.call(args, 1); 410 args = Array.prototype.slice.call(args, 1);
371 411
372 // Until 10 args, the 'new' operator is used. With more arguments we use a 412 // Until 10 args, the 'new' operator is used. With more arguments we use a
373 // generic way that may not work, particulary when the constructor does not 413 // generic way that may not work, particulary when the constructor does not
374 // have an "apply" method. 414 // have an "apply" method.
375 var ret = null; 415 var ret = null;
376 if (args.length === 0) { 416 if (args.length === 0) {
377 ret = new constructor(); 417 ret = new constructor();
378 } else if (args.length === 1) { 418 } else if (args.length === 1) {
379 ret = new constructor(args[0]); 419 ret = new constructor(args[0]);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 ' (out of ' + total + ' ever allocated).'; 468 ' (out of ' + total + ' ever allocated).';
429 } 469 }
430 470
431 // Return true if two JavaScript proxies are equal (==). 471 // Return true if two JavaScript proxies are equal (==).
432 function proxyEquals(args) { 472 function proxyEquals(args) {
433 return deserialize(args[0]) == deserialize(args[1]); 473 return deserialize(args[0]) == deserialize(args[1]);
434 } 474 }
435 475
436 // Return true if a JavaScript proxy is instance of a given type (instanceof). 476 // Return true if a JavaScript proxy is instance of a given type (instanceof).
437 function proxyInstanceof(args) { 477 function proxyInstanceof(args) {
438 return deserialize(args[0]) instanceof deserialize(args[1]); 478 var obj = unbind(deserialize(args[0]));
479 var type = unbind(deserialize(args[1]));
480 return obj instanceof type;
439 } 481 }
440 482
441 // Return true if a JavaScript proxy is instance of a given type (instanceof). 483 // Return true if a JavaScript proxy is instance of a given type (instanceof).
442 function proxyDeleteProperty(args) { 484 function proxyDeleteProperty(args) {
443 delete deserialize(args[0])[deserialize(args[1])]; 485 var obj = unbind(deserialize(args[0]));
486 var member = unbind(deserialize(args[1]));
487 delete obj[member];
444 } 488 }
445 489
446 function proxyConvert(args) { 490 function proxyConvert(args) {
447 return serialize(deserializeDataTree(args)); 491 return serialize(deserializeDataTree(args));
448 } 492 }
449 493
450 function deserializeDataTree(data) { 494 function deserializeDataTree(data) {
451 var type = data[0]; 495 var type = data[0];
452 var value = data[1]; 496 var value = data[1];
453 if (type === 'map') { 497 if (type === 'map') {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 if (data[0] == "objref") return proxiedObjectTable.globalize(data[1]); 561 if (data[0] == "objref") return proxiedObjectTable.globalize(data[1]);
518 // TODO(vsm): Do we ever need to globalize functions? 562 // TODO(vsm): Do we ever need to globalize functions?
519 throw 'Illegal type: ' + data[0]; 563 throw 'Illegal type: ' + data[0];
520 }); 564 });
521 makeGlobalPort('dart-js-invalidate', function(data) { 565 makeGlobalPort('dart-js-invalidate', function(data) {
522 if (data[0] == "objref") return proxiedObjectTable.invalidate(data[1]); 566 if (data[0] == "objref") return proxiedObjectTable.invalidate(data[1]);
523 // TODO(vsm): Do we ever need to globalize functions? 567 // TODO(vsm): Do we ever need to globalize functions?
524 throw 'Illegal type: ' + data[0]; 568 throw 'Illegal type: ' + data[0];
525 }); 569 });
526 })(); 570 })();
OLDNEW
« no previous file with comments | « no previous file | lib/js.dart » ('j') | lib/js.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698