Skip to content

Feat/arithmetic basic opcodes#8

Merged
garyschulte merged 14 commits into10d9e:mainfrom
daniellehrner:feat/arithmetic_basic_opcodes
Mar 5, 2026
Merged

Feat/arithmetic basic opcodes#8
garyschulte merged 14 commits into10d9e:mainfrom
daniellehrner:feat/arithmetic_basic_opcodes

Conversation

@daniellehrner
Copy link
Copy Markdown
Collaborator

@daniellehrner daniellehrner commented Feb 6, 2026

Add mainnet/default evm construction

  • initial/default evm opcode implementations
  • opcode benchmarking
  • fork specific Instruction construction

This is a pretty unwieldy pr, we might consider breaking it up into chunks for review, perhaps along those lines

daniellehrner and others added 3 commits February 6, 2026 16:14
Add ADD opcode (0x01) using peek-peek-shrink-overwrite pattern with native
wrapping arithmetic (+%). Add continue_ and stack_underflow to InstructionResult.
Benchmark uses div0 methodology (pre-fill 900, batch 400 ops) and is hardcoded
to ReleaseFast. Achieves ~2 ns/op, ~1200 MGas/sec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@daniellehrner daniellehrner force-pushed the feat/arithmetic_basic_opcodes branch from 49f4144 to 8d59c11 Compare February 6, 2026 16:15
garyschulte and others added 10 commits February 6, 2026 08:26
Signed-off-by: garyschulte <garyschulte@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
Signed-off-by: garyschulte <garyschulte@gmail.com>
@garyschulte garyschulte marked this pull request as ready for review February 9, 2026 18:11
@garyschulte
Copy link
Copy Markdown
Collaborator

@10d9e,

What do you think about the structure and layout? Were you anticipating implementing InterpreterType field for other evm contexts, like L2s which might have different instruction implementations? This PR has a concrete interpreter implementation, much like the stack and memory implementations that already exist.

Would you like to break this into smaller reviewable PRs chunks, or is a 6k+ line diff ok ?

@garyschulte garyschulte requested a review from 10d9e February 9, 2026 18:53
@10d9e
Copy link
Copy Markdown
Owner

10d9e commented Feb 17, 2026

Add mainnet/default evm construction

  • initial/default evm opcode implementations
  • opcode benchmarking
  • fork specific Instruction construction

This is a pretty unwieldy pr, we might consider breaking it up into chunks for review, perhaps along those lines

Yeah, my general rule of thumb is try to keep PRs less than 1000 LOC if possible. however, this looks like a structural refactor with lots of comprehensive tests.

Love this layout, much more ergonomic for the human eye. I'll comb through it more thoroughly in the coming days.

Copy link
Copy Markdown
Owner

@10d9e 10d9e left a comment

Choose a reason for hiding this comment

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

Excellent PR 🙌 , some minor knits/questions around duplicate vars, memory idioms, etc.

}

/// Build instruction table for a specific hardfork
pub fn makeInstructionTable(spec: primitives.SpecId) InstructionTable {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The instruction table is created (makeInstructionTable) and stored in the handler (Instructions struct), but I don't see it being used for actual opcode dispatch in the interpreter loop.
Is there a dispatch mechanism that uses the instruction table, or is it only for gas cost lookup? If it's only for gas costs maybe we could consider renaming to GasCostTable for clarity?


// Expand memory if needed
if (new_size > memory.size()) {
memory.buffer.resize(std.heap.c_allocator, new_size) catch return .memory_limit_oog;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Minor knit, perhaps more of a zig idiom than anything: it looks like the Memory struct manages it's own memory, which is fine, maybe we could consider if allocator should be passed through the interpreter context, "the zig way"? Not sure though.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We will definitely have to revisit this comprehensively soon, since the allocator we want to use in zkvm is not std

// Base gas costs
pub const G_ZERO = 0;
pub const G_BASE = 2;
pub const G_VERYLOW = 3;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Gas cost constants are defined in multiple places:

  • src/interpreter/gas_costs.zig (G_VERYLOW, G_LOW, etc.)
  • src/interpreter/opcodes/arithmetic.zig (GAS_VERYLOW, GAS_LOW, etc.)
  • src/interpreter/opcodes/memory.zig (GAS_VERYLOW, GAS_BASE, etc.)

Maybe we could import from gas_costs.zig instead of redefining?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

refactored this in subsequent PR

@10d9e 10d9e closed this Feb 25, 2026
@garyschulte
Copy link
Copy Markdown
Collaborator

we don't want to close this one :)

@garyschulte garyschulte reopened this Feb 25, 2026
@garyschulte garyschulte merged commit 7e0c42f into 10d9e:main Mar 5, 2026
5 checks passed
garyschulte added a commit to garyschulte/zevm that referenced this pull request Mar 12, 2026
* consistently handle log topics and data deinit() throughout.  fixes some broken spec tests in zevm-stateless

Signed-off-by: garyschulte <garyschulte@gmail.com>
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.

3 participants