Skip to content

Commit

Permalink
Add Lua language support.
Browse files Browse the repository at this point in the history
Lua FFI has a few notable differrences from regular generated C headers:
* Custom prelude/epilogue with `ffi.cdef` directive.
* Constants defined using `static const` syntax instead of `#define`.
* Different comments format using `--` or `[[` instead of `/* */`.
* Doesn't support `#include`, `#ifdef` or other macros.

Lua FFI described in more details at http://luajit.org/ext_ffi.html

Other changes:
* Added const generics support for the structs.
* Added implementation for array of any const size `N`.
* Added `try_as_str` implementation for `str_ref` and `slice_ref<u8>`.
  • Loading branch information
bocharov committed Sep 26, 2023
1 parent 0029467 commit 9bcad86
Show file tree
Hide file tree
Showing 26 changed files with 1,322 additions and 158 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,15 @@ jobs:
command: test
args: --features docs

- name: FFI test (C & C#?)
- name: Install LuaJIT and LuaRocks (Ubuntu)
run: sudo apt-get install -y luajit
if: matrix.os == 'ubuntu-latest'

- name: Install LuaJIT and LuaRocks (macOS)
run: brew install luajit
if: matrix.os == 'macos-latest'

- name: FFI test (C & C# & Lua?)
run: make -C ffi_tests
if: runner.os != 'Windows'
env:
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,19 @@ Point { x: 42.0, y: 42.0 }
## Development
### Dependencies
For running Lua tests (`test_lua_code`) please install `luajit` dependency:
MacOS:
```bash
brew install luajit
```
Ubuntu/Debian:
```bash
sudo apt-get install -y luajit
```
### Tests
safer-ffi includes three different tests suites that can be run.
Expand Down
4 changes: 2 additions & 2 deletions ffi_tests/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 58 additions & 0 deletions ffi_tests/generated.cffi
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,36 @@ typedef struct AnUnusedStruct {
Wow_t are_you_still_there;
} AnUnusedStruct_t;

typedef struct {
float idx[3];
} float_3_array_t;

typedef struct {
uint64_t idx[5];
} uint64_5_array_t;

typedef struct {
uint8_t idx[1];
} uint8_1_array_t;

typedef struct {
uint8_1_array_t idx[2];
} uint8_1_array_2_array_t;

typedef struct {
uint8_1_array_2_array_t idx[3];
} uint8_1_array_2_array_3_array_t;

typedef struct ArraysStruct {
float_3_array_t floats;

uint64_5_array_t sizes;

uint8_1_array_2_array_t dim_2;

uint8_1_array_2_array_3_array_t dim_3;
} ArraysStruct_t;

#define FOO ...

typedef enum Bar {
Expand All @@ -36,6 +66,34 @@ typedef struct next_generation {
void * (*cb)(bool);
} next_generation_t;

typedef struct ConstGenericStruct_uint8_1 {
uint8_1_array_t data;
} ConstGenericStruct_uint8_1_t;

typedef struct {
uint8_t idx[2];
} uint8_2_array_t;

typedef struct ConstGenericStruct_uint8_2 {
uint8_2_array_t data;
} ConstGenericStruct_uint8_2_t;

typedef struct {
uint16_t idx[3];
} uint16_3_array_t;

typedef struct ConstGenericStruct_uint16_3 {
uint16_3_array_t data;
} ConstGenericStruct_uint16_3_t;

typedef struct SpecificConstGenericContainer {
ConstGenericStruct_uint8_1_t field1;

ConstGenericStruct_uint8_2_t field2;

ConstGenericStruct_uint16_3_t field3;
} SpecificConstGenericContainer_t;

typedef enum triforce {
TRIFORCE_DIN,
TRIFORCE_FARORE,
Expand Down
75 changes: 75 additions & 0 deletions ffi_tests/generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,47 @@ public unsafe struct AnUnusedStruct_t {
public Wow_t are_you_still_there;
}

[StructLayout(LayoutKind.Sequential, Size = 12)]
public unsafe struct float_3_array_t {
public float _0;
public float _1;
public float _2;
}

[StructLayout(LayoutKind.Sequential, Size = 40)]
public unsafe struct uint64_5_array_t {
public fixed UInt64 arr[5];
}

[StructLayout(LayoutKind.Sequential, Size = 1)]
public unsafe struct uint8_1_array_t {
public fixed byte arr[1];
}

[StructLayout(LayoutKind.Sequential, Size = 2)]
public unsafe struct uint8_1_array_2_array_t {
public uint8_1_array_t _0;
public uint8_1_array_t _1;
}

[StructLayout(LayoutKind.Sequential, Size = 6)]
public unsafe struct uint8_1_array_2_array_3_array_t {
public uint8_1_array_2_array_t _0;
public uint8_1_array_2_array_t _1;
public uint8_1_array_2_array_t _2;
}

[StructLayout(LayoutKind.Sequential, Size = 64)]
public unsafe struct ArraysStruct_t {
public float_3_array_t floats;

public uint64_5_array_t sizes;

public uint8_1_array_2_array_t dim_2;

public uint8_1_array_2_array_3_array_t dim_3;
}

public unsafe partial class Ffi {
public const Int32 FOO = 42;
}
Expand Down Expand Up @@ -66,6 +107,40 @@ public unsafe struct next_generation_t {
public void_ptr_bool_fptr cb;
}

[StructLayout(LayoutKind.Sequential, Size = 1)]
public unsafe struct ConstGenericStruct_uint8_1_t {
public uint8_1_array_t data;
}

[StructLayout(LayoutKind.Sequential, Size = 2)]
public unsafe struct uint8_2_array_t {
public fixed byte arr[2];
}

[StructLayout(LayoutKind.Sequential, Size = 2)]
public unsafe struct ConstGenericStruct_uint8_2_t {
public uint8_2_array_t data;
}

[StructLayout(LayoutKind.Sequential, Size = 6)]
public unsafe struct uint16_3_array_t {
public fixed UInt16 arr[3];
}

[StructLayout(LayoutKind.Sequential, Size = 6)]
public unsafe struct ConstGenericStruct_uint16_3_t {
public uint16_3_array_t data;
}

[StructLayout(LayoutKind.Sequential, Size = 10)]
public unsafe struct SpecificConstGenericContainer_t {
public ConstGenericStruct_uint8_1_t field1;

public ConstGenericStruct_uint8_2_t field2;

public ConstGenericStruct_uint16_3_t field3;
}

/// <summary>
/// Hello, <c>World</c>!
/// </summary>
Expand Down
73 changes: 73 additions & 0 deletions ffi_tests/generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,41 @@ typedef struct AnUnusedStruct {
Wow_t are_you_still_there;
} AnUnusedStruct_t;

typedef struct {
float idx[3];
} float_3_array_t;

typedef struct {
uint64_t idx[5];
} uint64_5_array_t;

typedef struct {
uint8_t idx[1];
} uint8_1_array_t;

typedef struct {
uint8_1_array_t idx[2];
} uint8_1_array_2_array_t;

typedef struct {
uint8_1_array_2_array_t idx[3];
} uint8_1_array_2_array_3_array_t;

/** <No documentation available> */
typedef struct ArraysStruct {
/** <No documentation available> */
float_3_array_t floats;

/** <No documentation available> */
uint64_5_array_t sizes;

/** <No documentation available> */
uint8_1_array_2_array_t dim_2;

/** <No documentation available> */
uint8_1_array_2_array_3_array_t dim_3;
} ArraysStruct_t;

/** <No documentation available> */
#define FOO ((int32_t) 42)

Expand Down Expand Up @@ -76,6 +111,44 @@ typedef struct next_generation {
void * (*cb)(bool);
} next_generation_t;

/** <No documentation available> */
typedef struct ConstGenericStruct_uint8_1 {
/** <No documentation available> */
uint8_1_array_t data;
} ConstGenericStruct_uint8_1_t;

typedef struct {
uint8_t idx[2];
} uint8_2_array_t;

/** <No documentation available> */
typedef struct ConstGenericStruct_uint8_2 {
/** <No documentation available> */
uint8_2_array_t data;
} ConstGenericStruct_uint8_2_t;

typedef struct {
uint16_t idx[3];
} uint16_3_array_t;

/** <No documentation available> */
typedef struct ConstGenericStruct_uint16_3 {
/** <No documentation available> */
uint16_3_array_t data;
} ConstGenericStruct_uint16_3_t;

/** <No documentation available> */
typedef struct SpecificConstGenericContainer {
/** <No documentation available> */
ConstGenericStruct_uint8_1_t field1;

/** <No documentation available> */
ConstGenericStruct_uint8_2_t field2;

/** <No documentation available> */
ConstGenericStruct_uint16_3_t field3;
} SpecificConstGenericContainer_t;

/** \brief
* Hello, `World`!
*/
Expand Down
Loading

0 comments on commit 9bcad86

Please sign in to comment.