git ssb

0+

wanderer🌟 / js-primea-hypervisor



Commit 04dbe177869d576e3ab383ecd787fc9c1aed4f0d

updated evm interface

wanderer committed on 1/25/2017, 6:59:52 PM
Parent: 90c78a592cb45542546f035167e39d219a6eaaf1

Files changed

EVMinterface.jschanged
codeHandler.jschanged
common.jschanged
index.jschanged
vm.jsdeleted
wasmAgent.jsadded
EVMinterface.jsView
@@ -15,14 +15,14 @@
1515 const U256_SIZE_BYTES = 32
1616
1717 // The interface exposed to the WebAessembly VM
1818 module.exports = class Interface {
19- constructor (api, message) {
19+ constructor (api, message, results) {
20+ results.gasRefund = 0
2021 this.message = message
2122 this.kernel = api.kernel
22- this.state = api.kernel.state
2323 this.api = api
24- this._results = {}
24+ this.results = results
2525 const shimBin = fs.readFileSync(path.join(__dirname, '/wasm/interface.wasm'))
2626 const shimMod = WebAssembly.Module(shimBin)
2727 this.shims = WebAssembly.Instance(shimMod, {
2828 'interface': {
@@ -34,27 +34,12 @@
3434 })
3535 }
3636
3737 async initialize () {
38- this.block = await this.kernel.send(common.ROOT, new Message({
39- data: {
40- getValue: 'block'
41- },
42- sync: true
43- }))
44-
45- this.blockchain = await this.kernel.send(common.ROOT, new Message({
46- data: {
47- getValue: 'blockchain'
48- },
49- sync: true
50- }))
38+ this.block = await this.kernel.send(common.ROOT, common.getterMessage('block'))
39+ this.blockchain = await this.kernel.send(common.ROOT, common.getterMessage('blockchain'))
5140 }
5241
53- get results () {
54- return this._results
55- }
56-
5742 static get name () {
5843 return 'ethereum'
5944 }
6045
@@ -246,14 +231,10 @@
246231 */
247232 getCodeSize (cbIndex) {
248233 this.takeGas(2)
249234
250- const opPromise = this.state
251- .get('code')
252- .then(vertex => vertex.value.length)
253-
254235 // wait for all the prevouse async ops to finish before running the callback
255- this.kernel.pushOpsQueue(opPromise, cbIndex, length => length)
236+ this.kernel.pushOpsQueue(this.kernel.code.length, cbIndex, length => length)
256237 }
257238
258239 /**
259240 * Copys the code running in current environment to memory.
@@ -263,20 +244,10 @@
263244 */
264245 codeCopy (resultOffset, codeOffset, length, cbIndex) {
265246 this.takeGas(3 + Math.ceil(length / 32) * 3)
266247
267- let opPromise
268-
269- if (length) {
270- opPromise = this.state
271- .get('code')
272- .then(vertex => vertex.value)
273- } else {
274- opPromise = Promise.resolve([])
275- }
276-
277248 // wait for all the prevouse async ops to finish before running the callback
278- this.kernel.pushOpsQueue(opPromise, cbIndex, code => {
249+ this.kernel.pushOpsQueue(this.kernel.code, cbIndex, code => {
279250 if (code.length) {
280251 code = code.slice(codeOffset, codeOffset + length)
281252 this.setMemory(resultOffset, length, code)
282253 }
@@ -289,11 +260,10 @@
289260 * @return {integer}
290261 */
291262 getExternalCodeSize (addressOffset, cbOffset) {
292263 this.takeGas(20)
293- const address = ['accounts', ...this.getMemory(addressOffset, ADDRESS_SIZE_BYTES), 'code']
294- const opPromise = this.state.root
295- .get(address)
264+ const address = ['accounts', ...this.getMemory(addressOffset, ADDRESS_SIZE_BYTES)]
265+ const opPromise = this.kernel.sendMessage(common.ROOT, common.getterMessage('code', address))
296266 .then(vertex => vertex.value.length)
297267 .catch(() => 0)
298268
299269 // wait for all the prevouse async ops to finish before running the callback
@@ -309,13 +279,13 @@
309279 */
310280 externalCodeCopy (addressOffset, resultOffset, codeOffset, length, cbIndex) {
311281 this.takeGas(20 + Math.ceil(length / 32) * 3)
312282
313- const address = ['accounts', ...this.getMemory(addressOffset, ADDRESS_SIZE_BYTES), 'code']
283+ const address = ['accounts', ...this.getMemory(addressOffset, ADDRESS_SIZE_BYTES)]
314284 let opPromise
315285
316286 if (length) {
317- opPromise = this.state.root
287+ opPromise = this.kernel.sendMessage(common.ROOT, common.getterMessage('code', address))
318288 .get(address)
319289 .then(vertex => vertex.value)
320290 .catch(() => [])
321291 } else {
@@ -348,9 +318,9 @@
348318 */
349319 getBlockHash (number, offset, cbOffset) {
350320 this.takeGas(20)
351321
352- const diff = this.kernel.environment.block.number - number
322+ const diff = this.block.number - number
353323 let opPromise
354324
355325 if (diff > 256 || diff <= 0) {
356326 opPromise = Promise.resolve(new U256(0))
@@ -380,9 +350,9 @@
380350 */
381351 getBlockTimestamp () {
382352 this.takeGas(2)
383353
384- return this.kernel.environment.block.timestamp
354+ return this.block.timestamp
385355 }
386356
387357 /**
388358 * Get the block’s number.
@@ -390,9 +360,9 @@
390360 */
391361 getBlockNumber () {
392362 this.takeGas(2)
393363
394- return this.kernel.environment.block.number
364+ return this.block.number
395365 }
396366
397367 /**
398368 * Get the block’s difficulty.
@@ -400,9 +370,9 @@
400370 */
401371 getBlockDifficulty (offset) {
402372 this.takeGas(2)
403373
404- this.setMemory(offset, U256_SIZE_BYTES, this.kernel.environment.block.difficulty.toMemory())
374+ this.setMemory(offset, U256_SIZE_BYTES, this.block.difficulty.toMemory())
405375 }
406376
407377 /**
408378 * Get the block’s gas limit.
@@ -410,9 +380,9 @@
410380 */
411381 getBlockGasLimit () {
412382 this.takeGas(2)
413383
414- return this.kernel.environment.block.gasLimit
384+ return this.message.gasLimit
415385 }
416386
417387 /**
418388 * Creates a new log in the current environment
@@ -593,24 +563,24 @@
593563 const path = [new Buffer(this.getMemory(pathOffset, U256_SIZE_BYTES)).toString('hex')]
594564 // copy the value
595565 const value = this.getMemory(valueOffset, U256_SIZE_BYTES).slice(0)
596566 const valIsZero = value.every((i) => i === 0)
597- const opPromise = this.state.get(path)
567+ const opPromise = this.kernel.getValue(path)
598568 .then(vertex => vertex.value)
599569 .catch(() => null)
600570
601571 this.api.pushOpsQueue(opPromise, cbIndex, oldValue => {
602572 if (valIsZero && oldValue) {
603573 // delete a value
604- this.kernel.environment.gasRefund += 15000
605- this.state.del(path)
574+ this.results.gasRefund += 15000
575+ this.kernel.deleteValue(path)
606576 } else {
607577 if (!valIsZero && !oldValue) {
608578 // creating a new value
609579 this.takeGas(15000)
610580 }
611581 // update
612- this.state.set(path, new Vertex({
582+ this.kernel.setValue(path, new Vertex({
613583 value: value
614584 }))
615585 }
616586 })
@@ -626,9 +596,9 @@
626596
627597 // convert the path to an array
628598 const path = [new Buffer(this.getMemory(pathOffset, U256_SIZE_BYTES)).toString('hex')]
629599 // get the value from the state
630- const opPromise = this.state.get(path)
600+ const opPromise = this.kernel.getValue(path)
631601 .then(vertex => vertex.value)
632602 .catch(() => new Uint8Array(32))
633603
634604 this.api.pushOpsQueue(opPromise, cbIndex, value => {
@@ -642,9 +612,9 @@
642612 * @param {integer} length the length of the output data.
643613 */
644614 return (offset, length) {
645615 if (length) {
646- this.kernel.environment.returnValue = this.getMemory(offset, length).slice(0)
616+ this.results.returnValue = this.getMemory(offset, length).slice(0)
647617 }
648618 }
649619
650620 /**
@@ -652,11 +622,11 @@
652622 * balance to an address path
653623 * @param {integer} offset the offset to load the address from
654624 */
655625 selfDestruct (addressOffset) {
656- this.kernel.environment.selfDestruct = true
657- this.kernel.environment.selfDestructAddress = this.getMemory(addressOffset, ADDRESS_SIZE_BYTES)
658- this.kernel.environment.gasRefund += 24000
626+ this.results.selfDestruct = true
627+ this.results.selfDestructAddress = this.getMemory(addressOffset, ADDRESS_SIZE_BYTES)
628+ this.results.gasRefund += 24000
659629 }
660630
661631 getMemory (offset, length) {
662632 return new Uint8Array(this.api.memory(), offset, length)
codeHandler.jsView
@@ -1,5 +1,5 @@
1-const Wasm = require('./vm.js')
1+const Wasm = require('./wasmAgent.js')
22
33 const defaultHandler = {
44 test: (code) => {
55 return !code
common.jsView
@@ -1,2 +1,13 @@
1+const Message = require('./message')
2+
13 exports.PARENT = Symbol('parent')
24 exports.ROOT = Symbol('root')
5+exports.getterMessage = (name, path) => {
6+ return new Message({
7+ to: path,
8+ data: {
9+ getValue: name
10+ },
11+ sync: true
12+ })
13+}
index.jsView
@@ -22,14 +22,14 @@
2222 * The Kernel Stores all of its state in the Environment. The Interface is used
2323 * to by the VM to retrive infromation from the Environment.
2424 */
2525 async run (message, imports = this.imports) {
26- const state = this.state.copy()
27- const result = await this._vm.run(message, this, imports, state)
28- if (!result.execption) {
29- // update the state
30- this.state.set([], state)
31- }
26+ // const state = this.state.copy()
27+ const result = await this._vm.run(message, this, imports)
28+ // if (!result.execption) {
29+ // // update the state
30+ // this.state.set([], state)
31+ // }
3232 return result
3333 }
3434
3535 async recieve (message) {
@@ -58,5 +58,9 @@
5858
5959 getValue (name) {
6060 return this.state.get(name)
6161 }
62+
63+ deleteValue (name) {
64+ return this.state.del(name)
65+ }
6266 }
vm.jsView
@@ -1,66 +1,0 @@
1-module.exports = class Wasm {
2- /**
3- * The interface API is the api the exposed to interfaces. All queries about
4- * the enviroment and call to the kernel go through this API
5- */
6- constructor (code) {
7- this._module = WebAssembly.Module(code)
8- }
9- /**
10- * Runs the core VM with a given environment and imports
11- */
12- async run (message, kernel, imports, state) {
13- const responses = {}
14- /**
15- * Builds a import map with an array of given interfaces
16- */
17- async function buildImports (kernelApi, kernel, imports) {
18- const importMap = {}
19- for (const Import of imports) {
20- const response = responses[Import.name] = {}
21- const newIterface = new Import(kernelApi, message, response, state)
22- importMap[Import.name] = newIterface.exports
23- // initailize the import
24- await newIterface.initialize()
25- }
26- return importMap
27- }
28-
29- let instance
30- const interfaceApi = {
31- /**
32- * adds an aync operation to the operations queue
33- */
34- pushOpsQueue: (promise, callbackIndex, intefaceCallback) => {
35- this._opsQueue = Promise.all([this._opsQueue, promise]).then(values => {
36- const result = intefaceCallback(values.pop())
37- instance.exports.callback.get(callbackIndex)(result)
38- })
39- },
40- memory: () => {
41- return instance.exports.memory.buffer
42- },
43- kernel: kernel
44- }
45-
46- const initializedImports = await buildImports(interfaceApi, kernel, imports)
47- instance = WebAssembly.Instance(this._module, initializedImports)
48-
49- if (instance.exports.main) {
50- instance.exports.main()
51- }
52- await this.onDone()
53- return responses
54- }
55-
56- /**
57- * returns a promise that resolves when the wasm instance is done running
58- */
59- async onDone () {
60- let prevOps
61- while (prevOps !== this._opsQueue) {
62- prevOps = this._opsQueue
63- await this._opsQueue
64- }
65- }
66-}
wasmAgent.jsView
@@ -1,0 +1,66 @@
1+module.exports = class Wasm {
2+ /**
3+ * The interface API is the api the exposed to interfaces. All queries about
4+ * the enviroment and call to the kernel go through this API
5+ */
6+ constructor (code) {
7+ this._module = WebAssembly.Module(code)
8+ }
9+ /**
10+ * Runs the core VM with a given environment and imports
11+ */
12+ async run (message, kernel, imports) {
13+ const responses = {}
14+ /**
15+ * Builds a import map with an array of given interfaces
16+ */
17+ async function buildImports (kernelApi, kernel, imports) {
18+ const importMap = {}
19+ for (const Import of imports) {
20+ const response = responses[Import.name] = {}
21+ const newIterface = new Import(kernelApi, message, response)
22+ importMap[Import.name] = newIterface.exports
23+ // initailize the import
24+ await newIterface.initialize()
25+ }
26+ return importMap
27+ }
28+
29+ let instance
30+ const interfaceApi = {
31+ /**
32+ * adds an aync operation to the operations queue
33+ */
34+ pushOpsQueue: (promise, callbackIndex, intefaceCallback) => {
35+ this._opsQueue = Promise.all([this._opsQueue, promise]).then(values => {
36+ const result = intefaceCallback(values.pop())
37+ instance.exports.callback.get(callbackIndex)(result)
38+ })
39+ },
40+ memory: () => {
41+ return instance.exports.memory.buffer
42+ },
43+ kernel: kernel
44+ }
45+
46+ const initializedImports = await buildImports(interfaceApi, kernel, imports)
47+ instance = WebAssembly.Instance(this._module, initializedImports)
48+
49+ if (instance.exports.main) {
50+ instance.exports.main()
51+ }
52+ await this.onDone()
53+ return responses
54+ }
55+
56+ /**
57+ * returns a promise that resolves when the wasm instance is done running
58+ */
59+ async onDone () {
60+ let prevOps
61+ while (prevOps !== this._opsQueue) {
62+ prevOps = this._opsQueue
63+ await this._opsQueue
64+ }
65+ }
66+}

Built with git-ssb-web