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

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));
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(
165 JS('', 'new #(#, #, #)', constr, arg0, arg1, arg2));
166
167 case 4:
168 var arg0 = _convertToJS(JS('', '#[0]', arguments));
169 var arg1 = _convertToJS(JS('', '#[1]', arguments));
170 var arg2 = _convertToJS(JS('', '#[2]', arguments));
171 var arg3 = _convertToJS(JS('', '#[3]', arguments));
172 return _wrapToDart(
173 JS('', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3));
174 }
175 }
176
144 // The following code solves the problem of invoking a JavaScript 177 // The following code solves the problem of invoking a JavaScript
145 // constructor with an unknown number arguments. 178 // constructor with an unknown number arguments.
146 // First bind the constructor to the argument list using bind.apply(). 179 // 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 180 // The first argument to bind() is the binding of 'this', so add 'null' to
148 // the arguments list passed to apply(). 181 // the arguments list passed to apply().
149 // After that, use the JavaScript 'new' operator which overrides any binding 182 // After that, use the JavaScript 'new' operator which overrides any binding
150 // of 'this' with the new instance. 183 // of 'this' with the new instance.
151 var args = [null]..addAll(arguments.map(_convertToJS)); 184 var args = [null]..addAll(arguments.map(_convertToJS));
152 var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args); 185 var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
153 // Without this line, calling factoryFunction as a constructor throws 186 // Without this line, calling factoryFunction as a constructor throws
154 JS('String', 'String(#)', factoryFunction); 187 JS('String', 'String(#)', factoryFunction);
155 // This could return an UnknownJavaScriptObject, or a native 188 // This could return an UnknownJavaScriptObject, or a native
156 // object for which there is an interceptor 189 // object for which there is an interceptor
157 var jsObj = JS('JavaScriptObject', 'new #()', factoryFunction); 190 var jsObj = JS('', 'new #()', factoryFunction);
158 191
159 return _wrapToDart(jsObj); 192 return _wrapToDart(jsObj);
193
194 // TODO(sra): Investigate:
195 //
196 // var jsObj = JS('', 'Object.create(#.prototype)', constr);
197 // JS('', '#.apply(#, #)', constr, jsObj,
198 // []..addAll(arguments.map(_convertToJS)));
199 // return _wrapToDart(jsObj);
160 } 200 }
161 201
162 /** 202 /**
163 * Constructs a [JsObject] that proxies a native Dart object; _for expert use 203 * Constructs a [JsObject] that proxies a native Dart object; _for expert use
164 * only_. 204 * only_.
165 * 205 *
166 * Use this constructor only if you wish to get access to JavaScript 206 * 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 207 * properties attached to a browser host object, such as a Node or Blob, that
168 * is normally automatically converted into a native Dart object. 208 * is normally automatically converted into a native Dart object.
169 * 209 *
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 543
504 // The shared constructor function for proxies to Dart objects in JavaScript. 544 // The shared constructor function for proxies to Dart objects in JavaScript.
505 final _dartProxyCtor = JS('', 'function DartObject(o) { this.o = o; }'); 545 final _dartProxyCtor = JS('', 'function DartObject(o) { this.o = o; }');
506 546
507 dynamic _convertToJS(dynamic o) { 547 dynamic _convertToJS(dynamic o) {
508 // Note: we don't write `if (o == null) return null;` to make sure dart2js 548 // 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 549 // doesn't convert `return null;` into `return;` (which would make `null` be
510 // `undefined` in Javascprit). See dartbug.com/20305 for details. 550 // `undefined` in Javascprit). See dartbug.com/20305 for details.
511 if (o == null || o is String || o is num || o is bool) { 551 if (o == null || o is String || o is num || o is bool) {
512 return o; 552 return o;
513 } else if (o is Blob || o is Event || o is KeyRange || o is ImageData 553 }
514 || o is Node || o is TypedData || o is Window) { 554 if (o is JsObject) {
555 return o._jsObject;
556 }
557 if (o is Blob || o is Event || o is KeyRange || o is ImageData || o is Node ||
558 o is TypedData || o is Window) {
515 return o; 559 return o;
516 } else if (o is DateTime) { 560 }
561 if (o is DateTime) {
517 return Primitives.lazyAsJsDate(o); 562 return Primitives.lazyAsJsDate(o);
518 } else if (o is JsObject) { 563 }
519 return o._jsObject; 564 if (o is Function) {
520 } else if (o is Function) {
521 return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) { 565 return _getJsProxy(o, _JS_FUNCTION_PROPERTY_NAME, (o) {
522 var jsFunction = _convertDartFunction(o); 566 var jsFunction = _convertDartFunction(o);
523 // set a property on the JS closure referencing the Dart closure 567 // set a property on the JS closure referencing the Dart closure
524 _defineProperty(jsFunction, _DART_CLOSURE_PROPERTY_NAME, o); 568 _defineProperty(jsFunction, _DART_CLOSURE_PROPERTY_NAME, o);
525 return jsFunction; 569 return jsFunction;
526 }); 570 });
527 } else {
528 var ctor = _dartProxyCtor;
529 return _getJsProxy(o, _JS_OBJECT_PROPERTY_NAME,
530 (o) => JS('', 'new #(#)', ctor, o));
531 } 571 }
572 var ctor = _dartProxyCtor;
573 return _getJsProxy(o, _JS_OBJECT_PROPERTY_NAME,
574 (o) => JS('', 'new #(#)', ctor, o));
532 } 575 }
533 576
534 Object _getJsProxy(o, String propertyName, createProxy(o)) { 577 Object _getJsProxy(o, String propertyName, createProxy(o)) {
535 var jsProxy = _getOwnProperty(o, propertyName); 578 var jsProxy = _getOwnProperty(o, propertyName);
536 if (jsProxy == null) { 579 if (jsProxy == null) {
537 jsProxy = createProxy(o); 580 jsProxy = createProxy(o);
538 _defineProperty(o, propertyName, jsProxy); 581 _defineProperty(o, propertyName, jsProxy);
539 } 582 }
540 return jsProxy; 583 return jsProxy;
541 } 584 }
(...skipping 18 matching lines...) Expand all
560 return JS('', '#.o', o); 603 return JS('', '#.o', o);
561 } else { 604 } else {
562 return _wrapToDart(o); 605 return _wrapToDart(o);
563 } 606 }
564 } 607 }
565 608
566 JsObject _wrapToDart(o) { 609 JsObject _wrapToDart(o) {
567 if (JS('bool', 'typeof # == "function"', o)) { 610 if (JS('bool', 'typeof # == "function"', o)) {
568 return _getDartProxy(o, _DART_CLOSURE_PROPERTY_NAME, 611 return _getDartProxy(o, _DART_CLOSURE_PROPERTY_NAME,
569 (o) => new JsFunction._fromJs(o)); 612 (o) => new JsFunction._fromJs(o));
570 } else if (JS('bool', '# instanceof Array', o)) { 613 }
614 if (JS('bool', '# instanceof Array', o)) {
571 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME, 615 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
572 (o) => new JsArray._fromJs(o)); 616 (o) => new JsArray._fromJs(o));
573 } else {
574 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
575 (o) => new JsObject._fromJs(o));
576 } 617 }
618 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
619 (o) => new JsObject._fromJs(o));
577 } 620 }
578 621
579 Object _getDartProxy(o, String propertyName, createProxy(o)) { 622 Object _getDartProxy(o, String propertyName, createProxy(o)) {
580 var dartProxy = _getOwnProperty(o, propertyName); 623 var dartProxy = _getOwnProperty(o, propertyName);
581 // Temporary fix for dartbug.com/15193 624 // Temporary fix for dartbug.com/15193
582 // In some cases it's possible to see a JavaScript object that 625 // In some cases it's possible to see a JavaScript object that
583 // came from a different context and was previously proxied to 626 // came from a different context and was previously proxied to
584 // Dart in that context. The JS object will have a cached proxy 627 // 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. 628 // 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 629 // For now we throw away the cached proxy, but we should be able
587 // to cache proxies from multiple JS contexts and Dart isolates. 630 // to cache proxies from multiple JS contexts and Dart isolates.
588 if (dartProxy == null || !_isLocalObject(o)) { 631 if (dartProxy == null || !_isLocalObject(o)) {
589 dartProxy = createProxy(o); 632 dartProxy = createProxy(o);
590 _defineProperty(o, propertyName, dartProxy); 633 _defineProperty(o, propertyName, dartProxy);
591 } 634 }
592 return dartProxy; 635 return dartProxy;
593 } 636 }
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