Commit 891456b4ce75b2fdc83622388dc0ebf2837835cc
update to use new annotation lib
Signed-off-by: wanderer <mjbecze@gmail.com>wanderer committed on 3/21/2018, 7:21:38 PM
Parent: 857f72d754b591556c19ed6bfb5896e9fea412e0
Files changed
systemObjects.js | changed |
tests/wasm/globals.wasm | changed |
tests/wasmContainer.js | changed |
tests/wast/globals.json | changed |
tests/wast2wasm.js | changed |
wasmContainer.js | changed |
customTypes.js | deleted |
systemObjects.js | ||
---|---|---|
@@ -8,9 +8,9 @@ | ||
8 | 8 | } |
9 | 9 | |
10 | 10 | const DEFAULTS = { |
11 | 11 | elem: [], |
12 | - buf: Buffer.from([]), | |
12 | + data: Buffer.from([]), | |
13 | 13 | id: new cbor.Tagged(TAGS.id, 0), |
14 | 14 | mod: new cbor.Tagged(TAGS.mod, [{}, new cbor.Tagged(TAGS.id, 0)]), |
15 | 15 | link: {'/': null}, |
16 | 16 | func: new cbor.Tagged(TAGS.func, 0) |
tests/wasm/globals.wasm | ||
---|---|---|
@@ -1,4 +1,4 @@ | ||
1 | - asm globals `` ` +memoryexternalize memoryinternalize A~A~memory load store | |
1 | + asm persist n`` ` +memoryexternalize memoryinternalize A~A~memory load store | |
2 | 2 | |
3 | 3 | A A $ # A AA |
4 | 4 | A test |
tests/wasmContainer.js | ||
---|---|---|
@@ -56,8 +56,10 @@ | ||
56 | 56 | |
57 | 57 | const message = new Message({ |
58 | 58 | funcRef, |
59 | 59 | funcArguments: [5] |
60 | + }).on('execution:error', e => { | |
61 | + console.log(e) | |
60 | 62 | }) |
61 | 63 | hypervisor.send(message) |
62 | 64 | const stateRoot = await hypervisor.createStateRoot() |
63 | 65 | // t.deepEquals(stateRoot, expectedState, 'expected root!') |
tests/wast/globals.json | ||
---|---|---|
@@ -1,6 +1,7 @@ | ||
1 | 1 | { |
2 | - "globals": [{ | |
2 | + "persist": [{ | |
3 | + "form": "global", | |
3 | 4 | "index": 0, |
4 | - "type": "buf" | |
5 | + "type": "data" | |
5 | 6 | }] |
6 | 7 | } |
tests/wast2wasm.js | ||
---|---|---|
@@ -1,7 +1,7 @@ | ||
1 | 1 | const wabt = require('wabt') |
2 | 2 | const fs = require('fs') |
3 | -const types = require('../customTypes') | |
3 | +const annotations = require('primea-annotations') | |
4 | 4 | |
5 | 5 | function filesWast2wasm () { |
6 | 6 | const srcFiles = fs.readdirSync(`${__dirname}/wast`) |
7 | 7 | const wastFiles = srcFiles.filter(name => name.split('.').pop() === 'wast') |
@@ -21,10 +21,9 @@ | ||
21 | 21 | const r = mod.toBinary({log: true}) |
22 | 22 | let binary = Buffer.from(r.buffer) |
23 | 23 | if (json) { |
24 | 24 | console.log(json) |
25 | - const buf = types.encodeJSON(json) | |
26 | - binary = types.injectCustomSection(buf, binary) | |
25 | + binary = annotations.encodeAndInject(json, binary) | |
27 | 26 | } |
28 | 27 | fs.writeFileSync(`${__dirname}/wasm/${file}.wasm`, binary) |
29 | 28 | } catch (e) { |
30 | 29 | console.log(`failed at ${file}`) |
wasmContainer.js | ||
---|---|---|
@@ -1,17 +1,18 @@ | ||
1 | 1 | const {wasm2json, json2wasm} = require('wasm-json-toolkit') |
2 | +const annotations = require('primea-annotations') | |
2 | 3 | const wasmMetering = require('wasm-metering') |
3 | 4 | const ReferanceMap = require('reference-map') |
4 | 5 | const Message = require('./message.js') |
5 | -const customTypes = require('./customTypes.js') | |
6 | +// const customTypes = require('./customTypes.js') | |
6 | 7 | const injectGlobals = require('./injectGlobals.js') |
7 | 8 | const typeCheckWrapper = require('./typeCheckWrapper.js') |
8 | 9 | const {FunctionRef, ModuleRef, DEFAULTS} = require('./systemObjects.js') |
9 | 10 | |
10 | 11 | const nativeTypes = new Set(['i32', 'i64', 'f32', 'f64']) |
11 | 12 | const LANGUAGE_TYPES = { |
12 | 13 | 0x0: 'actor', |
13 | - 0x1: 'buf', | |
14 | + 0x1: 'data', | |
14 | 15 | 0x02: 'elem', |
15 | 16 | 0x03: 'link', |
16 | 17 | 0x04: 'id', |
17 | 18 | 0x7f: 'i32', |
@@ -67,17 +68,17 @@ | ||
67 | 68 | throw new Error('invalid wasm binary') |
68 | 69 | } |
69 | 70 | |
70 | 71 | let moduleJSON = wasm2json(wasm) |
71 | - const json = customTypes.mergeTypeSections(moduleJSON) | |
72 | + const json = annotations.mergeTypeSections(moduleJSON) | |
72 | 73 | moduleJSON = wasmMetering.meterJSON(moduleJSON, { |
73 | 74 | meterType: 'i32' |
74 | 75 | }) |
75 | 76 | |
76 | 77 | // initialize the globals |
77 | - let numOfGlobals = json.globals.length | |
78 | + let numOfGlobals = json.persist.length | |
78 | 79 | if (numOfGlobals) { |
79 | - moduleJSON = injectGlobals(moduleJSON, json.globals) | |
80 | + moduleJSON = injectGlobals(moduleJSON, json.persist) | |
80 | 81 | } |
81 | 82 | // recompile the wasm |
82 | 83 | wasm = json2wasm(moduleJSON) |
83 | 84 | const modRef = ModuleRef.fromMetaJSON(json, id) |
@@ -145,11 +146,11 @@ | ||
145 | 146 | new: dataRef => { |
146 | 147 | const mod = this.actor.createActor(dataRef) |
147 | 148 | return this.refs.add(mod, 'mod') |
148 | 149 | }, |
149 | - export: (modRef, bufRef) => { | |
150 | + export: (modRef, dataRef) => { | |
150 | 151 | const mod = this.refs.get(modRef, 'mod') |
151 | - let name = this.refs.get(bufRef, 'buf') | |
152 | + let name = this.refs.get(dataRef, 'data') | |
152 | 153 | name = Buffer.from(name).toString() |
153 | 154 | const funcRef = mod.getFuncRef(name) |
154 | 155 | return this.refs.add(funcRef, 'func') |
155 | 156 | }, |
@@ -158,20 +159,20 @@ | ||
158 | 159 | } |
159 | 160 | }, |
160 | 161 | memory: { |
161 | 162 | externalize: (index, length) => { |
162 | - const buf = Buffer.from(this.get8Memory(index, length)) | |
163 | - return this.refs.add(buf, 'buf') | |
163 | + const data = Buffer.from(this.get8Memory(index, length)) | |
164 | + return this.refs.add(data, 'data') | |
164 | 165 | }, |
165 | 166 | internalize: (dataRef, srcOffset, sinkOffset, length) => { |
166 | - let buf = this.refs.get(dataRef, 'buf') | |
167 | - buf = buf.subarray(srcOffset, length) | |
168 | - const mem = this.get8Memory(sinkOffset, buf.length) | |
169 | - mem.set(buf) | |
167 | + let data = this.refs.get(dataRef, 'data') | |
168 | + data = data.subarray(srcOffset, length) | |
169 | + const mem = this.get8Memory(sinkOffset, data.length) | |
170 | + mem.set(data) | |
170 | 171 | }, |
171 | 172 | length (dataRef) { |
172 | - let buf = this.refs.get(dataRef, 'buf') | |
173 | - return buf.length | |
173 | + let data = this.refs.get(dataRef, 'data') | |
174 | + return data.length | |
174 | 175 | } |
175 | 176 | }, |
176 | 177 | table: { |
177 | 178 | externalize: (index, length) => { |
@@ -232,14 +233,14 @@ | ||
232 | 233 | } |
233 | 234 | }) |
234 | 235 | |
235 | 236 | // setup globals |
236 | - let numOfGlobals = this.json.globals.length | |
237 | + let numOfGlobals = this.json.persist.length | |
237 | 238 | if (numOfGlobals) { |
238 | 239 | const refs = [] |
239 | 240 | while (numOfGlobals--) { |
240 | - const obj = this.actor.storage[numOfGlobals] || DEFAULTS[this.json.globals[numOfGlobals].type] | |
241 | - refs.push(this.refs.add(obj, this.json.globals[numOfGlobals].type)) | |
241 | + const obj = this.actor.storage[numOfGlobals] || DEFAULTS[this.json.persist[numOfGlobals].type] | |
242 | + refs.push(this.refs.add(obj, this.json.persist[numOfGlobals].type)) | |
242 | 243 | } |
243 | 244 | this.instance.exports.setter_globals(...refs) |
244 | 245 | } |
245 | 246 | |
@@ -251,16 +252,16 @@ | ||
251 | 252 | } |
252 | 253 | await this.onDone() |
253 | 254 | |
254 | 255 | // store globals |
255 | - numOfGlobals = this.json.globals.length | |
256 | + numOfGlobals = this.json.persist.length | |
256 | 257 | if (numOfGlobals) { |
257 | 258 | this.actor.storage = [] |
258 | 259 | this.instance.exports.getter_globals() |
259 | 260 | const mem = this.get32Memory(0, numOfGlobals) |
260 | 261 | while (numOfGlobals--) { |
261 | 262 | const ref = mem[numOfGlobals] |
262 | - this.actor.storage.push(this.refs.get(ref, this.json.globals[numOfGlobals].type)) | |
263 | + this.actor.storage.push(this.refs.get(ref, this.json.persist[numOfGlobals].type)) | |
263 | 264 | } |
264 | 265 | } |
265 | 266 | |
266 | 267 | this.refs.clear() |
customTypes.js | ||
---|---|---|
@@ -1,228 +1,0 @@ | ||
1 | -const Stream = require('buffer-pipe') | |
2 | -const leb = require('leb128') | |
3 | -const {findSections} = require('wasm-json-toolkit') | |
4 | - | |
5 | -const LANGUAGE_TYPES = { | |
6 | - 'actor': 0x0, | |
7 | - 'buf': 0x1, | |
8 | - 'elem': 0x2, | |
9 | - 'link': 0x3, | |
10 | - 'id': 0x4, | |
11 | - 'i32': 0x7f, | |
12 | - 'i64': 0x7e, | |
13 | - 'f32': 0x7d, | |
14 | - 'f64': 0x7c, | |
15 | - 'anyFunc': 0x70, | |
16 | - 'func': 0x60, | |
17 | - 'block_type': 0x40, | |
18 | - | |
19 | - 0x0: 'actor', | |
20 | - 0x1: 'buf', | |
21 | - 0x02: 'elem', | |
22 | - 0x03: 'link', | |
23 | - 0x04: 'id', | |
24 | - 0x7f: 'i32', | |
25 | - 0x7e: 'i64', | |
26 | - 0x7d: 'f32', | |
27 | - 0x7c: 'f64', | |
28 | - 0x70: 'anyFunc', | |
29 | - 0x60: 'func', | |
30 | - 0x40: 'block_type' | |
31 | -} | |
32 | - | |
33 | -function encodeJSON (json) { | |
34 | - const stream = new Stream() | |
35 | - encodeCustomSection('types', json, stream, encodeType) | |
36 | - encodeCustomSection('typeMap', json, stream, encodeTypeMap) | |
37 | - encodeCustomSection('globals', json, stream, encodeGlobals) | |
38 | - | |
39 | - return stream.buffer | |
40 | -} | |
41 | - | |
42 | -function encodeCustomSection (name, json, stream, encodingFunc) { | |
43 | - let payload = new Stream() | |
44 | - json = json[name] | |
45 | - | |
46 | - if (json) { | |
47 | - stream.write([0]) | |
48 | - // encode type | |
49 | - leb.unsigned.write(name.length, payload) | |
50 | - payload.write(name) | |
51 | - encodingFunc(json, payload) | |
52 | - // write the size of the payload | |
53 | - leb.unsigned.write(payload.bytesWrote, stream) | |
54 | - stream.write(payload.buffer) | |
55 | - } | |
56 | - return stream | |
57 | -} | |
58 | - | |
59 | -function encodeGlobals (json, stream) { | |
60 | - leb.unsigned.write(json.length, stream) | |
61 | - for (const entry of json) { | |
62 | - leb.unsigned.write(entry.index, stream) | |
63 | - leb.unsigned.write(LANGUAGE_TYPES[entry.type], stream) | |
64 | - } | |
65 | - return stream | |
66 | -} | |
67 | - | |
68 | -function decodeGlobals (buf) { | |
69 | - const stream = new Stream(Buffer.from(buf)) | |
70 | - let numOfEntries = leb.unsigned.read(stream) | |
71 | - const json = [] | |
72 | - while (numOfEntries--) { | |
73 | - json.push({ | |
74 | - index: leb.unsigned.readBn(stream).toNumber(), | |
75 | - type: LANGUAGE_TYPES[leb.unsigned.readBn(stream).toNumber()] | |
76 | - }) | |
77 | - } | |
78 | - return json | |
79 | -} | |
80 | - | |
81 | -function encodeTypeMap (json, stream) { | |
82 | - leb.unsigned.write(json.length, stream) | |
83 | - for (let entry of json) { | |
84 | - leb.unsigned.write(entry.func, stream) | |
85 | - leb.unsigned.write(entry.type, stream) | |
86 | - } | |
87 | - return stream | |
88 | -} | |
89 | - | |
90 | -function decodeTypeMap (buf) { | |
91 | - const stream = new Stream(Buffer.from(buf)) | |
92 | - let numOfEntries = leb.unsigned.read(stream) | |
93 | - const json = [] | |
94 | - while (numOfEntries--) { | |
95 | - json.push({ | |
96 | - func: leb.unsigned.readBn(stream).toNumber(), | |
97 | - type: leb.unsigned.readBn(stream).toNumber() | |
98 | - }) | |
99 | - } | |
100 | - return json | |
101 | -} | |
102 | - | |
103 | -function encodeType (json, stream = new Stream()) { | |
104 | - let binEntries = new Stream() | |
105 | - | |
106 | - leb.unsigned.write(json.length, binEntries) | |
107 | - for (let entry of json) { | |
108 | - // a single type entry binary encoded | |
109 | - binEntries.write([LANGUAGE_TYPES[entry.form]]) // the form | |
110 | - | |
111 | - const len = entry.params.length // number of parameters | |
112 | - leb.unsigned.write(len, binEntries) | |
113 | - if (len !== 0) { | |
114 | - binEntries.write(entry.params.map(type => LANGUAGE_TYPES[type])) // the paramter types | |
115 | - } | |
116 | - | |
117 | - binEntries.write([entry.return_type ? 1 : 0]) // number of return types | |
118 | - if (entry.return_type) { | |
119 | - binEntries.write([LANGUAGE_TYPES[entry.return_type]]) | |
120 | - } | |
121 | - } | |
122 | - | |
123 | - stream.write(binEntries.buffer) | |
124 | - return stream | |
125 | -} | |
126 | - | |
127 | -function decodeType (buf) { | |
128 | - const stream = new Stream(Buffer.from(buf)) | |
129 | - const numberOfEntries = leb.unsigned.readBn(stream).toNumber() | |
130 | - const json = [] | |
131 | - for (let i = 0; i < numberOfEntries; i++) { | |
132 | - let type = stream.read(1)[0] | |
133 | - const entry = { | |
134 | - form: LANGUAGE_TYPES[type], | |
135 | - params: [] | |
136 | - } | |
137 | - | |
138 | - let paramCount = leb.unsigned.readBn(stream).toNumber() | |
139 | - | |
140 | - // parse the entries | |
141 | - while (paramCount--) { | |
142 | - const type = stream.read(1)[0] | |
143 | - entry.params.push(LANGUAGE_TYPES[type]) | |
144 | - } | |
145 | - const numOfReturns = leb.unsigned.readBn(stream).toNumber() | |
146 | - if (numOfReturns) { | |
147 | - type = stream.read(1)[0] | |
148 | - entry.return_type = LANGUAGE_TYPES[type] | |
149 | - } | |
150 | - | |
151 | - json.push(entry) | |
152 | - } | |
153 | - return json | |
154 | -} | |
155 | - | |
156 | -function injectCustomSection (custom, wasm) { | |
157 | - const preramble = wasm.subarray(0, 8) | |
158 | - const body = wasm.subarray(8) | |
159 | - return Buffer.concat([preramble, custom, body]) | |
160 | -} | |
161 | - | |
162 | -function inject (wasm, json) { | |
163 | - const buf = encodeJSON(json) | |
164 | - return injectCustomSection(buf, wasm) | |
165 | -} | |
166 | - | |
167 | -function mergeTypeSections (json) { | |
168 | - const result = { | |
169 | - types: [], | |
170 | - indexes: {}, | |
171 | - exports: {}, | |
172 | - globals: [] | |
173 | - } | |
174 | - | |
175 | - const wantedSections = ['types', 'typeMap', 'globals', 'type', 'import', 'function', 'export'] | |
176 | - const iterator = findSections(json, wantedSections) | |
177 | - const mappedFuncs = new Map() | |
178 | - const mappedTypes = new Map() | |
179 | - const {value: customType} = iterator.next() | |
180 | - if (customType) { | |
181 | - const type = decodeType(customType.payload) | |
182 | - result.types = type | |
183 | - } | |
184 | - let {value: typeMap} = iterator.next() | |
185 | - if (typeMap) { | |
186 | - decodeTypeMap(typeMap.payload).forEach(map => mappedFuncs.set(map.func, map.type)) | |
187 | - } | |
188 | - | |
189 | - let {value: globals} = iterator.next() | |
190 | - if (globals) { | |
191 | - result.globals = decodeGlobals(globals.payload) | |
192 | - } | |
193 | - | |
194 | - const {value: type} = iterator.next() | |
195 | - const {value: imports = {entries: []}} = iterator.next() | |
196 | - const {value: functions = {entries: []}} = iterator.next() | |
197 | - functions.entries.forEach((typeIndex, funcIndex) => { | |
198 | - let customIndex = mappedFuncs.get(funcIndex) | |
199 | - if (customIndex === undefined) { | |
200 | - customIndex = mappedTypes.get(typeIndex) | |
201 | - } | |
202 | - if (customIndex === undefined) { | |
203 | - customIndex = result.types.push(type.entries[typeIndex]) - 1 | |
204 | - mappedTypes.set(typeIndex, customIndex) | |
205 | - } | |
206 | - result.indexes[funcIndex + imports.entries.length] = customIndex | |
207 | - }) | |
208 | - | |
209 | - const {value: exports = {entries: []}} = iterator.next() | |
210 | - exports.entries.forEach(entry => { | |
211 | - if (entry.kind === 'function') { | |
212 | - result.exports[entry.field_str] = entry.index | |
213 | - } | |
214 | - }) | |
215 | - return result | |
216 | -} | |
217 | - | |
218 | -module.exports = { | |
219 | - injectCustomSection, | |
220 | - inject, | |
221 | - decodeType, | |
222 | - decodeTypeMap, | |
223 | - decodeGlobals, | |
224 | - encodeType, | |
225 | - encodeTypeMap, | |
226 | - encodeJSON, | |
227 | - mergeTypeSections | |
228 | -} |
Built with git-ssb-web