Skip to main content

Module bundle

Module bundle 

Source
Expand description

Bundle format (.hb): one program’s modules in a single file.

magic "HTLB\x02"
u32 len, fingerprint      (Lua bytecode header this bundle was compiled by, or empty)
u32 len, htl version
u32 len, entry module name
u32 count, count x ( u32 len, host module name )   modules the host must provide
u32 count, count x ( u8 kind, u32 len, module name, u32 len, payload )
  kind 0 = Lua 5.4 bytecode (from this build's mlua), kind 1 = Lua source

All integers little-endian.

§Portability

Nothing about the CPU or the operating system is in a Lua chunk. What decides whether bytecode loads is Lua’s own chunk header, and that is what the fingerprint is: the first 31 bytes of a dumped chunk — signature, version byte, format, the LUAC_DATA probe, the sizes of Instruction / lua_Integer / lua_Number, and the LUAC_INT / LUAC_NUM probes that detect integer endianness and float format. Htl::install_bundle compares it to the host’s and refuses on mismatch, naming both sides (LuaHeader is the readable form), instead of Lua’s bare “bad binary format”.

The Lua htl vendors has a 4-byte instruction, an 8-byte integer and an 8-byte double on every 64-bit little-endian platform, so a bytecode bundle built on one of them runs on all of them: an arm64 Mac’s bundle loads on x86_64 Linux. What the check refuses is a big-endian host, and a Lua built with a non-default LUA_INT_TYPE / LUA_FLOAT_TYPE. Source modules (--source) load anywhere and are the answer for those cases, and for a bundle that has to outlive a Lua upgrade.

The header cannot tell one 5.4.x from another, and htl pins the vendored Lua through mlua, so htl version is the only record of which Lua produced the bytes. It is advisory: a bundle from an older htl whose header agrees still loads, and when the header disagrees the mismatch message says which htl built the bundle and which is running, since the header alone cannot say why two 5.4 builds differ.

Version 1 bundles (HTLB\x01: entry + bytecode modules, no metadata) still decode; format_version tells the two apart from the bytes.

Structs§

Bundle
A whole program as one file: decoded from bytes, encoded back to them, and installed into a state by Htl::install_bundle.
LuaHeader
What a fingerprint says, field by field: the Lua a bundle’s bytecode was compiled for. Display is the one-line form the mismatch message and htl bundle info use, Lua 5.4, format 0, 4/8/8, little-endian (the three numbers are the sizes of Instruction, lua_Integer and lua_Number in bytes).
Module
One module in a bundle: the name a require asks for, and the bytes that answer it.

Enums§

Kind
How a module’s payload is stored.

Constants§

MAGIC
What a bundle of the current format starts with. Public because a reader that has bytes from somewhere — a file, an embedded slice — tells a bundle from a Lua chunk or a script by this before it decides what to do with them; Bundle::is_bundle is the same question asked of both versions at once.

Functions§

describe_fingerprint
Human-readable form of a bytecode header (for mismatch messages): the LuaHeader line, or the byte count when the bytes are not a header.
format_version
The format version a byte string carries (1 for HTLB\x01, 2 for HTLB\x02), or None when it is not a bundle at all. Bundle::decode folds the two into one struct, so this is how a reader says which one it was given.