Commit 2a922dd52511e08d2503efb3f1e3e8b06b291cc4
Merge pull request #70 from ewasm/tables
use tables for callbacks instead of exportswanderer authored on 1/6/2017, 3:15:18 AM
GitHub committed on 1/6/2017, 3:15:18 AM
Parent: 26787afda66ed5f43ebf8e40d4edefbbcc133e01
Parent: a51f04b0499d6c309d071a010595bc54b0086074
Files changed
EVMimports.js | changed |
tests/interface/balance.wasm | changed |
tests/interface/balance.wast | changed |
tests/interface/call.wasm | changed |
tests/interface/call.wast | changed |
tests/interface/sstore.wasm | changed |
tests/interface/sstore.wast | changed |
tests/interfaceRunner.js | changed |
vm.js | changed |
EVMimports.js | ||
---|---|---|
@@ -187,9 +187,9 @@ | ||
187 | 187 | */ |
188 | 188 | callDataCopy (offset, dataOffset, length) { |
189 | 189 | this.takeGas(3 + Math.ceil(length / 32) * 3) |
190 | 190 | |
191 | - if (length) { | |
191 | + if (length > 0 && offset >= 0 && dataOffset >= 0) { | |
192 | 192 | const callData = this.kernel.environment.callData.slice(dataOffset, dataOffset + length) |
193 | 193 | this.setMemory(offset, length, callData) |
194 | 194 | } |
195 | 195 | } |
@@ -201,8 +201,9 @@ | ||
201 | 201 | * @param {integer} dataOffset the offset in the input data |
202 | 202 | */ |
203 | 203 | callDataCopy256 (offset, dataOffset) { |
204 | 204 | this.takeGas(3) |
205 | + | |
205 | 206 | const callData = this.kernel.environment.callData.slice(dataOffset, dataOffset + 32) |
206 | 207 | this.setMemory(offset, U256_SIZE_BYTES, callData) |
207 | 208 | } |
208 | 209 | |
@@ -336,9 +337,9 @@ | ||
336 | 337 | */ |
337 | 338 | getBlockCoinbase (offset) { |
338 | 339 | this.takeGas(2) |
339 | 340 | |
340 | - this.setMemory(offset, ADDRESS_SIZE_BYTES, this.kernel.environment.coinbase.toMemory()) | |
341 | + this.setMemory(offset, ADDRESS_SIZE_BYTES, this.kernel.environment.block.header.coinbase) | |
341 | 342 | } |
342 | 343 | |
343 | 344 | /** |
344 | 345 | * Get the block’s timestamp. |
@@ -603,11 +604,9 @@ | ||
603 | 604 | * @param {integer} offset the offset of the output data. |
604 | 605 | * @param {integer} length the length of the output data. |
605 | 606 | */ |
606 | 607 | return (offset, length) { |
607 | - if (length) { | |
608 | - this.kernel.environment.returnValue = this.getMemory(offset, length).slice(0) | |
609 | - } | |
608 | + this.kernel.environment.returnValue = this.getMemory(offset, length).slice(0) | |
610 | 609 | } |
611 | 610 | |
612 | 611 | /** |
613 | 612 | * Halt execution and register account for later deletion giving the remaining |
@@ -620,14 +619,20 @@ | ||
620 | 619 | this.kernel.environment.gasRefund += 24000 |
621 | 620 | } |
622 | 621 | |
623 | 622 | getMemory (offset, length) { |
624 | - return new Uint8Array(this.kernel.memory, offset, length) | |
623 | + if (offset >= 0 && length > 0) { | |
624 | + return new Uint8Array(this.kernel.memory, offset, length) | |
625 | + } else { | |
626 | + return new Uint8Array([]) | |
627 | + } | |
625 | 628 | } |
626 | 629 | |
627 | 630 | setMemory (offset, length, value) { |
628 | - const memory = new Uint8Array(this.kernel.memory, offset, length) | |
629 | - memory.set(value) | |
631 | + if (offset >= 0 && length > 0) { | |
632 | + const memory = new Uint8Array(this.kernel.memory, offset, length) | |
633 | + memory.set(value) | |
634 | + } | |
630 | 635 | } |
631 | 636 | |
632 | 637 | /* |
633 | 638 | * Takes gas from the tank. Only needs to check if there's gas left to be taken, |
tests/interface/balance.wasm | ||
---|---|---|
@@ -1,5 +1,5 @@ | ||
1 | 1 | asm |
2 | 2 | ` ` ethereum |
3 | -getBalance memory main 1 | |
3 | +getBalance p memory main callback A | |
4 | 4 | ' |
5 | - A A A @A ) B��������Q@ A ]H���r�h)���oJ-�{ | |
5 | + A A A @A ) B��������Q@ A ]H���r�h)���oJ-�{ |
tests/interface/balance.wast | ||
---|---|---|
@@ -4,12 +4,19 @@ | ||
4 | 4 | (memory 1 ) |
5 | 5 | (data (i32.const 0) "\5d\48\c1\01\89\04\a1\72\88\68\29\bb\bd\9c\6f\4a\2d\06\c4\7b") |
6 | 6 | (export "memory" (memory 0)) |
7 | 7 | (export "main" (func $main)) |
8 | - (export "1" (func $callback)) | |
9 | 8 | |
9 | + (table | |
10 | + (export "callback") | |
11 | + anyfunc | |
12 | + (elem | |
13 | + $callback | |
14 | + ) | |
15 | + ) | |
16 | + | |
10 | 17 | (func $main |
11 | - (call $balance (i32.const 0) (i32.const 0) (i32.const 1)) | |
18 | + (call $balance (i32.const 0) (i32.const 0) (i32.const 0)) | |
12 | 19 | ) |
13 | 20 | |
14 | 21 | (func $callback |
15 | 22 | (block |
tests/interface/call.wasm | ||
---|---|---|
@@ -1,2 +1,2 @@ | ||
1 | - asm `~` ` ethereumcall memory main 1 | |
2 | -:+ @A A6 A4A����6 B�A AA4AA8AA A F@ | |
1 | + asm `~` ` ethereumcall p memory main callback A | |
2 | +:+ @A A6 A4A����6 B�A AA4AA8AA A F@ |
tests/interface/call.wast | ||
---|---|---|
@@ -3,8 +3,17 @@ | ||
3 | 3 | (import "ethereum" "call" (func $call (param i64 i32 i32 i32 i32 i32 i32 i32) (result i32))) |
4 | 4 | (memory 1) |
5 | 5 | (export "memory" (memory 0)) |
6 | 6 | (export "main" (func $main)) |
7 | + | |
8 | + (table | |
9 | + (export "callback") | |
10 | + anyfunc | |
11 | + (elem | |
12 | + $callback | |
13 | + ) | |
14 | + ) | |
15 | + | |
7 | 16 | (func $main |
8 | 17 | (block |
9 | 18 | ;; Memory layout: |
10 | 19 | ;; 0 - 20 bytes: address (4) |
@@ -12,14 +21,13 @@ | ||
12 | 21 | ;; 52 - 56 bytes: data (0x42004200) |
13 | 22 | ;; 56 - 60 bytes: result |
14 | 23 | (i32.store (i32.const 0) (i32.const 0x4)) |
15 | 24 | (i32.store (i32.const 52) (i32.const 0x42004200)) |
16 | - (call $call (i64.const 2000) (i32.const 0) (i32.const 20) (i32.const 52) (i32.const 4) (i32.const 56) (i32.const 4) (i32.const 1)) | |
25 | + (call $call (i64.const 2000) (i32.const 0) (i32.const 20) (i32.const 52) (i32.const 4) (i32.const 56) (i32.const 4) (i32.const 0)) | |
17 | 26 | drop |
18 | 27 | ) |
19 | 28 | ) |
20 | 29 | |
21 | - (export "1" (func $callback)) | |
22 | 30 | (func $callback (param $result i32) |
23 | 31 | (if (i32.eq (i32.const 1) (get_local $result)) |
24 | 32 | (return) |
25 | 33 | ) |
tests/interface/sstore.wasm | ||
---|---|---|
@@ -1,3 +1,3 @@ | ||
1 | 1 | asm |
2 | -` ` 0ethereumstorageStore ethereumstorageLoad main memory 1 2 | |
3 | -L~@A B���݄ƥ�7 A� A A @A� A� A @A� ) B���݄ƥ�R@ | |
2 | +` ` 0ethereumstorageStore ethereumstorageLoad p memory callback main A | |
3 | +L~@A B���݄ƥ�7 A� A A @A� A� A @A� ) B���݄ƥ�R@ |
tests/interface/sstore.wast | ||
---|---|---|
@@ -3,27 +3,35 @@ | ||
3 | 3 | (import "ethereum" "storageStore" (func $sstore (param i32 i32 i32))) |
4 | 4 | (import "ethereum" "storageLoad" (func $sload (param i32 i32 i32))) |
5 | 5 | |
6 | 6 | (memory 1) |
7 | - (export "main" (func $main)) | |
8 | 7 | (export "memory" (memory 0)) |
8 | + | |
9 | + (table | |
10 | + (export "callback") | |
11 | + anyfunc | |
12 | + (elem | |
13 | + $callback | |
14 | + $callback2 | |
15 | + ) | |
16 | + ) | |
17 | + | |
9 | 18 | (func $main |
19 | + (export "main") | |
10 | 20 | (local $temp i64) |
11 | 21 | (block |
12 | 22 | ;; should roundtrip store and load a value from storage |
13 | 23 | (i64.store (i32.const 0) (i64.const 173553719826446289)) |
14 | - (call $sstore (i32.const 64) (i32.const 0) (i32.const 1)) | |
24 | + (call $sstore (i32.const 64) (i32.const 0) (i32.const 0)) | |
15 | 25 | ) |
16 | 26 | ) |
17 | 27 | |
18 | - (export "1" (func $callback)) | |
19 | 28 | (func $callback |
20 | 29 | (block |
21 | - (call $sload (i32.const 64) (i32.const 64) (i32.const 2)) | |
30 | + (call $sload (i32.const 64) (i32.const 64) (i32.const 1)) | |
22 | 31 | ) |
23 | 32 | ) |
24 | 33 | |
25 | - (export "2" (func $callback2)) | |
26 | 34 | (func $callback2 |
27 | 35 | (block |
28 | 36 | (if (i64.ne (i64.load (i32.const 64)) (i64.const 173553719826446289)) |
29 | 37 | (unreachable)) |
tests/interfaceRunner.js | ||
---|---|---|
@@ -3,16 +3,16 @@ | ||
3 | 3 | const path = require('path') |
4 | 4 | const Vertex = require('merkle-trie') |
5 | 5 | const Address = require('../deps/address') |
6 | 6 | const U256 = require('../deps/u256') |
7 | +const Block = require('../deps/block.js') | |
7 | 8 | |
8 | 9 | const Kernel = require('../index.js') |
9 | 10 | const Environment = require('../testEnvironment.js') |
10 | 11 | |
11 | 12 | const dir = path.join(__dirname, '/interface') |
12 | 13 | // get the test names |
13 | 14 | let tests = fs.readdirSync(dir).filter((file) => file.endsWith('.wast')) |
14 | -// tests = ['callDataSize.wast'] | |
15 | 15 | |
16 | 16 | runTests(tests) |
17 | 17 | |
18 | 18 | function runTests (tests) { |
@@ -23,11 +23,12 @@ | ||
23 | 23 | const rootVertex = new Vertex() |
24 | 24 | const code = fs.readFileSync(`${dir}/${testName}.wasm`) |
25 | 25 | const envData = JSON.parse(fs.readFileSync(`${dir}/${testName}.json`).toString()) |
26 | 26 | |
27 | + envData.block = new Block() | |
27 | 28 | envData.caller = new Address(envData.caller) |
28 | 29 | envData.address = new Address(envData.address) |
29 | - envData.coinbase = new Address(envData.coinbase) | |
30 | + envData.block.header.coinbase = new Address(envData.coinbase) | |
30 | 31 | envData.origin = new Address(envData.origin) |
31 | 32 | envData.callData = new Buffer(envData.callData.slice(2), 'hex') |
32 | 33 | envData.callValue = new U256(envData.callValue) |
33 | 34 |
vm.js | ||
---|---|---|
@@ -36,9 +36,9 @@ | ||
36 | 36 | */ |
37 | 37 | pushOpsQueue (promise, callbackIndex, intefaceCallback) { |
38 | 38 | this._opsQueue = Promise.all([this._opsQueue, promise]).then(values => { |
39 | 39 | const result = intefaceCallback(values.pop()) |
40 | - this._instance.exports[callbackIndex.toString()](result) | |
40 | + this._instance.exports.callback.get(callbackIndex)(result) | |
41 | 41 | }) |
42 | 42 | } |
43 | 43 | |
44 | 44 | sendMessage (message) { |
Built with git-ssb-web