1
;; -*- coding: utf-8; mode: scheme -*-
5
;; Copyright (c) 2006 KOGURO, Naoki (naoki@koguro.net)
7
;; Permission is hereby granted, free of charge, to any person
8
;; obtaining a copy of this software and associated
9
;; documentation files (the "Software"), to deal in the
10
;; Software without restriction, including without limitation
11
;; the rights to use, copy, modify, merge, publish, distribute,
12
;; sublicense, and/or sell copies of the Software, and to
13
;; permit persons to whom the Software is furnished to do so,
14
;; subject to the following conditions:
16
;; The above copyright notice and this permission notice shall
17
;; be included in all copies or substantial portions of the
20
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
21
;; KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
22
;; WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23
;; PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
24
;; OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25
;; OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
26
;; OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27
;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
;; $Id: c-ffilib.stub 379 2007-01-02 13:58:58Z naoki $
35
(define-enum FFI_BAD_TYPEDEF)
36
(define-enum FFI_BAD_ABI)
38
(define-type <ffi-type>
40
"ffi_type" ; description
41
"SCM_FFI_TYPEP" ; c-predicate
42
"SCM_FFI_TYPE_DATA" ; unboxer
43
"SCM_MAKE_FFI_TYPE" ; boxer
46
(define-type <ffi-cif>
48
"ffi_cif" ; description
49
"SCM_FFI_CIFP" ; c-predicate
50
"SCM_FFI_CIF_DATA" ; unboxer
51
"SCM_MAKE_FFI_CIF" ; boxer
54
(define-type <ffi-closure>
55
"ffi_closure*" ; c-type
56
"ffi_closure" ; description
57
"SCM_FFI_CLOSUREP" ; c-predicate
58
"SCM_FFI_CLOSURE_DATA" ; unboxer
59
"SCM_MAKE_FFI_CLOSURE" ; boxer
62
(define-type <uvector> "ScmUVector*" #f "SCM_UVECTORP" "SCM_UVECTOR")
64
(define-cclass <ffi-type> :built-in
65
"ScmFFIType*" "Scm_FFITypeClass"
68
(alignment :type <ushort>)
69
(type :type <ushort>)))
71
(define-cclass <ffi-cif> :built-in
72
"ScmFFICif*" "Scm_FFICifClass"
76
(define-cclass <ffi-closure> :built-in
77
"ScmFFIClosure*" "Scm_FFIClosureClass"
81
(define-cproc ffi-type-void ()
82
(code "SCM_RETURN(SCM_MAKE_FFI_TYPE(&ffi_type_void));"))
84
(define-cproc ffi-type-float ()
85
(code "SCM_RETURN(SCM_MAKE_FFI_TYPE(&ffi_type_float));"))
87
(define-cproc ffi-type-double ()
88
(code "SCM_RETURN(SCM_MAKE_FFI_TYPE(&ffi_type_double));"))
90
(define-cproc ffi-type-longdouble ()
91
(code "SCM_RETURN(SCM_MAKE_FFI_TYPE(&ffi_type_longdouble));"))
93
(define-cproc ffi-type-pointer ()
94
(code "SCM_RETURN(SCM_MAKE_FFI_TYPE(&ffi_type_pointer));"))
96
(define-cproc ffi-type-uchar ()
97
(code "SCM_RETURN(Scm_GetUnsignedFFIType(sizeof(unsigned char)));"))
99
(define-cproc ffi-type-schar ()
100
(code "SCM_RETURN(Scm_GetSignedFFIType(sizeof(signed char)));"))
102
(define-cproc ffi-type-ushort ()
103
(code "SCM_RETURN(Scm_GetUnsignedFFIType(sizeof(unsigned short)));"))
105
(define-cproc ffi-type-sshort ()
106
(code "SCM_RETURN(Scm_GetSignedFFIType(sizeof(signed short)));"))
108
(define-cproc ffi-type-uint ()
109
(code "SCM_RETURN(Scm_GetUnsignedFFIType(sizeof(unsigned int)));"))
111
(define-cproc ffi-type-sint ()
112
(code "SCM_RETURN(Scm_GetSignedFFIType(sizeof(signed int)));"))
114
(define-cproc ffi-type-ulong ()
115
(code "SCM_RETURN(Scm_GetUnsignedFFIType(sizeof(unsigned long)));"))
117
(define-cproc ffi-type-slong ()
118
(code "SCM_RETURN(Scm_GetSignedFFIType(sizeof(signed long)));"))
120
(define-cproc ffi-type-ulonglong ()
121
(code "SCM_RETURN(Scm_GetUnsignedFFIType(sizeof(unsigned long long)));"))
123
(define-cproc ffi-type-slonglong ()
124
(code "SCM_RETURN(Scm_GetSignedFFIType(sizeof(signed long long)));"))
126
(define-cproc ffi-prep-cif (rtype::<ffi-type> arglist::<list>)
127
(call "Scm_FFIPrepCIF"))
129
(define-cproc make-ffi-array-type (type::<ffi-type> size::<long>)
130
(call "Scm_MakeFFIArrayType"))
132
(define-cproc make-ffi-struct-type (elementlist::<list>)
133
(call "Scm_MakeFFIStructType"))
135
(define-cproc ffi-call (cif::<ffi-cif> fnPtrObj rvaluePtrObj avalues::<list>)
136
(call "Scm_FFICall"))
138
(define-cproc ffi-prep-closure (cif::<ffi-cif> proc::<procedure>)
139
(call "Scm_FFIPrepClosure"))
145
(define-cproc make-u8vector-nonatomic (size::<fixnum>)
146
(code "unsigned char *p = SCM_NEW2(unsigned char*, size);"
147
"SCM_RETURN(Scm_MakeU8VectorFromArrayShared(size, p));"))
149
(define-cproc null-ptr? (ptr)
150
(code "SCM_RETURN(SCM_MAKE_BOOL(BASIC_POINTERP(ptr) && POINTER_DATA(ptr) == NULL));"))
152
(define-cproc %ptr (obj)
153
(code "SCM_RETURN(MAKE_POINTER(PTR_CLASS(SCM_CLASS_OF(obj)), SCM_UVECTOR_ELEMENTS(BUFFER_OF(obj))));"))
155
(define-cproc %ptr-uvector (ptrClass uvec::<uvector>)
156
(code "SCM_RETURN(MAKE_POINTER(ptrClass, SCM_UVECTOR_ELEMENTS(uvec)));"))
158
(define-cproc %deref (ptrObj)
161
(define-cproc ptr->string (ptrObj)
162
(code "SCM_RETURN(SCM_MAKE_STR_IMMUTABLE((const char*) POINTER_DATA(ptrObj)));"))
164
(define-cproc %expand-u8vector (buf::<uvector> size::<long>)
165
(code "SCM_RETURN(Scm_MakeU8VectorFromArrayShared(size, SCM_U8VECTOR_ELEMENTS(buf)));"))
167
(define-cproc make-null-ptr ()
168
(code "SCM_RETURN(MAKE_VOID_POINTER(NULL));"))
171
static void finalize_pointer(ScmObj obj, void *data)
173
static ScmObj finalizeof_proc = SCM_FALSE;
174
ScmObj finalize_proc;
176
if (SCM_FALSEP(finalizeof_proc)) {
177
finalizeof_proc = SCM_SYMBOL_VALUE(MODULE_NAME, \"finalizer-of\");
180
finalize_proc = Scm_ApplyRec(finalizeof_proc, SCM_LIST1(obj));
181
if (!SCM_FALSEP(finalize_proc)) {
182
Scm_ApplyRec(finalize_proc, SCM_LIST1(obj));
184
Scm_UnregisterFinalizer(obj);
188
(define-cproc %register-finalizer! (ptrobj)
189
"if (!POINTERP(ptrobj)) {
190
Scm_Error(\"<c-ptr> required, but got %S\", ptrobj);
192
Scm_RegisterFinalizer(ptrobj, finalize_pointer, NULL);
193
SCM_RETURN(SCM_UNDEFINED);")
195
(define-cproc %unregister-finalizer! (ptrobj)
196
"if (!POINTERP(ptrobj)) {
197
Scm_Error(\"<c-ptr> required, but got %S\", ptrobj);
199
Scm_UnregisterFinalizer(ptrobj);
200
SCM_RETURN(SCM_UNDEFINED);")
202
(define-cproc foreign-pointer->c-ptr (ptrClass fptr::<foreign-pointer>)
203
(code "SCM_RETURN(MAKE_POINTER(ptrClass, fptr->ptr));"))
206
;; dlopen, dlsym, dlclose
208
(define-enum RTLD_LAZY)
209
(define-enum RTLD_NOW)
210
(define-enum RTLD_GLOBAL)
211
(define-enum RTLD_LOCAL)
213
(define-cproc dlopen (path::<const-cstring> mode::<fixnum>)
214
(code "void *handle = dlopen(path, mode);"
216
" SCM_RETURN(MAKE_VOID_POINTER(handle));"
218
" SCM_RETURN(SCM_FALSE);"
221
(define-cproc dlsym (handle symbol::<const-cstring>)
222
(code "void *ptr = dlsym(POINTER_DATA(handle), symbol);"
224
" SCM_RETURN(MAKE_VOID_POINTER(ptr));"
226
" SCM_RETURN(SCM_FALSE);"
229
(define-cproc dlsym-default (symbol::<const-cstring>)
230
(code "void *ptr = dlsym(RTLD_DEFAULT, symbol);"
232
" SCM_RETURN(MAKE_VOID_POINTER(ptr));"
234
" SCM_RETURN(SCM_FALSE);"
237
(define-cproc dlerror ()
238
(code "const char *errmsg = dlerror();"
240
" SCM_RETURN(SCM_MAKE_STR_IMMUTABLE(errmsg));"
242
" SCM_RETURN(SCM_FALSE);"
245
(define-cproc dlclose (handle)
246
(code "SCM_RETURN(SCM_MAKE_INT(dlclose(POINTER_DATA(handle))));"))
251
(define-cproc big-endian? ()
252
(code "#ifdef WORDS_BIGENDIAN"
253
"SCM_RETURN(SCM_TRUE);"
255
"SCM_RETURN(SCM_FALSE);"
258
(define-cproc objc-string (ptrClass str::<const-cstring>)
259
(code "#ifdef __OBJC__"
260
"NSString *nsstr = [NSString stringWithCString:str encoding:OBJC_STRING_ENCODING];"
261
"SCM_RETURN(MAKE_POINTER(ptrClass, nsstr));"
263
"Scm_Error(\"Unsupported operation 'objc-string'\");"