-
Notifications
You must be signed in to change notification settings - Fork 0
Upstreaming
Working tracker for getting the AmigaOS 3.x port accepted into upstream micropython/micropython. Captures the contributor-guideline requirements, the acceptance blockers/suggestions, and progress against them. The per-phase design log is on Amiga port design; the test runbook is on Amiga port testing. Snapshot date: 2026-06-21.
Legend: ✅ done · ◐ in progress · ☐ not started · ♻ ongoing responsibility
Upstream's ContributorGuidelines § Generative AI policy governs human conduct, not the code — there is no code checklist that makes a PR "compliant". What it requires:
- ♻ The human contributor reads and validates every line before
submitting — especially the core
py/changes (asm68k.c/.h,emitn68k.c, theemitnative.chunks,nlr68k.S). - ♻ The human engages personally and technically in review — no copy-pasting between maintainers and a chatbot (translation excepted).
- ♻ No AI agent opens or drives the PR autonomously; a human submits it and does the review work.
This port is large and heavily AI-assisted, so it will draw extra scrutiny. The bar is genuine understanding: be able to defend each core hunk from your own knowledge, without a chatbot in the loop.
Ordered by impact.
| # | Item | Status |
|---|---|---|
| 1 | Split the core py/ native-emitter changes into a separate PR from the port (plan) |
◐ |
| 2 | Drop the modjson.c fork; use upstream extmod/modjson.c
|
✅ |
| 3 | Curate the commit history (252 commits → small logical set) | ☐ |
| 4 | Remove the sync_upstream.yml fork-maintenance workflow from the PR |
✅ |
| 5 | Open a pre-submission Discussion + state a long-term maintenance commitment | ☐ |
| 6 | Run codeformat.py (uncrustify 0.71/0.72) and ruff format/check, and say so |
✅ |
| 7 |
emit68k.c → emitn68k.c (match emitn<arch>.c naming) |
✅ |
| 8 | Key the native-emitter endianness fixes on MP_ENDIANNESS_BIG, not N_68K
|
✅ |
| 9 | Move the 68k NLR implementation into py/ + py.mk (where every other arch lives) |
✅ |
| 10 | CI must build all three variants, not just standard (FPU link paths differ) |
☐ |
1 — Split the native emitter. Adding a whole new native-code
architecture (asm68k.c/.h ≈ 1k lines, emitn68k.c, emitnative.c
hunks, the .mpy ABI enum, NLR) is a large, self-contained review that
touches the most sensitive part of the tree. Bundling it with the
~9k-line port makes the combined PR much harder to land. Propose the port
first with the native emitter disabled, then the 68k backend as a focused
follow-up. The existing #if MICROPY_EMIT_68K / #if N_68K guards make
that split trivial.
3 — Commit history. Upstream wants small, logical, clean-rebasing
commits. Rebase the 252-commit branch into a coherent set (roughly: core
py/ changes; the port; tests; examples; CI; docs).
4 — sync_upstream.yml. ✅ Removed. It was fork-maintenance only.
ports_amiga.yml (the port build CI) is retained, but expect it to be
adapted to upstream CI conventions and a toolchain story they will host.
5 — Discuss first. A new port is a long-term maintenance commitment for the team. Open a GitHub Discussion (or post on Discord) before the PR, outline the port, and state explicitly who maintains it. A surprise mega-PR for a new architecture is the most likely thing to be closed unread.
10 — All variants in CI. Removing floatconv.c from the FPU builds
broke the 68040 link (undefined pow/tgamma) during this work — a
standard-only CI would not have caught it. Build standard, 68020fpu,
and 68040.
The goal: land the port as a small, reviewable PR with zero core changes, then add the 68k native backend as a focused follow-up. Two stacked PRs.
Inspection of the branch confirms the split is natural:
-
Every core
py/change on the branch (all 12 files) is native-emitter or NLR related. A bytecode-only port needs nopy/changes at all. - The native emitter is gated by one flag,
MICROPY_EMIT_68K(ports/amiga/mpconfigport.h). Unset ⇒ bytecode-only. - The register NLR (
nlr68k) is auto-selected for__m68k__inpy/nlr.h, and its purpose is nativetry/except(the handler PC rides a register that setjmp'sjmp_bufwould clobber). With the emitter off, the default setjmp NLR is correct — so the NLR work belongs with the emitter PR. -
.mpybytecode load (MICROPY_PERSISTENT_CODE_LOAD) and native.mpyload are independent: the port already setsMICROPY_PERSISTENT_CODE_LOAD_NATIVE = 0, so PR 1 keeps bytecode.mpyload and needs none of the native-arch plumbing.
Diff touches only these trees, no py//extmod//shared/ core edits:
-
ports/amiga/— all sources except the native config (see below). -
tests/ports/amiga/— all smoke tests except the native/viper ones. -
examples/amiga/,tools/amiga-*,.github/workflows/ports_amiga.yml.
Port config changes vs the current branch:
- Remove the
MICROPY_EMIT_68Kenable frommpconfigport.h(defaults off). - Do not carry the
py/nlr.h__m68k__block ⇒ NLR falls through to setjmp (correct, just slower ontry/except). - Soften the README: drop the
@micropython.native/viperfeature bullet and the native limitations note (they return in PR 2).
Excluded from PR 1 (these are PR 2's): test_native_emitter_smoke.py,
test_native_nested_smoke.py, test_native_nlr_smoke.py,
test_viper_shift_smoke.py.
New core files: py/asm68k.c, py/asm68k.h, py/emitn68k.c,
py/nlr68k.S, py/nlr68k_jump.c.
Modified core (the audited hunks): py/compile.c (NATIVE_EMITTER case),
py/emit.h (method-table decl), py/mpconfig.h (MICROPY_EMIT_68K in the
MICROPY_EMIT_NATIVE convenience macro), py/emitnative.c (the N_68K
register/codegen blocks + the MP_ENDIANNESS_BIG fixes), py/nlr.h
(MICROPY_NLR_M68K + reg count), py/persistentcode.h
(MP_NATIVE_ARCH_68K), py/py.mk (asm68k.o, emitn68k.o, nlr68k.o,
nlr68k_jump.o).
Port changes: set MICROPY_EMIT_68K = 1; switch NLR to register-based
(the py/nlr.h block); restore the README native section; add the four
native/viper smoke tests.
-
setjmp NLR build. Confirm all three variants build and the port runs
with setjmp NLR (no
nlr68k). Expected fine — setjmp is the universal fallback — but it has not yet been built that way. -
persistentcode.hnecessity.MP_NATIVE_ARCH_68Kis only reachable underMICROPY_PERSISTENT_CODE(save/load-native). The port has load-native off; confirm whether the enum is needed at all for PR 2's config, or only for completeness. Keep it in PR 2 regardless. - Optional: the register NLR is also a small perf win for bytecode. It could be its own tiny core PR between PR 1 and PR 2, but keeping PR 1 zero-core-change is the cleaner story.
-
PR 1: build
standard+68020fpu+68040bytecode-only; run the port smoke suite minus native/viper; spot-check REPL,socket,ssl,asyncio, frozen +.mpybytecode import. -
PR 2: build all three with the emitter on; run the native/viper/NLR
smoke tests plus the upstream
--emit nativetest variants.
This split is best done as part of the history curation (item #3): the
current amiga-port (252 commits, based on an old master) needs a rebase
onto current upstream master and a squash into logical commits before any
PR. Do that rebase first, then carve PR 1 (port, no py/) and PR 2
(py/ backend + enable) off the curated tree. The emitter changes are
isolated enough that PR 2's content = the five new py/ files + the listed
hunks + the port's native-enable lines; PR 1 = everything else.
These were investigated and found acceptable, so they are recorded here to avoid re-litigating them:
-
No other obsolete divergence.
modjson.cwas the only fork of an upstream file.modsocket.c/modos.c/modtime.care port-original AmigaOS implementations (parallel toports/unix/), not diverged copies — keep them. -
floatconv.cis legitimate — it overrides bebbo gcc 6.5b's broken soft-float libgcc/clib2 routines and provides thepow/tgammawraps needed on all variants (libm bugs, not soft-float bugs). It is not the modjson pattern; there is no general fix elsewhere. -
Core
py/diff is clean and well-guarded. 1192 insertions / 3 deletions across 10 files, following the established per-arch backend pattern; every shared-file change is a one-line arch addition or wrapped in#if N_68K, so other ports are provably unaffected. No TODO/FIXME/stub/abort(). The newMP_NATIVE_ARCH_68Kenum is appended last (no.mpyABI renumbering).
-
NLR file shape. The 68k NLR is a standalone
py/nlr68k.Splus a C helperpy/nlr68k_jump.c, rather than the single naked-asm.cother arches use (nlrthumb.c-style). This is forced: bebbo m68k gcc ignores__attribute__((naked)), so the register save/restore must be hand-written assembly.nlr68k.Sis#if defined(__m68k__)-guarded so it is inert on other ports (verified by building the unix port). Upstream may still prefer a different arrangement — worth raising in the Discussion.
Work done so far on this branch (commit hashes are on amiga-port):
-
3a63676— Drop modjson fork in favour ofextmod/modjson.c. The fork existed only to dodge anmp_obj_tstack-alignment bug that the generalMICROPY_OBJ_BASE_ALIGNMENT = aligned(4)fix already solves. Full extmod json suite + port json smoke test pass (14 tests / 286 cases). -
888cd94— Rewordmodos.cenv-var comment to lead with the real-AmigaOS rationale instead of a "Vamos workarounds" heading (comment-only). -
19f9f72— Key big-endian native codegen onMP_ENDIANNESS_BIG(prelude index, generator start-offset,code_state.n_state); then_stateshift is now word-width-sized. Native-generator path verified on 68k. -
40ff324— Renameemit68k.c→emitn68k.cand move the 68k NLR (nlr68k.S,nlr68k_jump.c) intopy/+py.mk. Both amiga variants and the unix port build cleanly; native/viper/NLR smoke tests pass. -
301fe33— Removesync_upstream.ymlfork-maintenance workflow. -
8f68627— Applycodeformat.py+ruff format(uncrustify fixes inpy/asm68k.handmain.c; ruff reflow of three examples and a smoke test).codeformat.pyis now idempotent on the port. -
1163c0d— Fix codespell findings: renamete→tencinurequests.py, and skip the auto-generatedports/amiga/modules/_amiga_*.pytables (API names likeDoubleClickcollide with the dictionary).
All three repo-wide linters that gate upstream PRs pass on the port:
-
ruff check(lint) — clean. -
ruff format --check— clean. -
tools/codeformat.py -c(uncrustify +fixup_c) — clean and idempotent. -
codespell(2.4.1, CI-style invocation) — clean.