Skip to content

Commit 17f908f

Browse files
authored
fix: Fix relational string comparisons when sizes differ (#1583)
1 parent d7ad482 commit 17f908f

10 files changed

+2447
-1888
lines changed

Diff for: std/assembly/string.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ import { Array } from "./array";
122122
var rightLength = right.length;
123123
if (!rightLength) return true;
124124
// @ts-ignore: string <-> String
125-
return compareImpl(left, 0, right, 0, min(leftLength, rightLength)) > 0;
125+
var res = compareImpl(left, 0, right, 0, min(leftLength, rightLength));
126+
return res ? res > 0 : leftLength > rightLength;
126127
}
127128

128129
@operator(">=") private static __gte(left: String, right: String): bool {
@@ -136,7 +137,8 @@ import { Array } from "./array";
136137
var leftLength = left.length;
137138
if (!leftLength) return true;
138139
// @ts-ignore: string <-> String
139-
return compareImpl(left, 0, right, 0, min(leftLength, rightLength)) < 0;
140+
var res = compareImpl(left, 0, right, 0, min(leftLength, rightLength));
141+
return res ? res < 0 : leftLength < rightLength;
140142
}
141143

142144
@operator("<=") private static __lte(left: String, right: String): bool {

Diff for: std/assembly/util/sort.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ export function COMPARATOR<T>(): (a: T, b: T) => i32 {
3232
if (a === b || a === null || b === null) return 0;
3333
var alen = changetype<string>(a).length;
3434
var blen = changetype<string>(b).length;
35-
if (!alen && !blen) return 0;
35+
if (!(alen | blen)) return 0;
3636
if (!alen) return -1;
3737
if (!blen) return 1;
38-
return compareImpl(changetype<string>(a), 0, changetype<string>(b), 0, <usize>min(alen, blen));
38+
let res = compareImpl(changetype<string>(a), 0, changetype<string>(b), 0, <usize>min(alen, blen));
39+
return res ? res : alen - blen;
3940
};
4041
} else {
4142
return (a: T, b: T): i32 => (i32(a > b) - i32(a < b));

Diff for: tests/compiler/std/array.optimized.wat

+10-3
Original file line numberDiff line numberDiff line change
@@ -6315,6 +6315,7 @@
63156315
(func $~lib/util/sort/COMPARATOR<~lib/string/String|null>~anonymous|0 (param $0 i32) (param $1 i32) (result i32)
63166316
(local $2 i32)
63176317
(local $3 i32)
6318+
(local $4 i32)
63186319
local.get $0
63196320
call $~lib/rt/pure/__retain
63206321
local.set $0
@@ -6333,23 +6334,22 @@
63336334
select
63346335
select
63356336
br_if $folding-inner0
6336-
i32.const 0
63376337
local.get $1
63386338
i32.const 20
63396339
i32.sub
63406340
i32.load offset=16
63416341
i32.const 1
63426342
i32.shr_u
63436343
local.tee $2
6344-
i32.eqz
63456344
local.get $0
63466345
i32.const 20
63476346
i32.sub
63486347
i32.load offset=16
63496348
i32.const 1
63506349
i32.shr_u
63516350
local.tee $3
6352-
select
6351+
i32.or
6352+
i32.eqz
63536353
br_if $folding-inner0
63546354
local.get $3
63556355
i32.eqz
@@ -6380,10 +6380,17 @@
63806380
i32.gt_s
63816381
select
63826382
call $~lib/util/string/compareImpl
6383+
local.set $4
63836384
local.get $0
63846385
call $~lib/rt/pure/__release
63856386
local.get $1
63866387
call $~lib/rt/pure/__release
6388+
local.get $4
6389+
local.get $3
6390+
local.get $2
6391+
i32.sub
6392+
local.get $4
6393+
select
63876394
return
63886395
end
63896396
local.get $0

Diff for: tests/compiler/std/array.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1067,4 +1067,4 @@ export class ArrayU32 extends Array<u32> {}
10671067
export class ArrayU8 extends Array<u8> {}
10681068
export class ArrayStr extends Array<string> {}
10691069
// TODO:
1070-
// export class ArrayArrayI32 extends Array<Array<i32>> {}
1070+
// export class ArrayArrayI32 extends Array<Array<i32>> {}

Diff for: tests/compiler/std/array.untouched.wat

+36-21
Original file line numberDiff line numberDiff line change
@@ -11778,13 +11778,9 @@
1177811778
call $~lib/string/String#get:length
1177911779
local.set $4
1178011780
local.get $3
11781+
local.get $4
11782+
i32.or
1178111783
i32.eqz
11782-
if (result i32)
11783-
local.get $4
11784-
i32.eqz
11785-
else
11786-
i32.const 0
11787-
end
1178811784
if
1178911785
i32.const 0
1179011786
local.set $2
@@ -11833,11 +11829,20 @@
1183311829
select
1183411830
call $~lib/util/string/compareImpl
1183511831
local.set $2
11832+
local.get $2
11833+
if (result i32)
11834+
local.get $2
11835+
else
11836+
local.get $3
11837+
local.get $4
11838+
i32.sub
11839+
end
11840+
local.set $5
1183611841
local.get $0
1183711842
call $~lib/rt/pure/__release
1183811843
local.get $1
1183911844
call $~lib/rt/pure/__release
11840-
local.get $2
11845+
local.get $5
1184111846
)
1184211847
(func $std/array/assertSorted<~lib/string/String|null>@varargs (param $0 i32) (param $1 i32)
1184311848
(local $2 i32)
@@ -12830,13 +12835,9 @@
1283012835
call $~lib/string/String#get:length
1283112836
local.set $4
1283212837
local.get $3
12838+
local.get $4
12839+
i32.or
1283312840
i32.eqz
12834-
if (result i32)
12835-
local.get $4
12836-
i32.eqz
12837-
else
12838-
i32.const 0
12839-
end
1284012841
if
1284112842
i32.const 0
1284212843
local.set $2
@@ -12885,11 +12886,20 @@
1288512886
select
1288612887
call $~lib/util/string/compareImpl
1288712888
local.set $2
12889+
local.get $2
12890+
if (result i32)
12891+
local.get $2
12892+
else
12893+
local.get $3
12894+
local.get $4
12895+
i32.sub
12896+
end
12897+
local.set $5
1288812898
local.get $0
1288912899
call $~lib/rt/pure/__release
1289012900
local.get $1
1289112901
call $~lib/rt/pure/__release
12892-
local.get $2
12902+
local.get $5
1289312903
)
1289412904
(func $std/array/assertSorted<~lib/string/String>@varargs (param $0 i32) (param $1 i32)
1289512905
(local $2 i32)
@@ -32588,13 +32598,9 @@
3258832598
call $~lib/string/String#get:length
3258932599
local.set $4
3259032600
local.get $3
32601+
local.get $4
32602+
i32.or
3259132603
i32.eqz
32592-
if (result i32)
32593-
local.get $4
32594-
i32.eqz
32595-
else
32596-
i32.const 0
32597-
end
3259832604
if
3259932605
i32.const 0
3260032606
local.set $2
@@ -32643,11 +32649,20 @@
3264332649
select
3264432650
call $~lib/util/string/compareImpl
3264532651
local.set $2
32652+
local.get $2
32653+
if (result i32)
32654+
local.get $2
32655+
else
32656+
local.get $3
32657+
local.get $4
32658+
i32.sub
32659+
end
32660+
local.set $5
3264632661
local.get $0
3264732662
call $~lib/rt/pure/__release
3264832663
local.get $1
3264932664
call $~lib/rt/pure/__release
32650-
local.get $2
32665+
local.get $5
3265132666
)
3265232667
(func $~lib/array/Array<~lib/string/String>#sort@varargs (param $0 i32) (param $1 i32) (result i32)
3265332668
(local $2 i32)

Diff for: tests/compiler/std/string-encoding.optimized.wat

+1-1
Original file line numberDiff line numberDiff line change
@@ -2591,7 +2591,7 @@
25912591
if
25922592
i32.const 0
25932593
i32.const 1504
2594-
i32.const 740
2594+
i32.const 742
25952595
i32.const 7
25962596
call $~lib/builtins/abort
25972597
unreachable

Diff for: tests/compiler/std/string-encoding.untouched.wat

+1-1
Original file line numberDiff line numberDiff line change
@@ -4388,7 +4388,7 @@
43884388
if
43894389
i32.const 0
43904390
i32.const 480
4391-
i32.const 740
4391+
i32.const 742
43924392
i32.const 7
43934393
call $~lib/builtins/abort
43944394
unreachable

0 commit comments

Comments
 (0)