Merge branch 'bytecode_cleanup' into mach
This commit is contained in:
@@ -154,3 +154,12 @@ struct JSCodeRegister {
|
||||
```
|
||||
|
||||
The constant pool holds all non-immediate values referenced by `LOADK` instructions: strings, large numbers, and other constants.
|
||||
|
||||
### Constant Pool Index Overflow
|
||||
|
||||
Named property instructions (`LOAD_FIELD`, `STORE_FIELD`, `DELETE`) use the iABC format where the constant pool key index occupies an 8-bit field (max 255). When a function references more than 256 unique property names, the serializer automatically falls back to a two-instruction sequence:
|
||||
|
||||
1. `LOADK tmp, key_index` — load the key string into a temporary register (iABx, 16-bit index)
|
||||
2. `LOAD_DYNAMIC` / `STORE_DYNAMIC` / `DELETEINDEX` — use the register-based variant
|
||||
|
||||
This is transparent to the mcode compiler and streamline optimizer.
|
||||
|
||||
@@ -10,11 +10,44 @@ Mcode is a JSON-based intermediate representation that can be interpreted direct
|
||||
## Pipeline
|
||||
|
||||
```
|
||||
Source → Tokenize → Parse (AST) → Fold → Mcode (JSON) → Streamline → Interpret
|
||||
Source → Tokenize → Parse (AST) → Fold → Mcode (JSON) → Streamline → Mach VM (default)
|
||||
→ Mcode Interpreter
|
||||
→ QBE → Native
|
||||
```
|
||||
|
||||
Mcode is produced by `mcode.cm`, which lowers the folded AST to JSON instruction arrays. The streamline optimizer (`streamline.cm`) then eliminates redundant operations. The result can be interpreted by `mcode.c`, or lowered to QBE IL by `qbe_emit.cm` for native compilation. See [Compilation Pipeline](pipeline.md) for the full overview.
|
||||
Mcode is produced by `mcode.cm`, which lowers the folded AST to JSON instruction arrays. The streamline optimizer (`streamline.cm`) then eliminates redundant operations. The result is serialized to binary bytecode by the Mach compiler (`mach.c`), interpreted directly by `mcode.c`, or lowered to QBE IL by `qbe_emit.cm` for native compilation. See [Compilation Pipeline](pipeline.md) for the full overview.
|
||||
|
||||
### Function Proxy Decomposition
|
||||
|
||||
When the compiler encounters a method call `obj.method(args)`, it emits a branching pattern to handle ƿit's function proxy protocol. An arity-2 function used as a proxy target receives the method name and argument array instead of a normal method call:
|
||||
|
||||
```json
|
||||
["is_proxy", check, obj]
|
||||
["jump_false", check, "record_path"]
|
||||
|
||||
// Proxy path: call obj(name, [args...]) with this=null
|
||||
["access", name_slot, "method"]
|
||||
["array", args_arr, N, arg0, arg1, ...]
|
||||
["null", null_slot]
|
||||
["frame", f, obj, 2]
|
||||
["setarg", f, 0, null_slot]
|
||||
["setarg", f, 1, name_slot]
|
||||
["setarg", f, 2, args_arr]
|
||||
["invoke", f, dest]
|
||||
["jump", "done"]
|
||||
|
||||
["LABEL", "record_path"]
|
||||
["load_field", method, obj, "method"]
|
||||
["frame", f2, method, N]
|
||||
["setarg", f2, 0, obj]
|
||||
["setarg", f2, 1, arg0]
|
||||
...
|
||||
["invoke", f2, dest]
|
||||
|
||||
["LABEL", "done"]
|
||||
```
|
||||
|
||||
The streamline optimizer can eliminate the dead branch when the type of `obj` is statically known.
|
||||
|
||||
## JSMCode Structure
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ description: "Overview of the compilation stages and optimizations"
|
||||
|
||||
## Overview
|
||||
|
||||
The compilation pipeline transforms source code through several stages, each adding information or lowering the representation toward execution. There are three execution backends: the Mach register VM (default), the Mcode interpreter (debug), and native code via QBE (experimental).
|
||||
The compilation pipeline transforms source code through several stages, each adding information or lowering the representation toward execution. All backends share the same path through mcode and streamline. There are three execution backends: the Mach register VM (default), the Mcode interpreter (debug), and native code via QBE (experimental).
|
||||
|
||||
```
|
||||
Source → Tokenize → Parse → Fold → Mach VM (default)
|
||||
→ Mcode → Streamline → Mcode Interpreter
|
||||
Source → Tokenize → Parse → Fold → Mcode → Streamline → Mach VM (default)
|
||||
→ Mcode Interpreter
|
||||
→ QBE → Native
|
||||
```
|
||||
|
||||
@@ -78,12 +78,18 @@ Provides operation implementations as QBE IL templates. Each arithmetic, compari
|
||||
|
||||
### Mach VM (default)
|
||||
|
||||
Binary 32-bit register VM. Used for production execution and bootstrapping.
|
||||
Binary 32-bit register VM. The Mach serializer (`mach.c`) converts streamlined mcode JSON into compact 32-bit bytecode with a constant pool. Used for production execution and bootstrapping.
|
||||
|
||||
```
|
||||
./cell script.ce
|
||||
```
|
||||
|
||||
Debug the mach bytecode output:
|
||||
|
||||
```
|
||||
./cell --core . --dump-mach script.ce
|
||||
```
|
||||
|
||||
### Mcode Interpreter
|
||||
|
||||
JSON-based interpreter. Used for debugging the compilation pipeline.
|
||||
|
||||
Reference in New Issue
Block a user