Embedding › 01 Concepts
Know exactly what you are hosting before writing any C.
C code meets Lopolith in exactly two ways, and they are different jobs:
| Native plugin | Embedding host | |
|---|---|---|
| You write | a .so that implements %native classes | a C program that owns the VM |
| Entry point | lopolith_get_native_classes | loth_engine_new / vm_new |
| Links the VM? | no — symbols come from the host | yes — the host is the process |
| Track | Native plugins | this track |
The language itself has no C API: .loth sources are compiled to
bytecode, and the two surfaces above are how C takes part.
An Engine owns loaded modules: classes, methods, bytecode, constant pools. They are read-only once linked, so one Engine can serve many VMs.
A VM owns runtime state: a heap, a GC, a singleton cache, threads. It points at the Engine's modules.
Engine (shared, read-only modules)
├── VM 1 heap + GC + singletons + threads
├── VM 2 heap + GC + singletons + threads
└── ...
Two consequences drive the rest of this track:
If you only want to extend the language with C code, you want a native plugin instead.
Every VM can run code on several threads. The GC is stop-the-world: it parks interpreter threads at safepoints, scans all their roots, and sweeps. A thread that runs language code must be attached to the VM, and a thread that blocks in C does not stall the collector. Native code that holds language values across allocations must root them. The concurrency chapter has the host-facing details.