Repository navigation
objc — the LispWorks Objective-C interface, reimplemented for SBCL on macOS #2614
Description
objc is a source-compatible reimplementation of the interface documented in the
LispWorks Objective-C and Cocoa Interface User Guide and Reference Manual. The
packages are literally named OBJC and COCOA, the exported symbols have the
LispWorks names and lambda lists, and code written against LispWorks 8.1 is
intended to load and run unchanged — including define-objc-class,
define-objc-method with real IMPs, structures passed and returned by value in
both directions, the standard-objc-object CLOS integration, and invoke-into's
full set of result dispositions.
Dispatch is dynamic rather than declared. A method's type encoding is read from
the Objective-C runtime, parsed, and turned into a compiled trampoline that calls
objc_msgSend through one exact non-variadic signature; the trampolines are
memoized, so the compiler runs once per distinct call shape. Classes defined from
Lisp get real IMPs built the same way in the other direction.
Past the manual, one deliberate addition: creating Objective-C blocks from Lisp
closures, which LispWorks does in its FLI and has no OBJC interface for at
all. That is what puts completion-handler APIs — NSURLSession, GCD, and most
modern Cocoa — in reach.
It is SBCL only, and macOS only, by construction. Dynamic dispatch is built on
sb-alien because CFFI cannot express a struct passed or returned by value
without libffi, and libffi cannot make an Apple arm64 variadic call. That
dependency is confined to one file, src/abi.lisp, and a test enforces it, so
porting is one file's work.
- Repository: https://github.com/lispnik/objc
- Source: git, master branch (tagged
v0.4.1) - License: MIT
- Systems:
objc(the library),objc/examples(worked examples, incl. the
manual's own, ported),objc/test(FiveAM suite) - Dependencies: cffi, alexandria, closer-mop, bordeaux-threads,
trivial-features, float-features (fiveam for the test system)
There is no C toolchain in the build: no cffi-grovel, no cffi-libffi, and no
shim library.
:description, :author and :license are set on every system, the README
documents the interface and the traps, and CI runs the suite on both
architectures — arm64 and Intel — on every push: 934 checks. The two differ in
the Objective-C ABI in ways that matter (BOOL encodes as c on x86-64 and B
on arm64; a large struct return goes through objc_msgSend_stret on Intel, a
function that does not exist on arm64), and nothing is conditionalised on
architecture — both are measured from the runtime, and the Intel leg is what
turns "should work" into "does work".
Behaviour the manual leaves ambiguous was settled by running LispWorks Personal
8.1 and recording what it actually did; those answers are committed and asserted
against, so the differential tests run without LispWorks installed.
Activity