-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.fs
234 lines (214 loc) · 5.71 KB
/
parser.fs
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
\ ------------------ Parser
0 Value fd-in
: open-input ( c-addr u -- ) r/o open-file throw to fd-in ;
: close-input ( -- ) fd-in close-file throw ;
: next-byte ( -- n )
fd-in key-file
;
: skip-bytes ( n -- )
0 ?DO
next-byte drop
LOOP
;
: read-bytes-packed ( c-addr n -- )
\ read-line sometimes corrups the last byte?
\ fd-in read-line throw 2drop
over + swap +DO
next-byte i !
LOOP
;
: read-bytes ( a-addr n -- )
cells over + swap +DO
next-byte i !
cell +LOOP
;
CREATE TYPES 32 2 * CELLS ALLOT \ tid*2 -> [nreturn nparams]
CREATE FN-TYPES 32 CELLS ALLOT \ fid -> tid
CREATE FN-INFOS 32 CELLS ALLOT \ fid -> pointer to [nlocals nbytes ...packed-code] OR [0 0 (ptr to host function)]
0 VALUE COUNT-FN
0 VALUE COUNT-FN-IMPORTED
0 Value MEMORY-SIZE
0 Value MEMORY-PTR
0 Value GLOBALS-PTR
-1 VALUE START-FN
: index-to-fid ( u -- u )
COUNT-FN-IMPORTED + ;
: ptr-to-real-addr ( ptr -- c-addr )
MEMORY-PTR +
;
: wasi_unstable.proc_exit ( s -- )
(bye) ;
: wasi_unstable.fd_write { fd ptr n addr-nwritten -- nwritten }
fd 1 <> IF ." fd_write: unsupported fd" bye ENDIF
n 0 ?DO
ptr ptr-to-real-addr
dup ul@ ptr-to-real-addr \ c-addr
swap 4 + ul@ \ u
type
LOOP
0
;
: wasi_unstable.args_sizes_get { a-ptr-argc a-ptr-argv-total-length -- 0 }
argc @
dup a-ptr-argc ptr-to-real-addr l!
0 swap \ sum argc
0 +DO
i arg nip +
LOOP
a-ptr-argv-total-length ptr-to-real-addr l!
0
;
: wasi_unstable.args_get { a-ptr-argv a-ptr-argv-buf -- 0 }
0
argc @
0 +DO
i arg ( offset addr len )
dup -rot ( offset len addr len )
fourth a-ptr-argv-buf + i 4 chars * a-ptr-argv ptr-to-real-addr + l!
fourth a-ptr-argv-buf + ptr-to-real-addr swap move
+
LOOP
drop 0
;
: parse-section-noop
next-byte skip-bytes
;
: parse-section-type
1 skip-bytes
next-byte \ number of types
0 ?DO
1 skip-bytes \ TODO handle other types apart from 60=function?
next-byte \ numbers of params
dup skip-bytes
next-byte \ numbers of return values
dup skip-bytes
TYPES i 2 * cells + 2!
LOOP
;
CREATE IMPORT-READ-BUFFER 128 ALLOT
: parse-section-imports
1 skip-bytes
next-byte
dup TO COUNT-FN-IMPORTED
0 ?DO
next-byte dup IMPORT-READ-BUFFER swap read-bytes-packed
IMPORT-READ-BUFFER swap
s" wasi_unstable" compare
IF ." import from unknown module" bye ENDIF
3 CELLS ALLOCATE throw
dup FN-INFOS i cells + !
0 over !
0 over cell+ !
2 cells +
CASE
next-byte dup IMPORT-READ-BUFFER swap read-bytes-packed
IMPORT-READ-BUFFER swap
2dup s" proc_exit" compare invert ?OF
2drop
['] wasi_unstable.proc_exit
ENDOF
2dup s" fd_write" compare invert ?OF
2drop
['] wasi_unstable.fd_write
ENDOF
2dup s" args_sizes_get" compare invert ?OF
2drop
['] wasi_unstable.args_sizes_get
ENDOF
2dup s" args_get" compare invert ?OF
2drop
['] wasi_unstable.args_get
ENDOF
." unknown import name" bye
ENDCASE
swap !
2 skip-bytes \ TODO other import types
LOOP
;
: parse-section-memory
1 skip-bytes
next-byte 1 = IF
next-byte 0 = IF
next-byte \ TODO use uleb128
dup TO MEMORY-SIZE
allocate throw TO MEMORY-PTR
MEMORY-PTR MEMORY-SIZE erase \ TODO use chars ?
ENDIF
ENDIF
;
: parse-section-start
1 skip-bytes
next-byte TO START-FN
;
: parse-section-functions
1 skip-bytes
next-byte
0 ?DO
next-byte
FN-TYPES i index-to-fid cells + !
LOOP
;
: parse-section-code
1 skip-bytes
next-byte \ number of functions
dup COUNT-FN-IMPORTED + TO COUNT-FN
0 ?DO
next-byte 1- \ bytes of code
next-byte \ how many locals
dup 2 * skip-bytes \ skip locals descriptor TODO there might be more possibilites
swap over 2 * -
dup chars 2 cells + allocate throw
dup FN-INFOS i index-to-fid cells + !
rot
over !
cell+
2dup !
cell+ swap read-bytes-packed
LOOP
;
: parse-section-data
1 skip-bytes
next-byte
0 ?DO
1 skip-bytes \ type TODO there could be more, assume `00`
1 skip-bytes next-byte 1 skip-bytes \ offset TODO interpret instead of assuming `i32.const X end`
ptr-to-real-addr
next-byte ( target length )
read-bytes-packed
LOOP
;
: parse-section-global
1 skip-bytes
next-byte
dup cells allocate throw TO GLOBALS-PTR
0 ?DO
1 skip-bytes \ TODO there could be more, assume `7f` = i32
1 skip-bytes \ ignore info about mutability
1 skip-bytes next-byte 1 skip-bytes \ initial value TODO interpret instead of assuming `i32.const X end`
i cells GLOBALS-PTR + !
LOOP
;
CREATE SECTION-HANDLERS
( 0 ) ' noop ,
( 1 ) ' parse-section-type ,
( 2 ) ' parse-section-imports ,
( 3 ) ' parse-section-functions ,
( 4 ) ' parse-section-noop ,
( 5 ) ' parse-section-memory ,
( 6 ) ' parse-section-global ,
( 7 ) ' parse-section-noop ,
( 8 ) ' parse-section-start ,
( 9 ) ' parse-section-noop ,
( 10 ) ' parse-section-code ,
( 11 ) ' parse-section-data ,
: parse-wasm
8 skip-bytes
BEGIN
next-byte dup -1 <>
WHILE
\ dup . cr
11 min
CELLS SECTION-HANDLERS + @ EXECUTE
REPEAT
drop
;