{"id":49866893,"url":"https://github.com/avwohl/iospharo","last_synced_at":"2026-05-15T03:36:21.643Z","repository":{"id":340353381,"uuid":"1126855565","full_name":"avwohl/iospharo","owner":"avwohl","description":"Pharo Smalltalk VM for iOS and Mac Catalyst — interpreter-only (no JIT), with low-bit oop encoding for ASLR compatibility","archived":false,"fork":false,"pushed_at":"2026-05-09T13:52:45.000Z","size":21931,"stargazers_count":12,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-05-09T14:10:52.894Z","etag":null,"topics":["cpp","ios","mac-catalyst","metal","mit-license","pharo","smalltalk","swift","virtual-machine"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avwohl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-02T17:44:31.000Z","updated_at":"2026-04-29T19:02:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/avwohl/iospharo","commit_stats":null,"previous_names":["avwohl/iospharo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/avwohl/iospharo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avwohl%2Fiospharo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avwohl%2Fiospharo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avwohl%2Fiospharo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avwohl%2Fiospharo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avwohl","download_url":"https://codeload.github.com/avwohl/iospharo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avwohl%2Fiospharo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33052823,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-15T02:00:06.351Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","ios","mac-catalyst","metal","mit-license","pharo","smalltalk","swift","virtual-machine"],"created_at":"2026-05-15T03:36:20.890Z","updated_at":"2026-05-15T03:36:21.637Z","avatar_url":"https://github.com/avwohl.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# iospharo\n\nA Pharo Smalltalk VM for iOS and macOS, written as a clean C++ interpreter.\n\n## Overview\n\niospharo runs standard Pharo 13 and Pharo 14 images on iOS devices and Mac\n(via Catalyst). It is a from-scratch interpreter implementation — not a port\nof the Cog JIT VM — with full support for the Sista V1 bytecode set, FFI with\ncallbacks, and the standard Pharo test suite.\n\n**Note:** Pharo 12 and earlier use a different class table layout that the VM\ndoes not yet handle.\n\n## Status\n\n**VM core (solid):**\n- **99.90% test pass rate** on Mac Catalyst (13,040 / 13,053)\n- **99.55% test pass rate** on iOS Simulator\n- FFI with callbacks (sigsetjmp/siglongjmp)\n- All standard VM plugins built-in (B2D, JPEG, DSA, SSL, etc.)\n- Third-party libraries: cairo, freetype, harfbuzz, pixman, libpng, OpenSSL, libssh2, libgit2\n\n**GUI (working):**\n- Metal rendering pipeline — Pharo desktop renders correctly\n- Menu bar, world menu, and context menus all functional\n- Touch-to-mouse event translation (tap, long-press, two-finger, pinch, drag)\n- Hardware keyboard support with modifier keys\n- Image library with download, import, and catalog management\n\n## Install from the App Store\n\nAvailable for iPad, iPhone, and Mac:\n\n[Download on the App Store](https://apps.apple.com/us/app/pharosmalltalk/id6759073615)\n\n**Requirements:**\n- iPad (5th gen / 2017 or newer) or iPhone (6s / 2015 or newer) or Mac (Apple Silicon or Intel)\n- iOS / iPadOS 15.0 or later, macOS 14.0 or later\n- ~150 MB free storage (app + image + sources)\n\nPharo images are downloaded in-app (no separate download needed).\n\n## Beta Testing (TestFlight)\n\nThere may be a newer pre-release version available via TestFlight:\n\n1. Install **TestFlight** from the App Store (free, ~30 MB)\n2. Open this invite link on your iPad or iPhone: [Join the Beta](https://testflight.apple.com/join/kGmPQFr9)\n3. Tap \"Accept\" then \"Install\" — the app appears on your home screen\n\nTestFlight builds expire after 90 days but auto-update when new builds\nare published.\n\n## Prerequisites\n\nInstall these before building:\n\n```bash\n# Xcode command-line tools (includes clang, make, etc.)\nxcode-select --install\n\n# CMake (build system)\nbrew install cmake\n\n# For third-party library builds (cairo, freetype, etc.)\nbrew install meson ninja pkg-config autoconf automake libtool\n```\n\nYou also need:\n- **Xcode 15+** (for the iOS/Mac Catalyst app)\n- **A Pharo 13 or 14 image** — download from https://pharo.org/download\n\n## Building\n\n### Step 1: Build libffi and SDL2 xcframeworks\n\n```bash\nscripts/build-libffi.sh\nscripts/build-sdl2.sh\n```\n\nThis downloads, cross-compiles, and packages libffi (FFI/callbacks) and SDL2\n(display driver) as xcframeworks for iOS device, simulator, Mac Catalyst, and\nmacOS. Takes about 10 minutes. The xcframeworks are gitignored due to size.\n\n### Step 2: Build third-party libraries\n\nCairo, freetype, harfbuzz, pixman, libpng, OpenSSL, libssh2, and libgit2\nare cross-compiled as static xcframeworks:\n\n```bash\nscripts/build-third-party.sh\n```\n\nThis downloads source tarballs and builds for iOS device, Simulator, and Mac Catalyst.\nTakes about 15 minutes on first run. Use `--no-crypto` to skip OpenSSL and libssh2\n(libgit2 is always built for local repository support).\n\n### Step 3: Build the app\n\n```bash\nopen iospharo.xcodeproj\n```\n\nSelect your target (iOS device, Simulator, or My Mac - Catalyst) and build.\n\nXcode has a \"Check XCFramework Freshness\" build phase that automatically runs\n`scripts/build-xcframework.sh` whenever VM source files (`src/vm/`, `src/platform/`)\nare newer than the xcframework. The first Xcode build will take several minutes\nwhile it compiles the VM; subsequent builds are fast unless you change VM sources.\n\nTo manually rebuild the VM xcframework (e.g. after a git pull):\n\n```bash\nscripts/build-xcframework.sh\n```\n\nThis produces `Frameworks/PharoVMCore.xcframework` with slices for iOS device\n(arm64), iOS Simulator (arm64 + x86_64), and Mac Catalyst (arm64 + x86_64).\n\n**Code signing (optional):** To deploy to a physical device or the App Store,\ncopy `Local.xcconfig.example` to `Local.xcconfig` and fill in your Apple\nDeveloper Team ID. `Local.xcconfig` is gitignored.\n\n### Quick development build (Mac only)\n\nFor faster iteration on VM internals. This builds a headless command-line binary\n(not the iOS/Catalyst app). Requires Steps 1 and 2 above — the cmake build\nlinks against the xcframeworks in `Frameworks/`.\n\n```bash\ncmake -B build -DCMAKE_BUILD_TYPE=Release\ncmake --build build\n\n# Run headless with a Pharo image\n./build/test_load_image /path/to/Pharo.image\n```\n\n## Project Structure\n\n```\niospharo/\n├── src/vm/           C++ VM: Interpreter, ObjectMemory, Primitives, FFI\n├── src/include/      VM headers (vmCallback.h, etc.)\n├── src/platform/     Platform abstraction (EventQueue, display)\n├── src/ios/          Generated interpreter reference (cointerp-cpp.c)\n├── iospharo/         SwiftUI app (Metal renderer, bridge, views)\n├── scripts/          Build scripts (VM xcframework, third-party libraries)\n├── docs/             Technical reference (bytecode spec, architecture)\n├── Frameworks/       Built xcframeworks (gitignored)\n└── CMakeLists.txt    CMake build for the VM library\n```\n\n## Architecture\n\n```\n┌─────────────────────────────┐\n│   SwiftUI App               │\n│   (ContentView, Settings)   │\n├─────────────────────────────┤\n│   PharoBridge.swift         │  VM lifecycle, event bridge\n├─────────────────────────────┤\n│   MetalRenderer.swift       │  GPU display rendering\n├─────────────────────────────┤\n│   C++ Interpreter           │  Sista V1 bytecodes, GC,\n│   (libPharoVMCore.a)        │  FFI, primitives, plugins\n└─────────────────────────────┘\n```\n\nThe image's OSSDL2Driver calls SDL2 functions via FFI. Our SDL2 stubs bridge\nthese to the Metal rendering pipeline. Touch gestures are mapped to Pharo\nmouse events (tap=left-click, long-press=right-click, two-finger tap=right-click).\n\n### Startup patches\n\nThe app applies Smalltalk patches on every launch to fix image bugs and adapt\nto VM differences (stubbed SDL2, missing font glyphs, etc.). Patches are\nversion-specific — the app detects the Pharo version and loads `startup-13.st`\nor `startup-14.st` accordingly. Users can add custom patches by creating\n`startup-user.st` next to the image file (it is never overwritten).\nSee [docs/startup-system.md](docs/startup-system.md) for the full details.\n\n## Configuration\n\nVM parameters are set in `PharoBridge.swift` when calling `vm_init()`:\n\n  maxOldSpaceSize   2 GB    Max heap (virtual, lazy commit)\n  edenSize          10 MB   Young generation size\n  maxCodeSize       0       JIT code space (unused)\n\n## Related\n\nOther repos in this collection:\n\n- **[smalltalk80-2026](https://github.com/avwohl/smalltalk80-2026)** — Smalltalk-80 VM implementation of the 1983 Blue Book Xerox virtual image, targeting macOS / Mac Catalyst, iOS, Windows, and Linux.\n- **[validate_smalltalk_image](https://github.com/avwohl/validate_smalltalk_image)** — Standalone validator and export tool for Spur-format Smalltalk image files (heap integrity, SHA-256 manifests, reference graphs).\n- **[pharo-headless-test](https://github.com/avwohl/pharo-headless-test)** — Headless Pharo test runner with a fake GUI; clicks menus, takes screenshots, runs SUnit without a display. Extracted from this project; included here as a submodule at `scripts/pharo-headless-test/`.\n- **[soogle](https://github.com/avwohl/soogle)** — Smalltalk code search engine that indexes packages across Pharo, Squeak, GemStone and more.\n- **[claude-skills](https://github.com/avwohl/claude-skills)** — Open source skills for Claude Code: reusable knowledge and algorithms packaged as `.claude/skills/` markdown files.\n\n## License\n\nMIT — see [LICENSE](LICENSE) and [THIRD_PARTY_LICENSES](THIRD_PARTY_LICENSES).\n\n## Credits and Acknowledgements\n\nThis project would not exist without the decades of work by the Smalltalk\ncommunity. The VM's interpreter, object memory, and primitives are a clean\nC++ reimplementation of the architecture defined by the Pharo and Squeak\nprojects.\n\n**Pharo and predecessors:**\n- [Pharo](https://pharo.org) — the Smalltalk environment this VM executes\n  (MIT; Copyright 2008-2019 The Pharo Project, Inria)\n- [OpenSmalltalk-VM](https://github.com/OpenSmalltalk/opensmalltalk-vm) —\n  the reference VM from which VMMaker-generated plugin code and headers\n  are taken (MIT; Copyright 2013 3D Immersive Collaboration Consulting, LLC)\n- [Squeak](http://squeak.org) — the original open source Smalltalk from which\n  Pharo descends (MIT; Copyright 1996-2008 Viewpoints Research Institute,\n  Apple Inc.)\n\n**VMMaker-generated plugins included in this repo:**\n- BalloonEnginePlugin (B2DPlugin.c) — vector graphics\n- DSAPlugin (DSAPrims.c) — digital signature algorithm\n- JPEGReaderPlugin, JPEGReadWriter2Plugin — JPEG codec wrappers\n- SqueakSSLPlugin (SqueakSSL.c, sqMacSSL.c by Andreas Raab and Tobias Pape)\n\n**Bundled libraries:**\n- [Independent JPEG Group](http://www.ijg.org) libjpeg 6b by Thomas G. Lane\n  (IJG license) — bundled in src/vm/plugins/jpeg/\n\n**Statically linked libraries (cross-compiled as xcframeworks):**\n- [libffi](https://github.com/libffi/libffi) 3.5.2 — Foreign Function Interface (MIT)\n- [SDL2](https://www.libsdl.org) 2.26.5 — Simple DirectMedia Layer (zlib)\n- [cairo](https://cairographics.org) 1.18.2 — 2D graphics (LGPL-2.1 / MPL-1.1)\n- [FreeType](https://freetype.org) 2.13.3 — font rendering (FTL)\n- [pixman](https://cairographics.org) 0.43.4 — pixel manipulation (MIT)\n- [HarfBuzz](https://github.com/harfbuzz/harfbuzz) 10.1.0 — text shaping (MIT)\n- [libpng](http://libpng.org) 1.6.43 — PNG support (libpng license)\n- [OpenSSL](https://www.openssl.org) 3.4.0 — cryptography (Apache-2.0)\n- [libssh2](https://www.libssh2.org) 1.11.1 — SSH client (BSD-3-Clause)\n- [libgit2](https://libgit2.org) 1.8.4 — Git library (GPL-2.0 with linking exception)\n\nThis software is based in part on the work of the Independent JPEG Group.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favwohl%2Fiospharo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favwohl%2Fiospharo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favwohl%2Fiospharo/lists"}