change _pointer to mean a reference to non-GCed memory; add _gcpointer (v4.2.2.6)

svn: r16546
This commit is contained in:
Matthew Flatt 2009-11-04 19:28:04 +00:00
parent 4edc044cb6
commit c49b22fa2c
21 changed files with 285 additions and 48 deletions

View File

@ -62,13 +62,13 @@
(provide* ctype-sizeof ctype-alignof compiler-sizeof (provide* ctype-sizeof ctype-alignof compiler-sizeof
(unsafe malloc) (unsafe free) (unsafe end-stubborn-change) (unsafe malloc) (unsafe free) (unsafe end-stubborn-change)
cpointer? ptr-equal? ptr-add (unsafe ptr-ref) (unsafe ptr-set!) cpointer? ptr-equal? ptr-add (unsafe ptr-ref) (unsafe ptr-set!) (unsafe cast)
ptr-offset ptr-add! offset-ptr? set-ptr-offset! ptr-offset ptr-add! offset-ptr? set-ptr-offset!
ctype? make-ctype make-cstruct-type (unsafe make-sized-byte-string) ctype->layout ctype? make-ctype make-cstruct-type (unsafe make-sized-byte-string) ctype->layout
_void _int8 _uint8 _int16 _uint16 _int32 _uint32 _int64 _uint64 _void _int8 _uint8 _int16 _uint16 _int32 _uint32 _int64 _uint64
_fixint _ufixint _fixnum _ufixnum _fixint _ufixint _fixnum _ufixnum
_float _double _double* _float _double _double*
_bool _pointer _scheme _fpointer function-ptr _bool _pointer _gcpointer _scheme _fpointer function-ptr
(unsafe memcpy) (unsafe memmove) (unsafe memset) (unsafe memcpy) (unsafe memmove) (unsafe memset)
(unsafe malloc-immobile-cell) (unsafe free-immobile-cell)) (unsafe malloc-immobile-cell) (unsafe free-immobile-cell))
@ -1257,6 +1257,49 @@
;; Similar to the above, but can tolerate null pointers (#f). ;; Similar to the above, but can tolerate null pointers (#f).
(define* _cpointer/null (cpointer-maker #t)) (define* _cpointer/null (cpointer-maker #t))
(define (cast p from-type to-type)
(unless (ctype? from-type)
(raise-type-error 'cast "ctype" from-type))
(unless (ctype? to-type)
(raise-type-error 'cast "ctype" to-type))
(unless (= (ctype-sizeof to-type)
(ctype-sizeof from-type))
(raise-mismatch-error (format "representation sizes of types differ: ~e to "
from-type)
to-type))
(let ([p2 (malloc from-type)])
(ptr-set! p2 from-type p)
(ptr-ref p2 to-type)))
(define* (_or-null ctype)
(let ([coretype (ctype-coretype ctype)])
(unless (memq coretype '(pointer gcpointer fpointer))
(raise-type-error '_or-null "ctype buit on pointer, gcpointer, or fpointer" ctype))
(make-ctype
(case coretype
[(pointer) _pointer]
[(gcpointer) _gcpointer]
[(fpointer) _fpointer])
(lambda (v) (and v (cast _pointer v)))
(lambda (v) (and v (cast ctype v))))))
(define* (_gcable ctype)
(unless (memq (ctype-coretype ctype) '(pointer gcpointer))
(raise-type-error '_or-null "pointer ctype" ctype))
(let loop ([ctype ctype])
(if (eq? ctype 'pointer)
_gcpointer
(make-ctype
(loop (ctype-basetype ctype))
(ctype-scheme->c ctype)
(ctype-c->scheme ctype)))))
(define (ctype-coretype c)
(let loop ([c (ctype-basetype c)])
(if (symbol? c)
c
(loop c))))
;; A macro version of the above two functions, using the defined name for a tag ;; A macro version of the above two functions, using the defined name for a tag
;; string, and defining a predicate too. The name should look like `_foo', the ;; string, and defining a predicate too. The name should look like `_foo', the
;; predicate will be `foo?', and the tag will be "foo". In addition, `foo-tag' ;; predicate will be `foo?', and the tag will be "foo". In addition, `foo-tag'

View File

@ -9,12 +9,12 @@ The unsafe @scheme[cpointer-has-tag?] and @scheme[cpointer-push-tag!]
operations manage tags to distinguish pointer types. operations manage tags to distinguish pointer types.
@defproc*[([(_cpointer [tag any/c] @defproc*[([(_cpointer [tag any/c]
[ptr-type ctype? _pointer] [ptr-type ctype? _xpointer]
[scheme-to-c (any/c . -> . any/c) values] [scheme-to-c (any/c . -> . any/c) values]
[c-to-scheme (any/c . -> . any/c) values]) [c-to-scheme (any/c . -> . any/c) values])
ctype] ctype]
[(_cpointer/null [tag any/c] [(_cpointer/null [tag any/c]
[ptr-type ctype? _pointer] [ptr-type ctype? _xpointer]
[scheme-to-c (any/c . -> . any/c) values] [scheme-to-c (any/c . -> . any/c) values]
[c-to-scheme (any/c . -> . any/c) values]) [c-to-scheme (any/c . -> . any/c) values])
ctype])]{ ctype])]{

View File

@ -54,6 +54,20 @@ Like @scheme[list->cblock], but for Scheme vectors.}
@section{Unsafe Miscellaneous Operations} @section{Unsafe Miscellaneous Operations}
@defproc[(cast [v any/c][from-type ctype?][to-type ctype?]) any/c]{
Converts @scheme[v] from a value matching @scheme[from-type] to a
value matching @scheme[to-type], where @scheme[(ctype-size from-type)]
matches @scheme[(ctype-size to-type)].
The conversion is equivalent to
@schemeblock[
(let ([p (malloc from-type)])
(ptr-set! p from-type v)
(ptr-ref p to-type))
]}
@defproc[(cblock->list [cblock any/c][type ctype?][length exact-nonnegative-integer?]) @defproc[(cblock->list [cblock any/c][type ctype?][length exact-nonnegative-integer?])
list?]{ list?]{

View File

@ -260,8 +260,8 @@ specification is required at minimum:
] ]
If no mode is specified, then @scheme['nonatomic] allocation is used If no mode is specified, then @scheme['nonatomic] allocation is used
when the type is any pointer-based type, and @scheme['atomic] when the type is a @scheme[_gcpointer]- or @scheme[_scheme]-based
allocation is used otherwise.} type, and @scheme['atomic] allocation is used otherwise.}
@defproc[(free [cptr cpointer?]) void]{ @defproc[(free [cptr cpointer?]) void]{

View File

@ -271,7 +271,28 @@ Corresponds to Scheme ``C pointer'' objects. These pointers can have
an arbitrary Scheme object attached as a type tag. The tag is ignored an arbitrary Scheme object attached as a type tag. The tag is ignored
by built-in functionality; it is intended to be used by interfaces. by built-in functionality; it is intended to be used by interfaces.
See @secref["foreign:tagged-pointers"] for creating pointer types that See @secref["foreign:tagged-pointers"] for creating pointer types that
use these tags for safety.} use these tags for safety. A @scheme[#f] value is converted to
@cpp{NULL} and vice-versa.
The address referenced by a @scheme[_pointer] value must not refer to
memory managed by the garbage collector (unless the address
corresponds to a value that supports interior pointers and that is
otherwise referenced to preserve the value from garbage collection).
The reference is not traced or updated by the garbage collector.}
@defthing[_gcpointer ctype?]{
Like @scheme[_pointer], but for a value that can refer to memory
managed by the garbage collector.
Although a @scheme[_gcpointer] can reference to memory that is not
managed by the garbage collector, beware of using an address that
might eventually become managed by the garbage collector. For example,
if a reference is created by @scheme[malloc] with @scheme['raw] and
released by @scheme[free], then the @scheme[free] may allow the memory
formerly occupied by the reference to be used later by the garbage
collector.}
@defthing[_scheme ctype?]{ @defthing[_scheme ctype?]{
@ -295,6 +316,24 @@ A type generated by @scheme[_cprocedure] builds on @scheme[_fpointer],
and normally @scheme[_cprocedure] should be used instead of and normally @scheme[_cprocedure] should be used instead of
@scheme[_fpointer].} @scheme[_fpointer].}
@defproc[(_or-null [ctype ctype?]) ctype?]{
Creates a type that is like @scheme[ctype], but @scheme[#f] is
converted to @cpp{NULL} and vice-versa. The given @scheme[ctype] must
have the same C representation as @scheme[_pointer],
@scheme[_gcpointer], or @scheme[_fpointer].}
@defproc[(_gcable [ctype ctype?]) ctype?]{
Creates a type that is like @scheme[ctype], but whose base
representation is like @scheme[_gcpointer] instead of
@scheme[_pointer]. The given @scheme[ctype] must have a base
representation like @scheme[_pointer] or @scheme[_gcpointer] (and in
the later case, the result is the @scheme[ctype]).}
@; ------------------------------------------------------------ @; ------------------------------------------------------------
@section[#:tag "foreign:procedures"]{Function Types} @section[#:tag "foreign:procedures"]{Function Types}

View File

@ -667,7 +667,21 @@ Creates a C-pointer object that encapsulates @var{ptr} and uses
the original @var{ptr} from the Scheme object, and the original @var{ptr} from the Scheme object, and
@cppi{SCHEME_CPTR_TYPE} extracts the type tag. @cppi{SCHEME_CPTR_TYPE} extracts the type tag.
The @cppi{SCHEME_CPTR_OFFSETVAL} macro returns @cpp{0} The @cppi{SCHEME_CPTR_OFFSETVAL} macro returns @cpp{0}
for the result Scheme object.} for the result Scheme object.
The @var{ptr} can refer to either memory managed by the garbage
collector or by some other memory manager. Beware, however, of
retaining a @var{ptr} that refers to memory released by another
memory manager, since the enclosing memory range might later become
managed by the garbage collector (in which case @var{ptr} might
become an invalid pointer that can crash the garbage collector).}
@function[(Scheme_Object* scheme_make_external_cptr
[void* ptr]
[const-Scheme_Object* typetag])]{
Like @cpp{scheme_make_cptr}, but @var{ptr} is never treated as
referencing memory managed by the garbage collector.}
@function[(Scheme_Object* scheme_make_offset_cptr @function[(Scheme_Object* scheme_make_offset_cptr
[void* ptr] [void* ptr]
@ -677,7 +691,20 @@ Creates a C-pointer object that encapsulates @var{ptr} and uses
Creates a C-pointer object that encapsulates both @var{ptr} and @var{offset}. Creates a C-pointer object that encapsulates both @var{ptr} and @var{offset}.
The @cppi{SCHEME_CPTR_OFFSETVAL} macro returns @var{offset} The @cppi{SCHEME_CPTR_OFFSETVAL} macro returns @var{offset}
for the result Scheme object (and the macro be used to change the offset, for the result Scheme object (and the macro be used to change the offset,
since it also works on objects with no offset).} since it also works on objects with no offset).
The @var{ptr} can refer to either memory managed by the garbage
collector or by some other memory manager; see also
@cpp{scheme_make_cptr}.}
@function[(Scheme_Object* scheme_make_offset_external_cptr
[void* ptr]
[long offset]
[const-Scheme_Object* typetag])]{
Like @cpp{scheme_make_offset_cptr}, but @var{ptr} is never treated as
referencing memory managed by the garbage collector.}
@function[(void scheme_set_type_printer @function[(void scheme_set_type_printer
[Scheme_Type type] [Scheme_Type type]

View File

@ -766,14 +766,24 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
* Predicate: SCHEME_FFIANYPTRP(<Scheme>) * Predicate: SCHEME_FFIANYPTRP(<Scheme>)
* Scheme->C: SCHEME_FFIANYPTR_VAL(<Scheme>) * Scheme->C: SCHEME_FFIANYPTR_VAL(<Scheme>)
* S->C offset: FFIANYPTR * S->C offset: FFIANYPTR
* C->Scheme: scheme_make_foreign_external_cpointer(<C>)
*/
#define FOREIGN_gcpointer (24)
/* Type Name: gcpointer
* LibFfi type: ffi_type_gcpointer
* C type: void*
* Predicate: SCHEME_FFIANYPTRP(<Scheme>)
* Scheme->C: SCHEME_FFIANYPTR_VAL(<Scheme>)
* S->C offset: FFIANYPTR
* C->Scheme: scheme_make_foreign_cpointer(<C>) * C->Scheme: scheme_make_foreign_cpointer(<C>)
*/ */
/* This is used for passing and Scheme_Object* value as is. Useful for /* This is used for passing and Scheme_Object* value as is. Useful for
* functions that know about Scheme_Object*s, like MzScheme's. */ * functions that know about Scheme_Object*s, like MzScheme's. */
#define FOREIGN_scheme (24) #define FOREIGN_scheme (25)
/* Type Name: scheme /* Type Name: scheme
* LibFfi type: ffi_type_pointer * LibFfi type: ffi_type_gcpointer
* C type: Scheme_Object* * C type: Scheme_Object*
* Predicate: 1 * Predicate: 1
* Scheme->C: <Scheme> * Scheme->C: <Scheme>
@ -784,7 +794,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
/* Special type, not actually used for anything except to mark values /* Special type, not actually used for anything except to mark values
* that are treated like pointers but not referenced. Used for * that are treated like pointers but not referenced. Used for
* creating function types. */ * creating function types. */
#define FOREIGN_fpointer (25) #define FOREIGN_fpointer (26)
/* Type Name: fpointer /* Type Name: fpointer
* LibFfi type: ffi_type_pointer * LibFfi type: ffi_type_pointer
* C type: void* * C type: void*
@ -817,12 +827,13 @@ typedef union _ForeignAny {
char* x_path; char* x_path;
char* x_symbol; char* x_symbol;
void* x_pointer; void* x_pointer;
void* x_gcpointer;
Scheme_Object* x_scheme; Scheme_Object* x_scheme;
void* x_fpointer; void* x_fpointer;
} ForeignAny; } ForeignAny;
/* This is a tag that is used to identify user-made struct types. */ /* This is a tag that is used to identify user-made struct types. */
#define FOREIGN_struct (26) #define FOREIGN_struct (27)
/*****************************************************************************/ /*****************************************************************************/
/* Type objects */ /* Type objects */
@ -876,6 +887,8 @@ int ctype_FIXUP(void *p) {
END_XFORM_SKIP; END_XFORM_SKIP;
#endif #endif
static ffi_type ffi_type_gcpointer;
#define CTYPE_BASETYPE(x) (((ctype_struct*)(x))->basetype) #define CTYPE_BASETYPE(x) (((ctype_struct*)(x))->basetype)
#define CTYPE_USERP(x) (CTYPE_BASETYPE(x) != NULL && SCHEME_CTYPEP(CTYPE_BASETYPE(x))) #define CTYPE_USERP(x) (CTYPE_BASETYPE(x) != NULL && SCHEME_CTYPEP(CTYPE_BASETYPE(x)))
#define CTYPE_PRIMP(x) (!CTYPE_USERP(x)) #define CTYPE_PRIMP(x) (!CTYPE_USERP(x))
@ -951,6 +964,7 @@ static int ctype_sizeof(Scheme_Object *type)
case FOREIGN_path: return sizeof(char*); case FOREIGN_path: return sizeof(char*);
case FOREIGN_symbol: return sizeof(char*); case FOREIGN_symbol: return sizeof(char*);
case FOREIGN_pointer: return sizeof(void*); case FOREIGN_pointer: return sizeof(void*);
case FOREIGN_gcpointer: return sizeof(void*);
case FOREIGN_scheme: return sizeof(Scheme_Object*); case FOREIGN_scheme: return sizeof(Scheme_Object*);
case FOREIGN_fpointer: return sizeof(void*); case FOREIGN_fpointer: return sizeof(void*);
/* for structs */ /* for structs */
@ -1148,6 +1162,9 @@ END_XFORM_SKIP;
#define scheme_make_foreign_cpointer(x) \ #define scheme_make_foreign_cpointer(x) \
((x==NULL)?scheme_false:scheme_make_cptr(x,NULL)) ((x==NULL)?scheme_false:scheme_make_cptr(x,NULL))
#define scheme_make_foreign_external_cpointer(x) \
((x==NULL)?scheme_false:scheme_make_external_cptr(x,NULL))
#define MYNAME "cpointer?" #define MYNAME "cpointer?"
static Scheme_Object *foreign_cpointer_p(int argc, Scheme_Object *argv[]) static Scheme_Object *foreign_cpointer_p(int argc, Scheme_Object *argv[])
{ {
@ -1206,7 +1223,7 @@ static Scheme_Object *C2SCHEME(Scheme_Object *type, void *src,
else else
return _scheme_apply(CTYPE_USER_C2S(type), 1, (Scheme_Object**)(&res)); return _scheme_apply(CTYPE_USER_C2S(type), 1, (Scheme_Object**)(&res));
} else if (CTYPE_PRIMLABEL(type) == FOREIGN_fpointer) { } else if (CTYPE_PRIMLABEL(type) == FOREIGN_fpointer) {
return scheme_make_foreign_cpointer(*(void **)W_OFFSET(src, delta)); return scheme_make_foreign_external_cpointer(*(void **)W_OFFSET(src, delta));
} else switch (CTYPE_PRIMLABEL(type)) { } else switch (CTYPE_PRIMLABEL(type)) {
case FOREIGN_void: return scheme_void; case FOREIGN_void: return scheme_void;
case FOREIGN_int8: return scheme_make_integer(REF_CTYPE(Tsint8)); case FOREIGN_int8: return scheme_make_integer(REF_CTYPE(Tsint8));
@ -1230,7 +1247,8 @@ static Scheme_Object *C2SCHEME(Scheme_Object *type, void *src,
case FOREIGN_bytes: return (REF_CTYPE(char*)==NULL)?scheme_false:scheme_make_byte_string_without_copying(REF_CTYPE(char*)); case FOREIGN_bytes: return (REF_CTYPE(char*)==NULL)?scheme_false:scheme_make_byte_string_without_copying(REF_CTYPE(char*));
case FOREIGN_path: return (REF_CTYPE(char*)==NULL)?scheme_false:scheme_make_path_without_copying(REF_CTYPE(char*)); case FOREIGN_path: return (REF_CTYPE(char*)==NULL)?scheme_false:scheme_make_path_without_copying(REF_CTYPE(char*));
case FOREIGN_symbol: return scheme_intern_symbol(REF_CTYPE(char*)); case FOREIGN_symbol: return scheme_intern_symbol(REF_CTYPE(char*));
case FOREIGN_pointer: return scheme_make_foreign_cpointer(REF_CTYPE(void*)); case FOREIGN_pointer: return scheme_make_foreign_external_cpointer(REF_CTYPE(void*));
case FOREIGN_gcpointer: return scheme_make_foreign_cpointer(REF_CTYPE(void*));
case FOREIGN_scheme: return REF_CTYPE(Scheme_Object*); case FOREIGN_scheme: return REF_CTYPE(Scheme_Object*);
case FOREIGN_fpointer: return (REF_CTYPE(void*)); case FOREIGN_fpointer: return (REF_CTYPE(void*));
case FOREIGN_struct: case FOREIGN_struct:
@ -1599,6 +1617,23 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, long delta,
scheme_wrong_type("Scheme->C","pointer",0,1,&(val)); scheme_wrong_type("Scheme->C","pointer",0,1,&(val));
return NULL; /* hush the compiler */ return NULL; /* hush the compiler */
} }
case FOREIGN_gcpointer:
# ifdef SCHEME_BIG_ENDIAN
if (sizeof(void*)<sizeof(int) && ret_loc) {
((int*)W_OFFSET(dst,delta))[0] = 0;
delta += (sizeof(int)-sizeof(void*));
}
# endif /* SCHEME_BIG_ENDIAN */
if (SCHEME_FFIANYPTRP(val)) {
void* tmp; long toff;
tmp = (void*)(SCHEME_FFIANYPTR_VAL(val));
toff = SCHEME_FFIANYPTR_OFFSET(val);
if (_offset) *_offset = toff;
(((void**)W_OFFSET(dst,delta))[0]) = tmp; return NULL;
} else {
scheme_wrong_type("Scheme->C","gcpointer",0,1,&(val));
return NULL; /* hush the compiler */
}
case FOREIGN_scheme: case FOREIGN_scheme:
# ifdef SCHEME_BIG_ENDIAN # ifdef SCHEME_BIG_ENDIAN
if (sizeof(Scheme_Object*)<sizeof(int) && ret_loc) { if (sizeof(Scheme_Object*)<sizeof(int) && ret_loc) {
@ -1609,13 +1644,7 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, long delta,
if (1) { if (1) {
Scheme_Object* tmp; Scheme_Object* tmp;
tmp = (Scheme_Object*)(val); tmp = (Scheme_Object*)(val);
if (basetype_p == NULL || tmp == NULL) { (((Scheme_Object**)W_OFFSET(dst,delta))[0]) = tmp; return NULL;
(((Scheme_Object**)W_OFFSET(dst,delta))[0]) = tmp;
return NULL;
} else {
*basetype_p = FOREIGN_scheme;
return tmp;
}
} else { } else {
scheme_wrong_type("Scheme->C","scheme",0,1,&(val)); scheme_wrong_type("Scheme->C","scheme",0,1,&(val));
return NULL; /* hush the compiler */ return NULL; /* hush the compiler */
@ -1845,7 +1874,7 @@ static Scheme_Object *foreign_malloc(int argc, Scheme_Object *argv[])
if ((num == 0) && (size == 0)) scheme_signal_error(MYNAME": no size given"); if ((num == 0) && (size == 0)) scheme_signal_error(MYNAME": no size given");
size = ((size==0) ? 1 : size) * ((num==0) ? 1 : num); size = ((size==0) ? 1 : size) * ((num==0) ? 1 : num);
if (mode == NULL) if (mode == NULL)
mf = (base != NULL && CTYPE_PRIMTYPE(base) == &ffi_type_pointer) mf = (base != NULL && CTYPE_PRIMTYPE(base) == &ffi_type_gcpointer)
? scheme_malloc : scheme_malloc_atomic; ? scheme_malloc : scheme_malloc_atomic;
else if (SAME_OBJ(mode, nonatomic_sym)) mf = scheme_malloc; else if (SAME_OBJ(mode, nonatomic_sym)) mf = scheme_malloc;
else if (SAME_OBJ(mode, atomic_sym)) mf = scheme_malloc_atomic; else if (SAME_OBJ(mode, atomic_sym)) mf = scheme_malloc_atomic;
@ -1862,7 +1891,10 @@ static Scheme_Object *foreign_malloc(int argc, Scheme_Object *argv[])
if (failok) res = scheme_malloc_fail_ok(mf,size); else res = mf(size); if (failok) res = scheme_malloc_fail_ok(mf,size); else res = mf(size);
if (((from != NULL) || (foff != 0)) && (res != NULL)) if (((from != NULL) || (foff != 0)) && (res != NULL))
memcpy(res, W_OFFSET(from, foff), size); memcpy(res, W_OFFSET(from, foff), size);
return scheme_make_foreign_cpointer(res); if (SAME_OBJ(mode, raw_sym))
return scheme_make_foreign_external_cpointer(res);
else
return scheme_make_foreign_cpointer(res);
} }
#undef MYNAME #undef MYNAME
@ -1906,7 +1938,7 @@ static Scheme_Object *foreign_free(int argc, Scheme_Object *argv[])
#define MYNAME "malloc-immobile-cell" #define MYNAME "malloc-immobile-cell"
static Scheme_Object *foreign_malloc_immobile_cell(int argc, Scheme_Object *argv[]) static Scheme_Object *foreign_malloc_immobile_cell(int argc, Scheme_Object *argv[])
{ {
return scheme_make_foreign_cpointer(scheme_malloc_immobile_box(argv[0])); return scheme_make_foreign_external_cpointer(scheme_malloc_immobile_box(argv[0]));
} }
#undef MYNAME #undef MYNAME
@ -1961,10 +1993,16 @@ static Scheme_Object *do_ptr_add(const char *who, int is_bang,
((Scheme_Offset_Cptr*)(argv[0]))->offset += noff; ((Scheme_Offset_Cptr*)(argv[0]))->offset += noff;
return scheme_void; return scheme_void;
} else { } else {
return scheme_make_offset_cptr if (SCHEME_CPTRP(argv[0]) && (SCHEME_CPTR_FLAGS(argv[0]) & 0x1))
(SCHEME_FFIANYPTR_VAL(argv[0]), return scheme_make_offset_external_cptr
SCHEME_FFIANYPTR_OFFSET(argv[0]) + noff, (SCHEME_FFIANYPTR_VAL(argv[0]),
(SCHEME_CPTRP(argv[0])) ? SCHEME_CPTR_TYPE(argv[0]) : NULL); SCHEME_FFIANYPTR_OFFSET(argv[0]) + noff,
(SCHEME_CPTRP(argv[0])) ? SCHEME_CPTR_TYPE(argv[0]) : NULL);
else
return scheme_make_offset_cptr
(SCHEME_FFIANYPTR_VAL(argv[0]),
SCHEME_FFIANYPTR_OFFSET(argv[0]) + noff,
(SCHEME_CPTRP(argv[0])) ? SCHEME_CPTR_TYPE(argv[0]) : NULL);
} }
} }
@ -2741,6 +2779,7 @@ void scheme_init_foreign(Scheme_Env *env)
Scheme_Env *menv; Scheme_Env *menv;
ctype_struct *t; ctype_struct *t;
Scheme_Object *s; Scheme_Object *s;
memcpy(&ffi_type_gcpointer, &ffi_type_pointer, sizeof(ffi_type_pointer));
menv = scheme_primitive_module(scheme_intern_symbol("#%foreign"), env); menv = scheme_primitive_module(scheme_intern_symbol("#%foreign"), env);
scheme_add_global("ffi-lib?", scheme_add_global("ffi-lib?",
scheme_make_prim_w_arity(foreign_ffi_lib_p, "ffi-lib?", 1, 1), menv); scheme_make_prim_w_arity(foreign_ffi_lib_p, "ffi-lib?", 1, 1), menv);
@ -2981,11 +3020,18 @@ void scheme_init_foreign(Scheme_Env *env)
t->scheme_to_c = ((Scheme_Object*)(void*)(&ffi_type_pointer)); t->scheme_to_c = ((Scheme_Object*)(void*)(&ffi_type_pointer));
t->c_to_scheme = ((Scheme_Object*)FOREIGN_pointer); t->c_to_scheme = ((Scheme_Object*)FOREIGN_pointer);
scheme_add_global("_pointer", (Scheme_Object*)t, menv); scheme_add_global("_pointer", (Scheme_Object*)t, menv);
s = scheme_intern_symbol("gcpointer");
t = (ctype_struct*)scheme_malloc_tagged(sizeof(ctype_struct));
t->so.type = ctype_tag;
t->basetype = (s);
t->scheme_to_c = ((Scheme_Object*)(void*)(&ffi_type_gcpointer));
t->c_to_scheme = ((Scheme_Object*)FOREIGN_gcpointer);
scheme_add_global("_gcpointer", (Scheme_Object*)t, menv);
s = scheme_intern_symbol("scheme"); s = scheme_intern_symbol("scheme");
t = (ctype_struct*)scheme_malloc_tagged(sizeof(ctype_struct)); t = (ctype_struct*)scheme_malloc_tagged(sizeof(ctype_struct));
t->so.type = ctype_tag; t->so.type = ctype_tag;
t->basetype = (s); t->basetype = (s);
t->scheme_to_c = ((Scheme_Object*)(void*)(&ffi_type_pointer)); t->scheme_to_c = ((Scheme_Object*)(void*)(&ffi_type_gcpointer));
t->c_to_scheme = ((Scheme_Object*)FOREIGN_scheme); t->c_to_scheme = ((Scheme_Object*)FOREIGN_scheme);
scheme_add_global("_scheme", (Scheme_Object*)t, menv); scheme_add_global("_scheme", (Scheme_Object*)t, menv);
s = scheme_intern_symbol("fpointer"); s = scheme_intern_symbol("fpointer");

View File

@ -704,6 +704,13 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
* ffi-obj and string values pass their pointer. When used as a return * ffi-obj and string values pass their pointer. When used as a return
* value, either a cpointer object or #f is returned. */ * value, either a cpointer object or #f is returned. */
@(defctype 'pointer @(defctype 'pointer
'ctype "void*"
'macro "FFIANYPTR"
'offset "FFIANYPTR"
'c->s "scheme_make_foreign_external_cpointer")
@(defctype 'gcpointer
'ftype "gcpointer"
'ctype "void*" 'ctype "void*"
'macro "FFIANYPTR" 'macro "FFIANYPTR"
'offset "FFIANYPTR" 'offset "FFIANYPTR"
@ -721,7 +728,7 @@ Scheme_Object *utf16_pointer_to_ucs4_string(unsigned short *utf)
/* This is used for passing and Scheme_Object* value as is. Useful for /* This is used for passing and Scheme_Object* value as is. Useful for
* functions that know about Scheme_Object*s, like MzScheme's. */ * functions that know about Scheme_Object*s, like MzScheme's. */
@(defctype 'scheme @(defctype 'scheme
'ftype "pointer" 'ftype "gcpointer"
'ctype "Scheme_Object*" 'ctype "Scheme_Object*"
'pred (lambda (x aux) "1") 'pred (lambda (x aux) "1")
's->c (lambda (x aux) x) 's->c (lambda (x aux) x)
@ -759,6 +766,8 @@ typedef union _ForeignAny {
[scheme_to_c "Scheme_Object*"] [scheme_to_c "Scheme_Object*"]
[c_to_scheme "Scheme_Object*"]] [c_to_scheme "Scheme_Object*"]]
static ffi_type ffi_type_gcpointer;
#define CTYPE_BASETYPE(x) (((ctype_struct*)(x))->basetype) #define CTYPE_BASETYPE(x) (((ctype_struct*)(x))->basetype)
#define CTYPE_USERP(x) (CTYPE_BASETYPE(x) != NULL && SCHEME_CTYPEP(CTYPE_BASETYPE(x))) #define CTYPE_USERP(x) (CTYPE_BASETYPE(x) != NULL && SCHEME_CTYPEP(CTYPE_BASETYPE(x)))
#define CTYPE_PRIMP(x) (!CTYPE_USERP(x)) #define CTYPE_PRIMP(x) (!CTYPE_USERP(x))
@ -950,6 +959,9 @@ ffi_abi sym_to_abi(char *who, Scheme_Object *sym)
#define scheme_make_foreign_cpointer(x) \ #define scheme_make_foreign_cpointer(x) \
((x==NULL)?scheme_false:scheme_make_cptr(x,NULL)) ((x==NULL)?scheme_false:scheme_make_cptr(x,NULL))
#define scheme_make_foreign_external_cpointer(x) \
((x==NULL)?scheme_false:scheme_make_external_cptr(x,NULL))
@cdefine[cpointer? 1]{ @cdefine[cpointer? 1]{
return SCHEME_FFIANYPTRP(argv[0]) ? scheme_true : scheme_false; return SCHEME_FFIANYPTRP(argv[0]) ? scheme_true : scheme_false;
} }
@ -999,7 +1011,7 @@ static Scheme_Object *C2SCHEME(Scheme_Object *type, void *src,
else else
return _scheme_apply(CTYPE_USER_C2S(type), 1, (Scheme_Object**)(&res)); return _scheme_apply(CTYPE_USER_C2S(type), 1, (Scheme_Object**)(&res));
} else if (CTYPE_PRIMLABEL(type) == FOREIGN_fpointer) { } else if (CTYPE_PRIMLABEL(type) == FOREIGN_fpointer) {
return scheme_make_foreign_cpointer(*(void **)W_OFFSET(src, delta)); return scheme_make_foreign_external_cpointer(*(void **)W_OFFSET(src, delta));
} else switch (CTYPE_PRIMLABEL(type)) { } else switch (CTYPE_PRIMLABEL(type)) {
@(map-types @(map-types
@list{case FOREIGN_@|cname|: return @; @list{case FOREIGN_@|cname|: return @;
@ -1307,7 +1319,7 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, long delta,
if ((num == 0) && (size == 0)) scheme_signal_error(MYNAME": no size given"); if ((num == 0) && (size == 0)) scheme_signal_error(MYNAME": no size given");
size = ((size==0) ? 1 : size) * ((num==0) ? 1 : num); size = ((size==0) ? 1 : size) * ((num==0) ? 1 : num);
if (mode == NULL) if (mode == NULL)
mf = (base != NULL && CTYPE_PRIMTYPE(base) == &ffi_type_pointer) mf = (base != NULL && CTYPE_PRIMTYPE(base) == &ffi_type_gcpointer)
? scheme_malloc : scheme_malloc_atomic; ? scheme_malloc : scheme_malloc_atomic;
else if (SAME_OBJ(mode, nonatomic_sym)) mf = scheme_malloc; else if (SAME_OBJ(mode, nonatomic_sym)) mf = scheme_malloc;
else if (SAME_OBJ(mode, atomic_sym)) mf = scheme_malloc_atomic; else if (SAME_OBJ(mode, atomic_sym)) mf = scheme_malloc_atomic;
@ -1324,7 +1336,10 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, long delta,
if (failok) res = scheme_malloc_fail_ok(mf,size); else res = mf(size); if (failok) res = scheme_malloc_fail_ok(mf,size); else res = mf(size);
if (((from != NULL) || (foff != 0)) && (res != NULL)) if (((from != NULL) || (foff != 0)) && (res != NULL))
memcpy(res, W_OFFSET(from, foff), size); memcpy(res, W_OFFSET(from, foff), size);
return scheme_make_foreign_cpointer(res); if (SAME_OBJ(mode, raw_sym))
return scheme_make_foreign_external_cpointer(res);
else
return scheme_make_foreign_cpointer(res);
} }
/* (end-stubborn-change ptr) */ /* (end-stubborn-change ptr) */
@ -1359,7 +1374,7 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, long delta,
/* (malloc-immobile-cell v) */ /* (malloc-immobile-cell v) */
@cdefine[malloc-immobile-cell 1]{ @cdefine[malloc-immobile-cell 1]{
return scheme_make_foreign_cpointer(scheme_malloc_immobile_box(argv[0])); return scheme_make_foreign_external_cpointer(scheme_malloc_immobile_box(argv[0]));
} }
/* (free-immobile-cell b) */ /* (free-immobile-cell b) */
@ -1410,10 +1425,16 @@ static Scheme_Object *do_ptr_add(const char *who, int is_bang,
((Scheme_Offset_Cptr*)(argv[0]))->offset += noff; ((Scheme_Offset_Cptr*)(argv[0]))->offset += noff;
return scheme_void; return scheme_void;
} else { } else {
return scheme_make_offset_cptr if (SCHEME_CPTRP(argv[0]) && (SCHEME_CPTR_FLAGS(argv[0]) & 0x1))
(SCHEME_FFIANYPTR_VAL(argv[0]), return scheme_make_offset_external_cptr
SCHEME_FFIANYPTR_OFFSET(argv[0]) + noff, (SCHEME_FFIANYPTR_VAL(argv[0]),
(SCHEME_CPTRP(argv[0])) ? SCHEME_CPTR_TYPE(argv[0]) : NULL); SCHEME_FFIANYPTR_OFFSET(argv[0]) + noff,
(SCHEME_CPTRP(argv[0])) ? SCHEME_CPTR_TYPE(argv[0]) : NULL);
else
return scheme_make_offset_cptr
(SCHEME_FFIANYPTR_VAL(argv[0]),
SCHEME_FFIANYPTR_OFFSET(argv[0]) + noff,
(SCHEME_CPTRP(argv[0])) ? SCHEME_CPTR_TYPE(argv[0]) : NULL);
} }
} }
@ -2112,6 +2133,7 @@ void scheme_init_foreign(Scheme_Env *env)
Scheme_Env *menv; Scheme_Env *menv;
ctype_struct *t; ctype_struct *t;
Scheme_Object *s; Scheme_Object *s;
memcpy(&ffi_type_gcpointer, &ffi_type_pointer, sizeof(ffi_type_pointer));
menv = scheme_primitive_module(scheme_intern_symbol("#%foreign"), env); menv = scheme_primitive_module(scheme_intern_symbol("#%foreign"), env);
@(maplines @(maplines
(lambda (x) (lambda (x)

View File

@ -300,6 +300,8 @@ scheme_get_unsigned_long_long_val
scheme_real_to_double scheme_real_to_double
scheme_make_cptr scheme_make_cptr
scheme_make_offset_cptr scheme_make_offset_cptr
scheme_make_external_cptr
scheme_make_offset_external_cptr
scheme_get_proc_name scheme_get_proc_name
scheme_utf8_decode scheme_utf8_decode
scheme_utf8_decode_as_prefix scheme_utf8_decode_as_prefix

View File

@ -311,6 +311,8 @@ scheme_get_unsigned_long_long_val
scheme_real_to_double scheme_real_to_double
scheme_make_cptr scheme_make_cptr
scheme_make_offset_cptr scheme_make_offset_cptr
scheme_make_external_cptr
scheme_make_offset_external_cptr
scheme_get_proc_name scheme_get_proc_name
scheme_utf8_decode scheme_utf8_decode
scheme_utf8_decode_as_prefix scheme_utf8_decode_as_prefix

View File

@ -288,6 +288,8 @@ EXPORTS
scheme_real_to_double scheme_real_to_double
scheme_make_cptr scheme_make_cptr
scheme_make_offset_cptr scheme_make_offset_cptr
scheme_make_external_cptr
scheme_make_offset_external_cptr
scheme_get_proc_name scheme_get_proc_name
scheme_utf8_decode scheme_utf8_decode
scheme_utf8_decode_as_prefix scheme_utf8_decode_as_prefix

View File

@ -303,6 +303,8 @@ EXPORTS
scheme_real_to_double scheme_real_to_double
scheme_make_cptr scheme_make_cptr
scheme_make_offset_cptr scheme_make_offset_cptr
scheme_make_external_cptr
scheme_make_offset_external_cptr
scheme_get_proc_name scheme_get_proc_name
scheme_utf8_decode scheme_utf8_decode
scheme_utf8_decode_as_prefix scheme_utf8_decode_as_prefix

View File

@ -564,7 +564,7 @@ typedef long (*Scheme_Secondary_Hash_Proc)(Scheme_Object *obj, void *cycle_data)
typedef struct Scheme_Cptr typedef struct Scheme_Cptr
{ {
Scheme_Object so; Scheme_Inclhash_Object so; /* 0x1 => an external pointer (not GCable) */
void *val; void *val;
Scheme_Object *type; Scheme_Object *type;
} Scheme_Cptr; } Scheme_Cptr;
@ -577,6 +577,7 @@ typedef struct Scheme_Offset_Cptr
#define SCHEME_CPTR_VAL(obj) (((Scheme_Cptr *)(obj))->val) #define SCHEME_CPTR_VAL(obj) (((Scheme_Cptr *)(obj))->val)
#define SCHEME_CPTR_TYPE(obj) (((Scheme_Cptr *)(obj))->type) #define SCHEME_CPTR_TYPE(obj) (((Scheme_Cptr *)(obj))->type)
#define SCHEME_CPTR_OFFSET(obj) (SAME_TYPE(_SCHEME_TYPE(obj), scheme_offset_cpointer_type) ? ((Scheme_Offset_Cptr *)obj)->offset : 0) #define SCHEME_CPTR_OFFSET(obj) (SAME_TYPE(_SCHEME_TYPE(obj), scheme_offset_cpointer_type) ? ((Scheme_Offset_Cptr *)obj)->offset : 0)
#define SCHEME_CPTR_FLAGS(obj) MZ_OPT_HASH_KEY(&((Scheme_Cptr *)(obj))->so)
#define SCHEME_SET_IMMUTABLE(obj) ((MZ_OPT_HASH_KEY((Scheme_Inclhash_Object *)(obj)) |= 0x1)) #define SCHEME_SET_IMMUTABLE(obj) ((MZ_OPT_HASH_KEY((Scheme_Inclhash_Object *)(obj)) |= 0x1))
#define SCHEME_SET_CHAR_STRING_IMMUTABLE(obj) SCHEME_SET_IMMUTABLE(obj) #define SCHEME_SET_CHAR_STRING_IMMUTABLE(obj) SCHEME_SET_IMMUTABLE(obj)

View File

@ -156,14 +156,18 @@ static int cpointer_obj_SIZE(void *p) {
} }
static int cpointer_obj_MARK(void *p) { static int cpointer_obj_MARK(void *p) {
gcMARK(SCHEME_CPTR_VAL(p)); if (!(SCHEME_CPTR_FLAGS(p) & 0x1)) {
gcMARK(SCHEME_CPTR_VAL(p));
}
gcMARK(SCHEME_CPTR_TYPE(p)); gcMARK(SCHEME_CPTR_TYPE(p));
return return
gcBYTES_TO_WORDS(sizeof(Scheme_Cptr)); gcBYTES_TO_WORDS(sizeof(Scheme_Cptr));
} }
static int cpointer_obj_FIXUP(void *p) { static int cpointer_obj_FIXUP(void *p) {
gcFIXUP(SCHEME_CPTR_VAL(p)); if (!(SCHEME_CPTR_FLAGS(p) & 0x1)) {
gcFIXUP(SCHEME_CPTR_VAL(p));
}
gcFIXUP(SCHEME_CPTR_TYPE(p)); gcFIXUP(SCHEME_CPTR_TYPE(p));
return return
gcBYTES_TO_WORDS(sizeof(Scheme_Cptr)); gcBYTES_TO_WORDS(sizeof(Scheme_Cptr));
@ -179,14 +183,18 @@ static int offset_cpointer_obj_SIZE(void *p) {
} }
static int offset_cpointer_obj_MARK(void *p) { static int offset_cpointer_obj_MARK(void *p) {
gcMARK(SCHEME_CPTR_VAL(p)); if (!(SCHEME_CPTR_FLAGS(p) & 0x1)) {
gcMARK(SCHEME_CPTR_VAL(p));
}
gcMARK(SCHEME_CPTR_TYPE(p)); gcMARK(SCHEME_CPTR_TYPE(p));
return return
gcBYTES_TO_WORDS(sizeof(Scheme_Offset_Cptr)); gcBYTES_TO_WORDS(sizeof(Scheme_Offset_Cptr));
} }
static int offset_cpointer_obj_FIXUP(void *p) { static int offset_cpointer_obj_FIXUP(void *p) {
gcFIXUP(SCHEME_CPTR_VAL(p)); if (!(SCHEME_CPTR_FLAGS(p) & 0x1)) {
gcFIXUP(SCHEME_CPTR_VAL(p));
}
gcFIXUP(SCHEME_CPTR_TYPE(p)); gcFIXUP(SCHEME_CPTR_TYPE(p));
return return
gcBYTES_TO_WORDS(sizeof(Scheme_Offset_Cptr)); gcBYTES_TO_WORDS(sizeof(Scheme_Offset_Cptr));

View File

@ -56,7 +56,9 @@ quotesyntax_obj {
cpointer_obj { cpointer_obj {
mark: mark:
gcMARK(SCHEME_CPTR_VAL(p)); if (!(SCHEME_CPTR_FLAGS(p) & 0x1)) {
gcMARK(SCHEME_CPTR_VAL(p));
}
gcMARK(SCHEME_CPTR_TYPE(p)); gcMARK(SCHEME_CPTR_TYPE(p));
size: size:
gcBYTES_TO_WORDS(sizeof(Scheme_Cptr)); gcBYTES_TO_WORDS(sizeof(Scheme_Cptr));
@ -64,7 +66,9 @@ cpointer_obj {
offset_cpointer_obj { offset_cpointer_obj {
mark: mark:
gcMARK(SCHEME_CPTR_VAL(p)); if (!(SCHEME_CPTR_FLAGS(p) & 0x1)) {
gcMARK(SCHEME_CPTR_VAL(p));
}
gcMARK(SCHEME_CPTR_TYPE(p)); gcMARK(SCHEME_CPTR_TYPE(p));
size: size:
gcBYTES_TO_WORDS(sizeof(Scheme_Offset_Cptr)); gcBYTES_TO_WORDS(sizeof(Scheme_Offset_Cptr));

View File

@ -342,6 +342,14 @@ Scheme_Object *scheme_make_cptr(void *cptr, Scheme_Object *typetag)
return o; return o;
} }
Scheme_Object *scheme_make_external_cptr(GC_CAN_IGNORE void *cptr, Scheme_Object *typetag)
{
Scheme_Object *o;
o = scheme_make_cptr(NULL, typetag);
SCHEME_CPTR_VAL(o) = cptr;
return o;
}
Scheme_Object *scheme_make_offset_cptr(void *cptr, long offset, Scheme_Object *typetag) Scheme_Object *scheme_make_offset_cptr(void *cptr, long offset, Scheme_Object *typetag)
{ {
Scheme_Object *o; Scheme_Object *o;
@ -355,6 +363,15 @@ Scheme_Object *scheme_make_offset_cptr(void *cptr, long offset, Scheme_Object *t
return o; return o;
} }
Scheme_Object *scheme_make_offset_external_cptr(GC_CAN_IGNORE void *cptr, long offset, Scheme_Object *typetag)
{
Scheme_Object *o;
o = scheme_make_offset_cptr(NULL, offset, typetag);
SCHEME_CPTR_VAL(o) = cptr;
return o;
}
/************************************************************************/ /************************************************************************/
/* allocation */ /* allocation */
/************************************************************************/ /************************************************************************/

View File

@ -576,6 +576,8 @@ XFORM_NONGCING MZ_EXTERN double scheme_real_to_double(Scheme_Object *r);
MZ_EXTERN Scheme_Object *scheme_make_cptr(void *cptr, Scheme_Object *typetag); MZ_EXTERN Scheme_Object *scheme_make_cptr(void *cptr, Scheme_Object *typetag);
MZ_EXTERN Scheme_Object *scheme_make_offset_cptr(void *cptr, long offset, Scheme_Object *typetag); MZ_EXTERN Scheme_Object *scheme_make_offset_cptr(void *cptr, long offset, Scheme_Object *typetag);
MZ_EXTERN Scheme_Object *scheme_make_external_cptr(void *cptr, Scheme_Object *typetag);
MZ_EXTERN Scheme_Object *scheme_make_offset_external_cptr(void *cptr, long offset, Scheme_Object *typetag);
MZ_EXTERN const char *scheme_get_proc_name(Scheme_Object *p, int *len, int for_error); MZ_EXTERN const char *scheme_get_proc_name(Scheme_Object *p, int *len, int for_error);

View File

@ -475,6 +475,8 @@ int (*scheme_get_unsigned_long_long_val)(Scheme_Object *o, umzlonglong *v);
double (*scheme_real_to_double)(Scheme_Object *r); double (*scheme_real_to_double)(Scheme_Object *r);
Scheme_Object *(*scheme_make_cptr)(void *cptr, Scheme_Object *typetag); Scheme_Object *(*scheme_make_cptr)(void *cptr, Scheme_Object *typetag);
Scheme_Object *(*scheme_make_offset_cptr)(void *cptr, long offset, Scheme_Object *typetag); Scheme_Object *(*scheme_make_offset_cptr)(void *cptr, long offset, Scheme_Object *typetag);
Scheme_Object *(*scheme_make_external_cptr)(void *cptr, Scheme_Object *typetag);
Scheme_Object *(*scheme_make_offset_external_cptr)(void *cptr, long offset, Scheme_Object *typetag);
const char *(*scheme_get_proc_name)(Scheme_Object *p, int *len, int for_error); const char *(*scheme_get_proc_name)(Scheme_Object *p, int *len, int for_error);
/*========================================================================*/ /*========================================================================*/
/* strings */ /* strings */

View File

@ -337,6 +337,8 @@
scheme_extension_table->scheme_real_to_double = scheme_real_to_double; scheme_extension_table->scheme_real_to_double = scheme_real_to_double;
scheme_extension_table->scheme_make_cptr = scheme_make_cptr; scheme_extension_table->scheme_make_cptr = scheme_make_cptr;
scheme_extension_table->scheme_make_offset_cptr = scheme_make_offset_cptr; scheme_extension_table->scheme_make_offset_cptr = scheme_make_offset_cptr;
scheme_extension_table->scheme_make_external_cptr = scheme_make_external_cptr;
scheme_extension_table->scheme_make_offset_external_cptr = scheme_make_offset_external_cptr;
scheme_extension_table->scheme_get_proc_name = scheme_get_proc_name; scheme_extension_table->scheme_get_proc_name = scheme_get_proc_name;
scheme_extension_table->scheme_utf8_decode = scheme_utf8_decode; scheme_extension_table->scheme_utf8_decode = scheme_utf8_decode;
scheme_extension_table->scheme_utf8_decode_as_prefix = scheme_utf8_decode_as_prefix; scheme_extension_table->scheme_utf8_decode_as_prefix = scheme_utf8_decode_as_prefix;

View File

@ -337,6 +337,8 @@
#define scheme_real_to_double (scheme_extension_table->scheme_real_to_double) #define scheme_real_to_double (scheme_extension_table->scheme_real_to_double)
#define scheme_make_cptr (scheme_extension_table->scheme_make_cptr) #define scheme_make_cptr (scheme_extension_table->scheme_make_cptr)
#define scheme_make_offset_cptr (scheme_extension_table->scheme_make_offset_cptr) #define scheme_make_offset_cptr (scheme_extension_table->scheme_make_offset_cptr)
#define scheme_make_external_cptr (scheme_extension_table->scheme_make_external_cptr)
#define scheme_make_offset_external_cptr (scheme_extension_table->scheme_make_offset_external_cptr)
#define scheme_get_proc_name (scheme_extension_table->scheme_get_proc_name) #define scheme_get_proc_name (scheme_extension_table->scheme_get_proc_name)
#define scheme_utf8_decode (scheme_extension_table->scheme_utf8_decode) #define scheme_utf8_decode (scheme_extension_table->scheme_utf8_decode)
#define scheme_utf8_decode_as_prefix (scheme_extension_table->scheme_utf8_decode_as_prefix) #define scheme_utf8_decode_as_prefix (scheme_extension_table->scheme_utf8_decode_as_prefix)

View File

@ -13,12 +13,12 @@
consistently.) consistently.)
*/ */
#define MZSCHEME_VERSION "4.2.2.5" #define MZSCHEME_VERSION "4.2.2.6"
#define MZSCHEME_VERSION_X 4 #define MZSCHEME_VERSION_X 4
#define MZSCHEME_VERSION_Y 2 #define MZSCHEME_VERSION_Y 2
#define MZSCHEME_VERSION_Z 2 #define MZSCHEME_VERSION_Z 2
#define MZSCHEME_VERSION_W 5 #define MZSCHEME_VERSION_W 6
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)