Merge branch 'master' of https://github.com/rathann/uBlock into patch

This commit is contained in:
Raymond Hill 2022-06-10 11:35:11 -04:00
commit 93d499a918
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
4 changed files with 601 additions and 601 deletions

View File

@ -64,92 +64,92 @@
(local $x i32) (local $x i32)
(local $y i32) (local $y i32)
;; trie index is a uint32 offset, need to convert to uint8 offset ;; trie index is a uint32 offset, need to convert to uint8 offset
get_local $icell local.get $icell
i32.const 2 i32.const 2
i32.shl i32.shl
set_local $icell local.set $icell
;; const buf32 = this.buf32; ;; const buf32 = this.buf32;
;; const buf8 = this.buf8; ;; const buf8 = this.buf8;
;; const char0 = buf32[CHAR0_SLOT]; ;; const char0 = buf32[CHAR0_SLOT];
i32.const 2060 i32.const 2060
i32.load align=4 i32.load align=4
set_local $char0 local.set $char0
;; const aR = buf32[HAYSTACK_SIZE_SLOT]; ;; const aR = buf32[HAYSTACK_SIZE_SLOT];
i32.const 2048 i32.const 2048
i32.load align=4 i32.load align=4
set_local $aR local.set $aR
;; let al = ai; ;; let al = ai;
get_local $ai local.get $ai
set_local $al local.set $al
block $matchFound block $matchFound
block $matchNotFound block $matchNotFound
;; for (;;) { ;; for (;;) {
loop $mainLoop loop $mainLoop
;; x = buf8[al]; ;; x = buf8[al];
get_local $al local.get $al
i32.load8_u i32.load8_u
set_local $x local.set $x
;; al += 1; ;; al += 1;
get_local $al local.get $al
i32.const 1 i32.const 1
i32.add i32.add
set_local $al local.set $al
;; // find matching segment ;; // find matching segment
;; for (;;) { ;; for (;;) {
block $nextSegment loop $findSegment block $nextSegment loop $findSegment
;; y = buf32[icell+SEGMENT_INFO]; ;; y = buf32[icell+SEGMENT_INFO];
get_local $icell local.get $icell
i32.load offset=8 align=4 i32.load offset=8 align=4
tee_local $y local.tee $y
;; bl = char0 + (y & 0x00FFFFFF); ;; bl = char0 + (y & 0x00FFFFFF);
i32.const 0x00FFFFFF i32.const 0x00FFFFFF
i32.and i32.and
get_local $char0 local.get $char0
i32.add i32.add
tee_local $bl local.tee $bl
;; if ( buf8[bl] === x ) { ;; if ( buf8[bl] === x ) {
i32.load8_u i32.load8_u
get_local $x local.get $x
i32.eq i32.eq
if if
;; y = (y >>> 24) - 1; ;; y = (y >>> 24) - 1;
get_local $y local.get $y
i32.const 24 i32.const 24
i32.shr_u i32.shr_u
i32.const 1 i32.const 1
i32.sub i32.sub
tee_local $y local.tee $y
;; if ( n !== 0 ) { ;; if ( n !== 0 ) {
if if
;; x = al + y; ;; x = al + y;
get_local $y local.get $y
get_local $al local.get $al
i32.add i32.add
tee_local $x local.tee $x
;; if ( x > aR ) { return 0; } ;; if ( x > aR ) { return 0; }
get_local $aR local.get $aR
i32.gt_u i32.gt_u
br_if $matchNotFound br_if $matchNotFound
;; for (;;) { ;; for (;;) {
loop loop
;; bl += 1; ;; bl += 1;
get_local $bl local.get $bl
i32.const 1 i32.const 1
i32.add i32.add
tee_local $bl local.tee $bl
;; if ( buf8[bl] !== buf8[al] ) { return 0; } ;; if ( buf8[bl] !== buf8[al] ) { return 0; }
i32.load8_u i32.load8_u
get_local $al local.get $al
i32.load8_u i32.load8_u
i32.ne i32.ne
br_if $matchNotFound br_if $matchNotFound
;; al += 1; ;; al += 1;
get_local $al local.get $al
i32.const 1 i32.const 1
i32.add i32.add
tee_local $al local.tee $al
;; if ( al === x ) { break; } ;; if ( al === x ) { break; }
get_local $x local.get $x
i32.ne i32.ne
br_if 0 br_if 0
end end
@ -158,11 +158,11 @@
br $nextSegment br $nextSegment
end end
;; icell = buf32[icell+CELL_OR]; ;; icell = buf32[icell+CELL_OR];
get_local $icell local.get $icell
i32.load offset=4 align=4 i32.load offset=4 align=4
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $icell local.tee $icell
;; if ( icell === 0 ) { return 0; } ;; if ( icell === 0 ) { return 0; }
i32.eqz i32.eqz
br_if $matchNotFound br_if $matchNotFound
@ -171,14 +171,14 @@
end end end end
;; // next segment ;; // next segment
;; icell = buf32[icell+CELL_AND]; ;; icell = buf32[icell+CELL_AND];
get_local $icell local.get $icell
i32.load align=4 i32.load align=4
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $icell local.tee $icell
;; const x = buf32[icell+BCELL_EXTRA]; ;; const x = buf32[icell+BCELL_EXTRA];
i32.load offset=8 align=4 i32.load offset=8 align=4
tee_local $x local.tee $x
;; if ( x <= BCELL_EXTRA_MAX ) { ;; if ( x <= BCELL_EXTRA_MAX ) {
i32.const 0x00FFFFFF i32.const 0x00FFFFFF
i32.le_u i32.le_u
@ -186,43 +186,43 @@
;; if ( x !== 0 && this.matchesExtra(ai, al, x) !== 0 ) { ;; if ( x !== 0 && this.matchesExtra(ai, al, x) !== 0 ) {
;; return 1; ;; return 1;
;; } ;; }
get_local $x local.get $x
if if
get_local $ai local.get $ai
get_local $al local.get $al
get_local $x local.get $x
call $matchesExtra call $matchesExtra
br_if $matchFound br_if $matchFound
end end
;; x = buf32[icell+BCELL_ALT_AND]; ;; x = buf32[icell+BCELL_ALT_AND];
get_local $icell local.get $icell
i32.load offset=4 align=4 i32.load offset=4 align=4
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $x local.tee $x
;; if ( x !== 0 && this.matchesLeft(x, ai, al) !== 0 ) { ;; if ( x !== 0 && this.matchesLeft(x, ai, al) !== 0 ) {
if if
get_local $x local.get $x
get_local $ai local.get $ai
get_local $al local.get $al
call $matchesLeft call $matchesLeft
br_if $matchFound br_if $matchFound
;; } ;; }
end end
;; icell = buf32[icell+BCELL_NEXT_AND]; ;; icell = buf32[icell+BCELL_NEXT_AND];
get_local $icell local.get $icell
i32.load align=4 i32.load align=4
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $icell local.tee $icell
;; if ( icell === 0 ) { return 0; } ;; if ( icell === 0 ) { return 0; }
i32.eqz i32.eqz
br_if $matchNotFound br_if $matchNotFound
;; } ;; }
end end
;; if ( al === aR ) { return 0; } ;; if ( al === aR ) { return 0; }
get_local $al local.get $al
get_local $aR local.get $aR
i32.ne i32.ne
br_if $mainLoop br_if $mainLoop
;; } ;; }
@ -255,60 +255,60 @@
;; const char0 = buf32[CHAR0_SLOT]; ;; const char0 = buf32[CHAR0_SLOT];
i32.const 2060 i32.const 2060
i32.load align=4 i32.load align=4
set_local $char0 local.set $char0
block $matchFound block $matchFound
block $matchNotFound block $matchNotFound
;; for (;;) { ;; for (;;) {
loop $mainLoop loop $mainLoop
;; if ( ar === 0 ) { return 0; } ;; if ( ar === 0 ) { return 0; }
get_local $ar local.get $ar
i32.eqz i32.eqz
br_if $matchNotFound br_if $matchNotFound
;; ar -= 1; ;; ar -= 1;
get_local $ar local.get $ar
i32.const 1 i32.const 1
i32.sub i32.sub
tee_local $ar local.tee $ar
;; x = buf8[ar]; ;; x = buf8[ar];
i32.load8_u i32.load8_u
set_local $x local.set $x
;; // find matching segment ;; // find matching segment
;; for (;;) { ;; for (;;) {
block $nextSegment loop $findSegment block $nextSegment loop $findSegment
;; y = buf32[icell+SEGMENT_INFO]; ;; y = buf32[icell+SEGMENT_INFO];
get_local $icell local.get $icell
i32.load offset=8 align=4 i32.load offset=8 align=4
tee_local $y local.tee $y
;; br = char0 + (y & 0x00FFFFFF); ;; br = char0 + (y & 0x00FFFFFF);
i32.const 0x00FFFFFF i32.const 0x00FFFFFF
i32.and i32.and
get_local $char0 local.get $char0
i32.add i32.add
tee_local $br local.tee $br
;; y = (y >>> 24) - 1; ;; y = (y >>> 24) - 1;
get_local $y local.get $y
i32.const 24 i32.const 24
i32.shr_u i32.shr_u
i32.const 1 i32.const 1
i32.sub i32.sub
tee_local $y local.tee $y
;; br += y; ;; br += y;
i32.add i32.add
tee_local $br local.tee $br
;; if ( buf8[br] === x ) { ;; if ( buf8[br] === x ) {
i32.load8_u i32.load8_u
get_local $x local.get $x
i32.eq i32.eq
if if
;; // all characters in segment must match ;; // all characters in segment must match
;; if ( y !== 0 ) { ;; if ( y !== 0 ) {
get_local $y local.get $y
if if
;; x = ar - y; ;; x = ar - y;
get_local $ar local.get $ar
get_local $y local.get $y
i32.sub i32.sub
tee_local $x local.tee $x
;; if ( x < 0 ) { return 0; } ;; if ( x < 0 ) { return 0; }
i32.const 0 i32.const 0
i32.lt_s i32.lt_s
@ -317,21 +317,21 @@
loop loop
;; ar -= 1; br -= 1; ;; ar -= 1; br -= 1;
;; if ( buf8[ar] !== buf8[br] ) { return 0; } ;; if ( buf8[ar] !== buf8[br] ) { return 0; }
get_local $ar local.get $ar
i32.const 1 i32.const 1
i32.sub i32.sub
tee_local $ar local.tee $ar
i32.load8_u i32.load8_u
get_local $br local.get $br
i32.const 1 i32.const 1
i32.sub i32.sub
tee_local $br local.tee $br
i32.load8_u i32.load8_u
i32.ne i32.ne
br_if $matchNotFound br_if $matchNotFound
;; if ( ar === x ) { break; } ;; if ( ar === x ) { break; }
get_local $ar local.get $ar
get_local $x local.get $x
i32.ne i32.ne
br_if 0 br_if 0
end end
@ -340,11 +340,11 @@
br $nextSegment br $nextSegment
end end
;; icell = buf32[icell+CELL_OR]; ;; icell = buf32[icell+CELL_OR];
get_local $icell local.get $icell
i32.load offset=4 align=4 i32.load offset=4 align=4
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $icell local.tee $icell
;; if ( icell === 0 ) { return 0; } ;; if ( icell === 0 ) { return 0; }
i32.eqz i32.eqz
br_if $matchNotFound br_if $matchNotFound
@ -353,14 +353,14 @@
end end end end
;; // next segment ;; // next segment
;; icell = buf32[icell+CELL_AND]; ;; icell = buf32[icell+CELL_AND];
get_local $icell local.get $icell
i32.load align=4 i32.load align=4
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $icell local.tee $icell
;; const x = buf32[icell+BCELL_EXTRA]; ;; const x = buf32[icell+BCELL_EXTRA];
i32.load offset=8 align=4 i32.load offset=8 align=4
tee_local $x local.tee $x
;; if ( x <= BCELL_EXTRA_MAX ) { ;; if ( x <= BCELL_EXTRA_MAX ) {
i32.const 0x00FFFFFF i32.const 0x00FFFFFF
i32.le_u i32.le_u
@ -368,20 +368,20 @@
;; if ( x !== 0 && this.matchesExtra(ar, r, x) !== 0 ) { ;; if ( x !== 0 && this.matchesExtra(ar, r, x) !== 0 ) {
;; return 1; ;; return 1;
;; } ;; }
get_local $x local.get $x
if if
get_local $ar local.get $ar
get_local $r local.get $r
get_local $x local.get $x
call $matchesExtra call $matchesExtra
br_if $matchFound br_if $matchFound
end end
;; icell = buf32[icell+BCELL_NEXT_AND]; ;; icell = buf32[icell+BCELL_NEXT_AND];
get_local $icell local.get $icell
i32.load align=4 i32.load align=4
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $icell local.tee $icell
;; if ( icell === 0 ) { return 0; } ;; if ( icell === 0 ) { return 0; }
i32.eqz i32.eqz
br_if $matchNotFound br_if $matchNotFound
@ -414,35 +414,35 @@
;; if ( ix !== 1 ) { ;; if ( ix !== 1 ) {
;; const iu = this.extraHandler(l, r, ix); ;; const iu = this.extraHandler(l, r, ix);
;; if ( iu === 0 ) { return 0; } ;; if ( iu === 0 ) { return 0; }
get_local $ix local.get $ix
i32.const 1 i32.const 1
i32.ne i32.ne
if if
get_local $l local.get $l
get_local $r local.get $r
get_local $ix local.get $ix
call $extraHandler call $extraHandler
tee_local $iu local.tee $iu
i32.eqz i32.eqz
br_if $fail br_if $fail
;; } else { ;; } else {
;; iu = -1; ;; iu = -1;
else else
i32.const -1 i32.const -1
set_local $iu local.set $iu
;; } ;; }
end end
;; this.buf32[RESULT_IU_SLOT] = iu; ;; this.buf32[RESULT_IU_SLOT] = iu;
i32.const 2076 i32.const 2076
get_local $iu local.get $iu
i32.store align=4 i32.store align=4
;; this.buf32[RESULT_L_SLOT] = l; ;; this.buf32[RESULT_L_SLOT] = l;
i32.const 2068 i32.const 2068
get_local $l local.get $l
i32.store align=4 i32.store align=4
;; this.buf32[RESULT_R_SLOT] = r; ;; this.buf32[RESULT_R_SLOT] = r;
i32.const 2072 i32.const 2072
get_local $r local.get $r
i32.store align=4 i32.store align=4
end ;; $succeed end ;; $succeed
i32.const 1 i32.const 1
@ -470,49 +470,49 @@
;; if ( haystackLeft < 0 || (haystackLeft + needleLen) > haystackRight ) { ;; if ( haystackLeft < 0 || (haystackLeft + needleLen) > haystackRight ) {
;; return 0; ;; return 0;
;; } ;; }
get_local $haystackLeft local.get $haystackLeft
i32.const 0 i32.const 0
i32.lt_s i32.lt_s
br_if $fail br_if $fail
get_local $haystackLeft local.get $haystackLeft
get_local $needleLen local.get $needleLen
i32.add i32.add
get_local $haystackRight local.get $haystackRight
i32.gt_u i32.gt_u
br_if $fail br_if $fail
;; const charCodes = this.buf8; ;; const charCodes = this.buf8;
;; needleLeft += this.buf32[CHAR0_SLOT]; ;; needleLeft += this.buf32[CHAR0_SLOT];
get_local $needleLeft local.get $needleLeft
i32.const 2060 ;; CHAR0_SLOT memory address i32.const 2060 ;; CHAR0_SLOT memory address
i32.load align=4 ;; CHAR0 memory address i32.load align=4 ;; CHAR0 memory address
i32.add ;; needle memory address i32.add ;; needle memory address
tee_local $needleLeft local.tee $needleLeft
;; const needleRight = needleLeft + needleLen; ;; const needleRight = needleLeft + needleLen;
get_local $needleLen local.get $needleLen
i32.add i32.add
set_local $needleRight local.set $needleRight
;; while ( charCodes[haystackLeft] === charCodes[needleLeft] ) { ;; while ( charCodes[haystackLeft] === charCodes[needleLeft] ) {
loop $compare loop $compare
get_local $haystackLeft local.get $haystackLeft
i32.load8_u i32.load8_u
get_local $needleLeft local.get $needleLeft
i32.load8_u i32.load8_u
i32.ne i32.ne
br_if $fail br_if $fail
;; needleLeft += 1; ;; needleLeft += 1;
get_local $needleLeft local.get $needleLeft
i32.const 1 i32.const 1
i32.add i32.add
tee_local $needleLeft local.tee $needleLeft
;; if ( needleLeft === needleRight ) { return 1; } ;; if ( needleLeft === needleRight ) { return 1; }
get_local $needleRight local.get $needleRight
i32.eq i32.eq
br_if $succeed br_if $succeed
;; haystackLeft += 1; ;; haystackLeft += 1;
i32.const 1 i32.const 1
get_local $haystackLeft local.get $haystackLeft
i32.add i32.add
set_local $haystackLeft local.set $haystackLeft
br $compare br $compare
end end
;; } ;; }
@ -545,76 +545,76 @@
block $fail block $fail
block $succeed block $succeed
;; if ( needleLen === 0 ) { return haystackLeft; } ;; if ( needleLen === 0 ) { return haystackLeft; }
get_local $needleLen local.get $needleLen
i32.eqz i32.eqz
br_if $succeed br_if $succeed
;; haystackEnd -= needleLen; ;; haystackEnd -= needleLen;
get_local $haystackEnd local.get $haystackEnd
get_local $needleLen local.get $needleLen
i32.sub i32.sub
tee_local $haystackEnd local.tee $haystackEnd
;; if ( haystackEnd < haystackLeft ) { return -1; } ;; if ( haystackEnd < haystackLeft ) { return -1; }
get_local $haystackLeft local.get $haystackLeft
i32.lt_s i32.lt_s
br_if $fail br_if $fail
;; needleLeft += this.buf32[CHAR0_SLOT]; ;; needleLeft += this.buf32[CHAR0_SLOT];
get_local $needleLeft local.get $needleLeft
i32.const 2060 ;; CHAR0_SLOT memory address i32.const 2060 ;; CHAR0_SLOT memory address
i32.load align=4 ;; CHAR0 memory address i32.load align=4 ;; CHAR0 memory address
i32.add ;; needle memory address i32.add ;; needle memory address
tee_local $needleLeft local.tee $needleLeft
;; const needleRight = needleLeft + needleLen; ;; const needleRight = needleLeft + needleLen;
get_local $needleLen local.get $needleLen
i32.add i32.add
set_local $needleRight local.set $needleRight
;; const charCodes = this.buf8; ;; const charCodes = this.buf8;
;; for (;;) { ;; for (;;) {
loop $mainLoop loop $mainLoop
;; let i = haystackLeft; ;; let i = haystackLeft;
;; let j = needleLeft; ;; let j = needleLeft;
get_local $haystackLeft local.get $haystackLeft
set_local $i local.set $i
get_local $needleLeft local.get $needleLeft
set_local $j local.set $j
;; while ( charCodes[i] === charCodes[j] ) { ;; while ( charCodes[i] === charCodes[j] ) {
block $breakMatchChars loop $matchChars block $breakMatchChars loop $matchChars
get_local $i local.get $i
i32.load8_u i32.load8_u
get_local $j local.get $j
i32.load8_u i32.load8_u
i32.ne i32.ne
br_if $breakMatchChars br_if $breakMatchChars
;; j += 1; ;; j += 1;
get_local $j local.get $j
i32.const 1 i32.const 1
i32.add i32.add
tee_local $j local.tee $j
;; if ( j === needleRight ) { return haystackLeft; } ;; if ( j === needleRight ) { return haystackLeft; }
get_local $needleRight local.get $needleRight
i32.eq i32.eq
br_if $succeed br_if $succeed
;; i += 1; ;; i += 1;
get_local $i local.get $i
i32.const 1 i32.const 1
i32.add i32.add
set_local $i local.set $i
br $matchChars br $matchChars
;; } ;; }
end end end end
;; haystackLeft += 1; ;; haystackLeft += 1;
get_local $haystackLeft local.get $haystackLeft
i32.const 1 i32.const 1
i32.add i32.add
tee_local $haystackLeft local.tee $haystackLeft
;; if ( haystackLeft > haystackEnd ) { break; } ;; if ( haystackLeft > haystackEnd ) { break; }
get_local $haystackEnd local.get $haystackEnd
i32.gt_u i32.gt_u
br_if $fail br_if $fail
br $mainLoop br $mainLoop
;; } ;; }
end end
end ;; $succeed end ;; $succeed
get_local $haystackLeft local.get $haystackLeft
return return
end ;; $fail end ;; $fail
;; return -1; ;; return -1;
@ -640,82 +640,82 @@
(local $j i32) (local $j i32)
(local $c0 i32) (local $c0 i32)
;; if ( needleLen === 0 ) { return haystackBeg; } ;; if ( needleLen === 0 ) { return haystackBeg; }
get_local $needleLen local.get $needleLen
i32.eqz i32.eqz
if if
get_local $haystackBeg local.get $haystackBeg
return return
end end
block $fail block $fail
block $succeed block $succeed
;; let haystackLeft = haystackEnd - needleLen; ;; let haystackLeft = haystackEnd - needleLen;
get_local $haystackEnd local.get $haystackEnd
get_local $needleLen local.get $needleLen
i32.sub i32.sub
tee_local $haystackLeft local.tee $haystackLeft
;; if ( haystackLeft < haystackBeg ) { return -1; } ;; if ( haystackLeft < haystackBeg ) { return -1; }
get_local $haystackBeg local.get $haystackBeg
i32.lt_s i32.lt_s
br_if $fail br_if $fail
;; needleLeft += this.buf32[CHAR0_SLOT]; ;; needleLeft += this.buf32[CHAR0_SLOT];
get_local $needleLeft local.get $needleLeft
i32.const 2060 ;; CHAR0_SLOT memory address i32.const 2060 ;; CHAR0_SLOT memory address
i32.load align=4 ;; CHAR0 memory address i32.load align=4 ;; CHAR0 memory address
i32.add ;; needle memory address i32.add ;; needle memory address
tee_local $needleLeft local.tee $needleLeft
;; const needleRight = needleLeft + needleLen; ;; const needleRight = needleLeft + needleLen;
get_local $needleLen local.get $needleLen
i32.add i32.add
set_local $needleRight local.set $needleRight
;; const charCodes = this.buf8; ;; const charCodes = this.buf8;
;; for (;;) { ;; for (;;) {
loop $mainLoop loop $mainLoop
;; let i = haystackLeft; ;; let i = haystackLeft;
;; let j = needleLeft; ;; let j = needleLeft;
get_local $haystackLeft local.get $haystackLeft
set_local $i local.set $i
get_local $needleLeft local.get $needleLeft
set_local $j local.set $j
;; while ( charCodes[i] === charCodes[j] ) { ;; while ( charCodes[i] === charCodes[j] ) {
block $breakMatchChars loop $matchChars block $breakMatchChars loop $matchChars
get_local $i local.get $i
i32.load8_u i32.load8_u
get_local $j local.get $j
i32.load8_u i32.load8_u
i32.ne i32.ne
br_if $breakMatchChars br_if $breakMatchChars
;; j += 1; ;; j += 1;
get_local $j local.get $j
i32.const 1 i32.const 1
i32.add i32.add
tee_local $j local.tee $j
;; if ( j === needleRight ) { return haystackLeft; } ;; if ( j === needleRight ) { return haystackLeft; }
get_local $needleRight local.get $needleRight
i32.eq i32.eq
br_if $succeed br_if $succeed
;; i += 1; ;; i += 1;
get_local $i local.get $i
i32.const 1 i32.const 1
i32.add i32.add
set_local $i local.set $i
br $matchChars br $matchChars
;; } ;; }
end end end end
;; if ( haystackLeft === haystackBeg ) { break; } ;; if ( haystackLeft === haystackBeg ) { break; }
;; haystackLeft -= 1; ;; haystackLeft -= 1;
get_local $haystackLeft local.get $haystackLeft
get_local $haystackBeg local.get $haystackBeg
i32.eq i32.eq
br_if $fail br_if $fail
get_local $haystackLeft local.get $haystackLeft
i32.const 1 i32.const 1
i32.sub i32.sub
set_local $haystackLeft local.set $haystackLeft
br $mainLoop br $mainLoop
;; } ;; }
end end
end ;; $succeed end ;; $succeed
get_local $haystackLeft local.get $haystackLeft
return return
end ;; $fail end ;; $fail
;; return -1; ;; return -1;

View File

@ -64,19 +64,19 @@
;; ;;
i32.const 264 ;; start of char section is stored at addr 264 i32.const 264 ;; start of char section is stored at addr 264
i32.load i32.load
set_local $char0 local.set $char0
;; let ineedle = this.buf[255]; ;; let ineedle = this.buf[255];
i32.const 255 ;; addr of needle is stored at addr 255 i32.const 255 ;; addr of needle is stored at addr 255
i32.load8_u i32.load8_u
set_local $ineedle local.set $ineedle
;; let icell = this.buf32[iroot+0]; ;; let icell = this.buf32[iroot+0];
get_local $iroot local.get $iroot
i32.const 2 i32.const 2
i32.shl i32.shl
i32.load i32.load
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $icell local.tee $icell
;; if ( icell === 0 ) { return -1; } ;; if ( icell === 0 ) { return -1; }
i32.eqz i32.eqz
if if
@ -86,43 +86,43 @@
;; for (;;) { ;; for (;;) {
block $noSegment loop $nextSegment block $noSegment loop $nextSegment
;; if ( ineedle === 0 ) { return -1; } ;; if ( ineedle === 0 ) { return -1; }
get_local $ineedle local.get $ineedle
i32.eqz i32.eqz
if if
i32.const -1 i32.const -1
return return
end end
;; ineedle -= 1; ;; ineedle -= 1;
get_local $ineedle local.get $ineedle
i32.const -1 i32.const -1
i32.add i32.add
tee_local $ineedle local.tee $ineedle
;; let c = this.buf[ineedle]; ;; let c = this.buf[ineedle];
i32.load8_u i32.load8_u
set_local $c local.set $c
;; for (;;) { ;; for (;;) {
block $foundSegment loop $findSegment block $foundSegment loop $findSegment
;; v = this.buf32[icell+2]; ;; v = this.buf32[icell+2];
get_local $icell local.get $icell
i32.load offset=8 i32.load offset=8
tee_local $v local.tee $v
;; i0 = char0 + (v >>> 8); ;; i0 = char0 + (v >>> 8);
i32.const 8 i32.const 8
i32.shr_u i32.shr_u
get_local $char0 local.get $char0
i32.add i32.add
tee_local $i0 local.tee $i0
;; if ( this.buf[i0] === c ) { break; } ;; if ( this.buf[i0] === c ) { break; }
i32.load8_u i32.load8_u
get_local $c local.get $c
i32.eq i32.eq
br_if $foundSegment br_if $foundSegment
;; icell = this.buf32[icell+0]; ;; icell = this.buf32[icell+0];
get_local $icell local.get $icell
i32.load i32.load
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $icell local.tee $icell
i32.eqz i32.eqz
if if
i32.const -1 i32.const -1
@ -131,44 +131,44 @@
br 0 br 0
end end end end
;; let n = v & 0x7F; ;; let n = v & 0x7F;
get_local $v local.get $v
i32.const 0x7F i32.const 0x7F
i32.and i32.and
tee_local $n local.tee $n
;; if ( n > 1 ) { ;; if ( n > 1 ) {
i32.const 1 i32.const 1
i32.gt_u i32.gt_u
if if
;; n -= 1; ;; n -= 1;
get_local $n local.get $n
i32.const -1 i32.const -1
i32.add i32.add
tee_local $n local.tee $n
;; if ( n > ineedle ) { return -1; } ;; if ( n > ineedle ) { return -1; }
get_local $ineedle local.get $ineedle
i32.gt_u i32.gt_u
if if
i32.const -1 i32.const -1
return return
end end
get_local $i0 local.get $i0
i32.const 1 i32.const 1
i32.add i32.add
tee_local $i0 local.tee $i0
;; const i1 = i0 + n; ;; const i1 = i0 + n;
get_local $n local.get $n
i32.add i32.add
set_local $i1 local.set $i1
;; do { ;; do {
loop loop
;; ineedle -= 1; ;; ineedle -= 1;
get_local $ineedle local.get $ineedle
i32.const -1 i32.const -1
i32.add i32.add
tee_local $ineedle local.tee $ineedle
;; if ( this.buf[i0] !== this.buf[ineedle] ) { return -1; } ;; if ( this.buf[i0] !== this.buf[ineedle] ) { return -1; }
i32.load8_u i32.load8_u
get_local $i0 local.get $i0
i32.load8_u i32.load8_u
i32.ne i32.ne
if if
@ -176,47 +176,47 @@
return return
end end
;; i0 += 1; ;; i0 += 1;
get_local $i0 local.get $i0
i32.const 1 i32.const 1
i32.add i32.add
tee_local $i0 local.tee $i0
;; } while ( i0 < i1 ); ;; } while ( i0 < i1 );
get_local $i1 local.get $i1
i32.lt_u i32.lt_u
br_if 0 br_if 0
end end
end end
;; if ( (v & 0x80) !== 0 ) { ;; if ( (v & 0x80) !== 0 ) {
get_local $v local.get $v
i32.const 0x80 i32.const 0x80
i32.and i32.and
if if
;; if ( ineedle === 0 || buf8[ineedle-1] === 0x2E /* '.' */ ) { ;; if ( ineedle === 0 || buf8[ineedle-1] === 0x2E /* '.' */ ) {
;; return ineedle; ;; return ineedle;
;; } ;; }
get_local $ineedle local.get $ineedle
i32.eqz i32.eqz
if if
i32.const 0 i32.const 0
return return
end end
get_local $ineedle local.get $ineedle
i32.const -1 i32.const -1
i32.add i32.add
i32.load8_u i32.load8_u
i32.const 0x2E i32.const 0x2E
i32.eq i32.eq
if if
get_local $ineedle local.get $ineedle
return return
end end
end end
;; icell = this.buf32[icell+1]; ;; icell = this.buf32[icell+1];
get_local $icell local.get $icell
i32.load offset=4 i32.load offset=4
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $icell local.tee $icell
;; if ( icell === 0 ) { break; } ;; if ( icell === 0 ) { break; }
br_if 0 br_if 0
end end end end
@ -245,7 +245,7 @@
;; let lhnchar = this.buf[255]; ;; let lhnchar = this.buf[255];
i32.const 255 i32.const 255
i32.load8_u i32.load8_u
tee_local $lhnchar local.tee $lhnchar
;; if ( lhnchar === 0 ) { return 0; } ;; if ( lhnchar === 0 ) { return 0; }
i32.eqz i32.eqz
if if
@ -281,21 +281,21 @@
end end
end end
;; let icell = this.buf32[iroot+0]; ;; let icell = this.buf32[iroot+0];
get_local $iroot local.get $iroot
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $iroot local.tee $iroot
i32.load i32.load
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $icell local.tee $icell
;; if ( this.buf32[icell+2] === 0 ) { ;; if ( this.buf32[icell+2] === 0 ) {
i32.eqz i32.eqz
if if
;; this.buf32[iroot+0] = this.addLeafCell(lhnchar); ;; this.buf32[iroot+0] = this.addLeafCell(lhnchar);
;; return 1; ;; return 1;
get_local $iroot local.get $iroot
get_local $lhnchar local.get $lhnchar
call $addLeafCell call $addLeafCell
i32.store i32.store
i32.const 1 i32.const 1
@ -304,37 +304,37 @@
;; const char0 = this.buf32[HNBIGTRIE_CHAR0_SLOT]; ;; const char0 = this.buf32[HNBIGTRIE_CHAR0_SLOT];
i32.const 264 i32.const 264
i32.load i32.load
set_local $char0 local.set $char0
;; for (;;) { ;; for (;;) {
loop $nextSegment loop $nextSegment
;; const v = this.buf32[icell+2]; ;; const v = this.buf32[icell+2];
get_local $icell local.get $icell
i32.load offset=8 i32.load offset=8
tee_local $v local.tee $v
;; let isegchar0 = char0 + (v >>> 8); ;; let isegchar0 = char0 + (v >>> 8);
i32.const 8 i32.const 8
i32.shr_u i32.shr_u
get_local $char0 local.get $char0
i32.add i32.add
tee_local $isegchar0 local.tee $isegchar0
;; if ( this.buf[isegchar0] !== this.buf[lhnchar-1] ) { ;; if ( this.buf[isegchar0] !== this.buf[lhnchar-1] ) {
i32.load8_u i32.load8_u
get_local $lhnchar local.get $lhnchar
i32.const -1 i32.const -1
i32.add i32.add
i32.load8_u i32.load8_u
i32.ne i32.ne
if if
;; inext = this.buf32[icell+0]; ;; inext = this.buf32[icell+0];
get_local $icell local.get $icell
i32.load i32.load
tee_local $inext local.tee $inext
;; if ( inext === 0 ) { ;; if ( inext === 0 ) {
i32.eqz i32.eqz
if if
;; this.buf32[icell+0] = this.addLeafCell(lhnchar); ;; this.buf32[icell+0] = this.addLeafCell(lhnchar);
get_local $icell local.get $icell
get_local $lhnchar local.get $lhnchar
call $addLeafCell call $addLeafCell
i32.store i32.store
;; return 1; ;; return 1;
@ -342,25 +342,25 @@
return return
end end
;; icell = inext; ;; icell = inext;
get_local $inext local.get $inext
i32.const 2 i32.const 2
i32.shl i32.shl
set_local $icell local.set $icell
br $nextSegment br $nextSegment
end end
;; let isegchar = 1; ;; let isegchar = 1;
i32.const 1 i32.const 1
set_local $isegchar local.set $isegchar
;; lhnchar -= 1; ;; lhnchar -= 1;
get_local $lhnchar local.get $lhnchar
i32.const -1 i32.const -1
i32.add i32.add
set_local $lhnchar local.set $lhnchar
;; const lsegchar = v & 0x7F; ;; const lsegchar = v & 0x7F;
get_local $v local.get $v
i32.const 0x7F i32.const 0x7F
i32.and i32.and
tee_local $lsegchar local.tee $lsegchar
;; if ( lsegchar !== 1 ) { ;; if ( lsegchar !== 1 ) {
i32.const 1 i32.const 1
i32.ne i32.ne
@ -368,69 +368,69 @@
;; for (;;) { ;; for (;;) {
block $mismatch loop block $mismatch loop
;; if ( isegchar === lsegchar ) { break; } ;; if ( isegchar === lsegchar ) { break; }
get_local $isegchar local.get $isegchar
get_local $lsegchar local.get $lsegchar
i32.eq i32.eq
br_if $mismatch br_if $mismatch
get_local $lhnchar local.get $lhnchar
i32.eqz i32.eqz
br_if $mismatch br_if $mismatch
;; if ( this.buf[isegchar0+isegchar] !== this.buf[lhnchar-1] ) { break; } ;; if ( this.buf[isegchar0+isegchar] !== this.buf[lhnchar-1] ) { break; }
get_local $isegchar0 local.get $isegchar0
get_local $isegchar local.get $isegchar
i32.add i32.add
i32.load8_u i32.load8_u
get_local $lhnchar local.get $lhnchar
i32.const -1 i32.const -1
i32.add i32.add
i32.load8_u i32.load8_u
i32.ne i32.ne
br_if $mismatch br_if $mismatch
;; isegchar += 1; ;; isegchar += 1;
get_local $isegchar local.get $isegchar
i32.const 1 i32.const 1
i32.add i32.add
set_local $isegchar local.set $isegchar
;; lhnchar -= 1; ;; lhnchar -= 1;
get_local $lhnchar local.get $lhnchar
i32.const -1 i32.const -1
i32.add i32.add
set_local $lhnchar local.set $lhnchar
br 0 br 0
end end end end
end end
;; const boundaryBit = v & 0x80; ;; const boundaryBit = v & 0x80;
get_local $v local.get $v
i32.const 0x80 i32.const 0x80
i32.and i32.and
set_local $boundaryBit local.set $boundaryBit
;; if ( isegchar === lsegchar ) { ;; if ( isegchar === lsegchar ) {
get_local $isegchar local.get $isegchar
get_local $lsegchar local.get $lsegchar
i32.eq i32.eq
if if
;; if ( lhnchar === 0 ) { ;; if ( lhnchar === 0 ) {
get_local $lhnchar local.get $lhnchar
i32.eqz i32.eqz
if if
;; if ( boundaryBit !== 0 ) { return 0; } ;; if ( boundaryBit !== 0 ) { return 0; }
get_local $boundaryBit local.get $boundaryBit
if if
i32.const 0 i32.const 0
return return
end end
;; this.buf32[icell+2] = v | 0x80; ;; this.buf32[icell+2] = v | 0x80;
get_local $icell local.get $icell
get_local $v local.get $v
i32.const 0x80 i32.const 0x80
i32.or i32.or
i32.store offset=8 i32.store offset=8
else else
;; if ( boundaryBit !== 0 ) { ;; if ( boundaryBit !== 0 ) {
get_local $boundaryBit local.get $boundaryBit
if if
;; if ( this.buf[lhnchar-1] === 0x2E /* '.' */ ) { return -1; } ;; if ( this.buf[lhnchar-1] === 0x2E /* '.' */ ) { return -1; }
get_local $lhnchar local.get $lhnchar
i32.const -1 i32.const -1
i32.add i32.add
i32.load8_u i32.load8_u
@ -442,36 +442,36 @@
end end
end end
;; inext = this.buf32[icell+1]; ;; inext = this.buf32[icell+1];
get_local $icell local.get $icell
i32.load offset=4 i32.load offset=4
tee_local $inext local.tee $inext
;; if ( inext !== 0 ) { ;; if ( inext !== 0 ) {
if if
;; icell = inext; ;; icell = inext;
get_local $inext local.get $inext
i32.const 2 i32.const 2
i32.shl i32.shl
set_local $icell local.set $icell
;; continue; ;; continue;
br $nextSegment br $nextSegment
end end
;; this.buf32[icell+1] = this.addLeafCell(lhnchar); ;; this.buf32[icell+1] = this.addLeafCell(lhnchar);
get_local $icell local.get $icell
get_local $lhnchar local.get $lhnchar
call $addLeafCell call $addLeafCell
i32.store offset=4 i32.store offset=4
end end
else else
;; isegchar0 -= char0; ;; isegchar0 -= char0;
get_local $icell local.get $icell
get_local $isegchar0 local.get $isegchar0
get_local $char0 local.get $char0
i32.sub i32.sub
tee_local $isegchar0 local.tee $isegchar0
;; this.buf32[icell+2] = isegchar0 << 8 | isegchar; ;; this.buf32[icell+2] = isegchar0 << 8 | isegchar;
i32.const 8 i32.const 8
i32.shl i32.shl
get_local $isegchar local.get $isegchar
i32.or i32.or
i32.store offset=8 i32.store offset=8
;; inext = this.addCell( ;; inext = this.addCell(
@ -479,39 +479,39 @@
;; this.buf32[icell+1], ;; this.buf32[icell+1],
;; isegchar0 + isegchar << 8 | boundaryBit | lsegchar - isegchar ;; isegchar0 + isegchar << 8 | boundaryBit | lsegchar - isegchar
;; ); ;; );
get_local $icell local.get $icell
i32.const 0 i32.const 0
get_local $icell local.get $icell
i32.load offset=4 i32.load offset=4
get_local $isegchar0 local.get $isegchar0
get_local $isegchar local.get $isegchar
i32.add i32.add
i32.const 8 i32.const 8
i32.shl i32.shl
get_local $boundaryBit local.get $boundaryBit
i32.or i32.or
get_local $lsegchar local.get $lsegchar
get_local $isegchar local.get $isegchar
i32.sub i32.sub
i32.or i32.or
call $addCell call $addCell
tee_local $inext local.tee $inext
;; this.buf32[icell+1] = inext; ;; this.buf32[icell+1] = inext;
i32.store offset=4 i32.store offset=4
;; if ( lhnchar !== 0 ) { ;; if ( lhnchar !== 0 ) {
get_local $lhnchar local.get $lhnchar
if if
;; this.buf32[inext+0] = this.addLeafCell(lhnchar); ;; this.buf32[inext+0] = this.addLeafCell(lhnchar);
get_local $inext local.get $inext
i32.const 2 i32.const 2
i32.shl i32.shl
get_local $lhnchar local.get $lhnchar
call $addLeafCell call $addLeafCell
i32.store i32.store
else else
;; this.buf32[icell+2] |= 0x80; ;; this.buf32[icell+2] |= 0x80;
get_local $icell local.get $icell
get_local $icell local.get $icell
i32.load offset=8 i32.load offset=8
i32.const 0x80 i32.const 0x80
i32.or i32.or
@ -547,24 +547,24 @@
i32.const 260 i32.const 260
i32.const 260 i32.const 260
i32.load i32.load
tee_local $icell local.tee $icell
i32.const 12 i32.const 12
i32.add i32.add
i32.store i32.store
;; this.buf32[icell+0] = idown; ;; this.buf32[icell+0] = idown;
get_local $icell local.get $icell
get_local $idown local.get $idown
i32.store i32.store
;; this.buf32[icell+1] = iright; ;; this.buf32[icell+1] = iright;
get_local $icell local.get $icell
get_local $iright local.get $iright
i32.store offset=4 i32.store offset=4
;; this.buf32[icell+2] = v; ;; this.buf32[icell+2] = v;
get_local $icell local.get $icell
get_local $v local.get $v
i32.store offset=8 i32.store offset=8
;; return icell; ;; return icell;
get_local $icell local.get $icell
i32.const 2 i32.const 2
i32.shr_u i32.shr_u
) )
@ -582,58 +582,58 @@
;; const r = this.buf32[TRIE1_SLOT] >>> 2; ;; const r = this.buf32[TRIE1_SLOT] >>> 2;
i32.const 260 i32.const 260
i32.load i32.load
tee_local $r local.tee $r
;; let i = r; ;; let i = r;
set_local $i local.set $i
;; while ( lsegchar > 127 ) { ;; while ( lsegchar > 127 ) {
block $lastSegment loop block $lastSegment loop
get_local $lsegchar local.get $lsegchar
i32.const 127 i32.const 127
i32.le_u i32.le_u
br_if $lastSegment br_if $lastSegment
;; this.buf32[i+0] = 0; ;; this.buf32[i+0] = 0;
get_local $i local.get $i
i32.const 0 i32.const 0
i32.store i32.store
;; this.buf32[i+1] = i + 3; ;; this.buf32[i+1] = i + 3;
get_local $i local.get $i
get_local $i local.get $i
i32.const 12 i32.const 12
i32.add i32.add
i32.const 2 i32.const 2
i32.shr_u i32.shr_u
i32.store offset=4 i32.store offset=4
;; this.buf32[i+2] = this.addSegment(lsegchar, lsegchar - 127); ;; this.buf32[i+2] = this.addSegment(lsegchar, lsegchar - 127);
get_local $i local.get $i
get_local $lsegchar local.get $lsegchar
get_local $lsegchar local.get $lsegchar
i32.const 127 i32.const 127
i32.sub i32.sub
call $addSegment call $addSegment
i32.store offset=8 i32.store offset=8
;; lsegchar -= 127; ;; lsegchar -= 127;
get_local $lsegchar local.get $lsegchar
i32.const 127 i32.const 127
i32.sub i32.sub
set_local $lsegchar local.set $lsegchar
;; i += 3; ;; i += 3;
get_local $i local.get $i
i32.const 12 i32.const 12
i32.add i32.add
set_local $i local.set $i
br 0 br 0
end end end end
;; this.buf32[i+0] = 0; ;; this.buf32[i+0] = 0;
get_local $i local.get $i
i32.const 0 i32.const 0
i32.store i32.store
;; this.buf32[i+1] = 0; ;; this.buf32[i+1] = 0;
get_local $i local.get $i
i32.const 0 i32.const 0
i32.store offset=4 i32.store offset=4
;; this.buf32[i+2] = this.addSegment(lsegchar, 0) | 0x80; ;; this.buf32[i+2] = this.addSegment(lsegchar, 0) | 0x80;
get_local $i local.get $i
get_local $lsegchar local.get $lsegchar
i32.const 0 i32.const 0
call $addSegment call $addSegment
i32.const 0x80 i32.const 0x80
@ -641,12 +641,12 @@
i32.store offset=8 i32.store offset=8
;; this.buf32[TRIE1_SLOT] = i + 3 << 2; ;; this.buf32[TRIE1_SLOT] = i + 3 << 2;
i32.const 260 i32.const 260
get_local $i local.get $i
i32.const 12 i32.const 12
i32.add i32.add
i32.store i32.store
;; return r; ;; return r;
get_local $r local.get $r
i32.const 2 i32.const 2
i32.shr_u i32.shr_u
) )
@ -666,7 +666,7 @@
(local $i i32) ;; iterator (local $i i32) ;; iterator
;; ;;
;; if ( lsegchar === 0 ) { return 0; } ;; if ( lsegchar === 0 ) { return 0; }
get_local $lsegchar local.get $lsegchar
i32.eqz i32.eqz
if if
i32.const 0 i32.const 0
@ -675,45 +675,45 @@
;; let char1 = this.buf32[HNBIGTRIE_CHAR1_SLOT]; ;; let char1 = this.buf32[HNBIGTRIE_CHAR1_SLOT];
i32.const 268 i32.const 268
i32.load i32.load
tee_local $char1 local.tee $char1
;; const isegchar = char1 - this.buf32[HNBIGTRIE_CHAR0_SLOT]; ;; const isegchar = char1 - this.buf32[HNBIGTRIE_CHAR0_SLOT];
i32.const 264 i32.const 264
i32.load i32.load
i32.sub i32.sub
set_local $isegchar local.set $isegchar
;; let i = lsegchar; ;; let i = lsegchar;
get_local $lsegchar local.get $lsegchar
set_local $i local.set $i
;; do { ;; do {
loop loop
;; this.buf[char1++] = this.buf[--i]; ;; this.buf[char1++] = this.buf[--i];
get_local $char1 local.get $char1
get_local $i local.get $i
i32.const -1 i32.const -1
i32.add i32.add
tee_local $i local.tee $i
i32.load8_u i32.load8_u
i32.store8 i32.store8
get_local $char1 local.get $char1
i32.const 1 i32.const 1
i32.add i32.add
set_local $char1 local.set $char1
;; } while ( i !== lsegend ); ;; } while ( i !== lsegend );
get_local $i local.get $i
get_local $lsegend local.get $lsegend
i32.ne i32.ne
br_if 0 br_if 0
end end
;; this.buf32[HNBIGTRIE_CHAR1_SLOT] = char1; ;; this.buf32[HNBIGTRIE_CHAR1_SLOT] = char1;
i32.const 268 i32.const 268
get_local $char1 local.get $char1
i32.store i32.store
;; return isegchar << 8 | lsegchar - lsegend; ;; return isegchar << 8 | lsegchar - lsegend;
get_local $isegchar local.get $isegchar
i32.const 8 i32.const 8
i32.shl i32.shl
get_local $lsegchar local.get $lsegchar
get_local $lsegend local.get $lsegend
i32.sub i32.sub
i32.or i32.or
) )

View File

@ -68,15 +68,15 @@
(func (export "lz4BlockEncodeBound") (func (export "lz4BlockEncodeBound")
(param $ilen i32) (param $ilen i32)
(result i32) (result i32)
get_local $ilen local.get $ilen
i32.const 0x7E000000 i32.const 0x7E000000
i32.gt_u i32.gt_u
if if
i32.const 0 i32.const 0
return return
end end
get_local $ilen local.get $ilen
get_local $ilen local.get $ilen
i32.const 255 i32.const 255
i32.div_u i32.div_u
i32.add i32.add
@ -123,14 +123,14 @@
(local $llen i32) ;; length of found literals (local $llen i32) ;; length of found literals
(local $moffset i32) ;; offset to found match from current input position (local $moffset i32) ;; offset to found match from current input position
(local $mlen i32) ;; length of found match (local $mlen i32) ;; length of found match
get_local $ilen ;; empty input = empty output local.get $ilen ;; empty input = empty output
i32.const 0x7E000000 ;; max input size: 0x7E000000 i32.const 0x7E000000 ;; max input size: 0x7E000000
i32.gt_u i32.gt_u
if if
i32.const 0 i32.const 0
return return
end end
get_local $ilen ;; "blocks < 13 bytes cannot be compressed" local.get $ilen ;; "blocks < 13 bytes cannot be compressed"
i32.const 13 i32.const 13
i32.lt_u i32.lt_u
if if
@ -138,78 +138,78 @@
return return
end end
call $getLinearMemoryOffset ;; hash table is at start of usable memory call $getLinearMemoryOffset ;; hash table is at start of usable memory
set_local $hashPtrBeg local.set $hashPtrBeg
get_local $inPtr local.get $inPtr
tee_local $anchorPtr local.tee $anchorPtr
get_local $ilen local.get $ilen
i32.add i32.add
tee_local $inPtrEnd local.tee $inPtrEnd
i32.const -5 ;; "The last 5 bytes are always literals." i32.const -5 ;; "The last 5 bytes are always literals."
i32.add i32.add
tee_local $inPtrEnd2 local.tee $inPtrEnd2
i32.const -7 ;; "The last match must start at least 12 bytes before end of block" i32.const -7 ;; "The last match must start at least 12 bytes before end of block"
i32.add i32.add
set_local $inPtrEnd1 local.set $inPtrEnd1
get_local $outPtr local.get $outPtr
set_local $outPtrBeg local.set $outPtrBeg
;; ;;
;; sequence processing loop ;; sequence processing loop
;; ;;
block $noMoreSequence loop $nextSequence block $noMoreSequence loop $nextSequence
get_local $inPtr local.get $inPtr
get_local $inPtrEnd1 local.get $inPtrEnd1
i32.ge_u ;; 5 or less bytes left? i32.ge_u ;; 5 or less bytes left?
br_if $noMoreSequence br_if $noMoreSequence
get_local $inPtr ;; first sequence of 3 bytes before match-finding loop local.get $inPtr ;; first sequence of 3 bytes before match-finding loop
i32.load8_u i32.load8_u
i32.const 8 i32.const 8
i32.shl i32.shl
get_local $inPtr local.get $inPtr
i32.load8_u offset=1 i32.load8_u offset=1
i32.const 16 i32.const 16
i32.shl i32.shl
i32.or i32.or
get_local $inPtr local.get $inPtr
i32.load8_u offset=2 i32.load8_u offset=2
i32.const 24 i32.const 24
i32.shl i32.shl
i32.or i32.or
set_local $seq32 local.set $seq32
;; ;;
;; match-finding loop ;; match-finding loop
;; ;;
loop $findMatch block $noMatchFound loop $findMatch block $noMatchFound
get_local $inPtr local.get $inPtr
get_local $inPtrEnd2 local.get $inPtrEnd2
i32.gt_u ;; less than 12 bytes left? i32.gt_u ;; less than 12 bytes left?
br_if $noMoreSequence br_if $noMoreSequence
get_local $seq32 ;; update last byte of current sequence local.get $seq32 ;; update last byte of current sequence
i32.const 8 i32.const 8
i32.shr_u i32.shr_u
get_local $inPtr local.get $inPtr
i32.load8_u offset=3 i32.load8_u offset=3
i32.const 24 i32.const 24
i32.shl i32.shl
i32.or i32.or
tee_local $seq32 local.tee $seq32
i32.const 0x9E3779B1 ;; compute 16-bit hash i32.const 0x9E3779B1 ;; compute 16-bit hash
i32.mul i32.mul
i32.const 16 i32.const 16
i32.shr_u ;; hash value is at top of stack i32.shr_u ;; hash value is at top of stack
i32.const 2 ;; lookup refPtr at hash entry i32.const 2 ;; lookup refPtr at hash entry
i32.shl i32.shl
get_local $hashPtrBeg local.get $hashPtrBeg
i32.add i32.add
tee_local $hashPtr local.tee $hashPtr
i32.load i32.load
set_local $refPtr local.set $refPtr
get_local $hashPtr ;; update hash entry with inPtr local.get $hashPtr ;; update hash entry with inPtr
get_local $inPtr local.get $inPtr
i32.store i32.store
get_local $inPtr local.get $inPtr
get_local $refPtr local.get $refPtr
i32.sub i32.sub
tee_local $moffset ;; remember match offset, we will need it in case of match local.tee $moffset ;; remember match offset, we will need it in case of match
i32.const 0xFFFF i32.const 0xFFFF
i32.gt_s ;; match offset > 65535 = unusable match i32.gt_s ;; match offset > 65535 = unusable match
br_if $noMatchFound br_if $noMatchFound
@ -217,177 +217,177 @@
;; confirm match: different sequences can yield same hash ;; confirm match: different sequences can yield same hash
;; compare-branch each byte to potentially save memory read ops ;; compare-branch each byte to potentially save memory read ops
;; ;;
get_local $seq32 ;; byte 0 local.get $seq32 ;; byte 0
i32.const 0xFF i32.const 0xFF
i32.and i32.and
get_local $refPtr local.get $refPtr
i32.load8_u i32.load8_u
i32.ne ;; refPtr[0] !== inPtr[0] i32.ne ;; refPtr[0] !== inPtr[0]
br_if $noMatchFound br_if $noMatchFound
get_local $seq32 ;; byte 1 local.get $seq32 ;; byte 1
i32.const 8 i32.const 8
i32.shr_u i32.shr_u
i32.const 0xFF i32.const 0xFF
i32.and i32.and
get_local $refPtr local.get $refPtr
i32.load8_u offset=1 i32.load8_u offset=1
i32.ne i32.ne
br_if $noMatchFound ;; refPtr[1] !== inPtr[1] br_if $noMatchFound ;; refPtr[1] !== inPtr[1]
get_local $seq32 ;; byte 2 local.get $seq32 ;; byte 2
i32.const 16 i32.const 16
i32.shr_u i32.shr_u
i32.const 0xFF i32.const 0xFF
i32.and i32.and
get_local $refPtr local.get $refPtr
i32.load8_u offset=2 i32.load8_u offset=2
i32.ne ;; refPtr[2] !== inPtr[2] i32.ne ;; refPtr[2] !== inPtr[2]
br_if $noMatchFound br_if $noMatchFound
get_local $seq32 ;; byte 3 local.get $seq32 ;; byte 3
i32.const 24 i32.const 24
i32.shr_u i32.shr_u
i32.const 0xFF i32.const 0xFF
i32.and i32.and
get_local $refPtr local.get $refPtr
i32.load8_u offset=3 i32.load8_u offset=3
i32.ne ;; refPtr[3] !== inPtr[3] i32.ne ;; refPtr[3] !== inPtr[3]
br_if $noMatchFound br_if $noMatchFound
;; ;;
;; a valid match has been found at this point ;; a valid match has been found at this point
;; ;;
get_local $inPtr ;; compute length of literals local.get $inPtr ;; compute length of literals
get_local $anchorPtr local.get $anchorPtr
i32.sub i32.sub
set_local $llen local.set $llen
get_local $inPtr ;; find match length local.get $inPtr ;; find match length
i32.const 4 ;; skip over confirmed 4-byte match i32.const 4 ;; skip over confirmed 4-byte match
i32.add i32.add
set_local $inPtr local.set $inPtr
get_local $refPtr local.get $refPtr
i32.const 4 i32.const 4
i32.add i32.add
tee_local $mlen ;; remember refPtr to later compute match length local.tee $mlen ;; remember refPtr to later compute match length
set_local $refPtr local.set $refPtr
block $endOfMatch loop ;; scan input buffer until match ends block $endOfMatch loop ;; scan input buffer until match ends
get_local $inPtr local.get $inPtr
get_local $inPtrEnd2 local.get $inPtrEnd2
i32.ge_u i32.ge_u
br_if $endOfMatch br_if $endOfMatch
get_local $inPtr local.get $inPtr
i32.load8_u i32.load8_u
get_local $refPtr local.get $refPtr
i32.load8_u i32.load8_u
i32.ne i32.ne
br_if $endOfMatch br_if $endOfMatch
get_local $inPtr local.get $inPtr
i32.const 1 i32.const 1
i32.add i32.add
set_local $inPtr local.set $inPtr
get_local $refPtr local.get $refPtr
i32.const 1 i32.const 1
i32.add i32.add
set_local $refPtr local.set $refPtr
br 0 br 0
end end $endOfMatch end end $endOfMatch
;; encode token ;; encode token
get_local $outPtr ;; output token local.get $outPtr ;; output token
get_local $llen local.get $llen
get_local $refPtr local.get $refPtr
get_local $mlen local.get $mlen
i32.sub i32.sub
tee_local $mlen local.tee $mlen
call $writeToken call $writeToken
get_local $outPtr local.get $outPtr
i32.const 1 i32.const 1
i32.add i32.add
set_local $outPtr local.set $outPtr
get_local $llen ;; encode/write length of literals if needed local.get $llen ;; encode/write length of literals if needed
i32.const 15 i32.const 15
i32.ge_s i32.ge_s
if if
get_local $outPtr local.get $outPtr
get_local $llen local.get $llen
call $writeLength call $writeLength
set_local $outPtr local.set $outPtr
end end
;; copy literals ;; copy literals
get_local $outPtr local.get $outPtr
get_local $anchorPtr local.get $anchorPtr
get_local $llen local.get $llen
call $copy call $copy
get_local $outPtr local.get $outPtr
get_local $llen local.get $llen
i32.add i32.add
set_local $outPtr local.set $outPtr
;; encode match offset ;; encode match offset
get_local $outPtr local.get $outPtr
get_local $moffset local.get $moffset
i32.store8 i32.store8
get_local $outPtr local.get $outPtr
get_local $moffset local.get $moffset
i32.const 8 i32.const 8
i32.shr_u i32.shr_u
i32.store8 offset=1 i32.store8 offset=1
get_local $outPtr local.get $outPtr
i32.const 2 i32.const 2
i32.add i32.add
set_local $outPtr local.set $outPtr
get_local $mlen ;; encode/write length of match if needed local.get $mlen ;; encode/write length of match if needed
i32.const 15 i32.const 15
i32.ge_s i32.ge_s
if if
get_local $outPtr local.get $outPtr
get_local $mlen local.get $mlen
call $writeLength call $writeLength
set_local $outPtr local.set $outPtr
end end
get_local $inPtr ;; advance anchor to current position local.get $inPtr ;; advance anchor to current position
set_local $anchorPtr local.set $anchorPtr
br $nextSequence br $nextSequence
end $noMatchFound end $noMatchFound
get_local $inPtr ;; no match found: advance to next byte local.get $inPtr ;; no match found: advance to next byte
i32.const 1 i32.const 1
i32.add i32.add
set_local $inPtr local.set $inPtr
br $findMatch end ;; match offset > 65535 = unusable match br $findMatch end ;; match offset > 65535 = unusable match
end end $noMoreSequence end end $noMoreSequence
;; ;;
;; generate last (match-less) sequence if compression succeeded ;; generate last (match-less) sequence if compression succeeded
;; ;;
get_local $outPtr local.get $outPtr
get_local $outPtrBeg local.get $outPtrBeg
i32.eq i32.eq
if if
i32.const 0 i32.const 0
return return
end end
get_local $outPtr local.get $outPtr
get_local $inPtrEnd local.get $inPtrEnd
get_local $anchorPtr local.get $anchorPtr
i32.sub i32.sub
tee_local $llen local.tee $llen
i32.const 0 i32.const 0
call $writeToken call $writeToken
get_local $outPtr local.get $outPtr
i32.const 1 i32.const 1
i32.add i32.add
set_local $outPtr local.set $outPtr
get_local $llen local.get $llen
i32.const 15 i32.const 15
i32.ge_u i32.ge_u
if if
get_local $outPtr local.get $outPtr
get_local $llen local.get $llen
call $writeLength call $writeLength
set_local $outPtr local.set $outPtr
end end
get_local $outPtr local.get $outPtr
get_local $anchorPtr local.get $anchorPtr
get_local $llen local.get $llen
call $copy call $copy
get_local $outPtr ;; return number of written bytes local.get $outPtr ;; return number of written bytes
get_local $llen local.get $llen
i32.add i32.add
get_local $outPtrBeg local.get $outPtrBeg
i32.sub i32.sub
) )
@ -413,128 +413,128 @@
(local $token i32) ;; sequence token (local $token i32) ;; sequence token
(local $clen i32) ;; number of bytes to copy (local $clen i32) ;; number of bytes to copy
(local $_ i32) ;; general purpose variable (local $_ i32) ;; general purpose variable
get_local $ilen ;; if ( ilen == 0 ) { return 0; } local.get $ilen ;; if ( ilen == 0 ) { return 0; }
i32.eqz i32.eqz
if if
i32.const 0 i32.const 0
return return
end end
get_local $inPtr0 local.get $inPtr0
tee_local $inPtr ;; current position in input buffer local.tee $inPtr ;; current position in input buffer
get_local $ilen local.get $ilen
i32.add i32.add
set_local $inPtrEnd local.set $inPtrEnd
get_local $outPtr0 ;; start of output buffer local.get $outPtr0 ;; start of output buffer
set_local $outPtr ;; current position in output buffer local.set $outPtr ;; current position in output buffer
block $noMoreSequence loop ;; iterate through all sequences block $noMoreSequence loop ;; iterate through all sequences
get_local $inPtr local.get $inPtr
get_local $inPtrEnd local.get $inPtrEnd
i32.ge_u i32.ge_u
br_if $noMoreSequence ;; break when nothing left to read in input buffer br_if $noMoreSequence ;; break when nothing left to read in input buffer
get_local $inPtr ;; read token -- consume one byte local.get $inPtr ;; read token -- consume one byte
i32.load8_u i32.load8_u
get_local $inPtr local.get $inPtr
i32.const 1 i32.const 1
i32.add i32.add
set_local $inPtr local.set $inPtr
tee_local $token ;; extract length of literals from token local.tee $token ;; extract length of literals from token
i32.const 4 i32.const 4
i32.shr_u i32.shr_u
tee_local $clen ;; consume extra length bytes if present local.tee $clen ;; consume extra length bytes if present
i32.eqz i32.eqz
if else if else
get_local $clen local.get $clen
i32.const 15 i32.const 15
i32.eq i32.eq
if loop if loop
get_local $inPtr local.get $inPtr
i32.load8_u i32.load8_u
get_local $inPtr local.get $inPtr
i32.const 1 i32.const 1
i32.add i32.add
set_local $inPtr local.set $inPtr
tee_local $_ local.tee $_
get_local $clen local.get $clen
i32.add i32.add
set_local $clen local.set $clen
get_local $_ local.get $_
i32.const 255 i32.const 255
i32.eq i32.eq
br_if 0 br_if 0
end end end end
get_local $outPtr ;; copy literals to ouput buffer local.get $outPtr ;; copy literals to ouput buffer
get_local $inPtr local.get $inPtr
get_local $clen local.get $clen
call $copy call $copy
get_local $outPtr ;; advance output buffer pointer past copy local.get $outPtr ;; advance output buffer pointer past copy
get_local $clen local.get $clen
i32.add i32.add
set_local $outPtr local.set $outPtr
get_local $clen ;; advance input buffer pointer past literals local.get $clen ;; advance input buffer pointer past literals
get_local $inPtr local.get $inPtr
i32.add i32.add
tee_local $inPtr local.tee $inPtr
get_local $inPtrEnd ;; exit if this is the last sequence local.get $inPtrEnd ;; exit if this is the last sequence
i32.eq i32.eq
br_if $noMoreSequence br_if $noMoreSequence
end end
get_local $outPtr ;; read match offset local.get $outPtr ;; read match offset
get_local $inPtr local.get $inPtr
i32.load8_u i32.load8_u
get_local $inPtr local.get $inPtr
i32.load8_u offset=1 i32.load8_u offset=1
i32.const 8 i32.const 8
i32.shl i32.shl
i32.or i32.or
i32.sub i32.sub
tee_local $matchPtr local.tee $matchPtr
get_local $outPtr ;; match position can't be outside input buffer bounds local.get $outPtr ;; match position can't be outside input buffer bounds
i32.eq i32.eq
br_if $noMoreSequence br_if $noMoreSequence
get_local $matchPtr local.get $matchPtr
get_local $inPtrEnd local.get $inPtrEnd
i32.lt_u i32.lt_u
br_if $noMoreSequence br_if $noMoreSequence
get_local $inPtr ;; advance input pointer past match offset bytes local.get $inPtr ;; advance input pointer past match offset bytes
i32.const 2 i32.const 2
i32.add i32.add
set_local $inPtr local.set $inPtr
get_local $token ;; extract length of match from token local.get $token ;; extract length of match from token
i32.const 15 i32.const 15
i32.and i32.and
i32.const 4 i32.const 4
i32.add i32.add
tee_local $clen local.tee $clen
i32.const 19 ;; consume extra length bytes if present i32.const 19 ;; consume extra length bytes if present
i32.eq i32.eq
if loop if loop
get_local $inPtr local.get $inPtr
i32.load8_u i32.load8_u
get_local $inPtr local.get $inPtr
i32.const 1 i32.const 1
i32.add i32.add
set_local $inPtr local.set $inPtr
tee_local $_ local.tee $_
get_local $clen local.get $clen
i32.add i32.add
set_local $clen local.set $clen
get_local $_ local.get $_
i32.const 255 i32.const 255
i32.eq i32.eq
br_if 0 br_if 0
end end end end
get_local $outPtr ;; copy match to ouput buffer local.get $outPtr ;; copy match to ouput buffer
get_local $matchPtr local.get $matchPtr
get_local $clen local.get $clen
call $copy call $copy
get_local $clen ;; advance output buffer pointer past copy local.get $clen ;; advance output buffer pointer past copy
get_local $outPtr local.get $outPtr
i32.add i32.add
set_local $outPtr local.set $outPtr
br 0 br 0
end end $noMoreSequence end end $noMoreSequence
get_local $outPtr ;; return number of written bytes local.get $outPtr ;; return number of written bytes
get_local $outPtr0 local.get $outPtr0
i32.sub i32.sub
) )
@ -552,18 +552,18 @@
(param $outPtr i32) (param $outPtr i32)
(param $llen i32) (param $llen i32)
(param $mlen i32) (param $mlen i32)
get_local $outPtr local.get $outPtr
get_local $llen local.get $llen
i32.const 15 i32.const 15
get_local $llen local.get $llen
i32.const 15 i32.const 15
i32.lt_u i32.lt_u
select select
i32.const 4 i32.const 4
i32.shl i32.shl
get_local $mlen local.get $mlen
i32.const 15 i32.const 15
get_local $mlen local.get $mlen
i32.const 15 i32.const 15
i32.lt_u i32.lt_u
select select
@ -582,32 +582,32 @@
(param $outPtr i32) (param $outPtr i32)
(param $len i32) (param $len i32)
(result i32) (result i32)
get_local $len local.get $len
i32.const 15 i32.const 15
i32.sub i32.sub
set_local $len local.set $len
loop loop
get_local $outPtr local.get $outPtr
get_local $len local.get $len
i32.const 255 i32.const 255
get_local $len local.get $len
i32.const 255 i32.const 255
i32.lt_u i32.lt_u
select select
i32.store8 i32.store8
get_local $outPtr local.get $outPtr
i32.const 1 i32.const 1
i32.add i32.add
set_local $outPtr local.set $outPtr
get_local $len local.get $len
i32.const 255 i32.const 255
i32.sub i32.sub
tee_local $len local.tee $len
i32.const 0 i32.const 0
i32.ge_s i32.ge_s
br_if 0 br_if 0
end end
get_local $outPtr local.get $outPtr
) )
;; ;;
@ -621,119 +621,119 @@
(param $src i32) (param $src i32)
(param $len i32) (param $len i32)
block $lessThan8 loop block $lessThan8 loop
get_local $len local.get $len
i32.const 8 i32.const 8
i32.lt_u i32.lt_u
br_if $lessThan8 br_if $lessThan8
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u i32.load8_u
i32.store8 i32.store8
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=1 i32.load8_u offset=1
i32.store8 offset=1 i32.store8 offset=1
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=2 i32.load8_u offset=2
i32.store8 offset=2 i32.store8 offset=2
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=3 i32.load8_u offset=3
i32.store8 offset=3 i32.store8 offset=3
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=4 i32.load8_u offset=4
i32.store8 offset=4 i32.store8 offset=4
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=5 i32.load8_u offset=5
i32.store8 offset=5 i32.store8 offset=5
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=6 i32.load8_u offset=6
i32.store8 offset=6 i32.store8 offset=6
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=7 i32.load8_u offset=7
i32.store8 offset=7 i32.store8 offset=7
get_local $dst local.get $dst
i32.const 8 i32.const 8
i32.add i32.add
set_local $dst local.set $dst
get_local $src local.get $src
i32.const 8 i32.const 8
i32.add i32.add
set_local $src local.set $src
get_local $len local.get $len
i32.const -8 i32.const -8
i32.add i32.add
set_local $len local.set $len
br 0 br 0
end end $lessThan8 end end $lessThan8
get_local $len local.get $len
i32.const 4 i32.const 4
i32.ge_u i32.ge_u
if if
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u i32.load8_u
i32.store8 i32.store8
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=1 i32.load8_u offset=1
i32.store8 offset=1 i32.store8 offset=1
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=2 i32.load8_u offset=2
i32.store8 offset=2 i32.store8 offset=2
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=3 i32.load8_u offset=3
i32.store8 offset=3 i32.store8 offset=3
get_local $dst local.get $dst
i32.const 4 i32.const 4
i32.add i32.add
set_local $dst local.set $dst
get_local $src local.get $src
i32.const 4 i32.const 4
i32.add i32.add
set_local $src local.set $src
get_local $len local.get $len
i32.const -4 i32.const -4
i32.add i32.add
set_local $len local.set $len
end end
get_local $len local.get $len
i32.const 2 i32.const 2
i32.ge_u i32.ge_u
if if
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u i32.load8_u
i32.store8 i32.store8
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u offset=1 i32.load8_u offset=1
i32.store8 offset=1 i32.store8 offset=1
get_local $dst local.get $dst
i32.const 2 i32.const 2
i32.add i32.add
set_local $dst local.set $dst
get_local $src local.get $src
i32.const 2 i32.const 2
i32.add i32.add
set_local $src local.set $src
get_local $len local.get $len
i32.const -2 i32.const -2
i32.add i32.add
set_local $len local.set $len
end end
get_local $len local.get $len
i32.eqz i32.eqz
if else if else
get_local $dst local.get $dst
get_local $src local.get $src
i32.load8_u i32.load8_u
i32.store8 i32.store8
end end

View File

@ -83,133 +83,133 @@
;; const iCharData = buf32[CHARDATA_PTR_SLOT]; ;; const iCharData = buf32[CHARDATA_PTR_SLOT];
i32.const 404 i32.const 404
i32.load i32.load
set_local $iCharData local.set $iCharData
;; let iNode = pslBuffer32[RULES_PTR_SLOT]; ;; let iNode = pslBuffer32[RULES_PTR_SLOT];
i32.const 400 i32.const 400
i32.load i32.load
i32.const 2 i32.const 2
i32.shl i32.shl
set_local $iNode local.set $iNode
;; let iLabel = LABEL_INDICES_SLOT; ;; let iLabel = LABEL_INDICES_SLOT;
i32.const 256 i32.const 256
set_local $iLabel local.set $iLabel
;; let cursorPos = -1; ;; let cursorPos = -1;
i32.const -1 i32.const -1
set_local $cursorPos local.set $cursorPos
;; label-lookup loop ;; label-lookup loop
;; for (;;) { ;; for (;;) {
block $labelLookupDone loop $labelLookup block $labelLookupDone loop $labelLookup
;; // Extract label indices ;; // Extract label indices
;; const labelBeg = buf8[iLabel+1]; ;; const labelBeg = buf8[iLabel+1];
;; const labelLen = buf8[iLabel+0] - labelBeg; ;; const labelLen = buf8[iLabel+0] - labelBeg;
get_local $iLabel local.get $iLabel
i32.load8_u i32.load8_u
get_local $iLabel local.get $iLabel
i32.load8_u offset=1 i32.load8_u offset=1
tee_local $labelBeg local.tee $labelBeg
i32.sub i32.sub
set_local $labelLen local.set $labelLen
;; // Match-lookup loop: binary search ;; // Match-lookup loop: binary search
;; let r = buf32[iNode+0] >>> 16; ;; let r = buf32[iNode+0] >>> 16;
;; if ( r === 0 ) { break; } ;; if ( r === 0 ) { break; }
get_local $iNode local.get $iNode
i32.load16_u offset=2 i32.load16_u offset=2
tee_local $r local.tee $r
i32.eqz i32.eqz
br_if $labelLookupDone br_if $labelLookupDone
;; const iCandidates = buf32[iNode+2]; ;; const iCandidates = buf32[iNode+2];
get_local $iNode local.get $iNode
i32.load offset=8 i32.load offset=8
i32.const 2 i32.const 2
i32.shl i32.shl
set_local $iCandidates local.set $iCandidates
;; let l = 0; ;; let l = 0;
;; let iFound = 0; ;; let iFound = 0;
i32.const 0 i32.const 0
tee_local $l local.tee $l
set_local $iFound local.set $iFound
;; while ( l < r ) { ;; while ( l < r ) {
block $binarySearchDone loop $binarySearch block $binarySearchDone loop $binarySearch
get_local $l local.get $l
get_local $r local.get $r
i32.ge_u i32.ge_u
br_if $binarySearchDone br_if $binarySearchDone
;; const iCandidate = l + r >>> 1; ;; const iCandidate = l + r >>> 1;
get_local $l local.get $l
get_local $r local.get $r
i32.add i32.add
i32.const 1 i32.const 1
i32.shr_u i32.shr_u
tee_local $iCandidate local.tee $iCandidate
;; const iCandidateNode = iCandidates + iCandidate + (iCandidate << 1); ;; const iCandidateNode = iCandidates + iCandidate + (iCandidate << 1);
i32.const 2 i32.const 2
i32.shl i32.shl
tee_local $_1 local.tee $_1
get_local $_1 local.get $_1
i32.const 1 i32.const 1
i32.shl i32.shl
i32.add i32.add
get_local $iCandidates local.get $iCandidates
i32.add i32.add
tee_local $iCandidateNode local.tee $iCandidateNode
;; const candidateLen = buf32[iCandidateNode+0] & 0x000000FF; ;; const candidateLen = buf32[iCandidateNode+0] & 0x000000FF;
i32.load8_u i32.load8_u
set_local $candidateLen local.set $candidateLen
;; let d = labelLen - candidateLen; ;; let d = labelLen - candidateLen;
get_local $labelLen local.get $labelLen
get_local $candidateLen local.get $candidateLen
i32.sub i32.sub
tee_local $d local.tee $d
;; if ( d === 0 ) { ;; if ( d === 0 ) {
i32.eqz i32.eqz
if if
;; const iCandidateChar = candidateLen <= 4 ;; const iCandidateChar = candidateLen <= 4
get_local $candidateLen local.get $candidateLen
i32.const 4 i32.const 4
i32.le_u i32.le_u
if if
;; ? iCandidateNode + 1 << 2 ;; ? iCandidateNode + 1 << 2
get_local $iCandidateNode local.get $iCandidateNode
i32.const 4 i32.const 4
i32.add i32.add
set_local $iCandidateChar local.set $iCandidateChar
else else
;; : buf32[CHARDATA_PTR_SLOT] + buf32[iCandidateNode+1]; ;; : buf32[CHARDATA_PTR_SLOT] + buf32[iCandidateNode+1];
get_local $iCharData local.get $iCharData
get_local $iCandidateNode local.get $iCandidateNode
i32.load offset=4 i32.load offset=4
i32.add i32.add
set_local $iCandidateChar local.set $iCandidateChar
end end
;; for ( let i = 0; i < labelLen; i++ ) { ;; for ( let i = 0; i < labelLen; i++ ) {
get_local $labelBeg local.get $labelBeg
tee_local $_1 local.tee $_1
get_local $labelLen local.get $labelLen
i32.add i32.add
set_local $_3 local.set $_3
get_local $iCandidateChar local.get $iCandidateChar
set_local $_2 local.set $_2
block $findDiffDone loop $findDiff block $findDiffDone loop $findDiff
;; d = buf8[labelBeg+i] - buf8[iCandidateChar+i]; ;; d = buf8[labelBeg+i] - buf8[iCandidateChar+i];
;; if ( d !== 0 ) { break; } ;; if ( d !== 0 ) { break; }
get_local $_1 local.get $_1
i32.load8_u i32.load8_u
get_local $_2 local.get $_2
i32.load8_u i32.load8_u
i32.sub i32.sub
tee_local $d local.tee $d
br_if $findDiffDone br_if $findDiffDone
get_local $_1 local.get $_1
i32.const 1 i32.const 1
i32.add i32.add
tee_local $_1 local.tee $_1
get_local $_3 local.get $_3
i32.eq i32.eq
br_if $findDiffDone br_if $findDiffDone
get_local $_2 local.get $_2
i32.const 1 i32.const 1
i32.add i32.add
set_local $_2 local.set $_2
br $findDiff br $findDiff
;; } ;; }
end end end end
@ -217,32 +217,32 @@
end end
;; if ( d < 0 ) { ;; if ( d < 0 ) {
;; r = iCandidate; ;; r = iCandidate;
get_local $d local.get $d
i32.const 0 i32.const 0
i32.lt_s i32.lt_s
if if
get_local $iCandidate local.get $iCandidate
set_local $r local.set $r
br $binarySearch br $binarySearch
end end
;; } else if ( d > 0 ) { ;; } else if ( d > 0 ) {
;; l = iCandidate + 1; ;; l = iCandidate + 1;
get_local $d local.get $d
i32.const 0 i32.const 0
i32.gt_s i32.gt_s
if if
get_local $iCandidate local.get $iCandidate
i32.const 1 i32.const 1
i32.add i32.add
set_local $l local.set $l
br $binarySearch br $binarySearch
end end
;; } else /* if ( d === 0 ) */ { ;; } else /* if ( d === 0 ) */ {
;; iFound = iCandidateNode; ;; iFound = iCandidateNode;
;; break; ;; break;
;; } ;; }
get_local $iCandidateNode local.get $iCandidateNode
set_local $iFound local.set $iFound
end end end end
;; } ;; }
;; // 2. If no rules match, the prevailing rule is "*". ;; // 2. If no rules match, the prevailing rule is "*".
@ -251,10 +251,10 @@
;; buf8[SUFFIX_NOT_FOUND_SLOT] = 1; ;; buf8[SUFFIX_NOT_FOUND_SLOT] = 1;
;; iFound = iCandidates; ;; iFound = iCandidates;
;; } ;; }
get_local $iFound local.get $iFound
i32.eqz i32.eqz
if if
get_local $iCandidates local.get $iCandidates
i32.load offset=4 i32.load offset=4
i32.const 0x2A i32.const 0x2A
i32.ne i32.ne
@ -262,12 +262,12 @@
i32.const 399 i32.const 399
i32.const 1 i32.const 1
i32.store8 i32.store8
get_local $iCandidates local.get $iCandidates
set_local $iFound local.set $iFound
end end
;; iNode = iFound; ;; iNode = iFound;
get_local $iFound local.get $iFound
tee_local $iNode local.tee $iNode
;; // 5. If the prevailing rule is a exception rule, modify it by ;; // 5. If the prevailing rule is a exception rule, modify it by
;; // removing the leftmost label. ;; // removing the leftmost label.
;; if ( (buf32[iNode+0] & 0x00000200) !== 0 ) { ;; if ( (buf32[iNode+0] & 0x00000200) !== 0 ) {
@ -277,15 +277,15 @@
;; break; ;; break;
;; } ;; }
i32.load8_u offset=1 i32.load8_u offset=1
tee_local $_1 local.tee $_1
i32.const 0x02 i32.const 0x02
i32.and i32.and
if if
get_local $iLabel local.get $iLabel
i32.const 256 i32.const 256
i32.gt_u i32.gt_u
if if
get_local $iLabel local.get $iLabel
i32.const -2 i32.const -2
i32.add i32.add
return return
@ -295,25 +295,25 @@
;; if ( (buf32[iNode+0] & 0x00000100) !== 0 ) { ;; if ( (buf32[iNode+0] & 0x00000100) !== 0 ) {
;; cursorPos = labelBeg; ;; cursorPos = labelBeg;
;; } ;; }
get_local $_1 local.get $_1
i32.const 0x01 i32.const 0x01
i32.and i32.and
if if
get_local $iLabel local.get $iLabel
set_local $cursorPos local.set $cursorPos
end end
;; if ( labelBeg === 0 ) { break; } ;; if ( labelBeg === 0 ) { break; }
get_local $labelBeg local.get $labelBeg
i32.eqz i32.eqz
br_if $labelLookupDone br_if $labelLookupDone
;; iLabel += 2; ;; iLabel += 2;
get_local $iLabel local.get $iLabel
i32.const 2 i32.const 2
i32.add i32.add
set_local $iLabel local.set $iLabel
br $labelLookup br $labelLookup
end end end end
get_local $cursorPos local.get $cursorPos
) )
;; ;;