summaryrefslogtreecommitdiff
path: root/test_ffi/src/lib.rs
diff options
context:
space:
mode:
authorAapo Alasuutari <aapo.alasuutari@gmail.com>2022-06-20 14:06:04 +0300
committerGitHub <noreply@github.com>2022-06-20 16:36:04 +0530
commit3d6fa64f19e74924813ece5e5fbd53023342bac8 (patch)
tree9786948872549be0a6e44ab769c04a3d474a7774 /test_ffi/src/lib.rs
parent60869c2598321386f57e55537e8c99ed011fbb95 (diff)
feat(ext/ffi): Callbacks (#14663)
This commit adds support for unstable FFI callbacks. A callback is registered using the `Deno.UnsafeCallback` API. The backing memory for the callback can be disposed of using `Deno.UnsafeCallback#close`. It is not safe to pass the callback after calling close. Callbacks from other than the isolate thread are not supported. Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com> Co-authored-by: Bert Belder <bertbelder@gmail.com>
Diffstat (limited to 'test_ffi/src/lib.rs')
-rw-r--r--test_ffi/src/lib.rs225
1 files changed, 225 insertions, 0 deletions
diff --git a/test_ffi/src/lib.rs b/test_ffi/src/lib.rs
index 9a06e29e7..5b813cd01 100644
--- a/test_ffi/src/lib.rs
+++ b/test_ffi/src/lib.rs
@@ -114,8 +114,233 @@ pub extern "C" fn get_sleep_blocking_ptr() -> *const c_void {
}
#[no_mangle]
+pub extern "C" fn call_fn_ptr(func: Option<extern "C" fn()>) {
+ if func.is_none() {
+ return;
+ }
+ let func = func.unwrap();
+ func();
+}
+
+#[no_mangle]
+pub extern "C" fn call_fn_ptr_many_parameters(
+ func: Option<
+ extern "C" fn(u8, i8, u16, i16, u32, i32, u64, i64, f32, f64, *const u8),
+ >,
+) {
+ if func.is_none() {
+ return;
+ }
+ let func = func.unwrap();
+ func(1, -1, 2, -2, 3, -3, 4, -4, 0.5, -0.5, BUFFER.as_ptr());
+}
+
+#[no_mangle]
+pub extern "C" fn call_fn_ptr_return_u8(func: Option<extern "C" fn() -> u8>) {
+ if func.is_none() {
+ return;
+ }
+ let func = func.unwrap();
+ println!("u8: {}", func());
+}
+
+#[allow(clippy::not_unsafe_ptr_arg_deref)]
+#[no_mangle]
+pub extern "C" fn call_fn_ptr_return_buffer(
+ func: Option<extern "C" fn() -> *const u8>,
+) {
+ if func.is_none() {
+ return;
+ }
+ let func = func.unwrap();
+ let ptr = func();
+ let buf = unsafe { std::slice::from_raw_parts(ptr, 8) };
+ println!("buf: {:?}", buf);
+}
+
+static mut STORED_FUNCTION: Option<extern "C" fn()> = None;
+static mut STORED_FUNCTION_2: Option<extern "C" fn(u8) -> u8> = None;
+
+#[no_mangle]
+pub extern "C" fn store_function(func: Option<extern "C" fn()>) {
+ unsafe { STORED_FUNCTION = func };
+ if func.is_none() {
+ println!("STORED_FUNCTION cleared");
+ }
+}
+
+#[no_mangle]
+pub extern "C" fn store_function_2(func: Option<extern "C" fn(u8) -> u8>) {
+ unsafe { STORED_FUNCTION_2 = func };
+ if func.is_none() {
+ println!("STORED_FUNCTION_2 cleared");
+ }
+}
+
+#[no_mangle]
+pub extern "C" fn call_stored_function() {
+ unsafe {
+ if STORED_FUNCTION.is_none() {
+ return;
+ }
+ STORED_FUNCTION.unwrap()();
+ }
+}
+
+#[no_mangle]
+pub extern "C" fn call_stored_function_2(arg: u8) {
+ unsafe {
+ if STORED_FUNCTION_2.is_none() {
+ return;
+ }
+ println!("{}", STORED_FUNCTION_2.unwrap()(arg));
+ }
+}
+
+// FFI performance helper functions
+#[no_mangle]
+pub extern "C" fn nop() {}
+
+#[no_mangle]
+pub extern "C" fn nop_u8(_a: u8) {}
+
+#[no_mangle]
+pub extern "C" fn nop_i8(_a: i8) {}
+
+#[no_mangle]
+pub extern "C" fn nop_u16(_a: u16) {}
+
+#[no_mangle]
+pub extern "C" fn nop_i16(_a: i16) {}
+
+#[no_mangle]
+pub extern "C" fn nop_u32(_a: u32) {}
+
+#[no_mangle]
+pub extern "C" fn nop_i32(_a: i32) {}
+
+#[no_mangle]
+pub extern "C" fn nop_u64(_a: u64) {}
+
+#[no_mangle]
+pub extern "C" fn nop_i64(_a: i64) {}
+
+#[no_mangle]
+pub extern "C" fn nop_usize(_a: usize) {}
+
+#[no_mangle]
+pub extern "C" fn nop_isize(_a: isize) {}
+
+#[no_mangle]
+pub extern "C" fn nop_f32(_a: f32) {}
+
+#[no_mangle]
+pub extern "C" fn nop_f64(_a: f64) {}
+
+#[no_mangle]
+pub extern "C" fn nop_buffer(_buffer: *mut [u8; 8]) {}
+
+#[no_mangle]
+pub extern "C" fn return_u8() -> u8 {
+ 255
+}
+
+#[no_mangle]
+pub extern "C" fn return_i8() -> i8 {
+ -128
+}
+
+#[no_mangle]
+pub extern "C" fn return_u16() -> u16 {
+ 65535
+}
+
+#[no_mangle]
+pub extern "C" fn return_i16() -> i16 {
+ -32768
+}
+
+#[no_mangle]
+pub extern "C" fn return_u32() -> u32 {
+ 4294967295
+}
+
+#[no_mangle]
+pub extern "C" fn return_i32() -> i32 {
+ -2147483648
+}
+
+#[no_mangle]
+pub extern "C" fn return_u64() -> u64 {
+ 18446744073709551615
+}
+
+#[no_mangle]
+pub extern "C" fn return_i64() -> i64 {
+ -9223372036854775808
+}
+
+#[no_mangle]
+pub extern "C" fn return_usize() -> usize {
+ 18446744073709551615
+}
+
+#[no_mangle]
+pub extern "C" fn return_isize() -> isize {
+ -9223372036854775808
+}
+
+#[no_mangle]
+pub extern "C" fn return_f32() -> f32 {
+ #[allow(clippy::excessive_precision)]
+ 0.20298023223876953125
+}
+
+#[no_mangle]
+pub extern "C" fn return_f64() -> f64 {
+ 1e-10
+}
+
+// Parameters iteration
+
+#[no_mangle]
+pub extern "C" fn nop_many_parameters(
+ _: u8,
+ _: i8,
+ _: u16,
+ _: i16,
+ _: u32,
+ _: i32,
+ _: u64,
+ _: i64,
+ _: usize,
+ _: isize,
+ _: f32,
+ _: f64,
+ _: *mut [u8; 8],
+ _: u8,
+ _: i8,
+ _: u16,
+ _: i16,
+ _: u32,
+ _: i32,
+ _: u64,
+ _: i64,
+ _: usize,
+ _: isize,
+ _: f32,
+ _: f64,
+ _: *mut [u8; 8],
+) {
+}
+
+// Statics
+#[no_mangle]
pub static static_u32: u32 = 42;
+#[no_mangle]
+pub static static_i64: i64 = -1242464576485;
+
#[repr(C)]
pub struct Structure {
_data: u32,