Bytecode Format: A Real Compile Artifact
Lesson, slides, and applied problem sets.
View SlidesLesson
Bytecode Format: A real compile artifact
A bytecode text format is not just serialization—it is an ABI of your compiler pipeline.
Why BC1 matters
- decouple compiler and VM implementation details,
- support persistence/debugging,
- validate compiler output shape before execution,
- make linker/runner deterministic.
If format checks are weak, runtime bugs become integration bugs.
Shape contract
- file starts with
BC1header, - zero or more
FUNC name [params...] ... ENDblocks, - one
MAIN ... ENDblock, - blank lines and comments (
#) are non-semantic.
Section order and names are part of identity for this pack.
Instruction line grammar
Opcodes may have:
- no args:
ADD,RETURN - integer arg:
JUMP 12,PUSH_NUM 7 - name arg:
LOAD x,DEFINE_VAR y - mixed:
CALL print 1 - string arg:
PUSH_STR "..."
A parser must validate both token count and arg types.
String and escaping discipline
PUSH_STR values must parse with quote-aware logic:
- collect characters until matching quote,
- decode
\n,\t,\",\\, - reject bare newline/unterminated quote.
On encode, escaped characters must be re-emitted safely.
Determinism and canonicalization
Round-trip expectation:
Decode -> objectshould reject malformed structure,Encodeshould emit stable deterministic order,- structural equivalence should preserve function names/order/sections and instructions.
If instruction ordering changes with equivalent content, diff tests become noisy and caches become unreliable.
Error model
Fail fast on first structural invalidity:
- missing header,
- unexpected end-of-section,
- missing
END, - unknown opcode,
- malformed integer,
- invalid string literal,
- wrong arg count.
Bytecode as contract between stages
Compile -> Encode -> Decode -> VM is where pipeline correctness is hardened:
- compile can be wrong,
- runtime might still crash in later phases,
- but decode catches representation mismatch early if format contract is strict.
Deep practice checkpoints (almost solved)
1) Basic sectioning
Input:
BC1
FUNC add a
LOAD a
RETURN
END
MAIN
PUSH_NUM 1
END
Expected:
- one function
add, one main section.
2) Missing section close
Input: BC1\nMAIN\nPUSH_NUM 1
Expected:
- decode error for missing final
END.
3) Unknown opcode
Input: BC1\nMAIN\nFOO\nEND
Expected:
- decode error: unknown opcode.
4) String parse correctness
Input: BC1\nMAIN\nPUSH_STR "a\\nb\"c"\nEND
Expected:
- decoded instruction string has newline and quote inside value.
5) Header requirement
Input without BC1
Expected:
- decode reject malformed header.
6) Deterministic encode behavior
Given same decoded object twice
Expected:
- encodings should be structurally equivalent (function/section order stable).
7) Mixed arg checks
Input: CALL\nCALL 1\nCALL f x
Expected:
- arity checks for each bad call shape.
8) Comment skipping
Input includes: # header comment
Expected:
- comments ignored and don't alter instruction stream.
9) Function param capture
FUNC add x y
Expected:
- params
x ycaptured as part of function identity in decode model.
10) Malformed line shape
Input: PUSH_STR unquoted
Expected:
- decode error for unterminated or malformed string literal.
Module Items
Bytecode IO