Commit 0785a47541b3b3611d965a9a48edcbe1ba110a9c
fix lint
Signed-off-by: wanderer <mjbecze@gmail.com>wanderer committed on 3/30/2018, 6:39:26 PM
Parent: 2d650d0a5b1ca2027397f4f674ca54f771a1c9f8
Files changed
index.js | changed |
package-lock.json | changed |
wasmContainer.js | deleted |
index.js | ||
---|---|---|
@@ -19,9 +19,8 @@ | ||
19 | 19 | containers.forEach(container => this.registerContainer(container)) |
20 | 20 | drivers.forEach(driver => this.registerDriver(driver)) |
21 | 21 | } |
22 | 22 | |
23 | - | |
24 | 23 | /** |
25 | 24 | * sends a message |
26 | 25 | * @param {Object} message - the [message](https://github.com/primea/js-primea-message) to send |
27 | 26 | * @returns {Promise} a promise that resolves once the receiving container is loaded |
package-lock.json | ||
---|---|---|
The diff is too large to show. Use a local git client to view these changes. Old file size: 370223 bytes New file size: 370223 bytes |
wasmContainer.js | ||
---|---|---|
@@ -1,305 +1,0 @@ | ||
1 | -const {wasm2json, json2wasm} = require('wasm-json-toolkit') | |
2 | -const annotations = require('primea-annotations') | |
3 | -const wasmMetering = require('wasm-metering') | |
4 | -const ReferanceMap = require('reference-map') | |
5 | -const injectGlobals = require('./injectGlobals.js') | |
6 | -const typeCheckWrapper = require('./typeCheckWrapper.js') | |
7 | -const {Message, FunctionRef, ModuleRef, DEFAULTS} = require('primea-objects') | |
8 | - | |
9 | -const nativeTypes = new Set(['i32', 'i64', 'f32', 'f64']) | |
10 | -const FUNC_INDEX_OFFSET = 1 | |
11 | - | |
12 | -function fromMetaJSON (json, id) { | |
13 | - const exports = {} | |
14 | - for (const ex in json.exports) { | |
15 | - const type = json.types[json.indexes[json.exports[ex].toString()]].params | |
16 | - exports[ex] = type | |
17 | - } | |
18 | - return new ModuleRef(exports, id) | |
19 | -} | |
20 | - | |
21 | -function generateWrapper (funcRef, container) { | |
22 | - let wrapper = typeCheckWrapper(funcRef.params) | |
23 | - const wasm = json2wasm(wrapper) | |
24 | - const mod = WebAssembly.Module(wasm) | |
25 | - const self = funcRef | |
26 | - wrapper = WebAssembly.Instance(mod, { | |
27 | - 'env': { | |
28 | - 'checkTypes': function () { | |
29 | - const args = [...arguments] | |
30 | - const checkedArgs = [] | |
31 | - while (args.length) { | |
32 | - const type = annotations.LANGUAGE_TYPES_BIN[args.shift()] | |
33 | - let arg = args.shift() | |
34 | - if (!nativeTypes.has(type)) { | |
35 | - arg = container.refs.get(arg, type) | |
36 | - } | |
37 | - checkedArgs.push(arg) | |
38 | - } | |
39 | - const message = new Message({ | |
40 | - funcRef: self, | |
41 | - funcArguments: checkedArgs | |
42 | - }) | |
43 | - container.actor.send(message) | |
44 | - } | |
45 | - } | |
46 | - }) | |
47 | - wrapper.exports.check.object = funcRef | |
48 | - return wrapper | |
49 | -} | |
50 | - | |
51 | -module.exports = class WasmContainer { | |
52 | - constructor (actor) { | |
53 | - this.actor = actor | |
54 | - this.refs = new ReferanceMap() | |
55 | - } | |
56 | - | |
57 | - static createModule (wasm, id) { | |
58 | - if (!WebAssembly.validate(wasm)) { | |
59 | - throw new Error('invalid wasm binary') | |
60 | - } | |
61 | - | |
62 | - let moduleJSON = wasm2json(wasm) | |
63 | - const json = annotations.mergeTypeSections(moduleJSON) | |
64 | - moduleJSON = wasmMetering.meterJSON(moduleJSON, { | |
65 | - meterType: 'i32' | |
66 | - }) | |
67 | - | |
68 | - // initialize the globals | |
69 | - if (json.persist.length) { | |
70 | - moduleJSON = injectGlobals(moduleJSON, json.persist) | |
71 | - } | |
72 | - // recompile the wasm | |
73 | - wasm = json2wasm(moduleJSON) | |
74 | - const modRef = fromMetaJSON(json, id) | |
75 | - return { | |
76 | - wasm, | |
77 | - json, | |
78 | - modRef | |
79 | - } | |
80 | - } | |
81 | - | |
82 | - static onCreation (unverifiedWasm, id, tree) { | |
83 | - const {modRef} = this.createModule(unverifiedWasm, id) | |
84 | - return modRef | |
85 | - } | |
86 | - | |
87 | - getInterface (funcRef) { | |
88 | - const self = this | |
89 | - return { | |
90 | - func: { | |
91 | - externalize: index => { | |
92 | - const func = this.instance.exports.table.get(index) | |
93 | - const object = func.object | |
94 | - if (object) { | |
95 | - // externalize a pervously internalized function | |
96 | - return self.refs.add(object) | |
97 | - } else { | |
98 | - const params = self.json.types[self.json.indexes[func.name - FUNC_INDEX_OFFSET]].params | |
99 | - const ref = new FunctionRef({ | |
100 | - identifier: [true, func.tableIndex], | |
101 | - params, | |
102 | - actorID: self.actor.id | |
103 | - }) | |
104 | - return self.refs.add(ref, 'func') | |
105 | - } | |
106 | - }, | |
107 | - internalize: (index, ref) => { | |
108 | - const funcRef = self.refs.get(ref, 'func') | |
109 | - const wrapper = generateWrapper(funcRef, self) | |
110 | - this.instance.exports.table.set(index, wrapper.exports.check) | |
111 | - }, | |
112 | - // catch: (ref, catchRef) => { | |
113 | - // const {funcRef} = self.refs.get(ref, FunctionRef) | |
114 | - // const {funcRef: catchFunc} = self.refs.get(ref, FunctionRef) | |
115 | - // funcRef.catch = catchFunc | |
116 | - // }, | |
117 | - get_gas_budget: (funcRef) => { | |
118 | - const func = self.refs.get(funcRef, 'func') | |
119 | - return func.gas | |
120 | - }, | |
121 | - set_gas_budget: (funcRef, amount) => { | |
122 | - const func = self.refs.get(funcRef, 'func') | |
123 | - func.gas = amount | |
124 | - } | |
125 | - }, | |
126 | - link: { | |
127 | - wrap: ref => { | |
128 | - const obj = this.refs.get(ref) | |
129 | - const link = {'/': obj} | |
130 | - return this.refs.add(link, 'link') | |
131 | - }, | |
132 | - unwrap: async (ref, cb) => { | |
133 | - const obj = this.refs.get(ref, 'link') | |
134 | - const promise = this.actor.tree.dataStore.get(obj) | |
135 | - await this._opsQueue.push(promise) | |
136 | - } | |
137 | - }, | |
138 | - module: { | |
139 | - new: dataRef => { | |
140 | - const mod = this.actor.createActor(dataRef) | |
141 | - return this.refs.add(mod, 'mod') | |
142 | - }, | |
143 | - export: (modRef, dataRef) => { | |
144 | - const mod = this.refs.get(modRef, 'mod') | |
145 | - let name = this.refs.get(dataRef, 'data') | |
146 | - name = Buffer.from(name).toString() | |
147 | - const funcRef = mod.getFuncRef(name) | |
148 | - return this.refs.add(funcRef, 'func') | |
149 | - }, | |
150 | - self: () => { | |
151 | - return this.refs.add(this.modSelf, 'mod') | |
152 | - } | |
153 | - }, | |
154 | - memory: { | |
155 | - externalize: (index, length) => { | |
156 | - const data = Buffer.from(this.get8Memory(index, length)) | |
157 | - return this.refs.add(data, 'data') | |
158 | - }, | |
159 | - internalize: (dataRef, srcOffset, sinkOffset, length) => { | |
160 | - let data = this.refs.get(dataRef, 'data') | |
161 | - data = data.subarray(srcOffset, length) | |
162 | - const mem = this.get8Memory(sinkOffset, data.length) | |
163 | - mem.set(data) | |
164 | - }, | |
165 | - length (dataRef) { | |
166 | - let data = this.refs.get(dataRef, 'data') | |
167 | - return data.length | |
168 | - } | |
169 | - }, | |
170 | - table: { | |
171 | - externalize: (index, length) => { | |
172 | - const mem = Buffer.from(this.get8Memory(index, length * 4)) | |
173 | - const objects = [] | |
174 | - while (length--) { | |
175 | - const ref = mem.readUInt32LE(length * 4) | |
176 | - const obj = this.refs.get(ref) | |
177 | - objects.unshift(obj) | |
178 | - } | |
179 | - return this.refs.add(objects, 'elem') | |
180 | - }, | |
181 | - internalize: (elemRef, srcOffset, sinkOffset, length) => { | |
182 | - let table = this.refs.get(elemRef, 'elem') | |
183 | - const buf = table.slice(srcOffset, srcOffset + length).map(obj => this.refs.add(obj)) | |
184 | - const mem = this.get32Memory(sinkOffset, length) | |
185 | - mem.set(buf) | |
186 | - }, | |
187 | - length (elemRef) { | |
188 | - let elem = this.refs.get(elemRef, 'elem') | |
189 | - return elem.length | |
190 | - } | |
191 | - }, | |
192 | - metering: { | |
193 | - usegas: amount => { | |
194 | - this.actor.incrementTicks(amount) | |
195 | - funcRef.gas -= amount | |
196 | - if (funcRef.gas < 0) { | |
197 | - throw new Error('out of gas! :(') | |
198 | - } | |
199 | - } | |
200 | - } | |
201 | - } | |
202 | - } | |
203 | - | |
204 | - async onMessage (message) { | |
205 | - const funcRef = message.funcRef | |
206 | - const intef = this.getInterface(funcRef) | |
207 | - this.instance = WebAssembly.Instance(this.mod, intef) | |
208 | - // map table indexes | |
209 | - const table = this.instance.exports.table | |
210 | - if (table) { | |
211 | - let length = table.length | |
212 | - while (length--) { | |
213 | - const func = table.get(length) | |
214 | - if (func) { | |
215 | - func.tableIndex = length | |
216 | - } | |
217 | - } | |
218 | - } | |
219 | - // import references | |
220 | - const args = message.funcArguments.map((arg, index) => { | |
221 | - const type = funcRef.params[index] | |
222 | - if (nativeTypes.has(type)) { | |
223 | - return arg | |
224 | - } else { | |
225 | - return this.refs.add(arg, type) | |
226 | - } | |
227 | - }) | |
228 | - | |
229 | - // setup globals | |
230 | - let numOfGlobals = this.json.persist.length | |
231 | - if (numOfGlobals) { | |
232 | - const refs = [] | |
233 | - while (numOfGlobals--) { | |
234 | - const obj = this.actor.storage[numOfGlobals] || DEFAULTS[this.json.persist[numOfGlobals].type] | |
235 | - refs.push(this.refs.add(obj, this.json.persist[numOfGlobals].type)) | |
236 | - } | |
237 | - this.instance.exports.setter_globals(...refs) | |
238 | - } | |
239 | - | |
240 | - // call entrypoint function | |
241 | - if (funcRef.identifier[0]) { | |
242 | - this.instance.exports.table.get(funcRef.identifier[1])(...args) | |
243 | - } else { | |
244 | - this.instance.exports[funcRef.identifier[1]](...args) | |
245 | - } | |
246 | - await this.onDone() | |
247 | - | |
248 | - // store globals | |
249 | - numOfGlobals = this.json.persist.length | |
250 | - if (numOfGlobals) { | |
251 | - const storage = [] | |
252 | - this.instance.exports.getter_globals() | |
253 | - const mem = this.get32Memory(0, numOfGlobals) | |
254 | - while (numOfGlobals--) { | |
255 | - const ref = mem[numOfGlobals] | |
256 | - storage.push(this.refs.get(ref, this.json.persist[numOfGlobals].type)) | |
257 | - } | |
258 | - this.actor.storage = storage | |
259 | - } | |
260 | - | |
261 | - this.refs.clear() | |
262 | - } | |
263 | - | |
264 | - /** | |
265 | - * returns a promise that resolves when the wasm instance is done running | |
266 | - * @returns {Promise} | |
267 | - */ | |
268 | - async onDone () { | |
269 | - let prevOps | |
270 | - while (prevOps !== this._opsQueue) { | |
271 | - prevOps = this._opsQueue | |
272 | - await prevOps | |
273 | - } | |
274 | - } | |
275 | - | |
276 | - /** | |
277 | - * Pushed an async operation to the a promise queue that | |
278 | - * @returns {Promise} the returned promise resolves in the order the intail | |
279 | - * operation was pushed to the queue | |
280 | - */ | |
281 | - pushOpsQueue (promise) { | |
282 | - this._opsQueue = Promise.all([this._opsQueue, promise]) | |
283 | - return this._opsQueue | |
284 | - } | |
285 | - | |
286 | - async onStartup () { | |
287 | - const code = this.actor.code | |
288 | - const {json, wasm, modRef} = WasmContainer.createModule(code, this.actor.id) | |
289 | - this.mod = WebAssembly.Module(wasm) | |
290 | - this.json = json | |
291 | - this.modSelf = modRef | |
292 | - } | |
293 | - | |
294 | - get8Memory (offset, length) { | |
295 | - return new Uint8Array(this.instance.exports.memory.buffer, offset, length) | |
296 | - } | |
297 | - | |
298 | - get32Memory (offset, length) { | |
299 | - return new Uint32Array(this.instance.exports.memory.buffer, offset, length) | |
300 | - } | |
301 | - | |
302 | - static get typeId () { | |
303 | - return 9 | |
304 | - } | |
305 | -} |
Built with git-ssb-web