# Interpretation
## How Languages Work — The Codex Coding
**URL:** https://thecodex.expert/coding/how-languages-work/interpretation/
**Type:** concept
**Confidence:** high
**Last verified:** 2026-06-01
**Sources:** 5

---

## CANONICAL DEFINITION

Interpretation is the execution of source code or an intermediate representation by a program called an interpreter, which reads and evaluates program instructions at runtime rather than translating the entire program to machine code ahead of time, enabling immediate execution without a separate compilation step and allowing dynamic language features that would be impossible to resolve statically.

---

## CONCEPT RELATIONSHIP MAP

**Requires first:** How Computers Work · Compilation

**Enables:** Python · JavaScript · Ruby · Concurrency (GIL context)

**Commonly confused with:** Compilation (not a binary distinction); JIT vs. AOT compilation

---

## CURIOUS LEVEL

An interpreter is a live translator — reads and runs code directly. A compiler produces a written translation first, then hands it over.

### Three Interpreter Types (in order of speed)

1. **Tree-walking** — parse to AST, walk and evaluate each node directly. Simple, slow. Used in early Ruby (MRI 1.8).
2. **Bytecode VM** — compile to compact bytecode, execute in a dispatch loop. CPython, YARV (Ruby), Lua, JVM.
3. **JIT-compiling VM** — start as bytecode VM; compile hot paths to native machine code at runtime. V8, HotSpot, LuaJIT.

### CPython

When you run `python script.py`: source → tokens → AST → CPython bytecode (.pyc) → bytecode VM executes. The VM is a stack machine. `dis.dis(fn)` shows the bytecode.

### JIT Compilation (V8)

V8 (JavaScript): Sparkplug (fast baseline) → Maglev → Turbofan (heavy optimise) for hot functions. Uses runtime type information for speculative optimisation. Deoptimises if type assumptions break.

### Why Use an Interpreter?

- eval() and runtime code generation require language machinery at runtime
- REPL environments
- Faster startup (no AOT compilation step)
- Dynamic features: monkey-patching, reflection, runtime class modification

---

## EXPLORING LEVEL

### Comparison Table

| Property | AOT Compilation | Interpretation / JIT |
|---|---|---|
| Startup time | Slow | Fast |
| Peak runtime performance | Highest | Competitive for hot code |
| Dynamic features | Limited | Full |
| Platform portability | Recompile per ISA | Bytecode runs anywhere with VM |
| Memory | Lower (no VM) | Higher (VM, JIT cache) |

### CPython Bytecode Detail

Stack machine. `LOAD_FAST`, `BINARY_OP`, `RETURN_VALUE`. Inspect with `import dis; dis.dis(fn)`.

CPython 3.11+ (PEP 659): specialising adaptive interpreter. Frequently-executed instructions replaced in-place with type-specialised versions (e.g. `BINARY_OP_ADD_INT` instead of generic `BINARY_OP`). Approaches direct threading performance.

### V8 Architecture

Ignition (bytecode interpreter) → Sparkplug (fast baseline JIT) → Maglev → Turbofan (optimising JIT). Hidden classes track object shapes for near-static property access. Polymorphic inline caches (PICs) cache method resolution. Deoptimisation when type assumptions fail.

### CPython GIL

Global Interpreter Lock: only one thread executes Python bytecode at a time. Simplifies reference counting. Prevents true CPU parallelism in multi-threaded Python. Python 3.13 experimental free-threaded build (PEP 703) removes the GIL.

### COMMONLY CONFUSED

- "Interpreted" ≠ slow. V8 JS, HotSpot Java, LuaJIT achieve near-native performance.
- Python does compile — to CPython bytecode. The .pyc files are the evidence.
- JIT ≠ AOT. JIT uses runtime type information; AOT uses whole-program static analysis.

---

## DEEP DIVE LEVEL

### Direct Threading

Naive dispatch: switch on opcode → mispredicts → pipeline stalls. Direct threading: each instruction stores its handler address; at end of handler, jump directly to next handler. No central dispatch. Faster on CPUs with good branch target buffers.

### Inline Caching and Hidden Classes

V8 hidden classes: internal representation of object shapes. Objects with the same property order share a hidden class. Property access becomes a fixed offset load — O(1) like a struct. Inline caches store (hidden class, offset) pairs at call sites. PICs handle multiple types. Transitions between hidden classes when properties are added in different orders — avoid this for performance.

### JVM HotSpot

Two JIT tiers: C1 (client compiler, fast, light optimisation) and C2 (server compiler, slow, heavy optimisation). C2 inlines virtual method calls speculatively based on observed call sites. Deoptimises if a new subclass is loaded. Adaptive compilation: methods compiled at C1 first, promoted to C2 if call frequency warrants.

### Primary Sources

- Aho, Lam, Sethi & Ullman (2006). Compilers: Principles, Techniques, and Tools. Pearson.
- Lindholm, T. et al. (2024). The Java Virtual Machine Specification, Java SE 21. Oracle. docs.oracle.com/javase/specs/.
- Python Software Foundation. dis — Disassembler. docs.python.org/3/library/dis.html.
- Google. V8 documentation. v8.dev/docs.
- PEP 659 — Specialising Adaptive Interpreter. peps.python.org/pep-0659/.

---

*The Codex Coding — thecodex.expert/coding/ — Free forever — Mumbai, India*
*Last verified: June 2026 · Source confidence: high*
