-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathupper.wat
102 lines (94 loc) · 5.27 KB
/
upper.wat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
;; Lovingly hand-crafted WAT "uppercase" module. Exports a single function that takes a
;; pointer to extism memory, consumes all bytes from that position, then returns them uppercased.
(module
(import "extism:host/env" "length" (func $length (param i64) (result i64)))
(import "extism:host/env" "load_u64" (func $load_u64 (param i64) (result i64)))
(import "extism:host/env" "load_u8" (func $load_u8 (param i64) (result i32)))
(import "extism:host/env" "store_u64" (func $store_u64 (param i64 i64)))
(import "extism:host/env" "store_u8" (func $store_u8 (param i64 i32)))
(func (export "host_reflect") (param $extism_offset i64) (result i64)
(local $len i64)
(local $offset i64)
(local $len64 i64)
(local $charas i64)
(local.set $offset (i64.const 0))
(local.set $len (call $length (local.get $extism_offset)))
(local.set $len64 (i64.shl (i64.shr_u (local.get $len) (i64.const 16)) (i64.const 16)))
(loop $to_upper
(local.set $charas (call $load_u64 (i64.add (local.get $extism_offset) (local.get $offset))))
;; nobody cared what charas these were... until they put on the mask
;; seriously though. grab each byte, subtract 96, div_u by 27 so that 0 == needs mask and all other numbers don't, eqz to flip the 0 to a 1, then
;; shl the result to the proper position. finally, invert
(call $store_u64
(i64.add (local.get $extism_offset) (local.get $offset))
(i64.and
(local.get $charas)
(i64.xor
(i64.or
(i64.shl
(i64.extend_i32_u (i64.eqz (i64.div_u (i64.sub (i64.and (i64.const 0xff) (local.get $charas)) (i64.const 96)) (i64.const 27))))
(i64.const 5)) ;; 5
(i64.or
(i64.shl
(i64.extend_i32_u (i64.eqz (i64.div_u (i64.sub (i64.and (i64.const 0xff) (i64.shr_u (local.get $charas) (i64.const 8))) (i64.const 96)) (i64.const 27))))
(i64.const 13)) ;; 5 + 8
(i64.or
(i64.shl
(i64.extend_i32_u (i64.eqz (i64.div_u (i64.sub (i64.and (i64.const 0xff) (i64.shr_u (local.get $charas) (i64.const 16))) (i64.const 96)) (i64.const 27))))
(i64.const 21)) ;; 5 + 16
(i64.or
(i64.shl
(i64.extend_i32_u (i64.eqz (i64.div_u (i64.sub (i64.and (i64.const 0xff) (i64.shr_u (local.get $charas) (i64.const 24))) (i64.const 96)) (i64.const 27))))
(i64.const 29)) ;; 5 + 24
(i64.or
(i64.shl
(i64.extend_i32_u (i64.eqz (i64.div_u (i64.sub (i64.and (i64.const 0xff) (i64.shr_u (local.get $charas) (i64.const 32))) (i64.const 96)) (i64.const 27))))
(i64.const 37)) ;; 5 + 32
(i64.or
(i64.shl
(i64.extend_i32_u (i64.eqz (i64.div_u (i64.sub (i64.and (i64.const 0xff) (i64.shr_u (local.get $charas) (i64.const 40))) (i64.const 96)) (i64.const 27))))
(i64.const 45)) ;; 5 + 40
(i64.or
(i64.shl
(i64.extend_i32_u (i64.eqz (i64.div_u (i64.sub (i64.and (i64.const 0xff) (i64.shr_u (local.get $charas) (i64.const 48))) (i64.const 96)) (i64.const 27))))
(i64.const 53)) ;; 5 + 48
(i64.shl
(i64.extend_i32_u (i64.eqz (i64.div_u (i64.sub (i64.and (i64.const 0xff) (i64.shr_u (local.get $charas) (i64.const 56))) (i64.const 96)) (i64.const 27))))
(i64.const 61)) ;; 5 + 56
)
)
)
)
)
)
)
(i64.const -1)
)
)
)
(local.set $offset (i64.add (local.get $offset) (i64.const 8)))
(br_if $to_upper (i64.lt_u (local.get $offset) (local.get $len64)))
)
(if (i64.ne (local.get $len64) (local.get $len)) (then
(loop $to_upper
(local.set $charas (i64.extend_i32_u (call $load_u8 (i64.add (local.get $extism_offset) (local.get $offset)))))
(call $store_u8
(i64.add (local.get $extism_offset) (local.get $offset))
(i32.wrap_i64 (i64.and
(local.get $charas)
(i64.xor
(i64.shl
(i64.extend_i32_u (i64.eqz (i64.div_u (i64.sub (i64.and (i64.const 0xff) (local.get $charas)) (i64.const 96)) (i64.const 27))))
(i64.const 5) ;; 5
)
(i64.const -1)
)
))
)
(local.set $offset (i64.add (i64.const 1) (local.get $offset)))
(br_if $to_upper (i64.lt_u (local.get $offset) (local.get $len)))
)
))
local.get $extism_offset
)
)