git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: d9ab14281e683bbcd8f54b5cb7874edbbdd088a7

Files: d9ab14281e683bbcd8f54b5cb7874edbbdd088a7 / index.js

2595 bytesRaw
1const EventEmitter = require('events')
2const Vertex = require('merkle-trie')
3const PortManager = require('./portManager.js')
4const imports = require('./EVMinterface.js')
5const codeHandler = require('./codeHandler.js')
6const common = require('./common.js')
7
8module.exports = class Kernel extends EventEmitter {
9 constructor (opts = {}) {
10 super()
11 const state = this.state = opts.state || new Vertex()
12 this.code = opts.code || state.value
13 this.path = state.path
14 this.imports = opts.imports || [imports]
15 this.ports = new PortManager(state, opts.parent, Kernel)
16 // rename sandbox?
17 this._vm = (opts.codeHandler || codeHandler).init(this.code)
18 this._state = 'idle'
19 this.ports.on('message', message => {
20 // was this kernel already visted?
21 if (message.isCyclic(this) || this._state === 'idle') {
22 this.run(message)
23 }
24 })
25 }
26
27 runNextMessage () {
28 this.ports.dequeue().then(message => {
29 if (message) {
30 this.run(message)
31 } else {
32 this._state = 'idle'
33 this.emit('idle')
34 }
35 })
36 }
37
38 /**
39 * run the kernels code with a given enviroment
40 * The Kernel Stores all of its state in the Environment. The Interface is used
41 * to by the VM to retrive infromation from the Environment.
42 */
43 async run (message, imports = this.imports) {
44 this._state = 'running'
45 const oldState = this.state.copy()
46 const result = await this._vm.run(message, this, imports) || {}
47
48 function revert () {
49 // revert the state
50 this.state.set([], oldState)
51 // revert all the sent messages
52 this.ports.outbox.revert()
53 this.runNextMessage()
54 }
55
56 if (result.execption) {
57 // failed messages
58 revert()
59 } else if (message.atomic) {
60 // messages
61 message.finished().then(this.runNextMessage).catch(revert)
62 } else {
63 // non-atomic messages
64 this.runNextMessage()
65 }
66 return result
67 }
68
69 async send (message) {
70 let portName = message.nextPort()
71 message.addVistedKernel(message)
72 this.lastMessage = message
73 // replace root with parent path to root
74 if (portName === common.ROOT) {
75 portName = common.PARENT
76 message.to = new Array(this.path.length).fill(common.PARENT).concat(message.to)
77 }
78 const port = await this.ports.get(portName)
79 return port.send(message)
80 }
81
82 setValue (name, value) {
83 this.state.set(name, value)
84 }
85
86 getValue (name) {
87 return this.state.get(name)
88 }
89
90 deleteValue (name) {
91 return this.state.del(name)
92 }
93
94 // remove from cache
95 shutdown () {}
96}
97

Built with git-ssb-web