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