Files: e5f317ee074967d082a366e35035d77ef081fa84 / injectGlobals.js
2290 bytesRaw
1 | const {findSections} = require('wasm-json-toolkit') |
2 | const wantedSections = ['type', 'import', 'function', 'export', 'code'] |
3 | |
4 | module.exports = function injectGlobals (json, globals) { |
5 | const iter = findSections(json, wantedSections) |
6 | const {value: type} = iter.next() |
7 | const getterType = type.entries.push(typeEntry()) - 1 |
8 | const setterType = type.entries.push(typeEntry(Array(globals.length).fill('i32'))) - 1 |
9 | |
10 | const {value: imports = {entries: []}} = iter.next() |
11 | const {value: func} = iter.next() |
12 | const getterIndex = func.entries.push(getterType) - 1 + imports.entries.length |
13 | const setterIndex = func.entries.push(setterType) - 1 + imports.entries.length |
14 | const {value: exports} = iter.next() |
15 | exports.entries.push(exportEntry('getter_globals', getterIndex)) |
16 | exports.entries.push(exportEntry('setter_globals', setterIndex)) |
17 | const {value: code} = iter.next() |
18 | const getterCode = [] |
19 | const setterCode = [] |
20 | globals.forEach((global, index) => { |
21 | const globalIndex = global.index |
22 | // getter |
23 | getterCode.push(i32_const(index * 4)) |
24 | getterCode.push(get_global(globalIndex)) |
25 | getterCode.push(i32_store()) |
26 | // setter |
27 | setterCode.push(get_local(index)) |
28 | setterCode.push(set_global(globalIndex)) |
29 | }) |
30 | |
31 | getterCode.push(end()) |
32 | setterCode.push(end()) |
33 | code.entries.push(section_code([], getterCode)) |
34 | code.entries.push(section_code([], setterCode)) |
35 | return json |
36 | } |
37 | |
38 | function exportEntry (field_str, index) { |
39 | return { |
40 | field_str, |
41 | kind: 'function', |
42 | index |
43 | } |
44 | } |
45 | |
46 | function typeEntry (params = []) { |
47 | return { |
48 | form: 'func', |
49 | params: params |
50 | } |
51 | } |
52 | |
53 | function end () { |
54 | return { |
55 | name: 'end' |
56 | } |
57 | } |
58 | |
59 | function get_local (index) { |
60 | return { |
61 | name: 'get_local', |
62 | immediates: index |
63 | } |
64 | } |
65 | |
66 | function get_global (index) { |
67 | return { |
68 | name: 'get_global', |
69 | immediates: index |
70 | } |
71 | } |
72 | |
73 | function set_global (index) { |
74 | return { |
75 | name: 'set_global', |
76 | immediates: index |
77 | } |
78 | } |
79 | |
80 | function i32_const (num) { |
81 | return { |
82 | 'return_type': 'i32', |
83 | 'name': 'const', |
84 | 'immediates': num |
85 | } |
86 | } |
87 | |
88 | function i32_store () { |
89 | return { |
90 | 'return_type': 'i32', |
91 | 'name': 'store', |
92 | 'immediates': { |
93 | 'flags': 2, |
94 | 'offset': 0 |
95 | } |
96 | } |
97 | } |
98 | |
99 | function section_code (locals, code) { |
100 | return { |
101 | locals: locals, |
102 | code: code |
103 | } |
104 | } |
105 |
Built with git-ssb-web