source: project/chicken/branches/hygienic/manual/Unit lolevel @ 10804

Last change on this file since 10804 was 10804, checked in by felix winkelmann, 12 years ago

added csi module, some doc fixes

File size: 16.7 KB
Line 
1[[tags: manual internals]]
2[[toc:]]
3
4
5== Unit lolevel
6
7
8This unit provides a number of handy low-level operations. '''Use
9at your own risk.'''
10
11
12This unit uses the {{srfi-4}} and {{extras}} units.
13
14=== Foreign pointers
15
16
17
18==== address->pointer
19
20 [procedure] (address->pointer ADDRESS)
21
22Creates a new foreign pointer object initialized to point to the address
23given in the integer {{ADDRESS}}.
24
25
26==== allocate
27
28 [procedure] (allocate BYTES)
29
30Returns a pointer to a freshly allocated region of static memory.
31This procedure could be defined as follows:
32
33<enscript highlight=scheme>
34(define allocate (foreign-lambda c-pointer "malloc" integer))
35</enscript>
36
37
38==== free
39
40 [procedure] (free POINTER)
41
42Frees the memory pointed to by {{POINTER}}.  This procedure could
43be defined as follows:
44
45<enscript highlight=scheme>
46(define free (foreign-lambda c-pointer "free" integer))
47</enscript>
48
49
50==== null-pointer
51
52 [procedure] (null-pointer)
53
54Another way to say {{(address->pointer 0)}}.
55
56
57==== null-pointer?
58
59 [procedure] (null-pointer? PTR)
60
61Returns {{#t}} if {{PTR}} contains a {{NULL}} pointer,
62or {{#f}} otherwise.
63
64
65==== object->pointer
66
67 [procedure] (object->pointer X)
68
69Returns a pointer pointing to the Scheme object X, which should be a
70non-immediate object.  Note that data in the garbage collected heap
71moves during garbage collection.
72
73
74==== pointer?
75
76 [procedure] (pointer? X)
77
78Returns {{#t}} if {{X}} is a foreign pointer object, and
79{{#f}} otherwise.
80
81==== pointer=?
82
83 [procedure] (pointer=? PTR1 PTR2)
84
85Returns {{#t}} if the pointer-like objects {{PTR1}} and {{PTR2}} point
86to the same address.
87
88
89
90==== pointer->address
91
92 [procedure] (pointer->address PTR)
93
94Returns the address, to which the pointer {{PTR}} points.
95
96
97==== pointer->object
98
99 [procedure] (pointer->object PTR)
100
101Returns the Scheme object pointed to by the pointer {{PTR}}.
102
103
104==== pointer-offset
105
106 [procedure] (pointer-offset PTR N)
107
108Returns a new pointer representing the pointer {{PTR}} increased
109by {{N}}.
110
111
112==== pointer-u8-ref
113
114 [procedure] (pointer-u8-ref PTR)
115
116Returns the unsigned byte at the address designated by {{PTR}}.
117
118
119==== pointer-s8-ref
120
121 [procedure] (pointer-s8-ref PTR)
122
123Returns the signed byte at the address designated by {{PTR}}.
124
125
126==== pointer-u16-ref
127
128 [procedure] (pointer-u16-ref PTR)
129
130Returns the unsigned 16-bit integer at the address designated by {{PTR}}.
131
132
133==== pointer-s16-ref
134
135 [procedure] (pointer-s16-ref PTR)
136
137Returns the signed 16-bit integer at the address designated by {{PTR}}.
138
139
140==== pointer-u32-ref
141
142 [procedure] (pointer-u32-ref PTR)
143
144Returns the unsigned 32-bit integer at the address designated by {{PTR}}.
145
146
147==== pointer-s32-ref
148
149 [procedure] (pointer-s32-ref PTR)
150
151Returns the signed 32-bit integer at the address designated by {{PTR}}.
152
153
154==== pointer-f32-ref
155
156 [procedure] (pointer-f32-ref PTR)
157
158Returns the 32-bit float at the address designated by {{PTR}}.
159
160
161==== pointer-f64-ref
162
163 [procedure] (pointer-f64-ref PTR)
164
165Returns the 64-bit double at the address designated by {{PTR}}.
166
167
168==== pointer-u8-set!
169
170 [procedure] (pointer-u8-set! PTR N)
171 [procedure] (set! (pointer-u8-ref PTR) N)
172
173Stores the unsigned byte {{N}} at the address designated by {{PTR}}.
174
175
176==== pointer-s8-set!
177
178 [procedure] (pointer-s8-set! PTR N)
179 [procedure] (set! (pointer-s8-ref PTR) N)
180
181Stores the signed byte {{N}} at the address designated by {{PTR}}.
182
183
184==== pointer-u16-set!
185
186 [procedure] (pointer-u16-set! PTR N)
187 [procedure] (set! (pointer-u16-ref PTR) N)
188
189Stores the unsigned 16-bit integer {{N}} at the address designated by {{PTR}}.
190
191
192==== pointer-s16-set!
193
194 [procedure] (pointer-s16-set! PTR N)
195 [procedure] (set! (pointer-s16-ref PTR) N)
196
197Stores the signed 16-bit integer {{N}} at the address designated by {{PTR}}.
198
199
200==== pointer-u32-set!
201
202 [procedure] (pointer-u32-set! PTR N)
203 [procedure] (set! (pointer-u32-ref PTR) N)
204
205Stores the unsigned 32-bit integer {{N}} at the address designated by {{PTR}}.
206
207
208==== pointer-s32-set!
209
210 [procedure] (pointer-s32-set! PTR N)
211 [procedure] (set! (pointer-s32-ref PTR) N)
212
213Stores the 32-bit integer {{N}} at the address designated by {{PTR}}.
214
215
216==== pointer-f32-set!
217
218 [procedure] (pointer-f32-set! PTR N)
219 [procedure] (set! (pointer-f32-ref PTR) N)
220
221Stores the 32-bit floating-point number {{N}} at the address designated by {{PTR}}.
222
223
224==== pointer-f64-set!
225
226 [procedure] (pointer-f64-set! PTR N)
227 [procedure] (set! (pointer-f64-ref PTR) N)
228
229Stores the 64-bit floating-point number {{N}} at the address designated by {{PTR}}.
230
231
232==== align-to-word
233
234 [procedure] (align-to-word PTR-OR-INT)
235
236Accepts either a machine pointer or an integer as argument and returns
237a new pointer or integer aligned to the native word size of the host
238platform.
239
240
241
242
243
244=== Tagged pointers
245
246''Tagged'' pointers are foreign pointer objects with an extra tag object.
247
248
249
250==== tag-pointer
251
252 [procedure] (tag-pointer PTR TAG)
253
254Creates a new tagged pointer object from the foreign pointer {{PTR}} with the
255tag {{TAG}}, which may an arbitrary Scheme object.
256
257
258==== tagged-pointer?
259
260 [procedure] (tagged-pointer? X TAG)
261
262Returns {{#t}}, if {{X}} is a tagged pointer object with the tag {{TAG}}
263(using an {{eq?}} comparison), or {{#f}} otherwise.
264
265
266==== pointer-tag
267
268 [procedure] (pointer-tag PTR)
269
270If {{PTR}} is a tagged pointer object, its tag is returned. If {{PTR}} is a normal,
271untagged foreign pointer object {{#f}} is returned. Otherwise an error is signalled.
272
273
274
275
276
277=== Extending procedures with data
278
279
280
281
282==== extend-procedure
283
284 [procedure] (extend-procedure PROCEDURE X)
285
286Returns a copy of the procedure {{PROCEDURE}} which contains an
287additional data slot initialized to {{X}}. If {{PROCEDURE}}
288is already an extended procedure, then its data slot is changed to
289contain {{X}} and the same procedure is returned.
290
291
292==== extended-procedure?
293
294 [procedure] (extended-procedure? PROCEDURE)
295
296Returns {{#t}} if {{PROCEDURE}} is an extended procedure,
297or {{#f}} otherwise.
298
299
300==== procedure-data
301
302 [procedure] (procedure-data PROCEDURE)
303
304Returns the data object contained in the extended procedure {{PROCEDURE}},
305or {{#f}} if it is not an extended procedure.
306
307
308==== set-procedure-data!
309
310 [procedure] (set-procedure-data! PROCEDURE X)
311
312Changes the data object contained in the extended procedure
313{{PROCEDURE}} to {{X}}.
314
315<enscript highlight=scheme>
316(define foo
317  (letrec ((f (lambda () (procedure-data x)))
318           (x #f) )
319    (set! x (extend-procedure f 123))
320    x) )
321(foo)                                         ==> 123
322(set-procedure-data! foo 'hello)
323(foo)                                         ==> hello
324</enscript>
325
326
327
328=== Data in unmanaged memory
329
330
331
332
333==== object-evict
334
335 [procedure] (object-evict X [ALLOCATOR])
336
337Copies the object {{X}} recursively into the memory pointed
338to by the foreign pointer object returned by {{ALLOCATOR}},
339which should be a procedure of a single argument (the number of bytes
340to allocate). The freshly copied object is returned.  This facility
341allows moving arbitrary objects into static memory, but care should be
342taken when mutating evicted data: setting slots in evicted vector-like
343objects to non-evicted data is not allowed. It '''is''' possible to
344set characters/bytes in evicted strings or byte-vectors, though.  It is
345advisable '''not''' to evict ports, because they might be mutated by
346certain file-operations.  {{object-evict}} is able to handle circular and
347shared structures, but evicted symbols are no longer unique: a fresh
348copy of the symbol is created, so
349
350<enscript highlight=scheme>
351(define x 'foo)
352(define y (object-evict 'foo))
353y                              ==> foo
354(eq? x y)                      ==> #f
355(define z (object-evict '(bar bar)))
356(eq? (car z) (cadr z))         ==> #t
357</enscript>
358
359The {{ALLOCATOR}} defaults to {{allocate}}.
360
361
362==== object-evict-to-location
363
364 [procedure] (object-evict-to-location X PTR [LIMIT])
365
366As {{object-evict}} but moves the object at the address pointed to by
367the machine pointer {{PTR}}. If the number of copied bytes exceeds
368the optional {{LIMIT}} then an error is signalled (specifically a composite
369condition of types {{exn}} and {{evict}}. The latter provides
370a {{limit}} property which holds the exceeded limit. Two values are
371returned: the evicted object and a new pointer pointing to the first
372free address after the evicted object.
373
374
375==== object-evicted?
376
377 [procedure] (object-evicted? X)
378
379Returns {{#t}} if {{X}} is a non-immediate evicted data object,
380or {{#f}} otherwise.
381
382
383==== object-size
384
385 [procedure] (object-size X)
386
387Returns the number of bytes that would be needed to evict the data
388object {{X}}.
389
390
391==== object-release
392
393 [procedure] (object-release X [RELEASER])
394
395Frees memory occupied by the evicted object {{X}} recursively.
396{{RELEASER}} should be a procedure of a single argument (a foreign
397pointer object to the static memory to be freed) and defaults to
398{{free}}.
399
400
401==== object-unevict
402
403 [procedure] (object-unevict X [FULL])
404
405Copies the object {{X}} and nested objects back into the normal
406Scheme heap.  Symbols are re-interned into the symbol table. Strings
407and byte-vectors are '''not''' copied, unless {{FULL}} is given and
408not {{#f}}.
409
410
411
412
413
414=== Locatives
415
416
417A ''locative'' is an object that points to an element of a containing object,
418much like a ''pointer'' in low-level, imperative programming languages like ''C''. The element can
419be accessed and changed indirectly, by performing access or change operations
420on the locative. The container object can be computed by calling the
421{{location->object}} procedure.
422
423Locatives may be passed to foreign procedures that expect pointer arguments.
424The effect of creating locatives for evicted data (see {{object-evict}}) is undefined.
425
426
427
428==== make-locative
429
430 [procedure] (make-locative EXP [INDEX])
431
432Creates a locative that refers to the element of the non-immediate object {{EXP}}
433at position {{INDEX}}. {{EXP}} may be a vector, pair, string, blob,
434SRFI-4 number-vector, or record. {{INDEX}} should be a fixnum. {{INDEX}} defaults to 0.
435
436
437==== make-weak-locative
438
439 [procedure] (make-weak-locative EXP [INDEX])
440
441Creates a ''weak'' locative. Even though the locative refers to an element of a container object,
442the container object will still be reclaimed by garbage collection if no other references
443to it exist.
444
445
446==== locative?
447
448 [procedure] (locative? X)
449
450Returns {{#t}} if {{X}} is a locative, or {{#f}} otherwise.
451
452
453==== locative-ref
454
455 [procedure] (locative-ref LOC)
456
457Returns the element to which the locative {{LOC}} refers. If the containing
458object has been reclaimed by garbage collection, an error is signalled.
459
460
461==== locative-set!
462
463 [procedure] (locative-set! LOC X)
464 [procedure] (set! (locative-ref LOC) X)
465
466Changes the element to which the locative {{LOC}} refers to {{X}}.
467If the containing
468object has been reclaimed by garbage collection, an error is signalled.
469
470
471==== locative->object
472
473 [procedure] (locative->object LOC)
474
475Returns the object that contains the element referred to by {{LOC}} or
476{{#f}} if the container has been reclaimed by garbage collection.
477
478
479
480
481
482=== Accessing toplevel variables
483
484
485
486
487==== global-bound?
488
489 [procedure] (global-bound? SYMBOL)
490
491Returns {{#t}}, if the global (''toplevel'') variable with the name {{SYMBOL}}
492is bound to a value, or {{#f}} otherwise.
493
494
495==== global-ref
496
497 [procedure] (global-ref SYMBOL)
498
499Returns the value of the global variable {{SYMBOL}}.
500If no variable under that name is bound, an error is signalled.
501
502Note that it is not possible to access a toplevel binding with {{global-ref}} or
503{{global-set!}} if it has been hidden in compiled code via {{(declare (hide ...))}},
504or if the code has been compiled in {{block}} mode.
505
506
507==== global-set!
508
509 [procedure] (global-set! SYMBOL X)
510 [procedure] (set! (global-ref SYMBOL) X)
511
512Sets the global variable named {{SYMBOL}} to the value {{X}}.
513
514
515
516
517
518=== Low-level data access
519
520
521==== block-ref
522
523 [procedure] (block-ref BLOCK INDEX)
524
525Returns the contents of the {{INDEX}}th slot of the object
526{{BLOCK}}.  {{BLOCK}} may be a vector, record structure,
527pair or symbol.
528
529
530==== block-set!
531
532 [procedure] (block-set! BLOCK INDEX X)
533 [procedure] (set! (block-ref BLOCK INDEX) X)
534
535Sets the contents of the {{INDEX}}th slot of the object
536{{BLOCK}} to the value of {{X}}.  {{BLOCK}} may be a
537vector, record structure, pair or symbol.
538
539
540==== object-copy
541
542 [procedure] (object-copy X)
543
544Copies {{X}} recursively and returns the fresh copy. Objects
545allocated in static memory are copied back into garbage collected storage.
546
547
548==== make-record-instance
549
550 [procedure] (make-record-instance SYMBOL ARG1 ...)
551
552Returns a new instance of the record type {{SYMBOL}}, with its
553slots initialized to {{ARG1 ...}}.  To illustrate:
554
555<enscript highlight=scheme>
556(define-record-type point (make-point x y) point?
557  (x point-x point-x-set!)
558  (y point-y point-y-set!))
559</enscript>
560
561expands into something quite similar to:
562
563<enscript highlight=scheme>
564(begin
565  (define (make-point x y)
566    (make-record-instance 'point x y) )
567  (define (point? x)
568    (and (record-instance? x)
569         (eq? 'point (block-ref x 0)) ) )
570  (define (point-x p) (block-ref p 1))
571  (define (point-x-set! p x) (block-set! p 1 x))
572  (define (point-y p) (block-ref p 2))
573  (define (point-y-set! p y) (block-set! p 1 y)) )
574</enscript>
575
576
577==== move-memory!
578
579 [procedure] (move-memory! FROM TO [BYTES [FROM-OFFSET [TO-OFFSET]])
580
581Copies {{BYTES}} bytes of memory from {{FROM}} to {{TO}}.
582{{FROM}} and {{TO}} may be strings, primitive byte-vectors,
583SRFI-4 byte-vectors (see: @ref{Unit srfi-4}), memory mapped files, foreign
584pointers (as obtained from a call to {{foreign-lambda}}, for
585example) or locatives. if {{BYTES}} is not given and the size of the source
586or destination operand is known then the maximal number of bytes will
587be copied. Moving memory to the storage returned by locatives will cause havoc,
588if the locative refers to containers of non-immediate data, like vectors
589or pairs.
590
591The additional fourth and fifth argument specify starting offsets
592(in bytes) for the source and destination arguments.
593
594
595==== number-of-bytes
596
597 [procedure] (number-of-bytes BLOCK)
598
599Returns the number of bytes that the object {{BLOCK}} contains.
600{{BLOCK}} may be any non-immediate value.
601
602
603==== number-of-slots
604
605 [procedure] (number-of-slots BLOCK)
606
607Returns the number of slots that the object {{BLOCK}} contains.
608{{BLOCK}} may be a vector, record structure, pair or symbol.
609
610
611==== record-instance?
612
613 [procedure] (record-instance? X)
614
615Returns {{#t}} if {{X}} is an instance of a record type.
616See also: {{make-record-instance}}.
617
618
619==== record->vector
620
621 [procedure] (record->vector BLOCK)
622
623Returns a new vector with the type and the elements of the record {{BLOCK}}.
624
625
626
627=== Procedure-call- and variable reference hooks
628
629
630==== set-invalid-procedure-call-handler!
631
632 [procedure] (set-invalid-procedure-call-handler! PROC)
633
634Sets an internal hook that is invoked when a call to an object other than a procedure
635is executed at runtime. The procedure {{PROC}} will in that case be called
636with two arguments: the object being called and a list of the passed arguments.
637
638<enscript highlight=scheme>
639;;; Access sequence-elements as in ARC:
640
641(set-invalid-procedure-call-handler!
642  (lambda (proc args)
643    (cond [(string? proc) (apply string-ref proc args)]
644          [(vector? proc) (apply vector-ref proc args)]
645          [else (error "call of non-procedure" proc)] ) ) )
646
647("hello" 4)    ==>  #\o
648</enscript>
649
650This facility does not work in code compiled with the ''unsafe'' setting.
651
652
653==== unbound-variable-value
654
655 [procedure] (unbound-variable-value [X])
656
657Defines the value that is returned for unbound variables. Normally an error
658is signalled, use this procedure to override the check and return {{X}}
659instead. To set the default behavior (of signalling an error), call
660{{unbound-variable-value}} with no arguments.
661
662This facility does not work in code compiled with the ''unsafe'' setting.
663
664
665
666
667
668=== Magic
669
670
671==== object-become!
672
673 [procedure] (object-become! ALIST)
674
675Changes the identity of the value of the car of each pair in
676{{ALIST}} to the value of the cdr. Both values may not be immediate
677(i.e. exact integers, characters, booleans or the empty list).
678
679<enscript highlight=scheme>
680(define x "i used to be a string")
681(define y '#(and now i am a vector))
682(object-become! (list (cons x y)))
683x                                    ==> #(and now i am a vector)
684y                                    ==> #(and now i am a vector)
685(eq? x y)                            ==> #t
686</enscript>
687
688Note: this operation invokes a major garbage collection.
689
690The effect of using {{object-become!}} on evicted data (see {{object-evict}})
691is undefined.
692
693
694==== mutate-procedure
695
696 [procedure] (mutate-procedure OLD PROC)
697
698Replaces the procedure {{OLD}} with the result of calling the one-argument
699procedure {{PROC}}. {{PROC}} will receive a copy of {{OLD}} that will
700be identical in behaviour to the result of {{PROC}}:
701
702<enscript highlight=scheme>
703;;; Replace arbitrary procedure with tracing one:
704
705(mutate-procedure my-proc
706  (lambda (new)
707    (lambda args
708      (printf "~s called with arguments: ~s~%" new args)
709      (apply new args) ) ) )
710</enscript>
711
712
713Previous: [[Unit tcp]]
714
715Next: [[Interface to external functions and variables]]
716
Note: See TracBrowser for help on using the repository browser.