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

Unified Diff: dart/lib/compiler/implementation/lib/interceptors.dart

Issue 11193032: Use JavaScript's Array.sort. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Minor tweak to sort$0 Created 8 years, 2 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
Index: dart/lib/compiler/implementation/lib/interceptors.dart
diff --git a/dart/lib/compiler/implementation/lib/interceptors.dart b/dart/lib/compiler/implementation/lib/interceptors.dart
index 680af43e4408e4c86110e683b17e77d774d02123..240b0dd3b39dc8da5b65e1e657663fb21266e929 100644
--- a/dart/lib/compiler/implementation/lib/interceptors.dart
+++ b/dart/lib/compiler/implementation/lib/interceptors.dart
@@ -364,13 +364,69 @@ every(receiver, f) {
sort$0(receiver) {
if (!isJsArray(receiver)) return UNINTERCEPTED(receiver.sort());
floitsch 2012/10/18 12:27:22 After this if I would call sort$1(receiver, Compar
Lasse Reichstein Nielsen 2012/10/18 13:04:00 The trick is that this is simpler because we know
floitsch 2012/10/18 13:46:51 Since the shortcut only applies when it is going t
checkMutable(receiver, 'sort');
- DualPivotQuicksort.sort(receiver, Comparable.compare);
+
+ int length = JS('int', '#.length', receiver);
+ if (length == 0 || length == 1) return;
Lasse Reichstein Nielsen 2012/10/18 13:04:00 <= 1 should be fine, a JS Array's length can't be
+ for (int i = 0; i < length; i++) {
+ // JavaScript's Array.prototype.sort has wierd semantics for null.
+ // It won't call compare and automatically pushes null/undefined
+ // to the end.
+ if (JS('var', '#[#]', receiver, i) == null) {
+ var other = JS('var', '#[#]', receiver, 0);
+ if (i == 0) {
+ other = JS('var', '#[#]', receiver, 1);
+ }
+ // Provoke a null error by comparing null to another element in
+ // the array.
+ Comparable.compare(null, other);
+ }
+ }
+
+ JS('void', '#.sort(#)', receiver, DART_CLOSURE_TO_JS(Comparable.compare));
}
sort$1(receiver, compare) {
if (!isJsArray(receiver)) return UNINTERCEPTED(receiver.sort(compare));
checkMutable(receiver, 'sort');
- DualPivotQuicksort.sort(receiver, compare);
+ int length = JS('int', '#.length', receiver);
floitsch 2012/10/18 12:27:22 Just tell dart2js that receiver is a JavaScript-ar
ahe 2012/11/23 08:43:42 How do I do that?
sra1 2012/11/23 10:57:33 This code is dominated by isJsArray(receiver). Why
floitsch 2012/11/23 13:00:51 It should be, and now with the new interceptor app
+ if (length == 0 || length == 1) return;
+ bool hasNull = false;
+ var array = receiver;
+ for (int i = 0; i < length; i++) {
floitsch 2012/10/18 12:27:22 Given that you already run through the array, you
sra1 2012/11/23 10:57:33 This assumes compareTo returns num, not int. I'm
+ // JavaScript's Array.prototype.sort has wierd semantics for null.
floitsch 2012/10/18 12:27:22 weird
+ // It won't call compare and automatically pushes null/undefined
+ // to the end.
+ if (JS('var', '#[#]', array, i) == null) {
+ if (!hasNull) {
+ array = JS('var', '#.slice(0)', array);
floitsch 2012/10/18 12:27:22 Why do we need a copy? To avoid the try/finally?
Lasse Reichstein Nielsen 2012/10/19 07:03:21 Because any NullSentinel in the original array wou
+ }
+ JS('var', '#[#] = #', array, i, const NullSentinel());
+ hasNull = true;
+ }
+ }
+ var jsCompare;
+ if (hasNull) {
floitsch 2012/10/18 12:27:22 I would special case for the Compare.compare: if (
+ jsCompare = DART_CLOSURE_TO_JS(compareHelperNull);
+ } else {
+ jsCompare = DART_CLOSURE_TO_JS(compareHelper);
+ }
+ // [DART_CLOSURE_TO_JS] only accepts static or top-level functions.
+ // So we use [compareHelper] and JavaScript's
+ // Function.prototype.bind to create a new closure we can safely
+ // pass to JavaScript.
+ jsCompare = JS('var', '#.bind(#, #)', jsCompare, null, compare);
Lasse Reichstein Nielsen 2012/10/18 11:54:50 Is 'bind' fast now? That would be great :) Try re
+
+ JS('void', '#.sort(#)', receiver, jsCompare);
+
+ if (hasNull) {
+ for (int i = 0; i < length; i++) {
+ var element = JS('var', '#[#]', array, i);
+ if (const NullSentinel() == element) {
+ element = null;
+ }
+ JS('var', '#[#] = #', receiver, i, element);
+ }
+ }
}
isNegative(receiver) {

Powered by Google App Engine
This is Rietveld 408576698