From 6bad547d3d129f9e9af69eff92339295aad74d94 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Mon, 12 May 2025 10:54:05 +0100 Subject: [PATCH] Unknown haystack length. --- sqlite3/libc/libc.wasm | Bin 5734 -> 5218 bytes sqlite3/libc/libc.wat | 1977 +++++++++++++++++-------------------- sqlite3/libc/libc_test.go | 1 + sqlite3/libc/math.h | 4 +- sqlite3/libc/string.h | 66 +- 5 files changed, 945 insertions(+), 1103 deletions(-) diff --git a/sqlite3/libc/libc.wasm b/sqlite3/libc/libc.wasm index d05849f44599d618082f3ebf47a6bac49008ff41..1fa577ae131e06b67fb164c937a514a4c9beb5e4 100755 GIT binary patch delta 2002 zcmaJ?OK%)S5UzgA%+B^c#;@35L2BBH1WLH(z=iEYhypSO`IbwtY)fV~>+B08D~AdH zAd!z8IPwGX6Zj7tbKn41jvO+GuX@%_6eQN(ncC{AuijmM-1+?@M@Nf^A|iD=ec^UL zPHOq6`dce+GVkpu`4|!zB5g^7QYv|If3K!=aymJlUXaQ_OrHF3N-DA@Q__(*o0E~V z`7tP)E|&Ahr{|OiaSWj}192`?mJ91_e*XPq>cnFxKUyTV#b&&dhvSg2n5P>h~V zs2>lPa~g`NV{xcxfsdB7hQq0_)*~v24V+ESg|*pAf!a!Dizo9X-RLRR{b_IK<*(|) zBu#><3j6ZUbYSgYTBVnNcR#32Y1stzxgD_`I=1hE~ns(gpdgFZ1{<1qXZqQ${1 z%7CTulZwI6h36bzu6(T4Vr(!7WlXIMe=$-)LT$f4IPAZ>Y>%)*h z*GmZ4yQ+KQUDM3X3*1Y5!1RJ=fl5Y6sK59}%t&$$?sspHiBY;~`;Pg%np zRAO4XWvWN;EkV*!0T*>dQeTAvepmQq#*lS-q(`4oD3+X#LoxOPCMiSK49j&+@Z13I zpel!~B`1Y}Jg+kWydk1yk2jcv@@vgr^OfIh4)65|GRQal=C$UyPoXYr)iaJan-lMF z4wM=g?yT~ez;?JOlR#w;id~BFKC6@|+$=It0Kv2@kwx=B8R#zDyG(9mIhIp_ap&>RdyU>OPfJ$Wq zDveJ8lpMpLPv-Yx)T@HRqO@s+2C%iaCHmh2j7*vhAEzrZWUnR{h)R_mv`;;x|C zwmcN3Gp`%6Z8P*;6!B}HH-|8iHzyc2LZX*5Z~Dri8lq8@IhvuUO3hKV z&iPsm;7ELPQW_LNJe1j$D#Nt216)ut)fuv(io_$8Rk*n?9N0n%-=1?63WI{6-kI~{ z&731A2Q_ff?s3qKP?+>M=N7Q$f9E{*w3a-My^TdN?VJl9+*hTMpmA?_X`=R?Sk1Zg zPvq5dd4zV*JK>!z!I8pvEteYV zjQ(N0`?`C%vA+2*VX8cCCy^?)y?Wh+T}V`+z1Q5%3Is`)+by0$qH-J82iI(O>)K+m zefi`1Ew%mfm-V|^nafw3cj}$Ez!s;=c56*9+NCv_n$_~MSGy~2EUd0HE|JMJYd6Pa z+Ih3L@_2SO@5-5MEhh}Ds-7@pXY~aZ|AWD!M|kby`)Gdj-STJ{C71K!YJsh__(x0G eTC%=2BKY(|R#seITdlLa!mIQ zM~aA4X`jWbg=x?zxVWNx3rKiGT9d{|Df4W5tx@4|kWW!|CL~?mmSw*ukPG!eC!Uovx7fCi`DKpsr^_peJlE8Vl)gyia{0?Z_wz z8`*SsM5$*^CzQ)pJ7UnFReWzsOJI(LbjEAN;4FCKeIcD|S7CJC9vnWLOzA>jsosz8 zuQW6((3`~T&1T4&gFGut4Dr8W9W|ZD ztT?y@wb)L>77m7Gx5_pkpKl*rH?S4^7Ln*1mYu@tbr=*uk*&cf!<&g>D?FPJ4CYRK zrGY@mSQ|54qbi@W9aj0U>}^6_=&~Z_2;T%@P<7D_*0C{`LZgqt8YlB;thuc+b+^TZ z)ZH(|7l{U&y}A^?xyzlLt|yiaEMRj`8W<5ba6`$4(cCc(INE4^#o9dFdw<#vW zwPDeXD=KV&F!+>cHsYOZCI1LJWMC_SABwwmX}PsZ zr+TSAE$wRcM8AkhuY>+X4=cF4S|Uo@a4xKxLk{Y)=Z^(~7}m&O=mur%`h6lw&{Omb z-Tk79l)>m=(nar~$8$z5jK*MQ(L?lT&KU>?V^ZiEJwO*-OB`~q8XuHVEm?B|Bqowr zu#t3>nfqS3pH$g*s|3etWM|23LelmB0smxoTVM`c^CqtQPGLd*HtF<@ObEL#5s*9B zlwpkW#`w9CxjvpZq=gV16DZ&e?kC2E5{~1x=$Th$7L?o9l~cH&J8E@zx;;sPG@O65 zQTz7Vq5^s2)F_)+`HJnA55+S?_3#BqY5tR&y?B`H= zvbRUV;D+D`4o>F}ki%02bKKK@F8(j7OmS;)BRxn&+`Ew|0SkZ50}h9k9=1mgx6P-` zevB;3y@C}jyi`ql!RC1M7AR^?V9|etqM%A^pxpn0NDUy#i1Du=$>Ro4iHRdY6!B61 zfJ0_js#}Q$FOWZhoMUVfIDQSAJo+x8Q-WnDFo^xraVlO3K!x$IN(YU8tO571p$q`4 z7?WUtc4VluvupO;Rm*|P%FwO3&r0iV0|TwQ4_u=vJD3X8su&<45_w?}Ih+{03L<*P z0=(v8P#%jQ9vuXMU@6Q8eoGpWP%%OIXGWeo)_I6Ps650g1v!d86cCoc$;)MCFSAQ& z$W)g>OU##NALZ|;aJH2%Uyvu^1<(*;myX4-;+y=ET7LdRepM?o`+ezhvqI(z6bHV{ zINY7;dAZS+7NfD5ml*b_!tiwk3XI4<^`mj8ecwmp?yKse=XraRSa?!f^o4+eA`yaA z7OAMkFWc$}EsVbzrIP2ApA4y5!i;MH^it(chZE3MQ`|Zrr Fe*yBu?d$*m diff --git a/sqlite3/libc/libc.wat b/sqlite3/libc/libc.wat index 12d33e1..9db0a23 100644 --- a/sqlite3/libc/libc.wat +++ b/sqlite3/libc/libc.wat @@ -3,7 +3,8 @@ (type $1 (func (param i32 i32 i32) (result i32))) (type $2 (func (param i32 i32 i32 i32) (result i32))) (type $3 (func (param i32) (result i32))) - (type $4 (func (param i32 i32 i32 i32))) + (type $4 (func (param i32 i32 i32 i32 i32) (result i32))) + (type $5 (func (param i32 i32 i32 i32))) (memory $0 256) (data $0 (i32.const 4096) "\01") (table $0 1 1 funcref) @@ -31,114 +32,6 @@ (export "stpncpy" (func $stpncpy)) (export "strncpy" (func $strncpy)) (export "qsort" (func $qsort)) - (func $bcmp (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (block $block - (if - (i32.ge_u - (local.get $2) - (i32.const 16) - ) - (then - (local.set $4 - (i32.const 1) - ) - (loop $label - (br_if $block - (v128.any_true - (v128.xor - (v128.load align=1 - (local.get $1) - ) - (v128.load align=1 - (local.get $0) - ) - ) - ) - ) - (local.set $1 - (i32.add - (local.get $1) - (local.tee $3 - (i32.add - (i32.and - (i32.sub - (local.get $2) - (i32.const 1) - ) - (i32.const 15) - ) - (i32.const 1) - ) - ) - ) - ) - (local.set $0 - (i32.add - (local.get $0) - (local.get $3) - ) - ) - (br_if $label - (local.tee $2 - (i32.sub - (local.get $2) - (local.get $3) - ) - ) - ) - ) - (return - (i32.const 0) - ) - ) - ) - (br_if $block - (i32.eqz - (local.get $2) - ) - ) - (loop $label1 - (if - (i32.ne - (i32.load8_u - (local.get $0) - ) - (i32.load8_u - (local.get $1) - ) - ) - (then - (return - (i32.const 1) - ) - ) - ) - (local.set $1 - (i32.add - (local.get $1) - (i32.const 1) - ) - ) - (local.set $0 - (i32.add - (local.get $0) - (i32.const 1) - ) - ) - (br_if $label1 - (local.tee $2 - (i32.sub - (local.get $2) - (i32.const 1) - ) - ) - ) - ) - ) - (local.get $4) - ) (func $memset (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (memory.fill (local.get $0) @@ -1949,6 +1842,11 @@ ) (func $memmem (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) (if (i32.eqz (local.get $3) @@ -1975,71 +1873,48 @@ (local.get $1) ) ) - (br_if $block + (if (i32.eq (local.get $3) (i32.const 1) ) + (then + (return + (local.get $4) + ) + ) ) - (br_if $block + (if (i32.eqz (local.get $4) ) - ) - (local.set $4 - (call $__memmem - (local.get $4) - (i32.sub - (i32.add - (local.get $0) - (local.get $1) - ) + (then + (return (local.get $4) ) - (local.get $2) + ) + ) + (br_if $block + (i32.lt_u + (local.tee $8 + (i32.add + (i32.sub + (local.get $0) + (local.get $4) + ) + (local.get $1) + ) + ) (local.get $3) ) ) - ) - (local.get $4) - ) - (func $__memmem (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 v128) - (local $12 v128) - (local $13 v128) - (local $14 v128) - (local $15 v128) - (local $16 v128) - (local $17 v128) - (local $18 v128) - (if - (i32.lt_u - (local.get $1) - (local.get $3) - ) - (then - (return - (i32.const 0) - ) - ) - ) - (block $block2 (if (i32.eqz (i32.and (i32.gt_u - (local.tee $9 - (i32.sub - (local.get $1) - (local.get $3) - ) + (i32.sub + (local.get $8) + (local.get $3) ) (i32.const 15) ) @@ -2050,269 +1925,14 @@ ) ) (then - (local.set $7 - (i32.load8_u - (local.get $2) - ) - ) - (local.set $5 - (local.tee $8 - (i32.sub - (local.get $3) - (i32.const 1) - ) - ) - ) - (block $block - (loop $label - (br_if $block - (i32.ne - (local.get $7) - (local.tee $6 - (i32.load8_u - (i32.add - (local.get $2) - (local.get $5) - ) - ) - ) - ) - ) - (br_if $label - (local.tee $5 - (i32.sub - (local.get $5) - (i32.const 1) - ) - ) - ) - ) - (local.set $6 - (i32.load8_u - (i32.add - (local.get $2) - (local.get $8) - ) - ) - ) - (local.set $5 + (return + (call $__memmem_raita + (local.get $4) (local.get $8) - ) - ) - (if - (i32.le_u - (local.get $0) - (local.tee $10 - (i32.sub - (i32.sub - (i32.shl - (memory.size) - (i32.const 16) - ) - (local.get $5) - ) - (i32.const 16) - ) - ) - ) - (then - (local.set $11 - (i8x16.splat - (local.get $6) - ) - ) - (local.set $13 - (i8x16.splat - (local.get $7) - ) - ) - (local.set $9 - (i32.add - (local.get $2) - (i32.const 1) - ) - ) - (loop $label2 - (block $block1 - (br_if $block1 - (i32.eqz - (v128.any_true - (local.tee $14 - (v128.and - (i8x16.eq - (local.get $11) - (v128.load align=1 - (i32.add - (local.get $0) - (local.get $5) - ) - ) - ) - (i8x16.eq - (local.get $13) - (v128.load align=1 - (local.get $0) - ) - ) - ) - ) - ) - ) - ) - (br_if $block1 - (i32.eqz - (local.tee $4 - (i8x16.bitmask - (local.get $14) - ) - ) - ) - ) - (loop $label1 - (br_if $block2 - (i32.eqz - (call $bcmp - (i32.add - (local.tee $6 - (i32.add - (local.get $0) - (i32.ctz - (local.get $4) - ) - ) - ) - (i32.const 1) - ) - (local.get $9) - (local.get $8) - ) - ) - ) - (br_if $label1 - (local.tee $4 - (i32.and - (i32.sub - (local.get $4) - (i32.const 1) - ) - (local.get $4) - ) - ) - ) - ) - ) - (if - (i32.lt_u - (local.get $1) - (local.tee $7 - (i32.sub - (local.get $1) - (i32.const 16) - ) - ) - ) - (then - (return - (i32.const 0) - ) - ) - ) - (if - (i32.gt_u - (local.get $3) - (local.get $7) - ) - (then - (return - (i32.const 0) - ) - ) - ) - (local.set $1 - (local.get $7) - ) - (br_if $label2 - (i32.le_u - (local.tee $0 - (i32.add - (local.get $0) - (i32.const 16) - ) - ) - (local.get $10) - ) - ) - ) - (local.set $9 - (i32.sub - (local.get $7) - (local.get $3) - ) - ) - ) - ) - (local.set $5 - (i32.const 0) - ) - (loop $label3 - (local.set $4 + (local.get $2) + (local.get $3) (i32.const 0) ) - (loop $label4 - (if - (i32.ne - (i32.load8_u - (i32.add - (local.get $2) - (local.get $4) - ) - ) - (i32.load8_u - (i32.add - (local.get $0) - (local.get $4) - ) - ) - ) - (then - (local.set $0 - (i32.add - (local.get $0) - (i32.const 1) - ) - ) - (local.set $6 - (i32.const 0) - ) - (br_if $label3 - (i32.le_u - (local.tee $5 - (i32.add - (local.get $5) - (i32.const 1) - ) - ) - (local.get $9) - ) - ) - (br $block2) - ) - ) - (br_if $label4 - (i32.ne - (local.get $3) - (local.tee $4 - (i32.add - (local.get $4) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (return - (local.get $0) ) ) ) @@ -2320,702 +1940,699 @@ (i32.const 4112) (select (i32.const -1) - (local.tee $8 + (local.tee $7 (i32.sub (local.get $3) (i32.const 1) ) ) - (local.tee $5 + (local.tee $0 (i32.gt_s - (local.get $8) + (local.get $7) (i32.const 254) ) ) ) (i32.const 256) ) - (block $block3 - (br_if $block3 + (block $block1 + (br_if $block1 (i32.ge_u - (local.tee $6 + (local.tee $1 (select (i32.sub (local.get $3) (i32.const 256) ) (i32.const 0) - (local.get $5) + (local.get $0) ) ) - (local.get $8) - ) - ) - (if - (i32.ge_u - (local.tee $10 - (i32.add - (i32.xor - (local.get $6) - (i32.const -1) - ) - (local.get $3) - ) - ) - (i32.const 16) - ) - (then - (local.set $4 - (i32.add - (local.get $2) - (local.get $6) - ) - ) - (local.set $14 - (i32x4.add - (local.tee $11 - (i32x4.splat - (local.get $6) - ) - ) - (v128.const i32x4 0x0000000c 0x0000000d 0x0000000e 0x0000000f) - ) - ) - (local.set $16 - (i32x4.add - (local.get $11) - (v128.const i32x4 0x00000008 0x00000009 0x0000000a 0x0000000b) - ) - ) - (local.set $17 - (i32x4.add - (local.get $11) - (v128.const i32x4 0x00000004 0x00000005 0x00000006 0x00000007) - ) - ) - (local.set $18 - (i32x4.add - (local.get $11) - (v128.const i32x4 0x00000000 0x00000001 0x00000002 0x00000003) - ) - ) - (local.set $6 - (i32.add - (local.get $6) - (local.tee $7 - (i32.and - (local.get $10) - (i32.const -16) - ) - ) - ) - ) - (local.set $13 - (i32x4.splat - (local.get $8) - ) - ) - (local.set $5 - (local.get $7) - ) - (loop $label5 - (v128.store8_lane 0 - (i32.add - (i32x4.extract_lane 0 - (local.tee $12 - (i32x4.extend_low_i16x8_u - (i16x8.extend_low_i8x16_u - (local.tee $15 - (v128.load align=1 - (local.get $4) - ) - ) - ) - ) - ) - ) - (i32.const 4112) - ) - (local.tee $11 - (i8x16.narrow_i16x8_u - (i16x8.narrow_i32x4_u - (v128.and - (i32x4.add - (local.get $13) - (v128.not - (local.get $18) - ) - ) - (v128.const i32x4 0x000000ff 0x000000ff 0x000000ff 0x000000ff) - ) - (v128.and - (i32x4.add - (local.get $13) - (v128.not - (local.get $17) - ) - ) - (v128.const i32x4 0x000000ff 0x000000ff 0x000000ff 0x000000ff) - ) - ) - (i16x8.narrow_i32x4_u - (v128.and - (i32x4.add - (local.get $13) - (v128.not - (local.get $16) - ) - ) - (v128.const i32x4 0x000000ff 0x000000ff 0x000000ff 0x000000ff) - ) - (v128.and - (i32x4.add - (local.get $13) - (v128.not - (local.get $14) - ) - ) - (v128.const i32x4 0x000000ff 0x000000ff 0x000000ff 0x000000ff) - ) - ) - ) - ) - ) - (v128.store8_lane 1 - (i32.add - (i32x4.extract_lane 1 - (local.get $12) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 2 - (i32.add - (i32x4.extract_lane 2 - (local.get $12) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 3 - (i32.add - (i32x4.extract_lane 3 - (local.get $12) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 4 - (i32.add - (i32x4.extract_lane 0 - (local.tee $12 - (i32x4.extend_low_i16x8_u - (i16x8.extend_low_i8x16_u - (i8x16.shuffle 4 5 6 7 0 0 0 0 0 0 0 0 0 0 0 0 - (local.get $15) - (local.get $11) - ) - ) - ) - ) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 5 - (i32.add - (i32x4.extract_lane 1 - (local.get $12) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 6 - (i32.add - (i32x4.extract_lane 2 - (local.get $12) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 7 - (i32.add - (i32x4.extract_lane 3 - (local.get $12) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 8 - (i32.add - (i32x4.extract_lane 0 - (local.tee $12 - (i32x4.extend_low_i16x8_u - (i16x8.extend_low_i8x16_u - (i8x16.shuffle 8 9 10 11 0 0 0 0 0 0 0 0 0 0 0 0 - (local.get $15) - (local.get $11) - ) - ) - ) - ) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 9 - (i32.add - (i32x4.extract_lane 1 - (local.get $12) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 10 - (i32.add - (i32x4.extract_lane 2 - (local.get $12) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 11 - (i32.add - (i32x4.extract_lane 3 - (local.get $12) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 12 - (i32.add - (i32x4.extract_lane 0 - (local.tee $15 - (i32x4.extend_low_i16x8_u - (i16x8.extend_low_i8x16_u - (i8x16.shuffle 12 13 14 15 0 0 0 0 0 0 0 0 0 0 0 0 - (local.get $15) - (local.get $11) - ) - ) - ) - ) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 13 - (i32.add - (i32x4.extract_lane 1 - (local.get $15) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 14 - (i32.add - (i32x4.extract_lane 2 - (local.get $15) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (v128.store8_lane 15 - (i32.add - (i32x4.extract_lane 3 - (local.get $15) - ) - (i32.const 4112) - ) - (local.get $11) - ) - (local.set $18 - (i32x4.add - (local.get $18) - (v128.const i32x4 0x00000010 0x00000010 0x00000010 0x00000010) - ) - ) - (local.set $4 - (i32.add - (local.get $4) - (i32.const 16) - ) - ) - (local.set $17 - (i32x4.add - (local.get $17) - (v128.const i32x4 0x00000010 0x00000010 0x00000010 0x00000010) - ) - ) - (local.set $16 - (i32x4.add - (local.get $16) - (v128.const i32x4 0x00000010 0x00000010 0x00000010 0x00000010) - ) - ) - (local.set $14 - (i32x4.add - (local.get $14) - (v128.const i32x4 0x00000010 0x00000010 0x00000010 0x00000010) - ) - ) - (br_if $label5 - (local.tee $5 - (i32.sub - (local.get $5) - (i32.const 16) - ) - ) - ) - ) - (br_if $block3 - (i32.eq - (local.get $7) - (local.get $10) - ) - ) - ) - ) - (local.set $4 - (i32.add - (local.get $2) - (local.get $6) + (local.get $7) ) ) (local.set $5 (i32.sub (i32.sub (local.get $3) - (local.get $6) + (local.get $1) ) (i32.const 2) ) ) - (loop $label6 - (i32.store8 - (i32.add - (i32.load8_u - (local.get $4) + (if + (local.tee $6 + (i32.and + (i32.add + (i32.xor + (local.get $1) + (i32.const -1) + ) + (local.get $3) ) - (i32.const 4112) - ) - (local.get $5) - ) - (local.set $4 - (i32.add - (local.get $4) - (i32.const 1) + (i32.const 3) ) ) - (br_if $label6 - (i32.ne - (local.tee $5 + (then + (local.set $0 + (local.get $5) + ) + (loop $label + (i32.store8 + (i32.add + (i32.load8_u + (i32.add + (local.get $1) + (local.get $2) + ) + ) + (i32.const 4112) + ) + (local.get $0) + ) + (local.set $0 (i32.sub - (local.get $5) + (local.get $0) (i32.const 1) ) ) - (i32.const -1) - ) - ) - ) - ) - (local.set $7 - (i32.load8_u - (local.get $2) - ) - ) - (local.set $5 - (local.get $8) - ) - (block $block4 - (loop $label7 - (br_if $block4 - (i32.ne - (local.get $7) - (local.tee $6 - (i32.load8_u - (i32.add - (local.get $2) - (local.get $5) - ) + (local.set $1 + (i32.add + (local.get $1) + (i32.const 1) ) ) - ) - ) - (br_if $label7 - (local.tee $5 - (i32.sub - (local.get $5) - (i32.const 1) - ) - ) - ) - ) - (local.set $6 - (i32.load8_u - (i32.add - (local.get $2) - (local.get $8) - ) - ) - ) - (local.set $5 - (local.get $8) - ) - ) - (if - (i32.le_u - (local.get $0) - (local.tee $10 - (i32.sub - (i32.sub - (i32.shl - (memory.size) - (i32.const 16) - ) - (local.get $5) - ) - (i32.const 16) - ) - ) - ) - (then - (local.set $11 - (i8x16.splat - (local.get $6) - ) - ) - (local.set $13 - (i8x16.splat - (local.get $7) - ) - ) - (local.set $7 - (i32.add - (local.get $3) - (i32.const 14) - ) - ) - (local.set $9 - (i32.add - (local.get $2) - (i32.const 1) - ) - ) - (loop $label9 - (block $block5 - (br_if $block5 - (i32.eqz - (v128.any_true - (local.tee $14 - (v128.and - (i8x16.eq - (local.get $11) - (v128.load align=1 - (i32.add - (local.get $0) - (local.get $5) - ) - ) - ) - (i8x16.eq - (local.get $13) - (v128.load align=1 - (local.get $0) - ) - ) - ) - ) - ) - ) - ) - (br_if $block5 - (i32.eqz - (local.tee $4 - (i8x16.bitmask - (local.get $14) - ) - ) - ) - ) - (loop $label8 - (br_if $block2 - (i32.eqz - (call $bcmp - (i32.add - (local.tee $6 - (i32.add - (local.get $0) - (i32.ctz - (local.get $4) - ) - ) - ) - (i32.const 1) - ) - (local.get $9) - (local.get $8) - ) - ) - ) - (br_if $label8 - (local.tee $4 - (i32.and - (i32.sub - (local.get $4) - (i32.const 1) - ) - (local.get $4) - ) - ) - ) - ) - ) - (local.set $6 - (i32.const 0) - ) - (br_if $block2 - (i32.lt_u - (local.get $1) - (local.tee $1 + (br_if $label + (local.tee $6 (i32.sub - (local.get $1) - (local.tee $4 - (i32.add - (i32.load8_u - (i32.add - (i32.load8_u - (i32.add - (local.get $0) - (local.get $7) - ) - ) - (i32.const 4112) - ) - ) - (i32.const 16) - ) - ) - ) - ) - ) - ) - (br_if $block2 - (i32.lt_u - (local.get $1) - (local.get $3) - ) - ) - (br_if $label9 - (i32.le_u - (local.tee $0 - (i32.add - (local.get $0) - (local.get $4) - ) - ) - (local.get $10) - ) - ) - ) - (local.set $9 - (i32.sub - (local.get $1) - (local.get $3) - ) - ) - ) - ) - (local.set $5 - (i32.const 0) - ) - (loop $label11 - (local.set $4 - (i32.const 0) - ) - (block $block6 - (loop $label10 - (br_if $block6 - (i32.ne - (i32.load8_u - (i32.add - (local.get $2) - (local.get $4) - ) - ) - (i32.load8_u - (i32.add - (local.get $0) - (local.get $4) - ) - ) - ) - ) - (br_if $label10 - (i32.ne - (local.get $3) - (local.tee $4 - (i32.add - (local.get $4) + (local.get $6) (i32.const 1) ) ) ) ) ) - (return - (local.get $0) + ) + (br_if $block1 + (i32.lt_u + (local.get $5) + (i32.const 3) ) ) (local.set $0 - (i32.add - (local.get $0) - (i32.const 1) + (i32.sub + (local.get $3) + (local.get $1) ) ) - (local.set $6 - (i32.const 0) + (local.set $5 + (local.get $2) ) - (br_if $label11 - (i32.le_u - (local.tee $5 - (i32.add - (local.get $5) - (i32.const 1) + (loop $label1 + (i32.store8 + (i32.add + (i32.load8_u + (local.tee $9 + (i32.add + (local.get $1) + (local.get $5) + ) + ) + ) + (i32.const 4112) + ) + (i32.sub + (local.get $0) + (i32.const 2) + ) + ) + (i32.store8 + (i32.add + (i32.load8_u + (i32.add + (local.get $9) + (i32.const 1) + ) + ) + (i32.const 4112) + ) + (i32.sub + (local.get $0) + (i32.const 3) + ) + ) + (i32.store8 + (i32.add + (i32.load8_u + (i32.add + (local.get $9) + (i32.const 2) + ) + ) + (i32.const 4112) + ) + (local.tee $6 + (i32.sub + (local.get $0) + (i32.const 4) ) ) - (local.get $9) ) + (i32.store8 + (i32.add + (i32.load8_u + (i32.add + (local.get $9) + (i32.const 3) + ) + ) + (i32.const 4112) + ) + (i32.sub + (local.get $0) + (i32.const 5) + ) + ) + (local.set $5 + (i32.add + (local.get $5) + (i32.const 4) + ) + ) + (local.set $0 + (local.get $6) + ) + (br_if $label1 + (i32.ne + (local.get $1) + (local.tee $7 + (i32.sub + (local.get $7) + (i32.const 4) + ) + ) + ) + ) + ) + ) + (local.set $6 + (call $__memmem_raita + (local.get $4) + (local.get $8) + (local.get $2) + (local.get $3) + (i32.const 4112) ) ) ) (local.get $6) ) + (func $__memmem_raita (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (local $14 i32) + (local $15 i32) + (local $16 i32) + (local $17 v128) + (local $18 v128) + (local $19 v128) + (local $20 v128) + (local.set $5 + (i32.load8_u + (local.get $2) + ) + ) + (local.set $6 + (local.tee $10 + (i32.sub + (local.get $3) + (i32.const 1) + ) + ) + ) + (block $block + (loop $label + (br_if $block + (i32.ne + (local.get $5) + (local.tee $7 + (i32.load8_u + (i32.add + (local.get $2) + (local.get $6) + ) + ) + ) + ) + ) + (br_if $label + (local.tee $6 + (i32.sub + (local.get $6) + (i32.const 1) + ) + ) + ) + ) + (local.set $7 + (i32.load8_u + (i32.add + (local.get $2) + (local.get $10) + ) + ) + ) + (local.set $6 + (local.get $10) + ) + ) + (block $block6 + (block $block1 + (br_if $block1 + (i32.lt_u + (local.tee $14 + (i32.sub + (i32.sub + (i32.shl + (memory.size) + (i32.const 16) + ) + (local.get $6) + ) + (i32.const 16) + ) + ) + (local.get $0) + ) + ) + (local.set $18 + (i8x16.splat + (local.get $7) + ) + ) + (local.set $19 + (i8x16.splat + (local.get $5) + ) + ) + (local.set $15 + (i32.add + (local.get $3) + (i32.const 14) + ) + ) + (local.set $16 + (i32.add + (local.get $2) + (i32.const 1) + ) + ) + (loop $label4 + (block $block2 + (br_if $block2 + (i32.eqz + (v128.any_true + (local.tee $20 + (v128.and + (i8x16.eq + (local.get $18) + (v128.load align=1 + (i32.add + (local.get $0) + (local.get $6) + ) + ) + ) + (i8x16.eq + (local.get $19) + (local.tee $17 + (v128.load align=1 + (local.get $0) + ) + ) + ) + ) + ) + ) + ) + ) + (block $block3 + (br_if $block3 + (i32.ne + (local.get $1) + (i32.const -1) + ) + ) + (br_if $block3 + (i8x16.all_true + (local.get $17) + ) + ) + (local.set $1 + (i32.const -1) + ) + (br $block1) + ) + (br_if $block2 + (i32.eqz + (local.tee $11 + (i8x16.bitmask + (local.get $20) + ) + ) + ) + ) + (loop $label3 + (br_if $block6 + (i32.eqz + (block $block5 (result i32) + (local.set $8 + (i32.add + (local.tee $7 + (i32.add + (local.get $0) + (i32.ctz + (local.get $11) + ) + ) + ) + (i32.const 1) + ) + ) + (local.set $5 + (local.get $16) + ) + (local.set $12 + (i32.const 0) + ) + (block $block4 + (if + (i32.ge_u + (local.tee $9 + (local.get $10) + ) + (i32.const 16) + ) + (then + (local.set $12 + (i32.const 1) + ) + (loop $label1 + (br_if $block4 + (v128.any_true + (v128.xor + (v128.load align=1 + (local.get $5) + ) + (v128.load align=1 + (local.get $8) + ) + ) + ) + ) + (local.set $5 + (i32.add + (local.get $5) + (local.tee $13 + (i32.add + (i32.and + (i32.sub + (local.get $9) + (i32.const 1) + ) + (i32.const 15) + ) + (i32.const 1) + ) + ) + ) + ) + (local.set $8 + (i32.add + (local.get $8) + (local.get $13) + ) + ) + (br_if $label1 + (local.tee $9 + (i32.sub + (local.get $9) + (local.get $13) + ) + ) + ) + ) + (br $block5 + (i32.const 0) + ) + ) + ) + (br_if $block4 + (i32.eqz + (local.get $9) + ) + ) + (loop $label2 + (drop + (br_if $block5 + (i32.const 1) + (i32.ne + (i32.load8_u + (local.get $8) + ) + (i32.load8_u + (local.get $5) + ) + ) + ) + ) + (local.set $5 + (i32.add + (local.get $5) + (i32.const 1) + ) + ) + (local.set $8 + (i32.add + (local.get $8) + (i32.const 1) + ) + ) + (br_if $label2 + (local.tee $9 + (i32.sub + (local.get $9) + (i32.const 1) + ) + ) + ) + ) + ) + (local.get $12) + ) + ) + ) + (br_if $label3 + (local.tee $11 + (i32.and + (i32.sub + (local.get $11) + (i32.const 1) + ) + (local.get $11) + ) + ) + ) + ) + ) + (local.set $5 + (if (result i32) + (local.get $4) + (then + (i32.add + (i32.load8_u + (i32.add + (local.get $4) + (i32.load8_u + (i32.add + (local.get $0) + (local.get $15) + ) + ) + ) + ) + (i32.const 16) + ) + ) + (else + (i32.const 16) + ) + ) + ) + (block $block7 + (if + (i32.ne + (local.get $1) + (i32.const -1) + ) + (then + (local.set $7 + (i32.const 0) + ) + (br_if $block6 + (i32.lt_u + (local.get $1) + (local.tee $1 + (i32.sub + (local.get $1) + (local.get $5) + ) + ) + ) + ) + (br_if $block6 + (i32.lt_u + (local.get $1) + (local.get $3) + ) + ) + (br $block7) + ) + ) + (local.set $1 + (i32.const -1) + ) + (br_if $block7 + (i8x16.all_true + (local.get $17) + ) + ) + (return + (i32.const 0) + ) + ) + (br_if $label4 + (i32.le_u + (local.tee $0 + (i32.add + (local.get $0) + (local.get $5) + ) + ) + (local.get $14) + ) + ) + ) + ) + (local.set $10 + (i32.sub + (local.get $1) + (local.get $3) + ) + ) + (local.set $4 + (i32.const 0) + ) + (local.set $1 + (i32.ne + (local.get $1) + (i32.const -1) + ) + ) + (loop $label5 + (local.set $6 + (i32.const 0) + ) + (loop $label6 + (local.set $7 + (i32.const 0) + ) + (br_if $block6 + (i32.eqz + (i32.or + (local.get $1) + (local.tee $5 + (i32.load8_u + (i32.add + (local.get $0) + (local.get $6) + ) + ) + ) + ) + ) + ) + (if + (i32.ne + (local.get $5) + (i32.load8_u + (i32.add + (local.get $2) + (local.get $6) + ) + ) + ) + (then + (local.set $0 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (br_if $label5 + (i32.le_u + (local.tee $4 + (i32.add + (local.get $4) + (i32.const 1) + ) + ) + (local.get $10) + ) + ) + (br $block6) + ) + ) + (br_if $label6 + (i32.ne + (local.get $3) + (local.tee $6 + (i32.add + (local.get $6) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (local.set $7 + (local.get $0) + ) + ) + (local.get $7) + ) (func $strstr (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) - (local $5 v128) - (local $6 v128) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 v128) + (local $10 v128) (block $block (br_if $block (i32.eqz - (local.tee $3 + (local.tee $4 (i32.load8_u (local.get $1) ) @@ -3025,10 +2642,10 @@ (block $block1 (if (v128.any_true - (local.tee $5 + (local.tee $9 (v128.or (i8x16.eq - (local.tee $5 + (local.tee $9 (v128.load (local.tee $2 (i32.and @@ -3041,10 +2658,10 @@ (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) ) (i8x16.eq - (local.get $5) - (local.tee $6 + (local.get $9) + (local.tee $10 (i8x16.splat - (local.get $3) + (local.get $4) ) ) ) @@ -3053,10 +2670,10 @@ ) (then (br_if $block1 - (local.tee $4 + (local.tee $3 (i32.and (i8x16.bitmask - (local.get $5) + (local.get $9) ) (i32.shl (i32.const -1) @@ -3071,7 +2688,7 @@ ) ) (loop $label - (local.set $5 + (local.set $9 (v128.load offset=16 (local.get $2) ) @@ -3085,15 +2702,15 @@ (br_if $label (i32.eqz (v128.any_true - (local.tee $5 + (local.tee $9 (v128.or (i8x16.eq - (local.get $5) + (local.get $9) (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) ) (i8x16.eq - (local.get $5) - (local.get $6) + (local.get $9) + (local.get $10) ) ) ) @@ -3101,9 +2718,9 @@ ) ) ) - (local.set $4 + (local.set $3 (i8x16.bitmask - (local.get $5) + (local.get $9) ) ) ) @@ -3112,13 +2729,13 @@ ) (br_if $block (i32.ne - (local.get $3) + (local.get $4) (i32.load8_u - (local.tee $2 + (local.tee $7 (i32.add (local.get $2) (i32.ctz - (local.get $4) + (local.get $3) ) ) ) @@ -3133,20 +2750,240 @@ ) (then (return + (local.get $7) + ) + ) + ) + (if + (i32.le_u + (i32.add + (local.tee $5 + (call $strlen + (local.get $1) + ) + ) + (i32.const 16) + ) + (i32.const 31) + ) + (then + (return + (call $__memmem_raita + (local.get $7) + (i32.const -1) + (local.get $1) + (local.get $5) + (i32.const 0) + ) + ) + ) + ) + (memory.fill + (i32.const 4112) + (select + (i32.const -1) + (local.tee $6 + (i32.sub + (local.get $5) + (i32.const 1) + ) + ) + (local.tee $0 + (i32.gt_s + (local.get $6) + (i32.const 254) + ) + ) + ) + (i32.const 256) + ) + (block $block2 + (br_if $block2 + (i32.ge_u + (local.tee $2 + (select + (i32.sub + (local.get $5) + (i32.const 256) + ) + (i32.const 0) + (local.get $0) + ) + ) + (local.get $6) + ) + ) + (local.set $3 + (i32.sub + (i32.sub + (local.get $5) + (local.get $2) + ) + (i32.const 2) + ) + ) + (if + (local.tee $4 + (i32.and + (i32.add + (local.get $5) + (i32.xor + (local.get $2) + (i32.const -1) + ) + ) + (i32.const 3) + ) + ) + (then + (local.set $0 + (local.get $3) + ) + (loop $label1 + (i32.store8 + (i32.add + (i32.load8_u + (i32.add + (local.get $1) + (local.get $2) + ) + ) + (i32.const 4112) + ) + (local.get $0) + ) + (local.set $0 + (i32.sub + (local.get $0) + (i32.const 1) + ) + ) + (local.set $2 + (i32.add + (local.get $2) + (i32.const 1) + ) + ) + (br_if $label1 + (local.tee $4 + (i32.sub + (local.get $4) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (br_if $block2 + (i32.lt_u + (local.get $3) + (i32.const 3) + ) + ) + (local.set $0 + (i32.sub + (local.get $5) (local.get $2) ) ) + (local.set $3 + (local.get $1) + ) + (loop $label2 + (i32.store8 + (i32.add + (i32.load8_u + (local.tee $8 + (i32.add + (local.get $2) + (local.get $3) + ) + ) + ) + (i32.const 4112) + ) + (i32.sub + (local.get $0) + (i32.const 2) + ) + ) + (i32.store8 + (i32.add + (i32.load8_u + (i32.add + (local.get $8) + (i32.const 1) + ) + ) + (i32.const 4112) + ) + (i32.sub + (local.get $0) + (i32.const 3) + ) + ) + (i32.store8 + (i32.add + (i32.load8_u + (i32.add + (local.get $8) + (i32.const 2) + ) + ) + (i32.const 4112) + ) + (local.tee $4 + (i32.sub + (local.get $0) + (i32.const 4) + ) + ) + ) + (i32.store8 + (i32.add + (i32.load8_u + (i32.add + (local.get $8) + (i32.const 3) + ) + ) + (i32.const 4112) + ) + (i32.sub + (local.get $0) + (i32.const 5) + ) + ) + (local.set $3 + (i32.add + (local.get $3) + (i32.const 4) + ) + ) + (local.set $0 + (local.get $4) + ) + (br_if $label2 + (i32.ne + (local.get $2) + (local.tee $6 + (i32.sub + (local.get $6) + (i32.const 4) + ) + ) + ) + ) + ) ) (local.set $0 - (call $__memmem - (local.get $2) - (call $strlen - (local.get $2) - ) + (call $__memmem_raita + (local.get $7) + (i32.const -1) (local.get $1) - (call $strlen - (local.get $1) - ) + (local.get $5) + (i32.const 4112) ) ) ) diff --git a/sqlite3/libc/libc_test.go b/sqlite3/libc/libc_test.go index 327bc72..a046e3b 100644 --- a/sqlite3/libc/libc_test.go +++ b/sqlite3/libc/libc_test.go @@ -733,6 +733,7 @@ func Test_strstr(t *testing.T) { {"fofofofofoofofoffofoobarfoo", "fofoffofoobarfoo", 11}, {"fofofofofofofoffofoobarfoo", "fofoffofoobarfoo", 10}, {"fofofofofoofofoffofoobarfoo", "foobars", -1}, + {"fofofofofofo\x00foffofoobar", "foffof", -1}, {"foofyfoobarfoobar", "y", 4}, {"oooooooooooooooooooooo", "r", -1}, {"oxoxoxoxoxoxoxoxoxoxoxoy", "oy", 22}, diff --git a/sqlite3/libc/math.h b/sqlite3/libc/math.h index 485a29d..8e8100d 100644 --- a/sqlite3/libc/math.h +++ b/sqlite3/libc/math.h @@ -23,8 +23,8 @@ double fma(double x, double y, double z) { const v128_t wx = wasm_f64x2_replace_lane(b, 0, x); const v128_t wy = wasm_f64x2_splat(y); const v128_t wz = wasm_f64x2_splat(z); - const v128_t wr = wasm_f64x2_relaxed_madd(wx, wy, wz); - return wasm_f64x2_extract_lane(wr, 0); + const v128_t wr = wasm_f64x2_relaxed_madd(wx, wy, wz); + return wasm_f64x2_extract_lane(wr, 0); } #endif // __wasm_relaxed_simd__ diff --git a/sqlite3/libc/string.h b/sqlite3/libc/string.h index 8613c88..b0515d8 100644 --- a/sqlite3/libc/string.h +++ b/sqlite3/libc/string.h @@ -87,7 +87,7 @@ void *memchr(const void *v, int c, size_t n) { // When n is zero, a function that locates a character finds no occurrence. // Otherwise, decrement n to ensure sub_overflow overflows // when n would go equal-to-or-below zero. - if (n-- == 0) { + if (!n--) { return NULL; } @@ -190,8 +190,7 @@ static int __strcmp(const char *s1, const char *s2) { for (; N >= sizeof(v128_t); N -= sizeof(v128_t)) { // Find any single bit difference. if (wasm_v128_any_true(wasm_v128_load(w1) ^ wasm_v128_load(w2))) { - // The strings may still be equal, - // if the terminator is found before that difference. + // The terminator may come before the difference. break; } // We know all characters are equal. @@ -250,8 +249,7 @@ int strncmp(const char *s1, const char *s2, size_t n) { for (; n >= sizeof(v128_t); n -= sizeof(v128_t)) { // Find any single bit difference. if (wasm_v128_any_true(wasm_v128_load(w1) ^ wasm_v128_load(w2))) { - // The strings may still be equal, - // if the terminator is found before that difference. + // The terminator may come before the difference. break; } // We know all characters are equal. @@ -465,13 +463,14 @@ size_t strcspn(const char *s, const char *c) { #undef _WASM_SIMD128_CHKBITS #undef _WASM_SIMD128_BITMAP256_T -static const char *__memmem_rabin(const char *haystk, size_t sh, +static const char *__memmem_raita(const char *haystk, size_t sh, const char *needle, size_t sn, uint8_t bmbc[256]) { + // https://www-igm.univ-mlv.fr/~lecroq/string/node22.html // http://0x80.pl/notesen/2016-11-28-simd-strfind.html // We've handled empty and single character needles. - // The needle is no longer than haystack. + // The needle is not longer than the haystack. __builtin_assume(2 <= sn && sn <= sh); // Find the farthest character not equal to the first one. @@ -494,6 +493,8 @@ static const char *__memmem_rabin(const char *haystk, size_t sh, const v128_t cmp = eq_fst & eq_lst; if (wasm_v128_any_true(cmp)) { + // The terminator may come before the match. + if (sh == SIZE_MAX && !wasm_i8x16_all_true(blk_fst)) break; // Find the offset of the first one bit (little-endian). // Each iteration clears that bit, tries again. for (uint32_t mask = wasm_i8x16_bitmask(cmp); mask; mask &= mask - 1) { @@ -508,17 +509,23 @@ static const char *__memmem_rabin(const char *haystk, size_t sh, // Apply the bad-character rule to the last checked // character of the haystack. if (bmbc) skip += bmbc[(unsigned char)haystk[sn + 14]]; - // Have we reached the end of the haystack? - if (__builtin_sub_overflow(sh, skip, &sh)) return NULL; - // Is the needle longer than the haystack? - if (sn > sh) return NULL; + if (sh != SIZE_MAX) { + // Have we reached the end of the haystack? + if (__builtin_sub_overflow(sh, skip, &sh)) return NULL; + // Is the needle longer than the haystack? + if (sn > sh) return NULL; + } else if (!wasm_i8x16_all_true(blk_fst)) { + // We found a terminator. + return NULL; + } haystk += skip; } // Baseline algorithm. for (size_t j = 0; j <= sh - sn; j++) { for (size_t i = 0;; i++) { - if (i >= sn) return haystk; + if (sn == i) return haystk; + if (sh == SIZE_MAX && !haystk[i]) return NULL; if (needle[i] != haystk[i]) break; } haystk++; @@ -526,12 +533,17 @@ static const char *__memmem_rabin(const char *haystk, size_t sh, return NULL; } -static const char *__memmem_raita(const char *haystk, size_t sh, - const char *needle, size_t sn) { - // https://www-igm.univ-mlv.fr/~lecroq/string/node22.html +static const char *__memmem(const char *haystk, size_t sh, // + const char *needle, size_t sn) { + // Is Boyer-Moore's bad-character rule useful? + if (sn < sizeof(v128_t) || sh - sn < sizeof(v128_t)) { + return __memmem_raita(haystk, sh, needle, sn, NULL); + } + + // https://www-igm.univ-mlv.fr/~lecroq/string/node14.html // We've handled empty and single character needles. - // The needle is no longer than haystack. + // The needle is not longer than the haystack. __builtin_assume(2 <= sn && sn <= sh); // Compute Boyer-Moore's bad-character shift function. @@ -551,24 +563,13 @@ static const char *__memmem_raita(const char *haystk, size_t sh, uint8_t bmbc[256]; memset(bmbc, c, sizeof(bmbc)); for (; i < n; i++) { - // One less than the usual offset. - // Added back later (as vector). + // One less than the usual offset because + // we advance at least one vector at a time. size_t t = n - i - 1; bmbc[(unsigned char)needle[i]] = t; } - return __memmem_rabin(haystk, sh, needle, sn, bmbc); -} - -static const char *__memmem(const char *haystk, size_t sh, // - const char *needle, size_t sn) { - // Return when needle is longer than haystack. - if (sn > sh) return NULL; - - // Decide if Boyer-Moore's bad-character rule will be useful. - return sn < sizeof(v128_t) || sh - sn < sizeof(v128_t) - ? __memmem_rabin(haystk, sh, needle, sn, NULL) - : __memmem_raita(haystk, sh, needle, sn); + return __memmem_raita(haystk, sh, needle, sn, bmbc); } __attribute__((weak)) @@ -585,7 +586,10 @@ void *memmem(const void *vh, size_t sh, const void *vn, size_t sn) { const char *haystk = (char *)memchr(vh, *needle, sh); if (!haystk || sn == 1) return (void *)haystk; + // The haystack got shorter, is the needle now longer? sh -= haystk - (char *)vh; + if (sn > sh) return NULL; + return (void *)__memmem(haystk, sh, needle, sn); } @@ -599,7 +603,7 @@ char *strstr(const char *haystk, const char *needle) { haystk = strchr(haystk, *needle); if (!haystk || !needle[1]) return (char *)haystk; - return (char *)__memmem(haystk, strlen(haystk), needle, strlen(needle)); + return (char *)__memmem(haystk, SIZE_MAX, needle, strlen(needle)); } // Given the above SIMD implementations,