Add basic version of concatenation#391
Conversation
| } | ||
|
|
||
| // TODO: support variadic arguments | ||
| forall a b . a:MemoryAttributes, b:MemoryAttributes => function concat(x: a, y: b) -> memory(bytes) { |
There was a problem hiding this comment.
This is here for discussion. It works in the deposit contract properly.
| // Concatenation | ||
|
|
||
|
|
||
| forall t . class t:MemoryAttributes { |
There was a problem hiding this comment.
There's some overlap with ABI encoding. I think in the long term there could be a generalized trait and then three specializations: ABI (calldata/returndata), storage, (runtime) memory.
| // The size needed for the value. | ||
| function len(v: t) -> word; | ||
| // If this is a non-memory type, memory is allocated first. | ||
| function ptr(v: t) -> word; |
There was a problem hiding this comment.
This is not actually needed yet, could remove for now.
| } | ||
| } | ||
|
|
||
| forall a . a:MemoryAttributes => function to_bytes(x: a) -> memory(bytes) { |
There was a problem hiding this comment.
This allows creating memory(bytes) of any supported type. If there was variadic input to concat, one could consider this as the single-argument specialization.
| } | ||
|
|
||
| // TODO: support variadic arguments | ||
| forall a b . a:MemoryAttributes, b:MemoryAttributes => function concat(x: a, y: b) -> memory(bytes) { |
There was a problem hiding this comment.
I know that this could be done with operators (such as Add), but that will always have two operands. Here I hope we could have variadic inputs and thus reducing the memory waste when dealign with 2+ inputs.
| // Placeholder for an empty memory area. | ||
| // The value is the size of the area in bytes. The area will be zeroed upon serialization. | ||
| // NOTE: not implementing Typedef by design. | ||
| data empty = empty(word); |
There was a problem hiding this comment.
This is a lightweight abstraction to avoid allocating memory. It only gets allocated as part of concat or to_bytes.
|
|
||
| // Zero out trailing bytes | ||
| for { } lt(ptr, end_ptr) { ptr := add(ptr, 1) } { | ||
| mstore8(ptr, 0) |
There was a problem hiding this comment.
If there's the dedicated zero slot (0x60-0x7f in classic solidity) then this could be an mcopy instead:
mcopy(ptr, 0x60, sub(end_ptr, ptr))
There was a problem hiding this comment.
There is, will update.
|
@mbenke should we merge this and then you can build your version on top of this reusing some of the helpers (empty/zeroize/...)? |
This adds the following features:
concat(a, b) -> memory(bytes), which takes two supported inputs and encodes it into a new memory arrayto_bytes(a) -> memory(bytes), which does the same but for a single inputempty(size), which represent asize-long memory array filled with the value 0MemoryAttributesclass which enables these features (currently implemented forbytes32,memory(bytes),empty(n))Example: