second-state/SOLL

implement setimmutable(offset, "name", value) and loadimmutable("name") for 0.8.6

jacky860226 opened this issue · 2 comments

setimmutable(offset, "name", value) assumes that the runtime code of the contract containing the given named immutable was copied to memory at offset offset and will write value to all positions in memory (relative to offset) that contain the placeholder that was generated for calls to loadimmutable("name") in the runtime code.

For reference:
The evm version will directly modify the immutable data on deployed bytecode in constructor.

Simple test case

object "a" {
    code {
        let memPtr := mload(64)
        codecopy(memPtr, dataoffset("Test_deployed"), datasize("Test_deployed"))
        setimmutable(
            0,
            "Name",
            address()
        )
        return(memPtr, datasize("Test_deployed"))
    }
    object "Test_deployed" {
        code {
            let addr := loadimmutable("Name")
            return(addr, 20)
            function fun() -> temp {
                temp := loadimmutable("Name")
            }
        }
    }
}
solc test_case.yul --strict-assembly

Binary representation:

604051605361001d8239306000818160010152602c0152605381f350fe7f0000000000000000000000000000000000000000000000000000000000000000601481f36051565b60007f000000000000000000000000000000000000000000000000000000000000000090505b90565b50

Consider to add immutable field as a string type placeholder on data section and embedded into deployed bytecode.
All loadimmutable ops are corresponding to the convert data placeholder into value types.
In the top layer setimmutable need calculate the offset of placeholder on deployed bytecode first, and generate replace the placeholder IR for setimmutable.

  • How to Insert bytes into data section of wasm?

    It's could reference to emitNestedBytecodeFunction in SOLL.