~ chicken-core (master) /lolevel.scm
Trap1;;;; lolevel.scm - Low-level routines for CHICKEN2;3; Copyright (c) 2008-2022, The CHICKEN Team4; Copyright (c) 2000-2007, Felix L. Winkelmann5; All rights reserved.6;7; Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following8; conditions are met:9;10; Redistributions of source code must retain the above copyright notice, this list of conditions and the following11; disclaimer.12; Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following13; disclaimer in the documentation and/or other materials provided with the distribution.14; Neither the name of the author nor the names of its contributors may be used to endorse or promote15; products derived from this software without specific prior written permission.16;17; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS18; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY19; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR20; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR21; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR22; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY23; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR24; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE25; POSSIBILITY OF SUCH DAMAGE.262728(declare29 (unit lolevel)30 (foreign-declare #<<EOF31#ifndef C_NONUNIX32# include <sys/mman.h>33#endif3435#define C_memmove_o(to, from, n, toff, foff) C_memmove((char *)(to) + (toff), (char *)(from) + (foff), (n))36EOF37) )3839(include "common-declarations.scm")4041(module chicken.memory42 (address->pointer align-to-word allocate free make-pointer-vector43 move-memory! object->pointer pointer+ pointer->address44 pointer->object pointer-f32-ref pointer-f32-set! pointer-f64-ref45 pointer-f64-set! pointer-like? pointer-s16-ref pointer-s16-set!46 pointer-s32-ref pointer-s32-set! pointer-s64-ref pointer-s64-set!47 pointer-s8-ref pointer-s8-set! pointer-tag pointer-u16-ref48 pointer-u16-set! pointer-u32-ref pointer-u32-set! pointer-u64-ref49 pointer-u64-set! pointer-u8-ref pointer-u8-set! pointer-vector50 pointer-vector-fill! pointer-vector-length pointer-vector-ref51 pointer-vector-set! pointer-vector? pointer=? pointer? tag-pointer52 tagged-pointer?)5354(import scheme chicken.base chicken.fixnum chicken.foreign)555657;;; Helpers:5859(define-inline (%pointer? x)60 (##core#inline "C_i_safe_pointerp" x))6162(define-inline (%generic-pointer? x)63 (or (%pointer? x)64 (##core#inline "C_locativep" x) ) )6566(define-inline (%special-block? x)67 ; generic-pointer, port, closure68 (and (##core#inline "C_blockp" x) (##core#inline "C_specialp" x)) )6970(define-inline (%generic-vector? x)71 (and (##core#inline "C_blockp" x)72 (not (or (##core#inline "C_specialp" x)73 (##core#inline "C_byteblockp" x)))) )7475(define-inline (%record-structure? x)76 (and (##core#inline "C_blockp" x) (##core#inline "C_structurep" x)) )77787980;;; Argument checking:8182(define (##sys#check-block x . loc)83 (unless (##core#inline "C_blockp" x)84 (##sys#error-hook85 (foreign-value "C_BAD_ARGUMENT_TYPE_NO_BLOCK_ERROR" int) (and (pair? loc) (car loc))86 x) ) )8788(define (##sys#check-become-alist x loc)89 (##sys#check-list x loc)90 (let loop ([lst x])91 (cond [(null? lst) ]92 [(pair? lst)93 (let ([a (car lst)])94 (##sys#check-pair a loc)95 (##sys#check-block (car a) loc)96 (##sys#check-block (cdr a) loc)97 (loop (cdr lst)) ) ]98 [else99 (##sys#signal-hook100 #:type-error loc101 "bad argument type - not an a-list of block objects" x) ] ) ) )102103(define (##sys#check-generic-structure x . loc)104 (unless (%record-structure? x)105 (##sys#signal-hook106 #:type-error (and (pair? loc) (car loc))107 "bad argument type - not a structure" x) ) )108109;; Vector, Structure, Pair, and Symbol110111(define (##sys#check-generic-vector x . loc)112 (unless (%generic-vector? x)113 (##sys#signal-hook114 #:type-error (and (pair? loc) (car loc))115 "bad argument type - not a vector-like object" x) ) )116117(define (##sys#check-pointer x . loc)118 (unless (%pointer? x)119 (##sys#error-hook120 (foreign-value "C_BAD_ARGUMENT_TYPE_NO_POINTER_ERROR" int)121 (and (pair? loc) (car loc))122 "bad argument type - not a pointer" x) ) )123124125;;; Move arbitrary blocks of memory around:126127(define move-memory!128 (let ((memmove1 (foreign-lambda void "C_memmove_o" c-pointer c-pointer int int int))129 (memmove2 (foreign-lambda void "C_memmove_o" c-pointer scheme-pointer int int int))130 (memmove3 (foreign-lambda void "C_memmove_o" scheme-pointer c-pointer int int int))131 (memmove4 (foreign-lambda void "C_memmove_o" scheme-pointer scheme-pointer int int int))132 (typerr (lambda (x)133 (##sys#error-hook134 (foreign-value "C_BAD_ARGUMENT_TYPE_ERROR" int)135 'move-memory! x)))136 (slot1structs '(mmap137 u8vector u16vector u32vector u64vector138 s8vector s16vector s32vector s64vector139 f32vector f64vector)) )140 (lambda (from to #!optional n (foffset 0) (toffset 0))141 ;142 (define (nosizerr)143 (##sys#error 'move-memory! "need number of bytes to move" from to))144 ;145 (define (sizerr . args)146 (apply ##sys#error 'move-memory! "number of bytes to move too large" from to args))147 ;148 (define (checkn1 n nmax off)149 (if (fx<= n (fx- nmax off))150 n151 (sizerr n nmax) ) )152 ;153 (define (checkn2 n nmax nmax2 off1 off2)154 (if (and (fx<= n (fx- nmax off1)) (fx<= n (fx- nmax2 off2)))155 n156 (sizerr n nmax nmax2) ) )157 ;158 (##sys#check-block from 'move-memory!)159 (##sys#check-block to 'move-memory!)160 (when (fx< foffset 0)161 (##sys#error 'move-memory! "negative source offset" foffset))162 (when (fx< toffset 0)163 (##sys#error 'move-memory! "negative destination offset" toffset))164 (let move ([from from] [to to] (n n))165 (cond [(##sys#generic-structure? from)166 (if (memq (##sys#slot from 0) slot1structs)167 (move (##sys#slot from 1) to n)168 (typerr from) ) ]169 [(##sys#generic-structure? to)170 (if (memq (##sys#slot to 0) slot1structs)171 (move from (##sys#slot to 1) n)172 (typerr to) ) ]173 ((string? from)174 (let ((buf (##sys#slot from 0)))175 (move buf to (or n (fx- (##sys#size buf) 1)))))176 ((string? to)177 (let ((buf (##sys#slot to 0)))178 (move from buf (or n (fx- (##sys#size buf) 1)))))179 [(%generic-pointer? from)180 (cond [(%generic-pointer? to)181 (memmove1 to from (or n (nosizerr)) toffset foffset)]182 ((##sys#bytevector? to)183 (memmove3 to from (checkn1 (or n (nosizerr)) (##sys#size to) toffset) toffset foffset) )184 [else185 (typerr to)] ) ]186 [(##sys#bytevector? from)187 (let ([nfrom (##sys#size from)])188 (cond [(%generic-pointer? to)189 (memmove2 to from (checkn1 (or n nfrom) nfrom foffset) toffset foffset)]190 ((##sys#bytevector? to)191 (memmove4 to from (checkn2 (or n nfrom) nfrom (##sys#size to) foffset toffset)192 toffset foffset) )193 [else194 (typerr to)] ) ) ]195 [else196 (typerr from)] ) ) ) ) )197198199;;; Pointer operations:200201(define allocate (foreign-lambda c-pointer "C_malloc" int))202(define free (foreign-lambda void "C_free" c-pointer))203204(define (pointer? x) (%pointer? x))205206(define (pointer-like? x) (%special-block? x))207208(define (address->pointer addr)209 (##sys#check-integer addr 'address->pointer)210 (##sys#address->pointer addr) )211212(define (pointer->address ptr)213 (##sys#check-special ptr 'pointer->address)214 (##sys#pointer->address ptr) )215216(define (object->pointer x)217 (and (##core#inline "C_blockp" x)218 ((foreign-lambda* nonnull-c-pointer ((scheme-object x)) "C_return((void *)x);") x) ) )219220(define (pointer->object ptr)221 (##sys#check-pointer ptr 'pointer->object)222 (##core#inline "C_pointer_to_object" ptr) )223224(define (pointer=? p1 p2)225 (##sys#check-special p1 'pointer=?)226 (##sys#check-special p2 'pointer=?)227 (##core#inline "C_pointer_eqp" p1 p2) )228229(define pointer+230 (foreign-lambda* nonnull-c-pointer ([c-pointer ptr] [integer off])231 "C_return((unsigned char *)ptr + off);") )232233(define align-to-word234 (let ([align (foreign-lambda integer "C_align" integer)])235 (lambda (x)236 (cond [(integer? x)237 (align x)]238 [(%special-block? x)239 (##sys#address->pointer (align (##sys#pointer->address x))) ]240 [else241 (##sys#signal-hook242 #:type-error 'align-to-word243 "bad argument type - not a pointer or integer" x)] ) ) ) )244245246;;; Tagged-pointers:247248(define (tag-pointer ptr tag)249 (let ([tp (##sys#make-tagged-pointer tag)])250 (if (%special-block? ptr)251 (##core#inline "C_copy_pointer" ptr tp)252 (##sys#error-hook (foreign-value "C_BAD_ARGUMENT_TYPE_NO_POINTER_ERROR" int) 'tag-pointer ptr) )253 tp) )254255(define (tagged-pointer? x #!optional tag)256 (and (##core#inline "C_blockp" x) (##core#inline "C_taggedpointerp" x)257 (or (not tag)258 (equal? tag (##sys#slot x 1)) ) ) )259260(define (pointer-tag x)261 (if (%special-block? x)262 (and (##core#inline "C_taggedpointerp" x)263 (##sys#slot x 1) )264 (##sys#error-hook (foreign-value "C_BAD_ARGUMENT_TYPE_NO_POINTER_ERROR" int) 'pointer-tag x) ) )265266267268269;;; SRFI-4 number-vector:270271(define (pointer-u8-set! p n) (##core#inline "C_u_i_pointer_u8_set" p n))272(define (pointer-s8-set! p n) (##core#inline "C_u_i_pointer_s8_set" p n))273(define (pointer-u16-set! p n) (##core#inline "C_u_i_pointer_u16_set" p n))274(define (pointer-s16-set! p n) (##core#inline "C_u_i_pointer_s16_set" p n))275(define (pointer-u32-set! p n) (##core#inline "C_u_i_pointer_u32_set" p n))276(define (pointer-s32-set! p n) (##core#inline "C_u_i_pointer_s32_set" p n))277(define (pointer-u64-set! p n) (##core#inline "C_u_i_pointer_u64_set" p n))278(define (pointer-s64-set! p n) (##core#inline "C_u_i_pointer_s64_set" p n))279(define (pointer-f32-set! p n) (##core#inline "C_u_i_pointer_f32_set" p n))280(define (pointer-f64-set! p n) (##core#inline "C_u_i_pointer_f64_set" p n))281282(define pointer-u8-ref283 (getter-with-setter284 (lambda (p) (##core#inline "C_u_i_pointer_u8_ref" p))285 pointer-u8-set!286 "(chicken.memory#pointer-u8-ref p)"))287288(define pointer-s8-ref289 (getter-with-setter290 (lambda (p) (##core#inline "C_u_i_pointer_s8_ref" p))291 pointer-s8-set!292 "(chicken.memory#pointer-s8-ref p)"))293294(define pointer-u16-ref295 (getter-with-setter296 (lambda (p) (##core#inline "C_u_i_pointer_u16_ref" p))297 pointer-u16-set!298 "(chicken.memory#pointer-u16-ref p)"))299300(define pointer-s16-ref301 (getter-with-setter302 (lambda (p) (##core#inline "C_u_i_pointer_s16_ref" p))303 pointer-s16-set!304 "(chicken.memory#pointer-s16-ref p)"))305306(define pointer-u32-ref307 (getter-with-setter308 (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_u32_ref" 6) p)) ;XXX hardcoded size309 pointer-u32-set!310 "(chicken.memory#pointer-u32-ref p)"))311312(define pointer-s32-ref313 (getter-with-setter314 (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_s32_ref" 6) p)) ;XXX hardcoded size315 pointer-s32-set!316 "(chicken.memory#pointer-s32-ref p)"))317318(define pointer-u64-ref319 (getter-with-setter320 (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_u64_ref" 7) p)) ;XXX hardcoded size321 pointer-u64-set!322 "(chicken.memory#pointer-u64-ref p)"))323324(define pointer-s64-ref325 (getter-with-setter326 (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_s64_ref" 7) p)) ;XXX hardcoded size327 pointer-s64-set!328 "(chicken.memory#pointer-s64-ref p)"))329330(define pointer-f32-ref331 (getter-with-setter332 (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_f32_ref" 4) p)) ;XXX hardcoded size333 pointer-f32-set!334 "(chicken.memory#pointer-f32-ref p)"))335336(define pointer-f64-ref337 (getter-with-setter338 (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_f64_ref" 4) p)) ;XXX hardcoded size339 pointer-f64-set!340 "(chicken.memory#pointer-f64-ref p)"))341342343;;; pointer vectors344345(define make-pointer-vector346 (let ((unset (list 'unset)))347 (lambda (n #!optional (init unset))348 (##sys#check-fixnum n 'make-pointer-vector)349 (let* ((words->bytes (foreign-lambda int "C_wordstobytes" int))350 (size (words->bytes n))351 (buf (##sys#make-bytevector size)))352 (unless (eq? init unset)353 (when init354 (##sys#check-pointer init 'make-pointer-vector))355 (do ((i 0 (fx+ i 1)))356 ((fx>= i n))357 (pv-buf-set! buf i init)))358 (##sys#make-structure 'pointer-vector n buf)))))359360(define (pointer-vector? x)361 (##sys#structure? x 'pointer-vector))362363(define (pointer-vector . ptrs)364 (let* ((n (length ptrs))365 (pv (make-pointer-vector n))366 (buf (##sys#slot pv 2))) ; buf367 (do ((ptrs ptrs (cdr ptrs))368 (i 0 (fx+ i 1)))369 ((null? ptrs) pv)370 (let ((ptr (car ptrs)))371 (##sys#check-pointer ptr 'pointer-vector)372 (pv-buf-set! buf i ptr)))))373374(define (pointer-vector-fill! pv ptr)375 (##sys#check-structure pv 'pointer-vector 'pointer-vector-fill!)376 (when ptr (##sys#check-pointer ptr 'pointer-vector-fill!))377 (let ((buf (##sys#slot pv 2)) ; buf378 (n (##sys#slot pv 1))) ; n379 (do ((i 0 (fx+ i 1)))380 ((fx>= i n))381 (pv-buf-set! buf i ptr))))382383(define pv-buf-ref384 (foreign-lambda* c-pointer ((scheme-object buf) (unsigned-int i))385 "C_return(*((void **)C_data_pointer(buf) + i));"))386387(define pv-buf-set!388 (foreign-lambda* void ((scheme-object buf) (unsigned-int i) (c-pointer ptr))389 "*((void **)C_data_pointer(buf) + i) = ptr;"))390391(define (pointer-vector-set! pv i ptr)392 (##sys#check-structure pv 'pointer-vector 'pointer-vector-ref)393 (##sys#check-range i 0 (##sys#slot pv 1)) ; len394 (when ptr (##sys#check-pointer ptr 'pointer-vector-set!))395 (pv-buf-set! (##sys#slot pv 2) i ptr))396397(define pointer-vector-ref398 (getter-with-setter399 (lambda (pv i)400 (##sys#check-structure pv 'pointer-vector 'pointer-vector-ref)401 (##sys#check-range i 0 (##sys#slot pv 1)) ; len402 (pv-buf-ref (##sys#slot pv 2) i)) ; buf403 pointer-vector-set!404 "(chicken.memory#pointer-vector-ref pv i)"))405406(define (pointer-vector-length pv)407 (##sys#check-structure pv 'pointer-vector 'pointer-vector-length)408 (##sys#slot pv 1))409410) ; chicken.memory411412413(module chicken.memory.representation414 (block-ref block-set! extend-procedure extended-procedure?415 make-record-instance mutate-procedure! number-of-bytes416 number-of-slots object-become! object-copy procedure-data417 record->vector record-instance-length record-instance-slot418 record-instance-slot-set! record-instance-type record-instance?419 set-procedure-data! vector-like? number-vector-data)420421(import scheme chicken.base chicken.fixnum chicken.foreign)422423424;;; Copy arbitrary object:425426(define (object-copy x)427 (let copy ((x x))428 (cond ((not (##core#inline "C_blockp" x)) x)429 ((symbol? x) (##sys#string->symbol (##sys#slot x 1)))430 (else431 (let* ((n (##sys#size x))432 (words (if (##core#inline "C_byteblockp" x) (##core#inline "C_words" n) n))433 (y (##core#inline "C_copy_block" x (##sys#make-vector words))))434 (unless (##core#inline "C_byteblockp" x)435 (do ((i (if (##core#inline "C_specialp" x) 1 0) (fx+ i 1)))436 ((fx>= i n))437 (##sys#setslot y i (copy (##sys#slot y i)))))438 y)))))439440441;;; Procedures extended with data:442443; Unique id for extended-procedures444(define xproc-tag (vector 'extended))445446(define (extend-procedure proc data)447 (##sys#check-closure proc 'extend-procedure)448 (##sys#decorate-lambda449 proc450 (lambda (x) (and (pair? x) (eq? xproc-tag (##sys#slot x 0))))451 (lambda (x i) (##sys#setslot x i (cons xproc-tag data)) x) ) )452453(define-inline (%procedure-data proc)454 (##sys#lambda-decoration proc (lambda (x) (and (pair? x) (eq? xproc-tag (##sys#slot x 0))))) )455456(define (extended-procedure? x)457 (and (##core#inline "C_blockp" x) (##core#inline "C_closurep" x)458 (%procedure-data x)459 #t) )460461(define (procedure-data x)462 (and (##core#inline "C_blockp" x) (##core#inline "C_closurep" x)463 (and-let* ([d (%procedure-data x)])464 (##sys#slot d 1) ) ) )465466(define (set-procedure-data! proc x)467 (unless (eq? proc (extend-procedure proc x))468 (##sys#signal-hook #:type-error 'set-procedure-data!469 "bad argument type - not an extended procedure" proc)))470471;;; Accessors for arbitrary vector-like block objects:472473(define (vector-like? x) (%generic-vector? x))474475(define block-set! ##sys#block-set!)476477(define block-ref478 (getter-with-setter479 ##sys#block-ref ##sys#block-set! "(chicken.memory.representation#block-ref x i)"))480481(define (number-of-slots x)482 (##sys#check-generic-vector x 'number-of-slots)483 (##sys#size x) )484485(define (number-of-bytes x)486 (cond ((not (##core#inline "C_blockp" x))487 (##sys#signal-hook488 #:type-error 'number-of-bytes489 "cannot compute number of bytes of immediate object" x) )490 ((##core#inline "C_stringp" x)491 (fx- (##sys#size (##sys#slot x 0)) 1))492 ((##core#inline "C_symbolp" x)493 (fx- (##sys#size (##sys#slot x 1)) 1))494 ((##core#inline "C_byteblockp" x)495 (##sys#size x))496 (else497 (##core#inline "C_bytes" (##sys#size x))) ) )498499500;;; Record objects:501502;; Record layout:503;504; 0 Tag (symbol)505; 1..N Slot (object)506507(define (make-record-instance type . args)508 (##sys#check-symbol type 'make-record-instance)509 (apply ##sys#make-structure type args) )510511(define (record-instance? x #!optional type)512 (and (%record-structure? x)513 (or (not type)514 (eq? type (##sys#slot x 0)))) )515516(define (record-instance-type x)517 (##sys#check-generic-structure x 'record-instance-type)518 (##sys#slot x 0) )519520(define (record-instance-length x)521 (##sys#check-generic-structure x 'record-instance-length)522 (fx- (##sys#size x) 1) )523524(define (record-instance-slot-set! x i y)525 (##sys#check-generic-structure x 'record-instance-slot-set!)526 (##sys#check-range i 0 (fx- (##sys#size x) 1) 'record-instance-slot-set!)527 (##sys#setslot x (fx+ i 1) y) )528529(define record-instance-slot530 (getter-with-setter531 (lambda (x i)532 (##sys#check-generic-structure x 'record-instance-slot)533 (##sys#check-range i 0 (fx- (##sys#size x) 1) 'record-instance-slot)534 (##sys#slot x (fx+ i 1)) )535 record-instance-slot-set!536 "(chicken.memory.representation#record-instance-slot x i)"))537538(define (record->vector x)539 (##sys#check-generic-structure x 'record->vector)540 (let* ([n (##sys#size x)]541 [v (##sys#make-vector n)] )542 (do ([i 0 (fx+ i 1)])543 [(fx>= i n) v]544 (##sys#setslot v i (##sys#slot x i)) ) ) )545546547;;; `become':548549(define (object-become! alst)550 (##sys#check-become-alist alst 'object-become!)551 (##sys#become! alst) )552553(define (mutate-procedure! old proc)554 (##sys#check-closure old 'mutate-procedure!)555 (##sys#check-closure proc 'mutate-procedure!)556 (let* ([n (##sys#size old)]557 [words (##core#inline "C_words" n)]558 [new (##core#inline "C_copy_block" old (##sys#make-vector words))] )559 (##sys#become! (list (cons old (proc new))))560 new ) )561562563;;; access backing store of numeric vector564565(define (number-vector-data v)566 (cond ((and (##core#inline "C_blockp" v)567 (##core#inline "C_bytevectorp" v))568 v)569 ((##sys#srfi-4-vector? v) (##sys#slot v 1))570 (else (##sys#signal-hook #:type-error 'number-vector-data571 "bad argument type - not a numeric vector" v))))572573574) ; chicken.memory.representation575576577(module chicken.locative578 (locative? make-locative make-weak-locative579 locative-ref locative-set! locative->object locative-index)580581(import scheme chicken.base)582583;;; locatives:584585;; Locative layout:586;587; 0 Object-address + Byte-offset (address)588; 1 Byte-offset (fixnum)589; 2 Type (fixnum)590; 0 vector or pair (C_SLOT_LOCATIVE)591; 1 string (C_CHAR_LOCATIVE)592; 2 u8vector or bytevector (C_U8_LOCATIVE)593; 3 s8vector (C_S8_LOCATIVE)594; 4 u16vector (C_U16_LOCATIVE)595; 5 s16vector (C_S16_LOCATIVE)596; 6 u32vector (C_U32_LOCATIVE)597; 7 s32vector (C_S32_LOCATIVE)598; 8 u64vector (C_U32_LOCATIVE)599; 9 s64vector (C_S32_LOCATIVE)600; 10 f32vector (C_F32_LOCATIVE)601; 11 f64vector (C_F64_LOCATIVE)602; 3 Object or #f, if weak (C_word)603604(define (make-locative obj . index)605 (##sys#make-locative obj (optional index 0) #f 'make-locative))606607(define (make-weak-locative obj . index)608 (##sys#make-locative obj (optional index 0) #t 'make-weak-locative))609610(define (locative-set! x y) (##core#inline "C_i_locative_set" x y))611612(define locative-ref613 (getter-with-setter614 (lambda (loc)615 (##core#inline_allocate ("C_a_i_locative_ref" 6) loc))616 locative-set!617 "(chicken.locative#locative-ref loc)"))618619(define (locative->object x)620 (##core#inline "C_i_locative_to_object" x))621622(define (locative-index x)623 (##core#inline "C_i_locative_index" x))624625(define (locative? x)626 (and (##core#inline "C_blockp" x) (##core#inline "C_locativep" x))))