Skip to content

feat: add symbolic stack backend path#85

Open
tcrypt25519 wants to merge 11 commits into
mainfrom
ts/jetdbg
Open

feat: add symbolic stack backend path#85
tcrypt25519 wants to merge 11 commits into
mainfrom
ts/jetdbg

Conversation

@tcrypt25519

Copy link
Copy Markdown
Owner

Summary

  • add a selectable symbolic stack backend and monomorphized stack operations
  • advance symbolic control-flow handling, including dynamic JUMP/JUMPI through conservative site-local switches
  • document the symbolic-stack roadmap and current CFG limitations

Verification

  • cargo check -p jet
  • cargo test -p jet --test test_roms
  • JET_SYMBOLIC_STACK=1 cargo test -p jet --test test_roms
  • cargo clippy -p jet --all-targets -- -D warnings

@semanticdiff-com

semanticdiff-com Bot commented May 16, 2026

Copy link
Copy Markdown

Review changes with  SemanticDiff

Changed Files
File Status
  crates/jet_ir/src/types.rs  76% smaller
  crates/jet/src/builder/ops.rs  30% smaller
  crates/jet/src/builder/contract.rs  20% smaller
  crates/jet_runtime/src/builtins.rs  13% smaller
  crates/jet/src/builder/env.rs  9% smaller
  crates/jet_runtime/src/runtime_builder.rs  3% smaller
  .github/workflows/ci.yml  0% smaller
  Cargo.lock Unsupported file format
  Cargo.toml Unsupported file format
  Makefile Unsupported file format
  README.md Unsupported file format
  crates/jet/src/builder/mod.rs  0% smaller
  crates/jet/src/builder/stack.rs  0% smaller
  crates/jet/src/builder/symbolic.rs  0% smaller
  crates/jet/src/engine/mod.rs  0% smaller
  crates/jet/tests/test_roms.rs  0% smaller
  crates/jet_ir/Cargo.toml Unsupported file format
  crates/jet_runtime/src/symbols.rs  0% smaller
  docs/adrs/adr-003.md Unsupported file format
  docs/architecture/architecture.md Unsupported file format
  docs/architecture/symbolic-stack.md Unsupported file format
  scripts/detect-llvm.sh Unsupported file format
  scripts/install-llvm.sh Unsupported file format
  scripts/llvm.sh Unsupported file format

# Conflicts:
#	Cargo.lock
#	Cargo.toml
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	crates/jet_ir/src/types.rs
Add symbolic block-state handling for static jumps and joins, share non-jump opcode dispatch between stack backends, and document the current lowering model.

Also add targeted JUMPI join tests and jumpdest indexing so symbolic target lookup stays explicit and cheap.
Lower symbolic dynamic JUMP and taken JUMPI through site-local switches over known JUMPDEST targets, carrying the post-pop symbolic stack to each conservative successor.

Add ROM coverage for computed JUMP and JUMPI targets in both runtime and symbolic modes, and update the symbolic stack design note.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a symbolic stack lowering path to the Jet EVM JIT compiler, enabling compile-time tracking of stack values and more efficient IR generation. It refactors opcode implementations to use a generic StackBackend trait, supporting both runtime and symbolic modes, and upgrades the project to LLVM 22. A new jetdbg CLI tool is also included for contract debugging. Review feedback identifies a bug in the symbolic handling of PUSH data where bytes are incorrectly reversed, and recommends using safe Inkwell methods to replace unnecessary unsafe blocks in the stack backend implementation.

IterItem::PushData(_, _, data) => {
let mut new_data = [0u8; 32];
new_data[..data.len()].copy_from_slice(data);
new_data[..data.len()].reverse();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The reverse() call here appears to be a bug. According to the architecture documentation and the instructions::Iter implementation, PUSH data is already converted to little-endian (bytes reversed) by the iterator. Since ops::push expects little-endian bytes to construct its i256 limbs, reversing them again here will turn them back into big-endian, leading to incorrect values for multi-byte PUSH opcodes.

                ops::push(bctx, new_data)?;

Comment thread crates/jet/src/builder/stack.rs Outdated
let loaded = bctx
.builder
.build_load(bctx.env.types().i256, ptr, "load_int")?;
let word = unsafe { IntValue::new(loaded.as_value_ref()) };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The use of unsafe and as_value_ref() here is unnecessary. Since loaded is a BasicValueEnum resulting from an i256 load, you can use the safe into_int_value() method provided by Inkwell.

Suggested change
let word = unsafe { IntValue::new(loaded.as_value_ref()) };
let word = loaded.into_int_value();

Comment thread crates/jet/src/builder/stack.rs Outdated
&[bctx.registers.exec_ctx.into(), index_value.into()],
"stack_peek_word_result",
)?;
let ptr = unsafe { PointerValue::new(ret.as_value_ref()) };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The use of unsafe and as_value_ref() can be avoided here by using into_pointer_value() on the result of the peek call.

Suggested change
let ptr = unsafe { PointerValue::new(ret.as_value_ref()) };
let ptr = ret.try_as_basic_value().left().unwrap().into_pointer_value();

Build symbolic-mode control flow from a fixed-point abstract stack pass before IR emission. Pre-create entry phis for planned block variants, specialize bytecode blocks by incoming stack height, and lower dynamic jumps through variants without falling back to runtime stack traffic.

Preserve known-u64 metadata through symbolic DUP so planned static jump edges and emitted symbolic state agree. Add ROM coverage for backward-only targets, duplicate-carried jump targets, and differing-height joins.
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