It takes in .idl files (in a special interface language) and converts it into .cpp files (and internally a block of lua code) of functions that convert lua calls into C/C++ calls.
Right now, only C/C++ is supported.
To simplify the process of porting native code to Lua, and to generate (memory and logic) SAFE code without too much effort.
lua-webidl --help
sigh here we go...
The Lua files generated by wasm2lua in binding generator mode will add in an extra block (and populate the module.bindings table). These functions are auto generated and should be SAFE to call. They are type checked.
Before calling any function, you MUST call module.init()
.
Classes can also go in module.bindings
. Classes are initiated by calling the class table as a function (e.g. module.bindings.ClassName(arg1,arg2)
).
WebIDL is obviously not designed for Lua, so we had to make some modifications to it. Mainly, WebIDL was augmented with lots of prefixes. They are used by writing prefix operations in square brackets, with occasional arguments for each prefix. WebIDL also has different typenames to C/C++.
NB: classes defined in WebIDL are always pointers to that class when used as arguments/returns. Using [Ref] on those classes makes them double pointers
Here is a list of the type name mapping:
WebIDL | C/C++ | Notes |
---|---|---|
octet | unsigned char / uint8_t | |
byte | char / int8_t | |
unsigned short | unsigned short int | |
long | int | |
boolean | bool | |
DOMString | char* | This has special bindings that auto convert args/returns to regular lua strings. Only works with NULL TERMINATED strings. |
any | void* | |
VoidPtr | void* |
Here are a list of all prefixes:
WebIDL Prefix | Argument | Notes |
---|---|---|
Array | Integer, length of array | It converts the suffix type to an array of that type. Useful for non-null terminated strings. |
ArrayLength | String, name of array argument | It automatically extracts the length of the array (when both the arraylength suffix and array suffix are arguments) and removes the arraylength argument. (i.e. you should not supply it when calling the binding function) MUST use with suffix type any |
ArrayRef | see Array | same as Array, except adds a * (pointer) to the suffix type |
ArrayLengthRef | see ArrayLength | same as ArrayLength, but expects the argument to point to an ArrayRef argument |
ConvertInputArray | none | Converts the input argument using metatable magic to be an internal WASM array. It means that the data is not stored in Lua, but rather in WASM memory. Use with care. Useful when an argument modifies an input variable as its output. |
Enum | string, name of enum type | Turns the suffix argument into an enum type. Suffix argument must be the any type |
Size | none | Turns the suffix argument into a size_t. Suffix argument must be the any type |
Const | none | Adds const to the suffix argument |
Ref | none | Makes the suffix argument a pointer |
Value | none | Makes the suffix argument a value type (dereferences it if applicable) |
ToWASMOwned | none | Compiler hint that the argument/return will be freed by C/C++ code. |
ToLuaOwned | none | Compiler hint that the argument/return will be freed when no Lua code references it. (using __gc) |
NoDelete | none | Compiler hint that even if an argument/return is owned by Lua, it MUST not be freed (disables automatic frees via __gc) |
OverrideCanWrite | none | Makes the suffix argument (for attributes) writable, regardless of whether it was readonly. This exists due to a webidl limitation |
- For
[Array]
, we actually copy all lua values into WASM memory and create a duplicate instance in WASM memory. This means that modifications that WASM makes to the array will not be directly transferred back to lua UNLESS[ConvertInputArray]
is used - For most cases, any libraries you use will not have a
main()
function because they're libraries (duh). So, lua-webidl has--libmode
which generates a stub main function and initialises libc for you. This stub function is used inmodule.init()
, and this is why it's important to call that function. namespace global {}
will actually reference the global C/C++ namespace. Using this, you can bind C libraries which populate their functions into the global C namespace. Otherwise, namespaces are analogous to C++ namespaces and can be used to reference a C++ namespace. When generating bindings, functions/classes inside a namespace will be put inside a Lua table. (e.g.module.bindings.namespaceName.funcName
)