Skip to content

Commit

Permalink
Add support for Julia enums. Fix several bugs related to types with p…
Browse files Browse the repository at this point in the history
…arameters. (#137)
  • Loading branch information
Taaitaaiger authored Jul 8, 2024
1 parent 057ae08 commit 4c1d991
Show file tree
Hide file tree
Showing 37 changed files with 1,171 additions and 279 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#### v0.21

- Support generating bindings for Julia enums with integer base types in combination with JlrsCore.Reflect and the `Enum` derive macro.

- Fix several bugs related to how type parameters are handled in code generated by `julia_module!`.

#### v0.20

- Add support for Julia 1.11. Bump MSRV to 1.77.
Expand Down
2 changes: 1 addition & 1 deletion benches/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2021"
lto = ["jlrs/lto"]

[dependencies]
jlrs = { version = "0.20", path = "../jlrs", features = ["full"] }
jlrs = { version = "0.21", path = "../jlrs", features = ["full"] }

[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports", "async"] }
Expand Down
2 changes: 1 addition & 1 deletion examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ publish = false
edition = "2021"

[dev-dependencies]
jlrs = { version = "0.20.0", path = "../jlrs", features = ["full"] }
jlrs = { version = "0.21.0", path = "../jlrs", features = ["full"] }
tokio = { version = "1", features = ["macros", "rt"]}

[[example]]
Expand Down
2 changes: 1 addition & 1 deletion jl_sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jl-sys"
version = "0.24.0"
version = "0.25.0"
authors = ["Thomas van Doornmalen <thomas.vandoornmalen@gmail.com>"]
description = """
jl-sys contains the generated bindings for the Julia C API used by jlrs.
Expand Down
36 changes: 36 additions & 0 deletions jl_sys/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//
// Julia is distributed without an import lib, so we need raw dylib linkage on Windows when we're
// building with the MSVC toolchain or with the "BinaryBuilder toolchain".

#[cfg_attr(
all(
any(windows, target_os = "windows", feature = "windows"),
Expand Down Expand Up @@ -1053,6 +1054,35 @@ extern "C" {
dims: *mut usize,
ndims: usize,
) -> *mut crate::types::jl_array_t;

#[cfg(not(any(
feature = "julia-1-6",
feature = "julia-1-7",
feature = "julia-1-8",
feature = "julia-1-9",
feature = "julia-1-10",
feature = "julia-1-11",
)))]
pub fn jl_get_binding_wr(
m: *mut crate::types::jl_module_t,
var: *mut crate::types::jl_sym_t,
alloc: std::ffi::c_int,
) -> *mut std::ffi::c_void;

#[cfg(not(any(
feature = "julia-1-6",
feature = "julia-1-7",
feature = "julia-1-8",
feature = "julia-1-9",
feature = "julia-1-10",
feature = "julia-1-11",
)))]
pub fn jl_checked_assignment(
m: *mut std::ffi::c_void,
m: *mut crate::types::jl_module_t,
var: *mut crate::types::jl_sym_t,
rhs: *mut crate::types::jl_value_t,
) -> *mut std::ffi::c_void;
}

// jlrs_cc functions
Expand Down Expand Up @@ -1341,4 +1371,10 @@ extern "C" {
) -> *mut std::ffi::c_char;

pub fn jlrs_init_missing_functions();

pub fn jlrs_set_global(
m: *mut crate::types::jl_module_t,
var: *mut crate::types::jl_sym_t,
val: *mut crate::types::jl_value_t,
);
}
2 changes: 1 addition & 1 deletion jl_sys/src/gc_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ impl GcStack {

// Safety: Julia must have been initialized, must only be called from a thread known to Julia via `jlrs_unsized_scope`.
#[inline]
unsafe extern "C" fn unsized_scope_trampoline<T, F>(
unsafe extern "C-unwind" fn unsized_scope_trampoline<T, F>(
frame: *mut jl_gcframe_t,
callback: *mut c_void,
result: *mut c_void,
Expand Down
10 changes: 10 additions & 0 deletions jl_sys/src/jlrs_cc/jlrs_cc_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,16 @@ extern "C"
return jl_genericmemory_how(a->ref.mem);
#else
return (int)a->flags.how;
#endif
}

void jlrs_set_global(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT)
{
#if JULIA_VERSION_MINOR >= 12
jl_binding_t *bp = jl_get_binding_wr(m, var, 1);
jl_checked_assignment(bp, m, var, val);
#else
jl_set_global(m, var, val);
#endif
}
#ifdef __cplusplus
Expand Down
2 changes: 2 additions & 0 deletions jl_sys/src/jlrs_cc/jlrs_cc_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ extern "C" {
#if JULIA_VERSION_MINOR <= 10
const jl_datatype_layout_t *jl_datatype_layout(jl_datatype_t *t);
#endif

void jlrs_set_global(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT);
#ifdef __cplusplus
}
#endif // __cplusplus
Expand Down
1 change: 0 additions & 1 deletion jl_sys/src/jlrs_cc/jlrs_cc_hacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ extern "C"
#if JULIA_VERSION_MINOR >= 7
void jlrs_lock_value(jl_value_t *v)
{

assert(jl_lock_value_func && "jl_lock_value_func not loaded");
jl_lock_value_func(v);
}
Expand Down
27 changes: 12 additions & 15 deletions jl_sys/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,23 +71,17 @@ impl jl_gcframe_t {

#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[cfg(not(any(
feature = "julia-1-6",
feature = "julia-1-7",
feature = "julia-1-8",
feature = "julia-1-9",
feature = "julia-1-10",
)))]
pub struct jl_genericmemory_t {
_unused: [u8; 0],
}

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct jl_genericmemoryref_t {
ptr_or_offset: *mut c_void,
mem: *mut jl_genericmemory_t,
}

#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct jl_handler_t {
_unused: [u8; 0],
}

pub type jl_markfunc_t =
unsafe extern "C" fn(ptls: *mut jl_tls_states_t, obj: *mut jl_value_t) -> usize;
pub type jl_sweepfunc_t = unsafe extern "C" fn(obj: *mut jl_value_t);
Expand All @@ -107,8 +101,11 @@ pub struct jlrs_catch_t {

pub type jlrs_try_catch_trampoline_t =
unsafe extern "C" fn(callback: *mut c_void, result: *mut c_void) -> jlrs_catch_t;
pub type jlrs_unsized_scope_trampoline_t =
unsafe extern "C" fn(frame: *mut jl_gcframe_t, callback: *mut c_void, result: *mut c_void);
pub type jlrs_unsized_scope_trampoline_t = unsafe extern "C-unwind" fn(
frame: *mut jl_gcframe_t,
callback: *mut c_void,
result: *mut c_void,
);

#[repr(C)]
#[derive(Copy, Clone, Debug)]
Expand Down
8 changes: 4 additions & 4 deletions jlrs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jlrs"
version = "0.20.0"
version = "0.21.0"
authors = ["Thomas van Doornmalen <thomas.vandoornmalen@gmail.com>"]
description = """
jlrs provides bindings to the Julia C API that enable Julia code to be called from Rust and more.
Expand Down Expand Up @@ -99,13 +99,13 @@ docs = ["jl-sys/docs", "full", "julia-1-12"]

[dependencies]
cfg-if = "1"
jl-sys = { version = "0.24", path = "../jl_sys" }
jlrs-macros = { version = "0.3", path = "../jlrs_macros" }
jl-sys = { version = "0.25", path = "../jl_sys" }
jlrs-macros = { version = "0.4", path = "../jlrs_macros" }
smallvec = {version = "1", features = ["const_generics"]}
thiserror = "1"
once_cell = "1"
parking_lot = "0.12"
rustc-hash = "1"
rustc-hash = "2"
lock_api = "0.4"
fnv = "1"
atomic = "0.6"
Expand Down
72 changes: 72 additions & 0 deletions jlrs/src/data/layout/julia_enum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#![allow(unused)]

use std::mem::size_of;

use crate::{
data::types::{
abstract_type::{AbstractChar, AbstractFloat, Integer, Signed, Unsigned},
construct_type::ConstructType,
},
inline_static_ref,
prelude::{Target, Value},
};

pub trait PrimitiveType: Copy {
const N_BITS: usize;
type Super: ConstructType;
}

pub trait IntegerType: PrimitiveType {}

macro_rules! impl_primitive_type {
($ty:ty, $super:ty) => {
impl PrimitiveType for $ty {
const N_BITS: usize = size_of::<Self>();
type Super = $super;
}
};
}

impl_primitive_type!(u8, Unsigned);
impl_primitive_type!(u16, Unsigned);
impl_primitive_type!(u32, Unsigned);
impl_primitive_type!(u64, Unsigned);
impl_primitive_type!(usize, Unsigned);
impl_primitive_type!(i8, Signed);
impl_primitive_type!(i16, Signed);
impl_primitive_type!(i32, Signed);
impl_primitive_type!(i64, Signed);
impl_primitive_type!(isize, Signed);

impl IntegerType for u8 {}
impl IntegerType for u16 {}
impl IntegerType for u32 {}
impl IntegerType for u64 {}
impl IntegerType for usize {}
impl IntegerType for i8 {}
impl IntegerType for i16 {}
impl IntegerType for i32 {}
impl IntegerType for i64 {}
impl IntegerType for isize {}

impl_primitive_type!(bool, Integer);
impl_primitive_type!(super::bool::Bool, Integer);

impl IntegerType for bool {}
impl IntegerType for char {}

impl_primitive_type!(char, AbstractChar);
impl_primitive_type!(super::char::Char, AbstractChar);

impl IntegerType for super::bool::Bool {}
impl IntegerType for super::char::Char {}

// impl_primitive_type!(f16, AbstractFloat);
impl_primitive_type!(f32, AbstractFloat);
impl_primitive_type!(f64, AbstractFloat);

pub unsafe trait Enum {
type Super: IntegerType;
fn as_value<'target, Tgt: Target<'target>>(&self, _: &Tgt) -> Value<'target, 'static>;
fn as_super(&self) -> Self::Super;
}
1 change: 1 addition & 0 deletions jlrs/src/data/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub mod complex;
#[cfg(feature = "f16")]
pub mod f16;
pub mod is_bits;
pub mod julia_enum;
pub mod nothing;
pub mod tuple;
pub mod typed_layout;
Expand Down
Loading

0 comments on commit 4c1d991

Please sign in to comment.