diff --git a/CHANGELOG.md b/CHANGELOG.md index 68a9120..3219399 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Change Log All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). +## [Unreleased] +### Fixed +- Long and double arguments to upcalls failed to compile in some cases +- Void return types on upcalls would crash on serialization + ## [0.1.251] - 2021-10-14 ### Fixed - Bug with the inline expansion of `make-serde-wrapper`, make it more maintainable @@ -63,6 +68,7 @@ All notable changes to this project will be documented in this file. This change - Support for serializing and deserializing arbitrary Clojure functions - Support for serializing and deserializing arbitrary Clojure data structures +[Unreleased]: https://github.com/IGJoshua/coffi/compare/v0.1.251...HEAD [0.1.251]: https://github.com/IGJoshua/coffi/compare/v0.1.246...v0.1.251 [0.1.246]: https://github.com/IGJoshua/coffi/compare/v0.1.241...v0.1.246 [0.1.241]: https://github.com/IGJoshua/coffi/compare/v0.1.220...v0.1.241 diff --git a/build.clj b/build.clj index 12135a5..039f034 100644 --- a/build.clj +++ b/build.clj @@ -17,7 +17,7 @@ [clojure.tools.build.api :as b])) (def lib-coord 'org.suskalo/coffi) -(def version (format "0.1.%s" (b/git-count-revs nil))) +(def version (format "0.2.%s" (b/git-count-revs nil))) (def resource-dirs ["resources/"]) diff --git a/src/clj/coffi/ffi.clj b/src/clj/coffi/ffi.clj index b742575..4693e0b 100644 --- a/src/clj/coffi/ffi.clj +++ b/src/clj/coffi/ffi.clj @@ -459,6 +459,10 @@ ::mem/double :dreturn ::mem/void :return}) +(def ^:private double-sized? + "Set of primitive types which require 2 indices in the constant pool." + #{::mem/double ::mem/long ::mem/long-long}) + (defn- upcall-class "Constructs a class definition for a class with a single method, `upcall`, which boxes any primitives passed to it and calls a closed over [[IFn]]." @@ -482,11 +486,18 @@ (insn-layout ret-type)) :emit [[:aload 0] [:getfield :this "upcall_ifn" IFn] - (map-indexed - (fn [idx arg] - [[(load-instructions (mem/primitive-type arg) :aload) (inc idx)] - (to-object-asm arg)]) - arg-types) + (loop [types arg-types + acc [] + idx 1] + (if (seq types) + (let [prim (mem/primitive-type (first types))] + (recur (rest types) + (conj acc [[(load-instructions prim) idx] + (to-object-asm (first types))]) + (cond-> (inc idx) + (double-sized? prim) + inc))) + acc)) [:invokeinterface IFn "invoke" (repeat (inc (count arg-types)) Object)] (to-prim-asm ret-type) [(return-for-type ret-type :areturn)]]}]}) @@ -538,8 +549,7 @@ (method-type arg-types ret-type) (function-descriptor arg-types ret-type)) (downcall-fn arg-types ret-type) - (cond-> - (not raw-fn?) (make-serde-wrapper arg-types ret-type))) + (cond-> (not raw-fn?) (make-serde-wrapper arg-types ret-type))) assoc ::address addr))) ;;; Static memory access diff --git a/src/clj/coffi/mem.clj b/src/clj/coffi/mem.clj index 8e87d4a..b003216 100644 --- a/src/clj/coffi/mem.clj +++ b/src/clj/coffi/mem.clj @@ -417,6 +417,10 @@ obj) (MemoryAddress/NULL))) +(defmethod serialize* ::void + [_obj _type _scope] + nil) + (defmulti serialize-into "Writes a serialized version of the `obj` to the given `segment`.