Carp/test/managed.carp

67 lines
1.6 KiB
Plaintext
Raw Normal View History

(load-and-use Test)
(defn assert-memory-balance [state f expected-balance descr]
(do
(Debug.reset-memory-balance!)
(f)
(assert-equal state expected-balance (Debug.memory-balance) descr)))
(register-type A "void*")
(register-type B "void*")
(defmodule A
(deftemplate init (Fn [] A)
"void* $NAME()" "$DECL { return CARP_MALLOC(128); }")
(deftemplate copy (Fn [&A] A)
"void* $NAME(void **p)" "$DECL { return CARP_MALLOC(128); }")
(implements copy A.copy)
(deftemplate delete (Fn [A] ())
"void $NAME(void *p)" "$DECL { CARP_FREE(p); }")
(implements delete A.delete))
(defmodule B
(deftemplate init (Fn [] B)
"void* $NAME()" "$DECL { return CARP_MALLOC(128); }")
(deftemplate copy (Fn [&B] B)
"void* $NAME(void **p)" "$DECL { return CARP_MALLOC(128); }")
(implements copy B.copy)
;; 'B' does *not* implement delete!
;; The user would have to call delete / free on it manually to avoid a leak.
)
(defn f-a []
(let [a (A)]
()))
(defn f-b []
(let [b (B)]
()))
(defn f-copy-a []
(let [a (A)
a2 @&a]
()))
(defn f-copy-b []
(let [b (B)
b2 @&b]
()))
(eval ;; temporary workaround to force evaluation of top-level 'when'
(when (not (managed? A))
(macro-error "Fail - A should be managed.")))
(eval
(when (managed? B)
(macro-error "Fail - B should not be managed.")))
(deftest test
(assert-memory-balance test f-a 0l "f-a correct, does not leak")
(assert-memory-balance test f-b 1l "f-b correct, leaks 1 value")
(assert-memory-balance test f-copy-a 0l "f-copy-a correct, does not leak")
(assert-memory-balance test f-copy-b 2l "f-copy-b correct, leaks 2 values"))