Skip to content

Conversation

@aarlt
Copy link
Collaborator

@aarlt aarlt commented Jul 26, 2020

Replaced by #10319, #10323, #10368, #10369, #10406.

@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-tests branch from a3cd729 to 20ade27 Compare July 26, 2020 20:20
@aarlt aarlt marked this pull request as draft July 26, 2020 21:07
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-ci branch 7 times, most recently from edd351a to d3eb416 Compare July 27, 2020 23:41
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-tests branch 3 times, most recently from c0b6db3 to 90e3deb Compare July 31, 2020 14:04
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-ci branch from d3eb416 to f496857 Compare July 31, 2020 14:37
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-tests branch 2 times, most recently from 5cd0a49 to 36193b2 Compare July 31, 2020 15:33
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-tests branch from 215b340 to 614734e Compare July 31, 2020 23:18
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-ci branch 4 times, most recently from 05269ce to cdddda1 Compare August 3, 2020 15:07
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-tests branch from 614734e to 71958e6 Compare August 3, 2020 15:08
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-ci branch from cdddda1 to 88af39d Compare August 3, 2020 15:41
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-tests branch from 71958e6 to 0c462ac Compare August 3, 2020 15:41
@aarlt aarlt mentioned this pull request Aug 3, 2020
3 tasks
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-ci branch from 88af39d to f66a09a Compare August 3, 2020 16:24
@axic
Copy link
Contributor

axic commented Oct 29, 2020

Rebased in order to get the changes from #10135.

@axic
Copy link
Contributor

axic commented Oct 29, 2020

We may want to clarify what memory model we are following with the EVM->Wasm translator. I assume we are trying to keep the memory matching with EVM aka. numbers stored are in big-endian order.

This means we need to byteswap balances, but can just copy addresses and storage, as those are not treated as numbers in ewasm host functions.

@leonardoalt
Copy link

@axic @aarlt do we need to discuss that in the round or are you confident that's the way to proceed?

@chriseth
Copy link
Contributor

inline assembly should "just work". mload(x) and mload(add(x, 1)) should return the same thing on ewasm and on evm.

@axic
Copy link
Contributor

axic commented Oct 30, 2020

I assume we are trying to keep the memory matching with EVM aka. numbers stored are in big-endian order.

inline assembly should "just work". mload(x) and mload(add(x, 1)) should return the same thing on ewasm and on evm.

Agreed.

I think in this case this PR may need quite a bit of work to only swap the correct things. It may be swapping sload/store right now which masks the problem.

@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-tests branch 2 times, most recently from 521e631 to d7e23f1 Compare November 2, 2020 22:42
@aarlt
Copy link
Collaborator Author

aarlt commented Nov 2, 2020

I think in this case this PR may need quite a bit of work to only swap the correct things. It may be swapping sload/store right now which masks the problem.

I added a test test/libsolidity/semanticTests/various/endianess.sol to check the behaviour of mload/mstore and sload/sstore. For mload/mstore ewasm is behaving exactly as in the EVM case. For sload/sstore I checked the "endianess" by adding debug output in evmone and hera. It turns out that the implementation is correct.

z3 := bswap64(i64.load(i32.add(pos, 16:i32)))
z4 := bswap64(i64.load(i32.add(pos, 24:i32)))
}
function mload_address(pos:i32) -> z2, z3, z4 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should start adding comments. Is this expecting to read 32 or 20 bytes from pos?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would read 24 bytes from pos. Yeah, we really need to add more comments in that file.

z4 := bswap64(i64.load(i32.add(pos, 24:i32)))
}
function mload_address(pos:i32) -> z2, z3, z4 {
z2 := i64.and(bswap64(i64.load(pos)), 0x00000000ffffffff)
Copy link
Contributor

@axic axic Nov 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just read 32-bits here? (And adjust the offset in the caller too)

Suggested change
z2 := i64.and(bswap64(i64.load(pos)), 0x00000000ffffffff)
z2 := bswap32(i32.load(pos))

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would only work, if we do something like bswap32(i64.extend_i32_u(i32.load(i32.add(pos, 4:i32)))). I think i64.and(bswap64(i64.load(pos)), 0x00000000ffffffff) is better readable.

Copy link
Contributor

@axic axic Nov 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really get it. As long as you only put in 20 bytes of the address in the memory and pos refers to that offset there is no extension needed. Why would bswap32 need i64 inputs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bswap32 is just defined like this - function bswap32(x) -> y. Maybe this can just be changed, I didn't tried that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just changed that. I think it is better now.

@axic
Copy link
Contributor

axic commented Nov 2, 2020

I think what needs to be done is documenting how this is supposed to operate above the polyfill:

  • memory layout
  • size and endianness of types (address, balance, storage)
  • etc.

@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-tests branch 4 times, most recently from 8fe45ba to 0b45a88 Compare November 9, 2020 20:27
@aarlt aarlt force-pushed the evmc-vms-evm-ewasm-tests branch from 0b45a88 to 162ee37 Compare November 17, 2020 02:16
// address need to be encoded as a little endian unsigned integer.
// balance is of type u128 represented as a 16 bytes long
// little endian unsigned integer in memory.
eth.getExternalBalance(12:i32, 32:i32)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following the hera implementation, eth.getExternalBalance(..) get the balance as big endian (evmc_uint256be), where this value is written to the defined offset via storeUint128, that uses storeMemoryReverse - resulting in little endianness.

// little endian unsigned integer in memory.
eth.getExternalBalance(12:i32, 32:i32)
z3 := i64.load(40:i32)
Copy link
Collaborator Author

@aarlt aarlt Nov 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand why this actually works.

If z1, z2, z3, z4 is big endian, where the data is currently encoded as little endian, should'nt this be z3 := bswap64(i64.load(40)) and z4 := bswap64(i64.load(32)) - or, if that data is already stored as big endian, shouldn't this be z3 := i64.load(32) and z4 := i64.load(40).

Both variants are not working.

I don't understand why the i64's need to get loaded "reversely" z3 := i64.load(40) and z4:= i64.load(32) without the need of using bswap64.

Comment on lines +34 to +36
// eth.getAddress: Gets address of currently executing account and stores it
// in memory at the given offset. This address is encoded as a 160 bit number,
// represented as a 20 bytes long little endian unsigned integer in memory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stores little-endian encoded 160 bit number

// mload_address takes the little endian unsigned integer from memory and converts
// it to an big endian unsigned integer (evm is big endian).
z2, z3, z4 := mload_address(0:i32)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds 4 again - could either use 4 here or 0 above.

lo := i64.and(x, 0xffffffff)
}
// xor(x, y): bitwise “xor” of x and y
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not use non-ascii characters

@aarlt aarlt marked this pull request as draft November 17, 2020 17:58
@axic
Copy link
Contributor

axic commented Nov 25, 2020

Is this PR still needed?

@axic
Copy link
Contributor

axic commented Nov 30, 2020

@aarlt can we close this?

@aarlt aarlt closed this Nov 30, 2020
@axic axic deleted the evmc-vms-evm-ewasm-tests branch November 30, 2020 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants