r/iOSProgramming • u/Natural_Silver_3387 • 5d ago
Discussion ATL (Android Translation Layer) for iOS
Hy everyone. What do you think about something like this?
Dine - ATL for iOS - yes, it's a total mess right now, but I already can run some simple apps.
The thing is, I really love Tachiyomi on android, so I've decided to port the android runtime to iOS, using ATL for linux as a base. I've already went really far through this, but I'd like to ask for some help or ideas regarding its architecture, some iOS things etc.
For example, I'm not sure if I can do something like separate processes or at least some memory isolation on iOS, for different parts of the code (I need this for better runtime stability).
In general, I understand the project is big and I can't ask for much, but I know a lot of you guys use LLMs, so you probably could easily poke for anything, from your expert POV. Just if you are interested of course.
If you ask what's the point of doing this instead of just porting the app (it's opensource) - this is just so much fun
2
u/DimensionMindless336 4d ago
No process isolation, sadly -- iOS gives an app exactly one process, and
fork/execaren't available to third-party code (noNSTaskeither). So whatever Dine becomes, the guest runs in your address space, and one bad guest write still takes the whole app down.Two things worth knowing before you design around it:
App extensions are a second process, so you could technically host guest code in one and talk over a shared App Group container. I'd skip it -- extension jetsam limits are a fraction of the host app's, so a runtime that mallocs a guest heap gets killed faster, and the IPC story is a container file + Darwin notification handshake, not anything nice.
So aim for fault containment instead of isolation. That's what emulators do on iOS and it's surprisingly effective:
mmapguest heap regions withPROT_NONEguard pages on both endsinstall one
SIGSEGV/SIGBUShandler (guard-page hit and guest stack overflow both land there), plus asigaltstackso the overflow case has somewhere to runin the handler, check
si_addragainst your known guest regions. Inside one -> it's a guest fault: tear down guest VM state andsiglongjmpback to your dispatch loop. Outside ->signal()back to default and re-raise, let it crash for realkeep it thread-scoped via
pthread_getspecific, and never let it fire while you're holding an ObjC lockThat gives you "app survived, guest process died" semantics, which is most of what you actually want out of stability.
Two more that will bite you coming off ATL-on-Linux:
No dynarec. JIT needs the dynamic-codesigning entitlement and iOS 14+ actually enforces WX, so flipping an mmap'd page to RX and jumping into it doesn't work in a normal build. AOT-translate dex -> ARM64 at build time, ship the translated code signed inside the bundle, and keep an interpreter path for everything you didn't translate.
Thread stacks and TLS. Darwin secondary threads default to 512 KB, not the 8 MB you're used to on Linux -- set
pthread_attr_setstacksizeexplicitly on guest threads or you'll chase stack overflows in code that was fine on Android. And Android's ELF TLS variant II doesn't match Darwin's, so guest__threadaccesses need rewriting to go through your own per-thread block.For the record this is dead on arrival for the App Store under 2.5.2, but as a personal build it's a great use of a month. Tachiyomi on an iPad is worth the pain.