Skip to content
This repository has been archived by the owner on Jan 5, 2019. It is now read-only.

Commit

Permalink
Merge pull request #264 from ewasm/callcall2
Browse files Browse the repository at this point in the history
Fix CALLs
  • Loading branch information
lrettig authored May 28, 2018
2 parents 4bd4810 + df34d9d commit 0561608
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 25 deletions.
3 changes: 2 additions & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ defaults:
command: |
git clone https://github.com/ewasm/hera
cd hera
git reset fd89562c7dcea5d66b5516cdc09ac21605be2c02 --hard
git reset 817d85bb4f09d24f11ddfc67bcc548032f708cfc --hard
git submodule update --init --recursive
cmake -DBUILD_SHARED_LIBS=ON .
make -j8
Expand Down Expand Up @@ -71,6 +71,7 @@ defaults:
testeth -t GeneralStateTests/stExample -- --testpath ~/tests --singlenet "Byzantium" --singletest "add11" --vm ~/libhera.so --evmc evm2wasm.js-trace=true
testeth -t GeneralStateTests/stStackTests -- --testpath ~/tests --singlenet "Byzantium" --vm ~/libhera.so --evmc evm2wasm.js=true
testeth -t GeneralStateTests/stBadOpcode -- --testpath ~/tests --singlenet "Byzantium" --vm ~/libhera.so --evmc evm2wasm.js=true
testeth -t GeneralStateTests/stCallCodes -- --testpath ~/tests --singlenet "Byzantium" --singletest "callcall_00" --vm ~/libhera.so --evmc evm2wasm.js=true
echo "ran the state tests."
cli-tests: &cli-tests
Expand Down
68 changes: 60 additions & 8 deletions wasm/generateInterface.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const interfaceManifest = {
CALL: {
name: 'call',
async: true,
input: ['i64', 'address', 'i128', 'readOffset', 'length', 'writeOffset', 'length'],
input: ['i64', 'address', 'i128', 'readOffset', 'length'],
output: ['i32']
},
CALLCODE: {
Expand Down Expand Up @@ -223,13 +223,33 @@ function generateManifest (interfaceManifest, opts) {
// the wasm memory offset is a new item on the EVM stack
spOffset++
call += `(i32.add (get_global $sp) (i32.const ${spOffset * 32}))`
} else if (input === 'i64' && opcode === 'CALL') {
// i64 param for CALL is the gas
// add 2300 gas subsidy
// for now this only works if the gas is a 64-bit value
// TODO: use 256-bit arithmetic
/*
call += `(call $check_overflow_i64
(i64.add (i64.const 2300)
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32}))))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 2})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 3}))))`
*/

// 2300 gas subsidy is done in Hera
call += `(call $check_overflow_i64
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 2})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 3}))))`
} else if (input === 'i32') {
call += `(call $check_overflow
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 2})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 3}))))`
} else if (input === 'i64') {
} else if (input === 'i64' && opcode !== 'CALL') {
call += `(call $check_overflow_i64
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8})))
Expand All @@ -245,7 +265,44 @@ function generateManifest (interfaceManifest, opts) {
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 2})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 3})))))`
call += `(get_local $offset${numOfLocals})`
} else if (input === 'length') {
} else if (input === 'length' && opcode === 'CALL') {
// CALLs in EVM have 7 arguments
// but in ewasm CALLs only have 5 arguments
// so delete the bottom two stack elements, after processing the 5th argument

locals += `(local $length${numOfLocals} i32)`
body += `(set_local $length${numOfLocals}
(call $check_overflow
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 2})))
(i64.load (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 3})))))
(call $memusegas (get_local $offset${numOfLocals}) (get_local $length${numOfLocals}))
(set_local $offset${numOfLocals} (i32.add (get_global $memstart) (get_local $offset${numOfLocals})))`

call += `(get_local $length${numOfLocals})`
numOfLocals++

// delete 6th stack element
spOffset--
call += `
;; zero out mem
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 4})) (i64.const 0))
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 3})) (i64.const 0))
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 2})) (i64.const 0))
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 1})) (i64.const 0))`

// delete 7th stack element
spOffset--
call += `
;; zero out mem
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 4})) (i64.const 0))
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 3})) (i64.const 0))
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 2})) (i64.const 0))
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 1})) (i64.const 0))`

} else if (input === 'length' && opcode !== 'CALL') {
locals += `(local $length${numOfLocals} i32)`
body += `(set_local $length${numOfLocals}
(call $check_overflow
Expand Down Expand Up @@ -279,10 +336,6 @@ function generateManifest (interfaceManifest, opts) {
;; zero out mem
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 3})) (i64.const 0))
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 2})) (i64.const 0))`

if (!op.async) {
call += '(drop (call $bswap_m128 (i32.add (i32.const 32)(get_global $sp))))'
}
} else if (output === 'address') {
call =
`${call} (i32.add (get_global $sp) (i32.const ${spOffset * 32}))`
Expand All @@ -292,7 +345,6 @@ function generateManifest (interfaceManifest, opts) {
}

call += `)
(drop (call $bswap_m160 (i32.add (get_global $sp) (i32.const ${spOffset * 32}))))
;; zero out mem
(i64.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 3})) (i64.const 0))
(i32.store (i32.add (get_global $sp) (i32.const ${spOffset * 32 + 8 * 2 + 4})) (i32.const 0))`
Expand Down
Loading

0 comments on commit 0561608

Please sign in to comment.