Skip to content

A zero-dependency Rust port of Lua 5.1.1 as supported in the World of Warcraft game client.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

wowemulation-dev/rilua

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

105 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

rilua

A Rust implementation of Lua 5.1.1.

License Rust Version

Overview

rilua is a from-scratch Lua 5.1.1 interpreter written in Rust. It targets behavioral equivalence with the PUC-Rio reference interpreter -- executed Lua code must produce identical results.

Part of the WoW Emulation project. Zero external dependencies -- only Rust's standard library.

Use Cases

rilua is built for the World of Warcraft emulation ecosystem:

  • Addon development and testing -- Run and test WoW addons outside the game client without launching WoW
  • Server-side scripting -- Embed in private server emulators (CMaNGOS, TrinityCore, AzerothCore) for scripted encounters, quests, and NPC behavior
  • Client Lua environment emulation -- Reproduce the WoW client's Lua sandbox including restricted stdlib, taint system, and WoW-specific extensions (bit library, string functions, global aliases)
  • Addon compatibility testing -- Automated test harness for verifying addons against the Lua 5.1.1 spec

It also serves as an embeddable Lua 5.1.1 interpreter for Rust applications and as a readable reference implementation for studying Lua internals. See docs/use-cases.md for details.

Why Lua 5.1.1

World of Warcraft's addon system uses Lua 5.1.1. Key 5.1-specific traits: unpack is a global (moved to table.unpack in 5.2), all numbers are f64 (5.3 added integers), no goto keyword (added in 5.2). See Warcraft Wiki: Lua.

Usage

Standalone Interpreter

rilua reproduces the PUC-Rio lua command-line interface:

# Run a Lua script
rilua script.lua

# Execute a string
rilua -e 'print("hello")'

# Interactive REPL
rilua -i

# All flags: -e stat, -l name, -i, -v, --, -
rilua -v
# Lua 5.1.1  Copyright (C) 1994-2006 Lua.org, PUC-Rio

Bytecode Compiler

riluac reproduces the PUC-Rio luac bytecode compiler and lister:

# Compile to bytecode
riluac -o output.luac script.lua

# List bytecode instructions
riluac -l script.lua

# Detailed listing (constants, locals, upvalues)
riluac -l -l script.lua

# Syntax check only
riluac -p script.lua

Binary chunks are cross-compatible with PUC-Rio in both directions.

Embedding in Rust

rilua provides a Rust-idiomatic API with IntoLua/FromLua conversion traits (inspired by mlua):

use rilua::{Lua, StdLib};

// Create interpreter with all standard libraries
let mut lua = Lua::new_with(StdLib::ALL)?;

// Execute Lua code
lua.exec("x = 1 + 2")?;

// Read and write globals with automatic type conversion
let x: f64 = lua.global("x")?;
assert_eq!(x, 3.0);
lua.set_global("greeting", "hello")?;

// Selective library loading for sandboxing
let mut sandbox = Lua::new_with(StdLib::BASE | StdLib::STRING | StdLib::TABLE)?;

See docs/api.md for the full API reference.

Supported Features

Language

All Lua 5.1.1 language features are implemented:

  • Variables, assignments, local declarations
  • Control flow: if/elseif/else, while, repeat/until, numeric for, generic for, break, return
  • Functions: closures, varargs (...), multiple return values, tail calls, method syntax (obj:method())
  • Tables: array and hash parts, constructors ({1, 2, key = "val"})
  • Metatables: all 17 metamethods (__index, __newindex, __call, __add, __sub, __mul, __div, __mod, __pow, __unm, __eq, __lt, __le, __concat, __len, __gc, __tostring)
  • String metatable: method syntax (("hello"):upper())
  • Coroutines: create, resume, yield, wrap, status, running
  • Environments: setfenv/getfenv, per-closure global tables
  • Protected calls: pcall, xpcall with error objects and stack traces
  • Error messages with variable names (matching PUC-Rio format)

Standard Libraries

All 9 standard libraries with all functions:

Library Functions Notes
base 29 print, assert, type, tostring, tonumber, pairs, ipairs, next, select, unpack, pcall, xpcall, error, loadstring, loadfile, dofile, load, setmetatable, getmetatable, rawget, rawset, rawequal, setfenv, getfenv, collectgarbage, newproxy, _G, _VERSION
string 14 len, byte, char, sub, rep, reverse, lower, upper, format, find, match, gmatch, gsub, dump. Pattern matching with all Lua 5.1.1 features. gfind alias included.
table 9 concat, insert, remove, sort, maxn, getn, setn, foreach, foreachi. Sort uses PUC-Rio's median-of-three quicksort.
math 28 abs through tanh, pi, huge, mod alias.
io 18 11 library functions + 7 file methods. stdin/stdout/stderr handles.
os 11 clock, date, difftime, execute, exit, getenv, remove, rename, setlocale, time, tmpname.
debug 14 getinfo, getlocal, setlocal, getupvalue, setupvalue, traceback, getregistry, getmetatable, setmetatable, getfenv, setfenv, gethook, sethook, debug.
package 9 require, module, loaded, preload, loaders, config, path, cpath, seeall, loadlib.
coroutine 6 create, resume, yield, wrap, status, running.

Bytecode and Compatibility

  • 38 register-based opcodes matching PUC-Rio encoding
  • string.dump and binary chunk loading
  • Binary chunks are cross-compatible with PUC-Rio (byte-identical output for simple programs, loadable in both directions)
  • Non-UTF-8 source files supported (\255, \0 in string literals)

Garbage Collector

Arena-based incremental mark-sweep with generational indices:

  • 5-state incremental collection (Pause, Propagate, SweepString, Sweep, Finalize)
  • Write barriers (backward for tables, forward for upvalues)
  • __gc finalizers with error propagation
  • Weak tables (__mode = "k", "v", or "kv")
  • collectgarbage() API: collect, stop, restart, count, step, setpause, setstepmul

Known Limitations

Not Yet Implemented

  • debug.debug() interactive mode: Stub (returns immediately).
  • C library loading: package.loadlib returns "not supported" (incompatible ABI). Lua file loading via require works.
  • SIGINT handling: No signal-based interruption of running code.

PUC-Rio Test Suite Compatibility

All 23 official Lua 5.1.1 test files pass, including the all.lua runner which executes all tests sequentially with aggressive GC settings. Tests: api, attrib, big, calls, checktable, closure, code, constructs, db, errors, events, files, gc, literals, locals, main, math, nextvar, pm, sort, strings, vararg, verybig.

The all.lua runner completes in ~17 seconds.

See docs/testing.md for details on running modes and the comparison script.

Architecture

Pipeline: Source -> Lexer -> Parser -> AST -> Compiler -> Proto -> VM

Component Description
Lexer Tokenizer with one-token lookahead, byte-based (&[u8])
Parser Recursive descent producing typed AST
Compiler AST walker emitting register-based bytecode into Proto
VM Register-based dispatch, PUC-Rio's 38 opcodes, CallInfo chain
GC Arena-based incremental mark-sweep, write barriers, finalizers
API Trait-based Rust-idiomatic embedding (IntoLua/FromLua)

See docs/architecture.md for design documentation.

Building

Development tools (Rust 1.92.0, markdownlint) can be installed automatically with Mise:

mise install
# Build
cargo build

# Run the interpreter
cargo run -- script.lua

# Run tests
cargo test

# Run quality gate
cargo fmt -- --check && cargo clippy --all-targets && cargo test && cargo doc --no-deps

Testing

Five test layers: unit tests inside compiler and VM modules, integration tests (Lua scripts with assert()), oracle comparison tests (same Lua code run in both rilua and PUC-Rio, comparing output), the PUC-Rio official test suite as a compatibility target, and behavioral equivalence tests for edge cases.

PUC-Rio tests pass both individually and through the all.lua runner. See docs/testing.md for the testing strategy and lua.org/tests/ for the official test documentation.

License

Dual-licensed under either:

Acknowledgments

  • Roberto Ierusalimschy, Waldemar Celes, and Luiz Henrique de Figueiredo for Lua
  • The Luau team at Roblox for demonstrating AST-based Lua compilation at scale
  • The mlua project for Rust-idiomatic Lua API patterns
  • Matthew Orlando (cogwheel) for lua-wow, documenting the WoW client's Lua configuration

Resources

About

A zero-dependency Rust port of Lua 5.1.1 as supported in the World of Warcraft game client.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published