LJIT2libc – LuaJIT IS “batteries included”Posted: September 1, 2015
I would say one of the most common complaints about any platform, framework, product is a paucity of available stuff to fiddle about with. I’ve heard this criticism a few times leveled at the lua world in general. Fatter frameworks are usually “batteries included”. That’s great, when you get a whole ton of stuff that makes writing all sorts of apps relatively easy to do right off the bat. The challenge of “batteries included” is that you get a whole ton of stuff, most of which you will never use, and some of which doesn’t have the best implementation.
Recently, I’ve been doing quite a lot off luajit bindings on the Linux platform:
If you were into anything from ASCII art graphics drivers to raw frame buffer management in a Linux system, these might start to look like batteries. They’re not included with the luajit compiler, but they’re relatively easy to add.
But, there’s another one that I’ve been playing with recently which I think is even better:
Well, the lua language has its own print routine, so this is a bit contrived, but let’s say you wanted to do it anyway. Well, to make this work, you need access to the function signature for the ‘puts’ routine and you need that to be accessible in the global namespace. So, it would actually look like this:
local ffi = require("ffi") ffi.cdef("int puts(const char *);"); puts = ffi.C.puts; puts("Hello, World!")
Great. A bit of work, and now I can program as wrecklessly as I could in C with all the batteries included in the libc and libm libraries. But, it gets tedious having to write that ffi stuff all over the place, so this is where the LJIT2libc thing comes in. It basically goes and implements a ton of the required ffi.cdef statements to make all those functions readily available to your script. An easy way to pull it into any script is to do the following:
local init = require("test_setup")() puts("Hello, World!");
That first line ‘init = …’ in this case pulls in all of the definitions, and puts them into the global namespace, so that you can simply write your program without having to know anything about the ffi, or where functions come from or anything like that. Just start writing your code knowing that the batteries are already included.
Now, this example might seem too trivial for words, but just think about what’s in a typical libc library. It’s all the file system, sockets, system calls, math, random numbers, everything you’re likely to need to create higher level application stuff. It’s a lot of stuff that other systems end up creating from scratch, as part of their ‘batteries’.
Of course this is trivializing what’s happening in those batteries, because what you’re getting here is the raw C implementations of things, with all the headaches and dangers that are typically associated with writing code at that level. But, for those who want to have access to that level of code, and apply the safety net of lua where they see fit, this is quite a useful tool I think.
In short, batteries ARE included with every luajit. Those batteries might be just anode, cathode, and electrolyte, without the shell, but there are the raw ingredients. Having these wrappers available just makes it that much easier to think about and deal with a lot of low level stuff where I might previously had to resort to some sort of ‘package’ to achieve something as simple as traverse the file system.
So there you have it. luajit is a ‘batteries included’ system.