Values that are set into library objects (mainly callbacks) are kept around

so they are not GC'ed.

original commit: bd52ddc5ee619a056d93a118aacefc4dc2f46e1f
This commit is contained in:
Eli Barzilay 2004-06-06 07:56:32 +00:00
parent 3dbb7a7670
commit 85dedecbf3

View File

@ -23,6 +23,7 @@
[(_ name expr) [(_ name expr)
(begin (provide name) (define name expr))])) (begin (provide name) (define name expr))]))
;; ----------------------------------------------------------------------------
;; Function type ;; Function type
;; internal, used by _fun ;; internal, used by _fun
@ -210,6 +211,7 @@
#,output-expr))))) #,output-expr)))))
#`(ffi-fun (list #,@(filtered-map car inputs)) #,(car output))))])) #`(ffi-fun (list #,@(filtered-map car inputs)) #,(car output))))]))
;; ----------------------------------------------------------------------------
;; String types ;; String types
;; The internal _string type uses the native ucs-4 encoding, also providing a ;; The internal _string type uses the native ucs-4 encoding, also providing a
@ -251,6 +253,9 @@
(define* _string/eof (define* _string/eof
(make-ctype _string #f (lambda (x) (or x eof)))) (make-ctype _string #f (lambda (x) (or x eof))))
;; ----------------------------------------------------------------------------
;; Utility types
;; Call this with a name (symbol) and a list of symbols, where a symbol can be ;; Call this with a name (symbol) and a list of symbols, where a symbol can be
;; followed by a '= and an integer to have a similar effect of C's enum. ;; followed by a '= and an integer to have a similar effect of C's enum.
(define (_enum* name symbols) (define (_enum* name symbols)
@ -325,6 +330,7 @@
[(_ syms) (with-syntax ([name (syntax-local-name)]) [(_ syms) (with-syntax ([name (syntax-local-name)])
#'(_bitmask* 'name syms))])) #'(_bitmask* 'name syms))]))
;; ----------------------------------------------------------------------------
;; Custom function type macros ;; Custom function type macros
;; These macros get expanded by the _fun type. They can expand to a form that ;; These macros get expanded by the _fun type. They can expand to a form that
@ -413,20 +419,40 @@
;; post is needed when this is used as a function output type ;; post is needed when this is used as a function output type
post: (x => (make-sized-byte-string x n)))])) post: (x => (make-sized-byte-string x n)))]))
;; Utilities ;; ----------------------------------------------------------------------------
;; Misc utilities
;; Easy wrappers for retrieving and setting library values ;; Wrappers for retrieving and setting library values
;; Used to convert strings and symbols to a byte-string that names an object
(define (get-ffi-obj-name name objname . args) (define (get-ffi-obj-name name objname . args)
(cond [(bytes? objname) objname] (cond [(bytes? objname) objname]
[(symbol? objname) (get-ffi-obj-name name (symbol->string objname))] [(symbol? objname) (get-ffi-obj-name name (symbol->string objname))]
[(string? objname) (string->bytes/utf-8 objname)] [(string? objname) (string->bytes/utf-8 objname)]
[else (apply raise-type-error name "object-name" 0 objname args)])) [else (apply raise-type-error name "object-name" 0 objname args)]))
(define* (get-ffi-obj name lib type) (define* (get-ffi-obj name lib type)
(ptr-ref (ffi-obj (get-ffi-obj-name 'get-ffi-obj name lib type) lib) (ptr-ref (ffi-obj (get-ffi-obj-name 'get-ffi-obj name lib type) lib)
type)) type))
;; It is important to use the set-ffi-obj! wrapper because it takes care of
;; keeping a handle on the object -- otherwise, setting a callback hook will
;; crash when the Scheme function is gone.
(define* (set-ffi-obj! name lib type new) (define* (set-ffi-obj! name lib type new)
(ptr-set! (ffi-obj (get-ffi-obj-name 'get-ffi-obj name lib type new) lib) (let ([obj (ffi-obj (get-ffi-obj-name 'get-ffi-obj name lib type new) lib)])
type new)) (let-values ([(new type) (get-lowlevel-object new type)])
(hash-table-put! ffi-objects-ref-table obj new)
(ptr-set! obj type new))))
(define ffi-objects-ref-table (make-hash-table))
;; Used by set-ffi-obj! to get the actual value so it can be kept around
(define (get-lowlevel-object x type)
(let ([basetype (ctype-basetype type)])
(if basetype
(let ([s->c (ctype-scheme->c type)])
(get-lowlevel-object (if s->c (s->c x) x) basetype))
(values x type))))
;; Converting Scheme lists to/from C vectors (going back requires a length) ;; Converting Scheme lists to/from C vectors (going back requires a length)
(define* (list->cblock l type) (define* (list->cblock l type)
@ -485,7 +511,8 @@
regexp-replace regexp-replace*) regexp-replace regexp-replace*)
(caar rs) str (cadar rs)) (cdr rs))))) (caar rs) str (cadar rs)) (cdr rs)))))
;; Safe memory blocks ;; ----------------------------------------------------------------------------
;; Safe raw vectors
(define-struct cvector (ptr type length)) (define-struct cvector (ptr type length))
@ -522,6 +549,7 @@
(define* (list->cvector l type) (define* (list->cvector l type)
(make-cvector (list->cblock l type) type (length l))) (make-cvector (list->cblock l type) type (length l)))
;; ----------------------------------------------------------------------------
;; SRFI-4 implementation ;; SRFI-4 implementation
(define-syntax (make-srfi-4 stx) (define-syntax (make-srfi-4 stx)
@ -593,6 +621,7 @@
(make-srfi-4 f32 _float) (make-srfi-4 f32 _float)
(make-srfi-4 f64 _double) (make-srfi-4 f64 _double)
;; ----------------------------------------------------------------------------
;; Tagged pointers ;; Tagged pointers
;; This is a kind of a pointer that gets a specific tag when converted to ;; This is a kind of a pointer that gets a specific tag when converted to
@ -638,6 +667,7 @@
TYPE-tag)))))] TYPE-tag)))))]
[(_ _TYPE) #'(_ _TYPE _pointer)])) [(_ _TYPE) #'(_ _TYPE _pointer)]))
;; ----------------------------------------------------------------------------
;; Struct wrappers ;; Struct wrappers
(define (compute-offsets types) (define (compute-offsets types)