git ssb

0+

wanderer🌟 / js-primea-hypervisor



Commit 6f92591fea03c67a9e18c1daab07a4ed7d693b21

update container format

Signed-off-by: wanderer <mjbecze@gmail.com>
wanderer committed on 2/3/2018, 12:54:31 AM
Parent: d386ffea54d493af4f2eb1eeadc633dd579cdbe3

Files changed

actor.jschanged
index.jschanged
tests/index.jschanged
wasmContainer.jschanged
actor.jsView
@@ -16,8 +16,9 @@
1616
1717 this.inbox = []
1818 this.ticks = 0
1919 this.running = false
20+ this.container = new this.Container(this)
2021 }
2122
2223 serializeMetaData () {
2324 return Actor.serializeMetaData(this.type, this.nonce)
@@ -40,10 +41,10 @@
4041
4142 /**
4243 * Runs the startup routine for the actor
4344 */
44- async startup () {
45- this.instance = await this.container.instance(this)
45+ startup () {
46+ return this.container.onStartup()
4647 }
4748
4849 /**
4950 * run the Actor with a given message
@@ -56,9 +57,10 @@
5657 this.ticks = message._fromTicks
5758 }
5859 try {
5960 this.currentMessage = message
60- await this.instance.exports[message.funcRef.name](...message.funcArguments)
61+ // console.log(this.container.onMessage)
62+ await this.container.onMessage(message)
6163 } catch (e) {
6264 message.emit('execution:error', e)
6365 }
6466 message.emit('done')
index.jsView
@@ -29,15 +29,15 @@
2929
3030 async loadActor (id) {
3131 const state = await this.tree.getSubTree(id)
3232 const {type, nonce} = Actor.deserializeMetaData(state.root['/'][3])
33- const container = this._containerTypes[type]
33+ const Container = this._containerTypes[type]
3434
3535 // create a new actor instance
3636 const actor = new Actor({
3737 hypervisor: this,
3838 state,
39- container,
39+ Container,
4040 id,
4141 nonce,
4242 type
4343 })
@@ -53,18 +53,18 @@
5353 * @param {Object} id - the id for the actor
5454 */
5555 async createActor (type, code, id = {nonce: this.nonce++, parent: null}) {
5656 const Container = this._containerTypes[type]
57- await Container.validate(code)
5857 const encoded = encodedID(id)
5958 const idHash = await this._getHashFromObj(encoded)
59+ const exports = await Container.onCreation(code, idHash)
6060 const metaData = Actor.serializeMetaData(type)
6161
6262 // save the container in the state
6363 this.tree.set(idHash, metaData)
6464 return {
6565 id: idHash,
66- exports: Container.exports(code, idHash)
66+ exports: exports
6767 }
6868 }
6969
7070 // get a hash from a POJO
tests/index.jsView
@@ -6,26 +6,35 @@
66 const RadixTree = require('dfinity-radix-tree')
77 const db = level('./testdb')
88
99 class BaseContainer {
10- static validate () {}
11- static get typeId () {
12- return 9
10+ constructor (actor) {
11+ this.actor = actor
1312 }
14-
15- static exports (m, id) {
16- return Object.keys(this.functions()).map(name => {
17- return {
13+ onStartup () {}
14+ static onCreation (code, id) {
15+ const exp = {}
16+ Object.getOwnPropertyNames(this.prototype).filter(name => name !== 'constructor').forEach(name => {
17+ exp[name] = {
1818 name,
1919 destId: id
2020 }
2121 })
22+ return exp
2223 }
23- static instance (actor) {
24+ getFuncRef (name) {
2425 return {
25- exports: this.functions(actor)
26+ name,
27+ destId: this.id
2628 }
2729 }
30+ onMessage (message) {
31+ return this[message.funcRef.name](...message.funcArguments)
32+ }
33+
34+ static get typeId () {
35+ return 9
36+ }
2837 }
2938
3039 tape('basic', async t => {
3140 t.plan(2)
@@ -37,24 +46,20 @@
3746 db: db
3847 })
3948
4049 class testVMContainer extends BaseContainer {
41- static functions () {
42- return {
43- onMessage: (m) => {
44- t.true(m === 1, 'should recive a message')
45- }
46- }
50+ main (m) {
51+ t.equals(m, 1, 'should recive a message')
4752 }
4853 }
4954
5055 const hypervisor = new Hypervisor(tree)
5156 hypervisor.registerContainer(testVMContainer)
5257
53- let {exports} = await hypervisor.createActor(testVMContainer.typeId)
58+ const {exports} = await hypervisor.createActor(testVMContainer.typeId)
5459
5560 const message = new Message({
56- funcRef: exports[0],
61+ funcRef: exports.main,
5762 funcArguments: [1]
5863 })
5964 hypervisor.send(message)
6065
@@ -72,28 +77,20 @@
7277 db: db
7378 })
7479
7580 class testVMContainerA extends BaseContainer {
76- static functions (actor) {
77- return {
78- onMessage: (funcRef) => {
79- const message = new Message({
80- funcRef: funcRef,
81- funcArguments: [2]
82- })
83- return actor.send(message)
84- }
85- }
81+ main (funcRef) {
82+ const message = new Message({
83+ funcRef: funcRef,
84+ funcArguments: [2]
85+ })
86+ return this.actor.send(message)
8687 }
8788 }
8889
8990 class testVMContainerB extends BaseContainer {
90- static functions () {
91- return {
92- onMessage: (args) => {
93- t.equals(args, 2, 'should recive a message')
94- }
95- }
91+ main (args) {
92+ t.equals(args, 2, 'should recive a message')
9693 }
9794
9895 static get typeId () {
9996 return 8
@@ -107,10 +104,10 @@
107104 const {exports: exportsB} = await hypervisor.createActor(testVMContainerB.typeId)
108105 const {exports: exportsA} = await hypervisor.createActor(testVMContainerA.typeId)
109106
110107 const message = new Message({
111- funcRef: exportsA[0],
112- funcArguments: exportsB
108+ funcRef: exportsA.main,
109+ funcArguments: [exportsB.main]
113110 })
114111
115112 hypervisor.send(message)
116113
@@ -128,28 +125,20 @@
128125 db: db
129126 })
130127
131128 class testVMContainerA extends BaseContainer {
132- static functions (actor) {
133- return {
134- onMessage: (funcRef) => {
135- const message = new Message({
136- funcRef: funcRef,
137- funcArguments: [2]
138- })
139- actor.send(message)
140- }
141- }
129+ main (funcRef) {
130+ const message = new Message({
131+ funcRef: funcRef,
132+ funcArguments: [2]
133+ })
134+ this.actor.send(message)
142135 }
143136 }
144137
145138 class testVMContainerB extends BaseContainer {
146- static functions () {
147- return {
148- onMessage: (arg) => {
149- t.equals(arg, 2, 'should recive a message')
150- }
151- }
139+ main (arg) {
140+ t.equals(arg, 2, 'should recive a message')
152141 }
153142
154143 static get typeId () {
155144 return 8
@@ -164,15 +153,15 @@
164153 let {exports: exportsA0} = await hypervisor.createActor(testVMContainerA.typeId)
165154 let {exports: exportsA1} = await hypervisor.createActor(testVMContainerA.typeId)
166155
167156 const message0 = new Message({
168- funcRef: exportsA0[0],
169- funcArguments: [exportsB[0]]
157+ funcRef: exportsA0.main,
158+ funcArguments: [exportsB.main]
170159 })
171160
172161 const message1 = new Message({
173- funcRef: exportsA1[0],
174- funcArguments: [exportsB[0]]
162+ funcRef: exportsA1.main,
163+ funcArguments: [exportsB.main]
175164 })
176165
177166 await hypervisor.send(message0)
178167 await hypervisor.send(message1)
@@ -191,29 +180,21 @@
191180 db: db
192181 })
193182
194183 class testVMContainerA extends BaseContainer {
195- static functions (actor) {
196- return {
197- onMessage: funcRef => {
198- actor.incrementTicks(1)
199- const message = new Message({
200- funcRef: funcRef,
201- funcArguments: [2]
202- })
203- actor.send(message)
204- }
205- }
184+ main (funcRef) {
185+ this.actor.incrementTicks(1)
186+ const message = new Message({
187+ funcRef: funcRef,
188+ funcArguments: [2]
189+ })
190+ this.actor.send(message)
206191 }
207192 }
208193
209194 class testVMContainerB extends BaseContainer {
210- static functions (actor) {
211- return {
212- onMessage: arg => {
213- t.equals(arg, 2, 'should recive a message')
214- }
215- }
195+ main (arg) {
196+ t.equals(arg, 2, 'should recive a message')
216197 }
217198
218199 static get typeId () {
219200 return 8
@@ -228,14 +209,14 @@
228209 let actorA0 = await hypervisor.createActor(testVMContainerA.typeId)
229210 let actorA1 = await hypervisor.createActor(testVMContainerA.typeId)
230211
231212 const message0 = new Message({
232- funcRef: actorA0.exports[0],
233- funcArguments: [actorB.exports[0]]
213+ funcRef: actorA0.exports.main,
214+ funcArguments: [actorB.exports.main]
234215 })
235216 const message1 = new Message({
236- funcRef: actorA1.exports[0],
237- funcArguments: actorB.exports
217+ funcRef: actorA1.exports.main,
218+ funcArguments: [actorB.exports.main]
238219 })
239220
240221 hypervisor.send(message0)
241222 hypervisor.send(message1)
@@ -254,31 +235,23 @@
254235 db: db
255236 })
256237
257238 class testVMContainerA extends BaseContainer {
258- static functions (actor) {
259- return {
260- onMessage: funcRef => {
261- const message = new Message({
262- funcRef
263- })
264- message.on('execution:error', () => {
265- t.pass('should recive a exeption')
266- })
267- actor.send(message)
268- }
269- }
239+ main (funcRef) {
240+ const message = new Message({
241+ funcRef
242+ })
243+ message.on('execution:error', () => {
244+ t.pass('should recive a exeption')
245+ })
246+ this.actor.send(message)
270247 }
271248 }
272249
273250 class testVMContainerB extends BaseContainer {
274- static functions (actor) {
275- return {
276- onMessage: funcRef => {
277- t.true(true, 'should recive a message')
278- throw new Error('test error')
279- }
280- }
251+ main (funcRef) {
252+ t.true(true, 'should recive a message')
253+ throw new Error('test error')
281254 }
282255
283256 static get typeId () {
284257 return 8
@@ -291,10 +264,10 @@
291264
292265 let {exports: exportsB} = await hypervisor.createActor(testVMContainerB.typeId)
293266 let {exports: exportsA} = await hypervisor.createActor(testVMContainerA.typeId)
294267 const message = new Message({
295- funcRef: exportsA[0],
296- funcArguments: exportsB
268+ funcRef: exportsA.main,
269+ funcArguments: [exportsB.main]
297270 })
298271 hypervisor.send(message)
299272 const stateRoot = await hypervisor.createStateRoot()
300273 t.deepEquals(stateRoot, expectedState, 'expected root!')
@@ -310,32 +283,24 @@
310283 db: db
311284 })
312285
313286 class testVMContainerA extends BaseContainer {
314- static functions (actor) {
315- return {
316- onCreation: async funcRef => {
317- const {exports} = await actor.createActor(testVMContainerB.typeId)
318- const message = new Message({
319- funcRef: exports[0],
320- funcArguments: [actor.getFuncRef('onMessage')]
321- })
322- actor.send(message)
323- },
324- onMessage: data => {
325- t.equals(data, 'test', 'should recive a response message')
326- }
327- }
287+ async start (funcRef) {
288+ const {exports} = await this.actor.createActor(testVMContainerB.typeId)
289+ const message = new Message({
290+ funcRef: exports.main,
291+ funcArguments: [this.actor.getFuncRef('main')]
292+ })
293+ this.actor.send(message)
328294 }
295+ main (data) {
296+ t.equals(data, 'test', 'should recive a response message')
297+ }
329298 }
330299
331300 class testVMContainerB extends BaseContainer {
332- static functions (actor) {
333- return {
334- onCreation: funcRef => {
335- actor.send(new Message({funcRef, funcArguments: ['test']}))
336- }
337- }
301+ main (funcRef) {
302+ this.actor.send(new Message({funcRef, funcArguments: ['test']}))
338303 }
339304
340305 static get typeId () {
341306 return 8
@@ -346,9 +311,9 @@
346311 hypervisor.registerContainer(testVMContainerA)
347312 hypervisor.registerContainer(testVMContainerB)
348313
349314 const {exports} = await hypervisor.createActor(testVMContainerA.typeId)
350- await hypervisor.send(new Message({funcRef: exports[0]}))
315+ await hypervisor.send(new Message({funcRef: exports.start}))
351316
352317 const stateRoot = await hypervisor.createStateRoot()
353318 t.deepEquals(stateRoot, expectedState, 'expected root!')
354319 })
@@ -363,50 +328,42 @@
363328 db: db
364329 })
365330
366331 class testVMContainerA extends BaseContainer {
367- static functions (actor) {
368- return {
369- onCreation: funcRef => {
370- const message1 = new Message({
371- funcArguments: ['first'],
372- funcRef
373- })
374- const message2 = new Message({
375- funcArguments: ['second'],
376- funcRef
377- })
378- const message3 = new Message({
379- funcArguments: ['third'],
380- funcRef
381- })
382- actor.send(message1)
383- actor.incrementTicks(1)
384- actor.send(message2)
385- actor.incrementTicks(1)
386- actor.send(message3)
387- }
388- }
332+ main (funcRef) {
333+ const message1 = new Message({
334+ funcArguments: ['first'],
335+ funcRef
336+ })
337+ const message2 = new Message({
338+ funcArguments: ['second'],
339+ funcRef
340+ })
341+ const message3 = new Message({
342+ funcArguments: ['third'],
343+ funcRef
344+ })
345+ this.actor.send(message1)
346+ this.actor.incrementTicks(1)
347+ this.actor.send(message2)
348+ this.actor.incrementTicks(1)
349+ this.actor.send(message3)
389350 }
390351 }
391352
392353 let recMsg = 0
393354
394355 class testVMContainerB extends BaseContainer {
395- static functions (actor) {
396- return {
397- onMessage: data => {
398- actor.incrementTicks(1)
399- if (recMsg === 0) {
400- t.equal(data, 'first', 'should recive fist message')
401- } else if (recMsg === 1) {
402- t.equal(data, 'second', 'should recive second message')
403- } else {
404- t.equal(data, 'third', 'should recive third message')
405- }
406- recMsg++
407- }
356+ main (data) {
357+ this.actor.incrementTicks(1)
358+ if (recMsg === 0) {
359+ t.equal(data, 'first', 'should recive fist message')
360+ } else if (recMsg === 1) {
361+ t.equal(data, 'second', 'should recive second message')
362+ } else {
363+ t.equal(data, 'third', 'should recive third message')
408364 }
365+ recMsg++
409366 }
410367
411368 static get typeId () {
412369 return 8
@@ -419,10 +376,10 @@
419376
420377 const {exports: exportsB} = await hypervisor.createActor(testVMContainerB.typeId)
421378 const {exports: exportsA} = await hypervisor.createActor(testVMContainerA.typeId)
422379 const message = new Message({
423- funcRef: exportsA[0],
424- funcArguments: exportsB
380+ funcRef: exportsA.main,
381+ funcArguments: [exportsB.main]
425382 })
426383 hypervisor.send(message)
427384
428385 const stateRoot = await hypervisor.createStateRoot()
@@ -440,38 +397,30 @@
440397 db: db
441398 })
442399
443400 class testVMContainerA extends BaseContainer {
444- static functions (actor) {
445- return {
446- onCreation: (funcRef, funcArguments) => {
447- actor.incrementTicks(1)
448- message = new Message({
449- funcRef,
450- funcArguments: [funcArguments]
451- })
452- return actor.send(message)
453- }
454- }
401+ main (funcRef, funcArguments) {
402+ this.actor.incrementTicks(1)
403+ message = new Message({
404+ funcRef,
405+ funcArguments: [funcArguments]
406+ })
407+ this.actor.send(message)
455408 }
456409 }
457410
458411 let recMsg = 0
459412
460413 class testVMContainerB extends BaseContainer {
461- static functions (actor) {
462- return {
463- onMessage: data => {
464- if (recMsg === 0) {
465- t.equal(data, 'first', 'should recive fist message')
466- } else if (recMsg === 1) {
467- t.equal(data, 'second', 'should recive second message')
468- } else {
469- t.equal(data, 'third', 'should recive third message')
470- }
471- recMsg++
472- }
414+ main (data) {
415+ if (recMsg === 0) {
416+ t.equal(data, 'first', 'should recive fist message')
417+ } else if (recMsg === 1) {
418+ t.equal(data, 'second', 'should recive second message')
419+ } else {
420+ t.equal(data, 'third', 'should recive third message')
473421 }
422+ recMsg++
474423 }
475424
476425 static get typeId () {
477426 return 8
@@ -483,23 +432,23 @@
483432 hypervisor.registerContainer(testVMContainerB)
484433
485434 let {exports: exportsB} = await hypervisor.createActor(testVMContainerB.typeId)
486435 hypervisor.send(new Message({
487- funcRef: exportsB[0],
436+ funcRef: exportsB.main,
488437 funcArguments: ['first']
489438 }))
490439
491440 const {exports: exportsA0} = await hypervisor.createActor(testVMContainerA.typeId)
492441
493442 hypervisor.send(new Message({
494- funcRef: exportsA0[0],
495- funcArguments: [exportsB[0], 'second']
443+ funcRef: exportsA0.main,
444+ funcArguments: [exportsB.main, 'second']
496445 }))
497446
498447 const {exports: exportsA1} = await hypervisor.createActor(testVMContainerA.typeId)
499448 hypervisor.send(new Message({
500- funcRef: exportsA1[0],
501- funcArguments: [exportsB[0], 'third']
449+ funcRef: exportsA1.main,
450+ funcArguments: [exportsB.main, 'third']
502451 }))
503452
504453 const stateRoot = await hypervisor.createStateRoot()
505454 t.deepEquals(stateRoot, expectedState, 'expected root!')
@@ -515,41 +464,33 @@
515464 db: db
516465 })
517466
518467 class testVMContainerA extends BaseContainer {
519- static functions (actor) {
520- return {
521- onMessage: (funcRef) => {
522- const message = new Message({
523- funcRef: funcRef,
524- funcArguments: [2]
525- })
526- actor.send(message)
468+ main (funcRef) {
469+ const message = new Message({
470+ funcRef: funcRef,
471+ funcArguments: [2]
472+ })
473+ this.actor.send(message)
527474
528- const message2 = new Message({
529- funcRef: funcRef,
530- funcArguments: [2]
531- })
532- actor.send(message2)
533- actor.incrementTicks(1)
534- return new Promise((resolve, reject) => {
535- setTimeout(() => {
536- resolve()
537- }, 10)
538- })
539- }
540- }
475+ const message2 = new Message({
476+ funcRef: funcRef,
477+ funcArguments: [2]
478+ })
479+ this.actor.send(message2)
480+ this.actor.incrementTicks(1)
481+ return new Promise((resolve, reject) => {
482+ setTimeout(() => {
483+ resolve()
484+ }, 10)
485+ })
541486 }
542487 }
543488
544489 class testVMContainerB extends BaseContainer {
545- static functions (actor) {
546- return {
547- onMessage: (args) => {
548- actor.incrementTicks(1)
549- t.equals(args, 2, 'should recive a message')
550- }
551- }
490+ main (args) {
491+ this.actor.incrementTicks(1)
492+ t.equals(args, 2, 'should recive a message')
552493 }
553494
554495 static get typeId () {
555496 return 8
@@ -563,10 +504,10 @@
563504 const {exports: exportsB} = await hypervisor.createActor(testVMContainerB.typeId)
564505 const {exports: exportsA} = await hypervisor.createActor(testVMContainerA.typeId)
565506
566507 const message = new Message({
567- funcRef: exportsA[0],
568- funcArguments: exportsB
508+ funcRef: exportsA.main,
509+ funcArguments: [exportsB.main]
569510 })
570511
571512 hypervisor.send(message)
572513
@@ -583,29 +524,25 @@
583524 db: db
584525 })
585526
586527 class BenchmarkContainer extends BaseContainer {
587- static functions (actor) {
588- return {
589- onMessage: function () {
590- const refs = [...arguments]
591- const ref = refs.pop()
592- const last = messageOrder[actor.id.toString('hex')]
593- const message = actor.currentMessage
594- if (last) {
595- t.ok(last <= message._fromTicks)
596- }
597- messageOrder[actor.id.toString('hex')] = message._fromTicks
598- numOfMsg++
599- actor.incrementTicks(10)
600- if (ref) {
601- actor.send(new Message({
602- funcRef: ref,
603- funcArguments: refs
604- }))
605- }
606- }
528+ main () {
529+ const refs = [...arguments]
530+ const ref = refs.pop()
531+ const last = messageOrder[this.actor.id.toString('hex')]
532+ const message = this.actor.currentMessage
533+ if (last) {
534+ t.ok(last <= message._fromTicks)
607535 }
536+ messageOrder[this.actor.id.toString('hex')] = message._fromTicks
537+ numOfMsg++
538+ this.actor.incrementTicks(10)
539+ if (ref) {
540+ this.actor.send(new Message({
541+ funcRef: ref,
542+ funcArguments: refs
543+ }))
544+ }
608545 }
609546 }
610547
611548 const hypervisor = new Hypervisor(tree)
@@ -614,9 +551,9 @@
614551 const refernces = []
615552 let _numOfActors = numOfActors
616553 while (_numOfActors--) {
617554 const {exports} = await hypervisor.createActor(BenchmarkContainer.typeId)
618- refernces.push(exports[0])
555+ refernces.push(exports.main)
619556 }
620557 _numOfActors = numOfActors
621558 let msgs = []
622559 while (_numOfActors--) {
wasmContainer.jsView
@@ -73,9 +73,9 @@
7373 module.exports = class WasmContainer {
7474 constructor () {
7575 this.refs = new ReferanceMap()
7676 }
77- onCreation (wasm) {
77+ onCreation (wasm, id, cachedb) {
7878 let moduleJSON = wasm2json(wasm)
7979 this.json = mergeTypeSections(moduleJSON)
8080 moduleJSON = wasmMetering.meterJSON(moduleJSON, {
8181 meterType: 'i32'
@@ -93,9 +93,12 @@
9393 const instance = WebAssembly.Instance(this.mod, {
9494 func: {
9595 externalize: () => {},
9696 internalize: (ref, index) => {
97- const {type, arg} = self.refs.get(ref, FunctionRef)
97+ const {type, arg} = self.refs.get(ref)
98+ if (type !== 'funcRef') {
99+ throw new Error('invalid type')
100+ }
98101 arg.container = self
99102 instance.exports.table.set(index, arg.wrapper.exports.check)
100103 },
101104 catch: (ref, catchRef) => {
@@ -141,9 +144,14 @@
141144 console.log('$$$$', a, b)
142145 }
143146 },
144147 metering: {
145- usegas: () => {}
148+ usegas: (amount) => {
149+ funcRef.gas -= amount
150+ if (funcRef.gas < 0) {
151+ throw new Error('out of gas! :(')
152+ }
153+ }
146154 }
147155 })
148156 const args = funcRef.args.map(arg => {
149157 if (nativeTypes.has(arg.type)) {

Built with git-ssb-web