wasi 目标下支持打印 unicode rune

This commit is contained in:
3dgen 2023-08-30 11:20:24 +08:00
parent 37299bc094
commit 7f484df65b
2 changed files with 55 additions and 24 deletions

View File

@ -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}}
)

View File

@ -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)