Skip to content

Add basic version of concatenation#391

Open
axic wants to merge 4 commits into
argotorg:mainfrom
axic:concat
Open

Add basic version of concatenation#391
axic wants to merge 4 commits into
argotorg:mainfrom
axic:concat

Conversation

@axic
Copy link
Copy Markdown
Contributor

@axic axic commented May 15, 2026

This adds the following features:

  1. concat(a, b) -> memory(bytes), which takes two supported inputs and encodes it into a new memory array
  2. to_bytes(a) -> memory(bytes), which does the same but for a single input
  3. the type empty(size), which represent a size-long memory array filled with the value 0
  4. the MemoryAttributes class which enables these features (currently implemented for bytes32, memory(bytes), empty(n))

Example:

concat(bytes32(0x1234), empty(12))  # output is 44 bytes

Comment thread std/std.solc
}

// TODO: support variadic arguments
forall a b . a:MemoryAttributes, b:MemoryAttributes => function concat(x: a, y: b) -> memory(bytes) {
Copy link
Copy Markdown
Contributor Author

@axic axic May 15, 2026

Choose a reason for hiding this comment

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

This is here for discussion. It works in the deposit contract properly.

Comment thread std/std.solc
// Concatenation


forall t . class t:MemoryAttributes {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Comment thread std/std.solc
// 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;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is not actually needed yet, could remove for now.

Comment thread std/std.solc
}
}

forall a . a:MemoryAttributes => function to_bytes(x: a) -> memory(bytes) {
Copy link
Copy Markdown
Contributor Author

@axic axic May 15, 2026

Choose a reason for hiding this comment

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

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.

Comment thread std/std.solc
}

// TODO: support variadic arguments
forall a b . a:MemoryAttributes, b:MemoryAttributes => function concat(x: a, y: b) -> memory(bytes) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Comment thread std/std.solc
// 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);
Copy link
Copy Markdown
Contributor Author

@axic axic May 15, 2026

Choose a reason for hiding this comment

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

This is a lightweight abstraction to avoid allocating memory. It only gets allocated as part of concat or to_bytes.

Comment thread std/std.solc Outdated

// Zero out trailing bytes
for { } lt(ptr, end_ptr) { ptr := add(ptr, 1) } {
mstore8(ptr, 0)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There is, will update.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

@axic
Copy link
Copy Markdown
Contributor Author

axic commented May 21, 2026

@mbenke should we merge this and then you can build your version on top of this reusing some of the helpers (empty/zeroize/...)?

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.

1 participant