Files: 08886ada2409d7516bf4a5654c170fa62fe5e439 / index.js
2557 bytesRaw
1 | const Vertex = require('merkle-trie') |
2 | const Cache = require('imperative-trie') |
3 | const imports = require('./EVMinterface.js') |
4 | const codeHandler = require('./codeHandler.js') |
5 | const MessageQueue = require('./messageQueue') |
6 | const common = require('./common.js') |
7 | |
8 | module.exports = class Kernel { |
9 | constructor (opts = {}) { |
10 | const state = this.state = opts.state || new Vertex() |
11 | state.value = opts.code || state.value |
12 | this.imports = opts.imports || [imports] |
13 | // RENAME agent |
14 | this._vm = (opts.codeHandler || codeHandler).init(state.value) |
15 | this._messageQueue = new MessageQueue(this) |
16 | this._instanceCache = new Cache() |
17 | } |
18 | |
19 | /** |
20 | * run the kernels code with a given enviroment |
21 | * The Kernel Stores all of its state in the Environment. The Interface is used |
22 | * to by the VM to retrive infromation from the Environment. |
23 | */ |
24 | async run (message, imports = this.imports) { |
25 | const state = this.state.copy() |
26 | const result = await this._vm.run(message, this, imports, state) |
27 | if (!result.execption) { |
28 | // update the state |
29 | this.state.set([], state) |
30 | } |
31 | return result |
32 | } |
33 | |
34 | async recieve (message) { |
35 | if (message.isCyclic(this)) { |
36 | const result = await this.run(message) |
37 | message.finished() |
38 | return result |
39 | } else { |
40 | return this._messageQueue.add(message) |
41 | } |
42 | } |
43 | |
44 | async send (port, message) { |
45 | message.sending(this, this._messageQueue.currentMessage) |
46 | // replace root with parent path to root |
47 | if (port === common.ROOT) { |
48 | port = common.PARENT |
49 | message.to = new Array(this.state.path.length - 1).fill(common.PARENT).concat(message.to) |
50 | } |
51 | |
52 | if (port === common.PARENT) { |
53 | message.from.push(this.state.name) |
54 | } else { |
55 | message.from.push(common.PARENT) |
56 | } |
57 | |
58 | const dest = await this.getPort(port) |
59 | return dest.recieve(message) |
60 | } |
61 | |
62 | setValue (name, value) { |
63 | return this.state.set(name, value) |
64 | } |
65 | |
66 | getValue (name) { |
67 | return this.state.get(name) |
68 | } |
69 | |
70 | async getPort (name) { |
71 | let kernel |
72 | if (name === common.PARENT) { |
73 | kernel = this.parent |
74 | } else { |
75 | kernel = this._instanceCache.get(name) |
76 | } |
77 | |
78 | if (kernel) { |
79 | return kernel |
80 | } else { |
81 | const destState = await ( |
82 | name === common.PARENT |
83 | ? this.state.getParent() |
84 | : this.state.get([name])) |
85 | |
86 | const kernel = new Kernel({ |
87 | state: destState |
88 | }) |
89 | |
90 | const cache = new Cache({value: kernel}) |
91 | kernel._instanceCache = cache |
92 | |
93 | this._instanceCache.set(name, kernel) |
94 | return kernel |
95 | } |
96 | } |
97 | } |
98 |
Built with git-ssb-web