From fa40902ce9671ca0711ce7852d7adcd88c7c20b3 Mon Sep 17 00:00:00 2001 From: Joshua Suskalo Date: Mon, 31 Oct 2022 13:23:31 -0500 Subject: [PATCH] Fix bug with inlined serdes causing complex pointer serdes to fail --- CHANGELOG.md | 1 + src/clj/coffi/ffi.clj | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfea49d..e706cb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. This change - New function to allow getting the backing memory segment of a `coffi.ffi.StaticVariable`, to replace the `Addressable` implementation lost in the migration to JDK 18 ### Fixed +- Bug where inline serde functions would fail on complex pointer types - Bug where padding in structs may be increased when fields have alignments less than their size - Bug where pointer alignment was incorrectly defined diff --git a/src/clj/coffi/ffi.clj b/src/clj/coffi/ffi.clj index f673dea..b95119b 100644 --- a/src/clj/coffi/ffi.clj +++ b/src/clj/coffi/ffi.clj @@ -251,10 +251,19 @@ ;; argument is not converted to [[MemoryAddress/NULL]] if it's ;; considered primitive. simple-args? (when const-args? - (every? mem/primitive? arg-types)) + (and (every? mem/primitive? arg-types) + ;; NOTE(Joshua): Pointer types with serdes (e.g. [::mem/pointer ::mem/int]) + ;; still require a scope, making them not qualify as "simple". + (every? keyword? (filter (comp #{::mem/pointer} mem/primitive-type) arg-types)))) const-ret? (s/valid? ::mem/type ret-type) - primitive-ret? (and const-ret? (or (mem/primitive? ret-type) - (#{::mem/void} ret-type))) + primitive-ret? (and const-ret? + (or (and (mem/primitive? ret-type) + ;; NOTE(Joshua): Pointer types with serdes require deserializing the + ;; return value, but don't require passing a scope to the downcall, + ;; making them cause the return to not be primitive, but it may still + ;; be "simple". + (or (keyword? ret-type) (not (#{::mem/pointer} (mem/primitive-type ret-type))))) + (#{::mem/void} ret-type))) simple-ret? (and const-ret? (mem/primitive-type ret-type)) no-serde? (and const-args? (empty? arg-types) primitive-ret?)]