A ZeroCourse project for Course 11.3: Compilers & Interpreters (Week 2).
Explore CRuby's YARV (Yet Another Ruby VM) bytecode by compiling Ruby source code with RubyVM::InstructionSequence and analyzing the resulting instructions.
Implement three classes:
| Class | Description |
|---|---|
Instruction |
Represents a single YARV instruction with metadata, category, and description |
BytecodeExplorer |
Compiles Ruby source and analyzes the resulting bytecode |
BytecodeComparator |
Compares bytecode efficiency between different Ruby constructs |
| Method | Description |
|---|---|
Instruction#category |
Classify instruction (:stack, :arithmetic, :control, etc.) |
Instruction#description |
Human-readable description from the DESCRIPTIONS constant |
Instruction#to_s |
Formatted line with offset, name, operands, and description |
BytecodeExplorer#compile |
Compile source and extract instructions |
BytecodeExplorer#disasm |
Raw disassembly from RubyVM::InstructionSequence |
BytecodeExplorer#instruction_counts |
Count instructions by category |
BytecodeExplorer#find_instructions(name) |
Find all instructions matching a name |
BytecodeExplorer#annotated_listing |
Full annotated bytecode listing |
BytecodeExplorer#local_variables |
Local variables in the compiled code |
BytecodeExplorer#stack_depth |
Maximum stack depth required |
BytecodeComparator.compare(a, b) |
Compare two source strings by instruction count |
BytecodeComparator.compare_loops |
Compare loop constructs (while vs times vs each) |
BytecodeComparator.report(a, b) |
Formatted comparison report |
-
Install dependencies:
bundle install
-
Run the tests (they will all fail initially):
bundle exec rspec -
Open
lib/bytecode_explorer.rband implement each method. -
Run the tests again to check your progress.
- Start with
Instruction— it's the simplest class and everything else builds on it. - Use
RubyVM::InstructionSequence.compile(source)to compile Ruby source into bytecode. iseq.to_areturns the instruction sequence as a nested array — the body is at index 13.- In the body array: integers are line numbers, symbols starting with
RUBY_EVENT_are trace events, and arrays are instructions (name + operands). iseq.to_a[10]gives you the local variable table.iseq.to_a[4][:stack_max]gives you the max stack depth.- The
CATEGORIESandDESCRIPTIONSconstants are already provided — use them!
- YARV Instructions
- Try
ruby -e 'puts RubyVM::InstructionSequence.compile("1 + 2").disasm'in your terminal
bundle exec rspec # Run all tests
bundle exec rspec --format doc # Verbose output
bundle exec rspec spec/ -e "category" # Run only specific tests