Files: e1f7b0f1b9dc6898db308a95307211a4ea191e3c / typeCheckWrapper.js
3083 bytesRaw
1 | const LANGUAGE_TYPES = { |
2 | 'actor': 0x0, |
3 | 'buf': 0x1, |
4 | 'i32': 0x7f, |
5 | 'i64': 0x7e, |
6 | 'f32': 0x7d, |
7 | 'f64': 0x7c, |
8 | 'anyFunc': 0x70, |
9 | 'func': 0x60, |
10 | 'block_type': 0x40 |
11 | } |
12 | |
13 | module.exports = function generateWrapper (type) { |
14 | const module = [{ |
15 | 'name': 'preramble', |
16 | 'magic': [ |
17 | 0, |
18 | 97, |
19 | 115, |
20 | 109 |
21 | ], |
22 | 'version': [ |
23 | 1, |
24 | 0, |
25 | 0, |
26 | 0 |
27 | ] |
28 | }, { |
29 | 'name': 'type', |
30 | 'entries': [{ |
31 | 'form': 'func', |
32 | 'params': [ |
33 | ] |
34 | }, { |
35 | 'form': 'func', |
36 | 'params': [ |
37 | // imported check |
38 | ] |
39 | }, { |
40 | 'form': 'func', |
41 | 'params': [ |
42 | // exported check |
43 | ] |
44 | }, { |
45 | 'form': 'func', |
46 | 'params': [ |
47 | // invoke |
48 | ] |
49 | }] |
50 | }, { |
51 | 'name': 'import', |
52 | 'entries': [{ |
53 | 'moduleStr': 'env', |
54 | 'fieldStr': 'checkTypes', |
55 | 'kind': 'function', |
56 | 'type': 0 |
57 | }] |
58 | }, { |
59 | 'name': 'function', |
60 | 'entries': [ |
61 | 1, |
62 | 2 |
63 | ] |
64 | }, { |
65 | 'name': 'table', |
66 | 'entries': [{ |
67 | 'elementType': 'anyFunc', |
68 | 'limits': { |
69 | 'flags': 1, |
70 | 'intial': 1, |
71 | 'maximum': 1 |
72 | } |
73 | }] |
74 | }, { |
75 | 'name': 'global', |
76 | 'entries': [] |
77 | }, { |
78 | 'name': 'export', |
79 | 'entries': [{ |
80 | 'field_str': 'table', |
81 | 'kind': 'table', |
82 | 'index': 0 |
83 | }, { |
84 | 'field_str': 'invoke', |
85 | 'kind': 'function', |
86 | 'index': 2 |
87 | }, { |
88 | 'field_str': 'check', |
89 | 'kind': 'function', |
90 | 'index': 1 |
91 | }] |
92 | }, { |
93 | 'name': 'code', |
94 | 'entries': [{ |
95 | 'locals': [], |
96 | 'code': [] |
97 | }, { |
98 | 'locals': [], |
99 | 'code': [] |
100 | }] |
101 | }] |
102 | const definedTypes = new Set(['actor', 'func', 'buf']) |
103 | const setGlobals = [] |
104 | const importType = module[1].entries[0].params |
105 | const checkType = module[1].entries[1].params |
106 | const invokerType = module[1].entries[2].params |
107 | const invokeType = module[1].entries[3].params |
108 | const checkCode = module[7].entries[0].code |
109 | const invokeCode = module[7].entries[1].code |
110 | |
111 | type.params.forEach((param, index) => { |
112 | let baseType = param |
113 | const typeCode = LANGUAGE_TYPES[param] |
114 | // import type |
115 | if (definedTypes.has(param)) { |
116 | baseType = 'i32' |
117 | } else { |
118 | baseType = param |
119 | } |
120 | |
121 | // check import |
122 | importType.push('i32') |
123 | importType.push('i32') |
124 | checkCode.push({ |
125 | 'return_type': 'i32', |
126 | 'name': 'const', |
127 | 'immediates': typeCode |
128 | }) |
129 | checkCode.push({ |
130 | 'name': 'get_local', |
131 | 'immediates': index |
132 | }) |
133 | invokeCode.push({ |
134 | 'name': 'get_local', |
135 | 'immediates': index |
136 | }) |
137 | // check export |
138 | checkType.push(baseType) |
139 | // invoke |
140 | invokeType.push(baseType) |
141 | invokerType.push(baseType) |
142 | }) |
143 | |
144 | module[7].entries[0].code = checkCode.concat(setGlobals, [{ |
145 | 'name': 'call', |
146 | 'immediates': '0' |
147 | }, { |
148 | 'name': 'end' |
149 | }]) |
150 | invokeCode.push({ |
151 | 'return_type': 'i32', |
152 | 'name': 'const', |
153 | 'immediates': '0' |
154 | }) |
155 | invokeCode.push({ |
156 | 'name': 'call_indirect', |
157 | 'immediates': { |
158 | 'index': 3, |
159 | 'reserved': 0 |
160 | } |
161 | }) |
162 | invokeCode.push({ |
163 | 'name': 'end' |
164 | }) |
165 | return module |
166 | } |
167 |
Built with git-ssb-web