idle sits you down and camps you, and the addons anchor, parse and draw
- five idle minutes sit you down and flag you AFK, thirty log you out through the ordinary countdown; holding a key is idle, moving the mouse is not, and a swimmer stays afloat (2092) - a knockdown no longer wedges: the landing froze the clip that held the base-animation lock, leaving a knocked-down player on their back for the session (2098); the perf cost pill starts hidden (2099) - Lua is exactly 1.12's 5.0 — no vararg expression, no #, no %, the remembered table size — so Cartographer loads without errors and Mik's Scrolling Battle Text shows its text, in its own shipped font now that addon TTFs load (2101, 2102, 2103) - a widget name is a Lua global for SetPoint and its kin, so Bartender2's bars spread out; a button's NormalText disowns its justify, the raise renumbers hidden frames too, and a missing toc file warns instead of erroring (2105, 2100, 2104, 2107, 2106) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Vendored
+28
-4
@@ -5,6 +5,12 @@ the version mlua 0.11 resolves to. Wired in through `[patch.crates-io]` in the w
|
||||
|
||||
## Why a fork exists at all
|
||||
|
||||
**benilla's Lua has to accept exactly the grammar the 1.12.1 client's Lua accepts — no more and no
|
||||
less.** Every hunk below is that one rule: three restore 5.0 constructs 5.1 deleted, three delete
|
||||
5.1 constructs 5.0 never had. A grammar difference in either direction is invisible to every
|
||||
instrument we own until an addon trips over it, and the corpus *asks about* the difference
|
||||
directly (decisions 1208, 2101).
|
||||
|
||||
The 1.12 addon corpus is Lua **5.0** code. It uses the iterator-less generic-for:
|
||||
|
||||
```lua
|
||||
@@ -35,23 +41,41 @@ downgrade, and it is the entire reason this is a one-hunk fork rather than a ven
|
||||
|
||||
## The delta, and the command that proves it
|
||||
|
||||
**Current state: three hunks, in three files.** `src/lib.rs` additionally differs by having Lua
|
||||
**Current state: six hunks, in three files.** `src/lib.rs` additionally differs by having Lua
|
||||
5.2/5.3/5.4/5.5 stripped from the `Version` enum (with their source trees deleted) — benilla builds
|
||||
5.1 and only 5.1, and a fork that still *offered* the other four would answer a request for one with
|
||||
a missing directory at build time instead of a compile error.
|
||||
|
||||
**Three hunks restore what 5.1 removed:**
|
||||
|
||||
| file | hunk | why | record |
|
||||
|---|---|---|---|
|
||||
| `lvm.c` | 5.0's `OP_TFORPREP` table→`next` substitution, folded into the top of `OP_TFORLOOP` | `for k, v in someTable do` raised "attempt to call a table value"; it was the first session-start error for **60** corpus addons | 1215 |
|
||||
| `luaconf.h` | `LUA_COMPAT_LSTR` `1` → `2` | 5.1 kept 5.0's nesting machinery and put an advisory error in front of it; two corpus addons died on "nesting of `[[...]]` is deprecated" | — |
|
||||
| `lparser.c` | 5.0's compat-semicolon skip restored at the top of `constructor()`'s field loop — 5.0's own line, verbatim, comment included | one extra `;` after a field separator inside a table constructor (`Back_Title = AL["Factions"];;`, ×20 in AtlasLoot's `ButtonRegistry.lua`) parses on the client and died here with "unexpected symbol near `;`"; statement-level `;;` stays rejected by both dialects | 1315 |
|
||||
|
||||
**Three delete what 5.1 added** — all in `lparser.c`, all byte-read out of the client's own parser
|
||||
(`simpleexp 0x6fd240`, `getunopr 0x6fe0a0`, `getbinopr 0x6fe0c0`), all landing on 5.0's own
|
||||
`unexpected symbol` at `prefixexp 0x6fde40`:
|
||||
|
||||
| hunk | why | record |
|
||||
|---|---|---|
|
||||
| `simpleexp`'s `case TK_DOTS` deleted — `...` is no longer an expression | the Ace2 corpus **asks** which interpreter it is on by compiling `return function(...) return ... end`; 170 `loadstring` sites in the 219-addon corpus are that question and 92 library files gate on it. Answering `true` put Cartographer on its client-2.0 branch, hooking `CloseSpecialWindows` — a name 1.12 does not have. Also restores 5.0's rule that **every** vararg function gets its `arg` table | 1208, 2101 |
|
||||
| `getunopr`'s `case '#'` deleted — no length operator | the client's `getunopr` tests exactly two tokens (`-`, `not`) and its `OPR_NOUNOPR` is **2**: a three-member enum, 5.0's. 5.0 asks a table with `table.getn` and a string with `string.len` | 2101 |
|
||||
| `getbinopr`'s `case '%'` deleted — no modulo operator | the client's `getbinopr` switch is based at `'*'` (0x2A), so `%` (0x25) is below its range and reaches `OPR_NOBINOPR` = **14**: a fifteen-member `BinOpr`, 5.0's. 5.0 spells it `math.mod` | 2101 |
|
||||
|
||||
The ordering was deliberate and it held: the fork landed **inert**, byte-identical to upstream, so
|
||||
the build pipeline was proven transparent *before* any behavioural payload went into it — and when
|
||||
the suite then moved, the patch was the only thing that could have moved it. Both hunks are measured
|
||||
against the 218-addon corpus rather than argued: the long-string one alone took loaded 134 → 139 and
|
||||
the suite then moved, the patch was the only thing that could have moved it. Every hunk is measured
|
||||
against the corpus rather than argued: the long-string one alone took loaded 134 → 139 and
|
||||
survivors 99 → 104.
|
||||
|
||||
**The deletions are safe because nothing the reference runs uses those constructs, and that was
|
||||
scanned rather than assumed** (2101 §4): a comment/string-stripping scan of the extracted 1.12
|
||||
FrameXML (177 files), GlueXML, Blizzard's own addons and the director's installed AddOns folder
|
||||
finds **zero** sites of all three. Our own engine Lua did use them and was rewritten into the 5.0
|
||||
spellings; the rule now is that no chunk of ours may use a construct the client's parser rejects.
|
||||
|
||||
To verify the Lua sources against upstream at any time:
|
||||
|
||||
```sh
|
||||
@@ -60,7 +84,7 @@ diff -r third_party/lua-src/lua-5.1.5 \
|
||||
~/.cargo/registry/src/*/lua-src-550.0.0/lua-5.1.5
|
||||
```
|
||||
|
||||
That must print **exactly** the three hunks in the table above and nothing else. If it ever prints
|
||||
That must print **exactly** the six hunks in the tables above and nothing else. If it ever prints
|
||||
more, something crept in.
|
||||
|
||||
## Status of the payload
|
||||
|
||||
+55
-12
@@ -742,8 +742,8 @@ static void primaryexp (LexState *ls, expdesc *v) {
|
||||
|
||||
|
||||
static void simpleexp (LexState *ls, expdesc *v) {
|
||||
/* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
|
||||
constructor | FUNCTION body | primaryexp */
|
||||
/* simpleexp -> NUMBER | STRING | NIL | true | false | constructor |
|
||||
FUNCTION body | primaryexp */
|
||||
switch (ls->t.token) {
|
||||
case TK_NUMBER: {
|
||||
init_exp(v, VKNUM, 0);
|
||||
@@ -766,14 +766,39 @@ static void simpleexp (LexState *ls, expdesc *v) {
|
||||
init_exp(v, VFALSE, 0);
|
||||
break;
|
||||
}
|
||||
case TK_DOTS: { /* vararg */
|
||||
FuncState *fs = ls->fs;
|
||||
check_condition(ls, fs->f->is_vararg,
|
||||
"cannot use " LUA_QL("...") " outside a vararg function");
|
||||
fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
|
||||
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
|
||||
break;
|
||||
}
|
||||
/* BENILLA: 5.1's vararg EXPRESSION arm, deleted (decision 2101; see
|
||||
** third_party/lua-src/BENILLA.md). Lua 5.0 has no grammar for `...' as a
|
||||
** value -- a vararg function reads its extra arguments out of the implicit
|
||||
** `arg' table -- and `...' as an expression is the construct the Ace2 corpus
|
||||
** uses to ASK which interpreter it is running:
|
||||
**
|
||||
** local lua51 = loadstring("return function(...) return ... end") and true or false
|
||||
**
|
||||
** 170 loadstring sites across the 219-addon corpus are that question, and 92
|
||||
** library files in 24 folders gate on it (decision 1208). Answering it wrong
|
||||
** makes every one of them take a client-2.0 branch on a 1.12 client -- which
|
||||
** is how Cartographer came to hook `CloseSpecialWindows', a name 1.12 does
|
||||
** not have.
|
||||
**
|
||||
** Byte-verified in the client itself, not inferred from stock 5.0. simpleexp
|
||||
** is 0x6fd240; it switches on `token - 0x7B' bounded at 0xA3, indexes the
|
||||
** byte table at 0x6fd338 and jumps through the 8-entry table at 0x6fd318.
|
||||
** TK_DOTS is 0x118 (TK_NAME is 0x116 -- wow-5875-re system/ui/scratch/
|
||||
** lua-dialect.md 9), so its index byte is 0x9D, whose value is 7: the DEFAULT
|
||||
** arm, 0x6fd30a, which tail-jumps to primaryexp 0x6fdb00. The seven real arms
|
||||
** are `{', TK_FALSE, TK_FUNCTION, TK_NIL, TK_TRUE, TK_NUMBER and TK_STRING --
|
||||
** stock Lua 5.0's simpleexp exactly, with no vararg case.
|
||||
**
|
||||
** So `...' as a value reaches prefixexp 0x6fde40, whose head accepts only `('
|
||||
** or TK_NAME and otherwise raises "unexpected symbol" (0x871e80) -- the same
|
||||
** reject site lua-dialect.md 9 documents for a stray `;'. Deleting the arm
|
||||
** reproduces that error here, verbatim.
|
||||
**
|
||||
** It also restores 5.0's `arg' rule for free: the deleted line cleared
|
||||
** VARARG_NEEDSARG for any function that mentioned `...', so `arg' was not
|
||||
** built for it. With the arm gone, NEEDSARG is never cleared and EVERY vararg
|
||||
** function gets its `arg' table -- which is what 5.0 does and what all 177
|
||||
** files of the shipped 1.12 FrameXML read. */
|
||||
case '{': { /* constructor */
|
||||
constructor(ls, v);
|
||||
return;
|
||||
@@ -796,7 +821,15 @@ static UnOpr getunopr (int op) {
|
||||
switch (op) {
|
||||
case TK_NOT: return OPR_NOT;
|
||||
case '-': return OPR_MINUS;
|
||||
case '#': return OPR_LEN;
|
||||
/* BENILLA: 5.1's `#' length operator, deleted (decision 2101). 5.0 asks a
|
||||
** table for its size with table.getn/getn and a string with string.len; the
|
||||
** operator does not exist and neither does its __len metamethod.
|
||||
** Byte-verified: getunopr is 0x6fe0a0, a leaf with exactly TWO token tests
|
||||
** -- `cmp ecx,0x2D' (`-') then `cmp ecx,0x10E' (TK_NOT), then setne/inc -- so
|
||||
** its OPR_NOUNOPR is 2, i.e. the enum has three members, not 5.1's four. The
|
||||
** metamethod-name pool at 0x871896 agrees: no __len (wow-5875-re
|
||||
** system/ui/scratch/lua-dialect.md 1, discriminator 4). A `#' therefore
|
||||
** reaches simpleexp's default arm and raises "unexpected symbol near `#'". */
|
||||
default: return OPR_NOUNOPR;
|
||||
}
|
||||
}
|
||||
@@ -808,7 +841,17 @@ static BinOpr getbinopr (int op) {
|
||||
case '-': return OPR_SUB;
|
||||
case '*': return OPR_MUL;
|
||||
case '/': return OPR_DIV;
|
||||
case '%': return OPR_MOD;
|
||||
/* BENILLA: 5.1's `%' modulo operator, deleted (decision 2101). 5.0 spells it
|
||||
** math.mod (and the bare global `mod'), which this VM already publishes.
|
||||
** Byte-verified: getbinopr is 0x6fe0c0 and its switch is based at `ecx-0x2A'
|
||||
** -- `*', the LOWEST token it handles. `%' is 0x25, below the base, so it is
|
||||
** outside the range test (`cmp eax,0xF2; ja') and falls to the default,
|
||||
** 0x6fe129, `mov eax,0xE' = OPR_NOBINOPR 14 -- a 15-member BinOpr, 5.0's, not
|
||||
** 5.1's 16-member one with OPR_MOD. Had 5.1's `%' case been present the
|
||||
** switch would have been based at 0x25. The metamethod pool has no __mod
|
||||
** either (wow-5875-re system/ui/scratch/lua-dialect.md 1, discriminator 4).
|
||||
** priority[] is indexed by the BinOpr enum, which is untouched -- only the
|
||||
** token that reaches OPR_MOD is gone. */
|
||||
case '^': return OPR_POW;
|
||||
case TK_CONCAT: return OPR_CONCAT;
|
||||
case TK_NE: return OPR_NE;
|
||||
|
||||
Reference in New Issue
Block a user