@asmlift/core 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -16
- package/package.json +1 -1
- package/src/backend/c.ts +1 -0
- package/src/backend/cfamily.ts +270 -171
- package/src/backend/cpp.ts +1 -0
- package/src/backend/pascal.ts +26 -12
- package/src/contracts.ts +243 -39
- package/src/declare.ts +41 -4
- package/src/frontend/mips.ts +11 -0
- package/src/frontend/ppc.ts +43 -7
- package/src/frontend/ssa.ts +404 -29
- package/src/frontend/thumb.ts +2176 -686
- package/src/ir/alias.ts +78 -0
- package/src/ir/bits.ts +75 -0
- package/src/ir/core.ts +345 -2
- package/src/ir/opcodes.ts +176 -21
- package/src/ir/parse.ts +19 -2
- package/src/ir/print.ts +27 -2
- package/src/ir/simplify.ts +190 -3
- package/src/ir/struct-names.ts +42 -0
- package/src/ir/verify.ts +43 -49
- package/src/l3/address.ts +62 -0
- package/src/l3/advance.ts +373 -0
- package/src/l3/argbase.ts +6 -5
- package/src/l3/ast.ts +510 -59
- package/src/l3/basecse.ts +686 -78
- package/src/l3/coalesce.ts +432 -46
- package/src/l3/dce.ts +31 -9
- package/src/l3/gates.ts +96 -1
- package/src/l3/hoist.ts +293 -14
- package/src/l3/homesplit.ts +285 -0
- package/src/l3/initfirst.ts +301 -0
- package/src/l3/inlinebase.ts +193 -0
- package/src/l3/mentions.ts +176 -0
- package/src/l3/mulfirst.ts +42 -0
- package/src/l3/nearbase.ts +152 -0
- package/src/l3/offmember.ts +371 -0
- package/src/l3/parkfirst.ts +96 -0
- package/src/l3/pollguard.ts +154 -0
- package/src/l3/ptrfield.ts +227 -0
- package/src/l3/regspell.ts +114 -89
- package/src/l3/reindex.ts +722 -80
- package/src/l3/scopebase.ts +649 -220
- package/src/l3/sinkinit.ts +40 -0
- package/src/l3/slotorder.ts +123 -0
- package/src/l3/storage.ts +48 -0
- package/src/l3/symbol-refs.ts +41 -8
- package/src/l3/tailmerge.ts +16 -1
- package/src/l3/typing.ts +198 -9
- package/src/l3/unmerge.ts +687 -0
- package/src/l3/unreduce.ts +971 -0
- package/src/l3/volatileptr.ts +207 -0
- package/src/l3/volatileval.ts +130 -0
- package/src/l3/volstore.ts +229 -0
- package/src/l3/zerosub.ts +62 -0
- package/src/pattern/engine.ts +239 -16
- package/src/pipeline.ts +173 -60
- package/src/proto.ts +112 -14
- package/src/raise/arrays.ts +6 -1
- package/src/raise/const.ts +203 -3
- package/src/raise/divpow2.ts +4 -4
- package/src/raise/extscale.ts +342 -0
- package/src/raise/globalshape.ts +1058 -0
- package/src/raise/gvn.ts +33 -18
- package/src/raise/latch.ts +126 -0
- package/src/raise/magicdiv.ts +2 -2
- package/src/raise/memberarrays.ts +594 -0
- package/src/raise/narrow.ts +124 -0
- package/src/raise/narrowlocal.ts +572 -0
- package/src/raise/paramwidth.ts +201 -0
- package/src/raise/pre-recovery.ts +169 -21
- package/src/raise/recover.ts +56 -23
- package/src/raise/retsink.ts +585 -19
- package/src/raise/shortcircuit.ts +1050 -89
- package/src/raise/struct-arrays.ts +19 -2
- package/src/raise/structs.ts +34 -4
- package/src/raise/tailsink.ts +126 -0
- package/src/rank-declare.ts +256 -0
- package/src/rank-variations.ts +760 -0
- package/src/rank.ts +2122 -326
- package/src/structure/analysis.ts +1398 -150
- package/src/structure/bitfields.ts +432 -0
- package/src/structure/globalaccess.ts +300 -0
- package/src/structure/hazards.ts +411 -20
- package/src/structure/loops.ts +2 -49
- package/src/structure/namecoalesce.ts +454 -0
- package/src/structure/structure.ts +3979 -612
- package/src/structure/switch-recover.ts +710 -145
- package/src/symbols.ts +188 -6
- package/src/target.ts +495 -32
- package/src/trace.ts +112 -33
- package/src/variation-definitions.ts +1540 -0
- package/src/variation-gates.ts +89 -0
- package/src/variation-tokens.ts +355 -0
package/README.md
CHANGED
|
@@ -58,8 +58,8 @@ Everything under `src/` is importable as `@asmlift/core/<path>` (e.g.
|
|
|
58
58
|
|
|
59
59
|
## Architecture
|
|
60
60
|
|
|
61
|
-
Three ISA frontends (ARMv4T/Thumb, MIPS, PowerPC),
|
|
62
|
-
CodeWarrior), three language backends over one neutral AST — all scored across the package seam
|
|
61
|
+
Three ISA frontends (ARMv4T/Thumb, MIPS, PowerPC), five compilers (agbcc, IDO, KMC GCC, GCC
|
|
62
|
+
2.7.2, CodeWarrior), three language backends over one neutral AST — all scored across the package seam
|
|
63
63
|
by [`@asmlift/cli`](../cli/README.md) with the community `objdiff` engine (in-process, pinned
|
|
64
64
|
`objdiff-wasm`; asmlift never hand-rolls a diff).
|
|
65
65
|
|
|
@@ -79,20 +79,20 @@ injected via hooks, never copied. `verify()` runs after every IR-mutating pass;
|
|
|
79
79
|
|
|
80
80
|
### Modules
|
|
81
81
|
|
|
82
|
-
| Module | What it is
|
|
83
|
-
| ----------------------------------------------- |
|
|
84
|
-
| `ir/{types,core,opcodes,print,parse,verify}.ts` | MLIR-lite substrate: CFG of blocks + typed **block-arguments**, the typed opcode registry (`Opcode`, the one `effects` table DCE and hoist guards derive from), printer + parser (round-trip for L1/scalar types — see the domain note in parse.ts), verifier (arity/attrs/terminators/SSA dominance, located errors)
|
|
85
|
-
| `frontend/{thumb,mips,ppc}.ts` | ISA frontends: decode → CFG → L1 with **Braun-2013 block-arg SSA** (`ssa.ts`), incl. loops, calls (signature-driven arity), memory, jump tables. Shared scaffolding: `disasm.ts` (objdump parsing), `splat.ts` (Splat-dialect MIPS → objdump-shaped instrs), `format.ts` (input-format classification), `emit.ts` (per-block emitter kit + `switch_br`), `opaque.ts` (the unmodelled-op → loud-`opaque` contract), `errors.ts` (`FrontendUnsupportedError`; PPC's subclass), `registry.ts`, `asmdata.ts` (Regime-B jump-table side-table)
|
|
86
|
-
| `pattern/engine.ts` | Idiom layer: **rewrite patterns as data** + greedy driver + DCE; `patternApplies` gates on Target capabilities
|
|
87
|
-
| `raise/*.ts` | The pre-recovery recognizers, in ONE ordered list (`pre-recovery.ts`): const materialize → magic division (`magicdiv.ts`, Hacker's Delight inverse) → soft division → array legalize → struct-array → struct-pointer → short-circuit; plus `recover.ts` (L1→L2 type recovery), `retsink.ts` (return-sinking), `errors.ts` (`RaiseUnsupportedError`)
|
|
88
|
-
| `structure/*.ts` | L2→L3 in
|
|
89
|
-
| `l3/*.ts` | `ast.ts`: language-**neutral** structured AST, the one traversal vocabulary (`exprChildren` etc.), and the `LanguageBackend` seam. Post-structure passes `dce.ts` + `basecse.ts`, the shared hoist mechanism `hoist.ts`, the differ-ranked
|
|
90
|
-
| `backend/{c,cpp,cfamily,pascal}.ts` | Three backends: C and C++ (CodeWarrior mangling via `mangle.ts`) over the shared `cfamily.ts` substrate, and Pascal (`:=`, `div`, tail-position returns; unspellable constructs throw)
|
|
91
|
-
| `pipeline.ts` | `decompile()` + the shared tower spine + annotate-mode stubs/diagnostics
|
|
92
|
-
| `trace.ts` | `decompileTraced` — the traced tower (per-stage IR dumps + pattern before/after events), browser-pure; @asmlift/cli's `report.ts` enriches it with objdiff scores/candidates, the playground's Pipeline tab renders it directly
|
|
93
|
-
| `rank.ts` | Pure candidate enumeration + `rankBy` (an injected score function ranks). @asmlift/cli's differ ranks through `rankBy`; the playground's wasm scorer consumes the same enumeration with its own async loop
|
|
94
|
-
| `target.ts` | `TargetDescription` (ABI + capabilities + compilerBehaviors as data — no `arch ==` in shared code); toolchain paths live in `@asmlift/toolchains`
|
|
95
|
-
| `contracts.ts`, `proto.ts`, `mangle.ts` | Boundary contracts; prototype tables; the CodeWarrior mangler
|
|
82
|
+
| Module | What it is |
|
|
83
|
+
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
84
|
+
| `ir/{types,core,opcodes,print,parse,verify}.ts` | MLIR-lite substrate: CFG of blocks + typed **block-arguments**, the typed opcode registry (`Opcode`, the one `effects` table DCE and hoist guards derive from), printer + parser (round-trip for L1/scalar types — see the domain note in parse.ts), verifier (arity/attrs/terminators/SSA dominance, located errors); `core.ts` also owns the CFG facts every level reads — `successorsOf`, `predecessors`, `dominators` |
|
|
85
|
+
| `frontend/{thumb,mips,ppc}.ts` | ISA frontends: decode → CFG → L1 with **Braun-2013 block-arg SSA** (`ssa.ts`), incl. loops, calls (signature-driven arity), memory, jump tables. Shared scaffolding: `disasm.ts` (objdump parsing), `splat.ts` (Splat-dialect MIPS → objdump-shaped instrs), `format.ts` (input-format classification), `emit.ts` (per-block emitter kit + `switch_br`), `opaque.ts` (the unmodelled-op → loud-`opaque` contract), `errors.ts` (`FrontendUnsupportedError`; PPC's subclass), `registry.ts`, `asmdata.ts` (Regime-B jump-table side-table) |
|
|
86
|
+
| `pattern/engine.ts` | Idiom layer: **rewrite patterns as data** + greedy driver + DCE; `patternApplies` gates on Target capabilities |
|
|
87
|
+
| `raise/*.ts` | The pre-recovery recognizers, in ONE ordered list (`pre-recovery.ts`): const materialize → magic division (`magicdiv.ts`, Hacker's Delight inverse) → soft division → array legalize → struct-array → member-array (`memberarrays.ts`, a constant offset feeding a variable-index walk is a struct's ARRAY member) → struct-pointer → short-circuit → narrow-reads (`narrow.ts`) → narrow locals (`narrowlocal.ts`, a carrier read only through its own extension IS that width) → parameter width (`paramwidth.ts`, a parameter extended in the prologue is DECLARED at that width); plus `recover.ts` (L1→L2 type recovery), `retsink.ts` (return-sinking), `latch.ts` (empty-latch folding), `errors.ts` (`RaiseUnsupportedError`) |
|
|
88
|
+
| `structure/*.ts` | L2→L3 in six modules: `loops.ts` (natural-loop discovery, over `ir/core.ts`'s dominators), `analysis.ts` (use registry, liveness, C4 materialization), `switch-recover.ts` (Regime-A comparison-tree recovery), `hazards.ts` (the checks a loop emitter runs before committing to a loop form), `namecoalesce.ts` (copy coalescing over the interference graph — the `/merge-names` variation), `structure.ts` (SSA-destruction coalescing with interference checks + emission: if/while/do-while/for/switch, break/early-return) |
|
|
89
|
+
| `l3/*.ts` | `ast.ts`: language-**neutral** structured AST, the one traversal vocabulary (`exprChildren` etc.), and the `LanguageBackend` seam. Post-structure passes `dce.ts` + `basecse.ts`, the shared hoist mechanism `hoist.ts`, the differ-ranked respell variations `regspell.ts` + `reindex.ts` + `argbase.ts` + `scopebase.ts`, and `typing.ts` (the rendered-expression C type the backends and contracts share) |
|
|
90
|
+
| `backend/{c,cpp,cfamily,pascal}.ts` | Three backends: C and C++ (CodeWarrior mangling via `mangle.ts`) over the shared `cfamily.ts` substrate, and Pascal (`:=`, `div`, tail-position returns; unspellable constructs throw) |
|
|
91
|
+
| `pipeline.ts` | `decompile()` + the shared tower spine + annotate-mode stubs/diagnostics |
|
|
92
|
+
| `trace.ts` | `decompileTraced` — the traced tower (per-stage IR dumps + pattern before/after events), browser-pure; @asmlift/cli's `report.ts` enriches it with objdiff scores/candidates, the playground's Pipeline tab renders it directly |
|
|
93
|
+
| `rank.ts` | Pure candidate enumeration + `rankBy` (an injected score function ranks). @asmlift/cli's differ ranks through `rankBy`; the playground's wasm scorer consumes the same enumeration with its own async loop |
|
|
94
|
+
| `target.ts` | `TargetDescription` (ABI + capabilities + compilerBehaviors as data — no `arch ==` in shared code); toolchain paths live in `@asmlift/toolchains` |
|
|
95
|
+
| `contracts.ts`, `proto.ts`, `mangle.ts` | Boundary contracts; prototype tables; the CodeWarrior mangler |
|
|
96
96
|
|
|
97
97
|
Scoring and ranking live across the package seam in [`@asmlift/cli`](../cli/README.md):
|
|
98
98
|
`score.ts` + `objdiff.ts` (toolchain compiles → in-process pinned `objdiff-wasm`, fail-closed)
|
|
@@ -133,6 +133,12 @@ Landmarks (not exhaustive — suites are named for what they pin):
|
|
|
133
133
|
- `contract-invariant` / `contracts` — the loud-fail contract, mutation-proven.
|
|
134
134
|
- `structure-guard` / `structure-soundness` / `audit-regression` — the adversarial-audit repro
|
|
135
135
|
locks.
|
|
136
|
+
- `one-version` — a WORKSPACE-scope invariant, like `offline-list`: every dependency that two or
|
|
137
|
+
more workspace packages declare must be declared AND resolved at one version. It exists because
|
|
138
|
+
`packages/cli` scored with `objdiff-wasm` 3.7.3 while `apps/web` scored with 3.7.0, so the
|
|
139
|
+
playground silently showed 229 where the benchmark published 233 on a byte-identical object
|
|
140
|
+
pair. Both the package set and the dependency set are derived, so a third consumer is covered
|
|
141
|
+
without editing the test.
|
|
136
142
|
|
|
137
143
|
**`test/corpus/` is load-bearing beyond this suite.** The committed disassembly fixtures in
|
|
138
144
|
`test/corpus/` are ALSO imported (via Vite `?raw`) by the playground's example gallery —
|
package/package.json
CHANGED
package/src/backend/c.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { cComment }; // re-export: the shared spelling lives in cfamily.ts
|
|
|
12
12
|
|
|
13
13
|
export const cBackend: LanguageBackend = {
|
|
14
14
|
id: 'c',
|
|
15
|
+
spellsSwitchFallthrough: true,
|
|
15
16
|
emit(fn: SFn): string {
|
|
16
17
|
const params = fn.params.map((p) => `${cType(p.type)} ${p.name}`).join(', ') || 'void';
|
|
17
18
|
return emitCFamily(`${cType(fn.retType)} ${fn.name}(${params})`, fn);
|