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

Side by Side Diff: sdk/lib/js/dart2js/js_dart2js.dart

Issue 1152673003: dart:js - speed up constructor calls with few arguments. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 7 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 | no next file » | 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 /** 5 /**
6 * Support for interoperating with JavaScript. 6 * Support for interoperating with JavaScript.
7 * 7 *
8 * This library provides access to JavaScript objects from Dart, allowing 8 * This library provides access to JavaScript objects from Dart, allowing
9 * Dart code to get and set properties, and call methods of JavaScript objects 9 * Dart code to get and set properties, and call methods of JavaScript objects
10 * and invoke JavaScript functions. The library takes care of converting 10 * and invoke JavaScript functions. The library takes care of converting
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 134
135 /** 135 /**
136 * Constructs a new JavaScript object from [constructor] and returns a proxy 136 * Constructs a new JavaScript object from [constructor] and returns a proxy
137 * to it. 137 * to it.
138 */ 138 */
139 factory JsObject(JsFunction constructor, [List arguments]) { 139 factory JsObject(JsFunction constructor, [List arguments]) {
140 var constr = _convertToJS(constructor); 140 var constr = _convertToJS(constructor);
141 if (arguments == null) { 141 if (arguments == null) {
142 return _wrapToDart(JS('', 'new #()', constr)); 142 return _wrapToDart(JS('', 'new #()', constr));
143 } 143 }
144
145 if (JS('bool', '# instanceof Array', arguments)) {
146 int argumentCount = JS('int', '#.length', arguments);
147 switch (argumentCount) {
148 case 0:
149 return _wrapToDart(JS('', 'new #()', constr));
150
151 case 1:
152 var arg0 = _convertToJS(JS('', '#[0]', arguments));
153 return _wrapToDart(JS('', 'new #(#)', constr, arg0));
154
155 case 2:
156 var arg0 = _convertToJS(JS('', '#[0]', arguments));
157 var arg1 = _convertToJS(JS('', '#[1]', arguments));
158 return _wrapToDart(JS('', 'new #(#, #)', constr, arg0, arg1));
Siggi Cherem (dart-lang) 2015/05/26 16:35:18 any reason why not write these 3 lines as: return
sra1 2015/05/26 17:58:58 Not really, but the expression gets big and any au
159
160 case 3:
161 var arg0 = _convertToJS(JS('', '#[0]', arguments));
162 var arg1 = _convertToJS(JS('', '#[1]', arguments));
163 var arg2 = _convertToJS(JS('', '#[2]', arguments));
164 return _wrapToDart(JS('', 'new #(#, #, #)', constr, arg0, arg1, arg2)) ;
Siggi Cherem (dart-lang) 2015/05/26 16:35:18 wrap
sra1 2015/05/26 17:58:59 Done.
165
166 case 4:
167 var arg0 = _convertToJS(JS('', '#[0]', arguments));
168 var arg1 = _convertToJS(JS('', '#[1]', arguments));
169 var arg2 = _convertToJS(JS('', '#[2]', arguments));
170 var arg3 = _convertToJS(JS('', '#[3]', arguments));
171 return _wrapToDart(
172 JS('', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3));
173 }
174 }
175
144 // The following code solves the problem of invoking a JavaScript 176 // The following code solves the problem of invoking a JavaScript
145 // constructor with an unknown number arguments. 177 // constructor with an unknown number arguments.
146 // First bind the constructor to the argument list using bind.apply(). 178 // First bind the constructor to the argument list using bind.apply().
147 // The first argument to bind() is the binding of 'this', so add 'null' to 179 // The first argument to bind() is the binding of 'this', so add 'null' to
148 // the arguments list passed to apply(). 180 // the arguments list passed to apply().
149 // After that, use the JavaScript 'new' operator which overrides any binding 181 // After that, use the JavaScript 'new' operator which overrides any binding
150 // of 'this' with the new instance. 182 // of 'this' with the new instance.
151 var args = [null]..addAll(arguments.map(_convertToJS)); 183 var args = [null]..addAll(arguments.map(_convertToJS));
152 var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args); 184 var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
153 // Without this line, calling factoryFunction as a constructor throws 185 // Without this line, calling factoryFunction as a constructor throws
154 JS('String', 'String(#)', factoryFunction); 186 JS('String', 'String(#)', factoryFunction);
155 // This could return an UnknownJavaScriptObject, or a native 187 // This could return an UnknownJavaScriptObject, or a native
156 // object for which there is an interceptor 188 // object for which there is an interceptor
157 var jsObj = JS('JavaScriptObject', 'new #()', factoryFunction); 189 var jsObj = JS('', 'new #()', factoryFunction);
Siggi Cherem (dart-lang) 2015/05/26 16:35:18 I'm not familiar with this annotation here - any r
sra1 2015/05/26 17:58:58 The constructor could be a constructor for somethi
158 190
159 return _wrapToDart(jsObj); 191 return _wrapToDart(jsObj);
192
193 // TODO(sra): Investigate:
194 //
195 // var jsObj = JS('', 'Object.create(#.prototype)', constr);
196 // JS('', '#.apply(#, #)', constr, jsObj,
197 // []..addAll(arguments.map(_convertToJS)));
198 // return _wrapToDart(jsObj);
160 } 199 }
161 200
162 /** 201 /**
163 * Constructs a [JsObject] that proxies a native Dart object; _for expert use 202 * Constructs a [JsObject] that proxies a native Dart object; _for expert use
164 * only_. 203 * only_.
165 * 204 *
166 * Use this constructor only if you wish to get access to JavaScript 205 * Use this constructor only if you wish to get access to JavaScript
167 * properties attached to a browser host object, such as a Node or Blob, that 206 * properties attached to a browser host object, such as a Node or Blob, that
168 * is normally automatically converted into a native Dart object. 207 * is normally automatically converted into a native Dart object.
169 * 208 *
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 542
504 // The shared constructor function for proxies to Dart objects in JavaScript. 543 // The shared constructor function for proxies to Dart objects in JavaScript.
505 final _dartProxyCtor = JS('', 'function DartObject(o) { this.o = o; }'); 544 final _dartProxyCtor = JS('', 'function DartObject(o) { this.o = o; }');
506 545
507 dynamic _convertToJS(dynamic o) { 546 dynamic _convertToJS(dynamic o) {
508 // Note: we don't write `if (o == null) return null;` to make sure dart2js 547 // Note: we don't write `if (o == null) return null;` to make sure dart2js
509 // doesn't convert `return null;` into `return;` (which would make `null` be 548 // doesn't convert `return null;` into `return;` (which would make `null` be
510 // `undefined` in Javascprit). See dartbug.com/20305 for details. 549 // `undefined` in Javascprit). See dartbug.com/20305 for details.
511 if (o == null || o is String || o is num || o is bool) { 550 if (o == null || o is String || o is num || o is bool) {
512 return o; 551 return o;
513 } else if (o is Blob || o is Event || o is KeyRange || o is ImageData 552 }
514 || o is Node || o is TypedData || o is Window) { 553 if (o is JsObject) {
Siggi Cherem (dart-lang) 2015/05/26 16:35:18 just to make sure I'm not missing something, these
sra1 2015/05/26 17:58:59 Yes. Initially I had just moved || to the end of
554 return o._jsObject;
555 }
556 if (o is Blob || o is Event || o is KeyRange || o is ImageData || o is Node ||
557 o is TypedData || o is Window) {
515 return o; 558 return o;
516 } else if (o is DateTime) { 559 }
560 if (o is DateTime) {
517 return Primitives.lazyAsJsDate(o); 561 return Primitives.lazyAsJsDate(o);
518 } else if (o is JsObject) { 562 }
519 return o._jsObject; 563 if (o is Function) {
520 } else if (o is Function) {
521 return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) { 564 return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) {
522 var jsFunction = _convertDartFunction(o); 565 var jsFunction = _convertDartFunction(o);
523 // set a property on the JS closure referencing the Dart closure 566 // set a property on the JS closure referencing the Dart closure
524 _defineProperty(jsFunction, _DART_CLOSURE_PROPERTY_NAME, o); 567 _defineProperty(jsFunction, _DART_CLOSURE_PROPERTY_NAME, o);
525 return jsFunction; 568 return jsFunction;
526 }); 569 });
527 } else {
528 var ctor = _dartProxyCtor;
529 return _getJsProxy(o, _JS_OBJECT_PROPERTY_NAME,
530 (o) => JS('', 'new #(#)', ctor, o));
531 } 570 }
571 var ctor = _dartProxyCtor;
572 return _getJsProxy(o, _JS_OBJECT_PROPERTY_NAME,
573 (o) => JS('', 'new #(#)', ctor, o));
532 } 574 }
533 575
534 Object _getJsProxy(o, String propertyName, createProxy(o)) { 576 Object _getJsProxy(o, String propertyName, createProxy(o)) {
535 var jsProxy = _getOwnProperty(o, propertyName); 577 var jsProxy = _getOwnProperty(o, propertyName);
536 if (jsProxy == null) { 578 if (jsProxy == null) {
537 jsProxy = createProxy(o); 579 jsProxy = createProxy(o);
538 _defineProperty(o, propertyName, jsProxy); 580 _defineProperty(o, propertyName, jsProxy);
539 } 581 }
540 return jsProxy; 582 return jsProxy;
541 } 583 }
(...skipping 18 matching lines...) Expand all
560 return JS('', '#.o', o); 602 return JS('', '#.o', o);
561 } else { 603 } else {
562 return _wrapToDart(o); 604 return _wrapToDart(o);
563 } 605 }
564 } 606 }
565 607
566 JsObject _wrapToDart(o) { 608 JsObject _wrapToDart(o) {
567 if (JS('bool', 'typeof # == "function"', o)) { 609 if (JS('bool', 'typeof # == "function"', o)) {
568 return _getDartProxy(o, _DART_CLOSURE_PROPERTY_NAME, 610 return _getDartProxy(o, _DART_CLOSURE_PROPERTY_NAME,
569 (o) => new JsFunction._fromJs(o)); 611 (o) => new JsFunction._fromJs(o));
570 } else if (JS('bool', '# instanceof Array', o)) { 612 }
613 if (JS('bool', '# instanceof Array', o)) {
571 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME, 614 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
572 (o) => new JsArray._fromJs(o)); 615 (o) => new JsArray._fromJs(o));
573 } else {
574 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
575 (o) => new JsObject._fromJs(o));
576 } 616 }
617 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
618 (o) => new JsObject._fromJs(o));
577 } 619 }
578 620
579 Object _getDartProxy(o, String propertyName, createProxy(o)) { 621 Object _getDartProxy(o, String propertyName, createProxy(o)) {
580 var dartProxy = _getOwnProperty(o, propertyName); 622 var dartProxy = _getOwnProperty(o, propertyName);
581 // Temporary fix for dartbug.com/15193 623 // Temporary fix for dartbug.com/15193
582 // In some cases it's possible to see a JavaScript object that 624 // In some cases it's possible to see a JavaScript object that
583 // came from a different context and was previously proxied to 625 // came from a different context and was previously proxied to
584 // Dart in that context. The JS object will have a cached proxy 626 // Dart in that context. The JS object will have a cached proxy
585 // but it won't be a valid Dart object in this context. 627 // but it won't be a valid Dart object in this context.
586 // For now we throw away the cached proxy, but we should be able 628 // For now we throw away the cached proxy, but we should be able
587 // to cache proxies from multiple JS contexts and Dart isolates. 629 // to cache proxies from multiple JS contexts and Dart isolates.
588 if (dartProxy == null || !_isLocalObject(o)) { 630 if (dartProxy == null || !_isLocalObject(o)) {
589 dartProxy = createProxy(o); 631 dartProxy = createProxy(o);
590 _defineProperty(o, propertyName, dartProxy); 632 _defineProperty(o, propertyName, dartProxy);
591 } 633 }
592 return dartProxy; 634 return dartProxy;
593 } 635 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698