git ssb

0+

wanderer🌟 / js-primea-hypervisor



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.jschanged
package-lock.jsonchanged
wasmContainer.jsdeleted
index.jsView
@@ -19,9 +19,8 @@
1919 containers.forEach(container => this.registerContainer(container))
2020 drivers.forEach(driver => this.registerDriver(driver))
2121 }
2222
23-
2423 /**
2524 * sends a message
2625 * @param {Object} message - the [message](https://github.com/primea/js-primea-message) to send
2726 * @returns {Promise} a promise that resolves once the receiving container is loaded
package-lock.jsonView
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.jsView
@@ -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