LuaCocoa
The next-generation successor to the LuaObjCBridge for Objective-C 2.0.
It uses BridgeSupport, libffi, and a whole lot of blood, sweat, and tears to bridge both C and Objective-C including objects, constants, enums, functions, and structs.
It is similar to PyObjC, RubyCocoa, and JSCocoa.
LuaCocoa is under the MIT license.
The Mercurial repository is hosted at Bitbucket and can be found here.
Dedication:
In memory of my mother who lost her long fight to GIST cancer. (Much of this code was written during long waits at the hospital.) More here.
Features:
- Full bridging to classes/objects, C functions, macros, selectors, structs, enums, constants
- 32-bit and 64-bit support (uses new Obj-C 2.0 runtime), PowerPC & Intel
- Support Obj-C garbage collection and non garbage collection modes
- Subclassing and Categories in Lua
- Full Obj-C blocks support (create, convert, invoke, auto-coercion)
- Obj-C/C APIs and easily embeddable framework to allow easy integration into existing Obj-C applications
- Scripting Bridge support to allow Applescript control written in Lua scripts instead of Applescript
- Conversion of Lua tables to NSArray and NSDictionary
- Metamethods on NSArray and NSDictionary to respond like Lua tables
- Convenience metamethods to access struct fields
- Auto-boxing of numbers and structs into NSNumbers and NSValues when necessary
- Setter dot notation in Lua
- Proper handling of BOOL types to native Lua boolean types
- Return pass-by-reference out parameters as multiple Lua return values
News:
December 2017:
macOS 10.13 (High Sierra) introduced new bugs which broke their BridgeSupport format. They broke the format for compound structs (such as NSRect), nil terminated variadic methods & functions (e.g. NSArray arrayWithObjects), and removed the data in BridgeSupport which lists all the dependent libraries/frameworks for a given framework (which brnow will require you to explicitly LuaCocoa.import() all the frameworks you indirectly need).
I filed 3 bugs with Apple. If you depend on BridgeSupport for any of your projects, please file duplicates with Apple Radar and list these bug numbers in your bug reports. (Apple does count the number of bug reports and has influence over prioritization.)
35844688 10.13 broke BridgeSupport for compound struct definitions
35844763 10.13 broke BridgeSupport and compatibility with existing apps for variadic nil terminated methods/functions
35844832 10.13 broke BridgeSupport format for listing dependency framework information
The fixes I pushed to LuaCocoa will deal with the first problem. You must workaround the second & third problems in your code. The LuaCocoa examples have been updated to do this and run on 10.13 now.
October 2016:
I presented The History & Design of LuaCocoa at the prestegious Lua Workshop 2016. It lays out a lot of the technical design of LuaCocoa, from what capabilities it needed to how they were implemented. I highly recommend it for those who want to understand how LuaCocoa works, or for those who want to implement their own language bridges to Cocoa.
The Lua Workshop has made the video and slides available.
Older News:
Version 0.3.3 has been released and major changes have already been pushed into mainline for 0.4.0. (0.4.0 has been in heavy development on my Assembla branch for over a month now and is now merged into mainline.) Already in the branch is full support for Obj-C blocks which allow you to do everything you might expect, e.g. create blocks from Lua functions, auto-coerce Lua functions when passed as a parameter to a function expecting a block, invoke blocks from Lua, pass blocks through both sides of the bridge, etc. This even works fully with structs.
Like everything else in LuaCocoa, the details have been worked out to make memory management automatic on the Lua side and works with both classic Obj-C memory management and Obj-C garbage collection. Also, special safeguards have been implemented to make sure block callbacks that callback on a different thread are re-routed back to the originating (Lua) thread.
Obj-C Categories have also been added to LuaCocoa. The interface works like subclassing.
And there have been improvements for structs including much faster performance.
Due to the requirements for blocks, 0.4 will may impact backwards compatibility, particularly on 10.5. For the moment, as long as you don't use blocks on 10.5, LuaCocoa should work. But after the 0.4.0 release, 10.5 will likely be dropped.
Please try out the tip and let me know how it works. I plan on releasing this very soon.
Release Notes:
v 0.3.3: (CoreGraphics fix for CFTypes moving through the bridge, new sample project showing subclassing/delegate pattern in Lua with NSOpenPanel and NSSavePanel)
- Dealt with bug where CFTypes from CoreGraphics crossing through the bridge were being corrupted.
- Added new example demonstrating the classic delegate pattern featuring NSOpenPanel and NSSavePanel. This example will be complimented by a new example showing the blocks (closure) pattern in the next release utilizing the new Obj-C blocks APIs for NSOpenPanel and NSSavePanel.
v 0.3.2: (More Lion fixes, command line libreadline support, PowerPC dropped)
⁃ Fixed bug for prepping ffi data return values for structs which was manifesting itself as a ffi failure on Lion 64-bit calling cascadeTopLeftFromPoint in the MinimalAppKit example .
⁃ The command line tools lua and luacocoa are now compiled with LUA_USE_READLINE defined allowing things like up-arrow history searching/repeating.
⁃ Notes on readline support:
⁃ Linking against libreadline is problematic for backwards compatibility because Apple always writes the resolved symbolic link in the executable. To work around this, I added a shell script phase that rewrites the resolved symbolic link (libedit.3.dylib) to the symbolic link. This rewrite will fail if the resolved link name is not exactly libedit.3.dylib (say you compile against the 10.6 or 10.8 SDK and not 10.7). And this will not work if libedit breaks compatibility between versions. (rdar://10157076)
⁃ Xcode 4 seems to have a bug where typing in the Xcode debugger console while running under the debugger will echo all the input you enter. This does not necessarily impact functionality as the echo characters don't seem to be actually submitted to the process. (rdar://10660201)
⁃ All the command line tools (lua, luac, luacocoa) have been changed to compile with garbage collection mode as 'unsupported'. This is to avoid potential problems with 3rd party .so Lua modules that weren't compiled with garbage collection in mind. (This is the likely case.) If there is demand for a gc-enabled-variant, we could consider including a luacocoa_gc tool to the package.
⁃ Worked around a Lion bug where [LuaCocoa collectExhaustivelyWaitUntilDone:true] causes SimpleLuaView and SimpleLuaOpenGLView cause the application to hang on quit. objc_collect(OBJC_EXHAUSTIVE_COLLECTION | OBJC_WAIT_UNTIL_DONE) never returns and the program is blocks. My suspicion is that it is connected to subclassing in Lua because the SimpleLuaView examples both hang but the CoreAnimationScriptability example does not hang. The two SimpleLuaView applications have been altered to use 'false' to avoid the problem. Filed rdar://10660280
⁃ Now compiling release binaries under 10.7 against the 10.7 SDK with the Deployment Target still set to 10.5. There seemed to be weird runtime problems when compiled under Xcode 3/10.5/10.6 and running on 10.7. But this means PowerPC is now dropped from the binary release.
⁃ Note: The Xcode 3 project has not been updated with any of these changes.
v 0.3.1:
- Fixed selector related bug due to Lion/non-Full bridgesupport switchover.
v 0.3: (Xcode 4 / Lion compatibility changes, final PowerPC release?)
- Changed LuaCocoa to use the non-'Full' .bridgesupport files instead of the 'Full' bridgesupport files because Lion removed the 'Full' versions without warning.
- As fallout from this change, LuaCocoa no longer requires Obj-C classes to be fully specified in BridgeSupport data to refer to them in Lua code (i.e. Using NSClassFromString to refer to a is no longer necessary to refer to an unspecified class.)
- Added new Xcode 4 project to deal with Xcode 4 compatibility, plus minor Xcode script phase compatibility fixes.
- This might be the last PowerPC release because building PowerPC is hard in Xcode 4 and Lion
- Remove use of helper categories in LuaCocoa implementation to avoid headaches with static linking.
- Added APIS: LuaCocoa_PrependToLuaSearchPath, LuaCocoa_PrependToCSearchPath, LuaCocoa_AppendToCSearchPath. These APIs help you add more search paths for Lua plugins and Lua files.
- The LuaCocoa class will add the .app bundle's PlugIns path to the begining of the search path.
- The luacocoa shell tool has been modified to look in */Library/Application Support/LuaCocoa/PlugIns for additional .so modules, and */Library/Application Support/LuaCocoa/Scripts for additional .lua scripts.
- Bug fix for returning const char* (strings) through the bridge, e.g. nstring:UTF8String().
- Added new preprocessor define LUACOCOA_DONT_USE_BUNDLED_LUA_HEADERS so #include "lua.h" can be used instead of <LuaCocoa/lua.h> in case people need to use a custom version of Lua which is not located in a LuaCocoa subdirectory (for people building LuaCocoa themselves).
- Optional Source Code: Added simple lua_isinteger implementation to stand in for projects that need LuaCocoa but use a stock version of Lua without LNUM. It is located the the directory: 'etc'
- Updated bundled LPeg to 0.10.
- Doxygen (in repo): Experimenting with man page generation in addition to html and Xcode DocSets
v 0.2: (Faster, Smaller, Better)
- Big performance improvements over 0.1.
- Optimized initialization/load times. Names are now resolved through a metatable (which calls LuaCocoa.resolveName) so launch times are now very fast.
- Cached parsed XML data so repeated method calls don't have to reparse XML data.
- The LuaCocoa core framework is now over 30% smaller
- Removed ParseKit dependency
- Added LuaCocoa.toCocoa and LuaCocoa.toLua functions to convert between Cocoa and Lua types within Lua scripts.
- Started formalizing support for instance variables in Lua subclassing. (Put your variables in a special table named __ivars.)
(Thanks to Jonathan Mitchell for feedback, testing, and patches for this.)
- Bug fixes, logging clean ups
- Initial Doxygen for Obj-C & C APIs. Xcode DocSet Documentation provided too.