From 7f484df65b1e84ac4332e987549315f3a5b8585b Mon Sep 17 00:00:00 2001 From: 3dgen <476582@qq.com> Date: Wed, 30 Aug 2023 11:20:24 +0800 Subject: [PATCH] =?UTF-8?q?wasi=20=E7=9B=AE=E6=A0=87=E4=B8=8B=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=89=93=E5=8D=B0=20unicode=20rune?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- waroot/src/runtime/print_wasi.wat.ws | 23 ------------ waroot/src/runtime/runtime_wasi.wa | 56 +++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/waroot/src/runtime/print_wasi.wat.ws b/waroot/src/runtime/print_wasi.wat.ws index bcaf29e..7e4aca2 100644 --- a/waroot/src/runtime/print_wasi.wat.ws +++ b/waroot/src/runtime/print_wasi.wat.ws @@ -38,26 +38,3 @@ ;; {{$$runtime.waPuts/body/end}} ) - -;; 打印字符 -(func $$runtime.waPrintRune (param $ch i32) - ;; {{$$runtime.waPrintRune/body/begin}} - - (local $sp i32) - (local $p_ch i32) - - ;; 保存栈指针状态 - (local.set $sp (global.get $__stack_ptr)) - - ;; 分配字符 - (local.set $p_ch (call $$waStackAlloc (i32.const 4))) - (i32.store offset=0 align=1 (local.get $p_ch) (local.get $ch)) - - ;; 输出字符 - (call $$runtime.waPuts (local.get $p_ch) (i32.const 1)) - - ;; 重置栈指针 - (global.set $__stack_ptr (local.get $sp)) - - ;; {{$$runtime.waPrintRune/body/begin}} -) diff --git a/waroot/src/runtime/runtime_wasi.wa b/waroot/src/runtime/runtime_wasi.wa index 9ec0f68..1ccdb5e 100644 --- a/waroot/src/runtime/runtime_wasi.wa +++ b/waroot/src/runtime/runtime_wasi.wa @@ -114,8 +114,62 @@ func waPrintString(s: string) { printString(s) } +const ( + MaxRune = '\U0010FFFF' + RuneError = '\uFFFD' + surrogateMin = 0xD800 + surrogateMax = 0xDFFF + tx = 0b10000000 + t2 = 0b11000000 + t3 = 0b11100000 + t4 = 0b11110000 + maskx = 0b00111111 + + rune1Max = 1<<7 - 1 + rune2Max = 1<<11 - 1 + rune3Max = 1<<16 - 1 +) #wa:linkname $runtime.waPrintRune -func waPrintRune(ch: i32) +func waPrintRune(r: i32) { + p := make([]byte, 0, 4) + n : int + + switch i := uint32(r); { + case i <= rune1Max: + p[0] = byte(r) + n = 1 + case i <= rune2Max: + _ = p[1] // eliminate bounds checks + p[0] = t2 | byte(r>>6) + p[1] = tx | byte(r)&maskx + n = 2 + case i > MaxRune, surrogateMin <= i && i <= surrogateMax: + r = RuneError + // fallthrough + { + _ = p[2] // eliminate bounds checks + p[0] = t3 | byte(r>>12) + p[1] = tx | byte(r>>6)&maskx + p[2] = tx | byte(r)&maskx + n = 3 + } + case i <= rune3Max: + _ = p[2] // eliminate bounds checks + p[0] = t3 | byte(r>>12) + p[1] = tx | byte(r>>6)&maskx + p[2] = tx | byte(r)&maskx + n = 3 + default: + _ = p[3] // eliminate bounds checks + p[0] = t4 | byte(r>>18) + p[1] = tx | byte(r>>12)&maskx + p[2] = tx | byte(r>>6)&maskx + p[3] = tx | byte(r)&maskx + n = 4 + } + + printString(string(p[:n])) +} #wa:linkname $runtime.waPuts func waPuts(ptr: i32, len: i32)