Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix writing boolean fields to memory #386

Open
ivoysey opened this issue Nov 8, 2021 · 0 comments
Open

fix writing boolean fields to memory #386

ivoysey opened this issue Nov 8, 2021 · 0 comments
Assignees
Labels
Milestone

Comments

@ivoysey
Copy link
Collaborator

ivoysey commented Nov 8, 2021

This is a test case that should work and doesn't right now.

contract Container{
    int x;
    int y;
    bool b;
    int z;

    transaction set() {
	b = true;
        z = 4;
        y = 9;
	x = -2;
    }

    transaction get() returns int{
        if (b) {
	    return x * y;
	} else {
	    return y + z;
	}
    }
}

main contract SGNotJustInts{
    transaction main() returns int{
        Container c = new Container();
        c.set();
        return c.get();
    }
}

We generate this Yul, after optimization:

object "SGNotJustInts" {
    code {
        {
            mstore(64, 128)
            if callvalue() { revert(0, 0) }
            let _1 := datasize("SGNotJustInts_deployed")
            codecopy(0, dataoffset("SGNotJustInts_deployed"), _1)
            return(0, _1)
        }
    }
    object "SGNotJustInts_deployed" {
        code {
            {
                mstore(64, 128)
                if iszero(lt(calldatasize(), 4))
                {
                    let _1 := 0
                    switch shr(224, calldataload(_1))
                    case 0xdffeadd0 {
                        if callvalue() { revert(_1, _1) }
                        abi_decode_tuple(calldatasize())
                        let _dd_ret := main()
                        let memPos := mload(64)
                        return(memPos, sub(abi_encode_to1(memPos, _dd_ret), memPos))
                    }
                    case 0xd49c9f7d {
                        if callvalue() { revert(_1, _1) }
                        abi_decode_tuple(calldatasize())
                        Container_set(address())
                        return(mload(64), _1)
                    }
                    case 0x89fe7992 {
                        if callvalue() { revert(_1, _1) }
                        abi_decode_tuple(calldatasize())
                        let _dd_ret_1 := Container_get(address())
                        let memPos_1 := mload(64)
                        return(memPos_1, sub(abi_encode_to1(memPos_1, _dd_ret_1), memPos_1))
                    }
                }
                revert(0, 0)
            }
            function abi_decode_tuple(dataEnd)
            {
                if slt(add(dataEnd, not(3)), 0) { revert(0, 0) }
            }
            function abi_encode_to1(headStart, value0) -> tail
            {
                tail := add(headStart, 32)
                mstore(headStart, value0)
            }
            function main() -> _ret
            {
                let memPtr := mload(0x40)
                let newFreePtr := add(memPtr, 96)
                if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr))
                {
                    mstore(0, shl(224, 0x4e487b71))
                    mstore(4, 0x41)
                    revert(0, 0x24)
                }
                mstore(0x40, newFreePtr)
                Container_set(memPtr)
                _ret := Container_get(memPtr)
            }
            function Container_set(this)
            {
                let _1 := add(this, 64)
                mstore(_1, true)
                mstore(_1, 4)
                mstore(add(this, 32), 9)
                mstore(this, not(1))
            }
            function Container_get(this) -> _ret
            {
                switch mload(add(this, 64))
                case true {
                    let _tmp := mload(this)
                    _ret := mul(_tmp, mload(add(this, 32)))
                    leave
                }
                case false {
                    _ret := add(mload(add(this, 32)), false)
                    leave
                }
            }
        }
    }
}

I think even just doing mstore(_1, true) is garbage, so I need to trace out exactly how booleans are getting represented and written out to memory.

@ivoysey ivoysey self-assigned this Nov 8, 2021
@ivoysey ivoysey added the bug label Nov 8, 2021
@ivoysey ivoysey added this to the m1 milestone Nov 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant