1*39e910beSAlex Crichton;;! multi_memory = true 2*39e910beSAlex Crichton 3*39e910beSAlex Crichton;; Transcode a utf16 string to latin1+utf16, but the original string is 4*39e910beSAlex Crichton;; out-of-bounds. Should report a first-class error. 5*39e910beSAlex Crichton(component 6*39e910beSAlex Crichton (component $dst 7*39e910beSAlex Crichton (core module $m 8*39e910beSAlex Crichton (func (export "recv") (param i32 i32)) 9*39e910beSAlex Crichton (func (export "realloc") (param i32 i32 i32 i32) (result i32) i32.const 0) 10*39e910beSAlex Crichton (memory (export "memory") 1) 11*39e910beSAlex Crichton ) 12*39e910beSAlex Crichton (core instance $i (instantiate $m)) 13*39e910beSAlex Crichton (func (export "recv") (param "a" string) 14*39e910beSAlex Crichton (canon lift (core func $i "recv") (realloc (func $i "realloc")) (memory $i "memory") 15*39e910beSAlex Crichton string-encoding=latin1+utf16) 16*39e910beSAlex Crichton ) 17*39e910beSAlex Crichton ) 18*39e910beSAlex Crichton 19*39e910beSAlex Crichton ;; Source component: uses utf16 encoding. 20*39e910beSAlex Crichton ;; Passes a string placed near the END of linear memory to $dst. 21*39e910beSAlex Crichton (component $src 22*39e910beSAlex Crichton (import "recv" (func $recv (param "a" string))) 23*39e910beSAlex Crichton (core module $libc 24*39e910beSAlex Crichton (memory (export "memory") 1) ;; 1 page = 65536 bytes 25*39e910beSAlex Crichton (func (export "realloc") (param i32 i32 i32 i32) (result i32) i32.const 0) 26*39e910beSAlex Crichton ) 27*39e910beSAlex Crichton (core instance $libc (instantiate $libc)) 28*39e910beSAlex Crichton ;; canon lower with utf16 — the source side of the mismatch. 29*39e910beSAlex Crichton (core func $recv_lowered (canon lower (func $recv) string-encoding=utf16 (memory $libc "memory"))) 30*39e910beSAlex Crichton (core module $m 31*39e910beSAlex Crichton (import "" "" (func $recv (param i32 i32))) 32*39e910beSAlex Crichton (import "libc" "memory" (memory 0)) 33*39e910beSAlex Crichton (func (export "run") 34*39e910beSAlex Crichton ;; Write 8 UTF-16 code units (16 bytes) of 'A' (U+0041) at the end of memory. 35*39e910beSAlex Crichton ;; Offsets 65520–65535: exactly fills to the last byte of the page. 36*39e910beSAlex Crichton (i32.store (i32.const 65520) (i32.const 0x00410041)) 37*39e910beSAlex Crichton (i32.store (i32.const 65524) (i32.const 0x00410041)) 38*39e910beSAlex Crichton (i32.store (i32.const 65528) (i32.const 0x00410041)) 39*39e910beSAlex Crichton (i32.store (i32.const 65532) (i32.const 0x00410041)) 40*39e910beSAlex Crichton 41*39e910beSAlex Crichton ;; Pass ptr=65520, len=10 CODE UNITS (not bytes). 42*39e910beSAlex Crichton ;; We wrote 8 code units but claim 10 — the extra 2 are past end of memory. 43*39e910beSAlex Crichton (call $recv (i32.const 65520) (i32.const 10)) 44*39e910beSAlex Crichton ) 45*39e910beSAlex Crichton ) 46*39e910beSAlex Crichton (core instance $i (instantiate $m 47*39e910beSAlex Crichton (with "" (instance (export "" (func $recv_lowered)))) 48*39e910beSAlex Crichton (with "libc" (instance $libc)) 49*39e910beSAlex Crichton )) 50*39e910beSAlex Crichton (func (export "run") 51*39e910beSAlex Crichton (canon lift (core func $i "run")) 52*39e910beSAlex Crichton ) 53*39e910beSAlex Crichton ) 54*39e910beSAlex Crichton 55*39e910beSAlex Crichton ;; Wire the components together and run. 56*39e910beSAlex Crichton (instance $dst_inst (instantiate $dst)) 57*39e910beSAlex Crichton (instance $i (instantiate $src (with "recv" (func $dst_inst "recv")))) 58*39e910beSAlex Crichton 59*39e910beSAlex Crichton (export "run" (func $i "run")) 60*39e910beSAlex Crichton) 61*39e910beSAlex Crichton 62*39e910beSAlex Crichton(assert_trap (invoke "run") "string content out-of-bounds") 63