source: project/wiki/Unit lolevel @ 5530

Last change on this file since 5530 was 5530, checked in by Kon Lovett, 13 years ago

Udpate for blob move to library unit.

File size: 16.6 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 point x y)
557</enscript>
558
559expands into something quite similar to:
560
561<enscript highlight=scheme>
562(begin
563  (define (make-point x y)
564    (make-record-instance 'point x y) )
565  (define (point? x)
566    (and (record-instance? x)
567         (eq? 'point (block-ref x 0)) ) )
568  (define (point-x p) (block-ref p 1))
569  (define (point-x-set! p x) (block-set! p 1 x))
570  (define (point-y p) (block-ref p 2))
571  (define (point-y-set! p y) (block-set! p 1 y)) )
572</enscript>
573
574
575==== move-memory!
576
577 [procedure] (move-memory! FROM TO [BYTES [FROM-OFFSET [TO-OFFSET]])
578
579Copies {{BYTES}} bytes of memory from {{FROM}} to {{TO}}.
580{{FROM}} and {{TO}} may be strings, primitive byte-vectors,
581SRFI-4 byte-vectors (see: @ref{Unit srfi-4}), memory mapped files, foreign
582pointers (as obtained from a call to {{foreign-lambda}}, for
583example) or locatives. if {{BYTES}} is not given and the size of the source
584or destination operand is known then the maximal number of bytes will
585be copied. Moving memory to the storage returned by locatives will cause havoc,
586if the locative refers to containers of non-immediate data, like vectors
587or pairs.
588
589The additional fourth and fifth argument specify starting offsets
590(in bytes) for the source and destination arguments.
591
592
593==== number-of-bytes
594
595 [procedure] (number-of-bytes BLOCK)
596
597Returns the number of bytes that the object {{BLOCK}} contains.
598{{BLOCK}} may be any non-immediate value.
599
600
601==== number-of-slots
602
603 [procedure] (number-of-slots BLOCK)
604
605Returns the number of slots that the object {{BLOCK}} contains.
606{{BLOCK}} may be a vector, record structure, pair or symbol.
607
608
609==== record-instance?
610
611 [procedure] (record-instance? X)
612
613Returns {{#t}} if {{X}} is an instance of a record type.
614See also: {{make-record-instance}}.
615
616
617==== record->vector
618
619 [procedure] (record->vector BLOCK)
620
621Returns a new vector with the type and the elements of the record {{BLOCK}}.
622
623
624
625=== Procedure-call- and variable reference hooks
626
627
628==== set-invalid-procedure-call-handler!
629
630 [procedure] (set-invalid-procedure-call-handler! PROC)
631
632Sets an internal hook that is invoked when a call to an object other than a procedure
633is executed at runtime. The procedure {{PROC}} will in that case be called
634with two arguments: the object being called and a list of the passed arguments.
635
636<enscript highlight=scheme>
637;;; Access sequence-elements as in ARC:
638
639(set-invalid-procedure-call-handler!
640  (lambda (proc args)
641    (cond [(string? proc) (apply string-ref proc args)]
642          [(vector? proc) (apply vector-ref proc args)]
643          [else (error "call of non-procedure" proc)] ) ) )
644
645("hello" 4)    ==>  #\o
646</enscript>
647
648This facility does not work in code compiled with the ''unsafe'' setting.
649
650
651==== unbound-variable-value
652
653 [procedure] (unbound-variable-value [X])
654
655Defines the value that is returned for unbound variables. Normally an error
656is signalled, use this procedure to override the check and return {{X}}
657instead. To set the default behavior (of signalling an error), call
658{{unbound-variable-value}} with no arguments.
659
660This facility does not work in code compiled with the ''unsafe'' setting.
661
662
663
664
665
666=== Magic
667
668
669==== object-become!
670
671 [procedure] (object-become! ALIST)
672
673Changes the identity of the value of the car of each pair in
674{{ALIST}} to the value of the cdr. Both values may not be immediate
675(i.e. exact integers, characters, booleans or the empty list).
676
677<enscript highlight=scheme>
678(define x "i used to be a string")
679(define y '#(and now i am a vector))
680(object-become! (list (cons x y)))
681x                                    ==> #(and now i am a vector)
682y                                    ==> #(and now i am a vector)
683(eq? x y)                            ==> #t
684</enscript>
685
686Note: this operation invokes a major garbage collection.
687
688The effect of using {{object-become!}} on evicted data (see {{object-evict}})
689is undefined.
690
691
692==== mutate-procedure
693
694 [procedure] (mutate-procedure OLD PROC)
695
696Replaces the procedure {{OLD}} with the result of calling the one-argument
697procedure {{PROC}}. {{PROC}} will receive a copy of {{OLD}} that will
698be identical in behaviour to the result of {{PROC}}:
699
700<enscript highlight=scheme>
701;;; Replace arbitrary procedure with tracing one:
702
703(mutate-procedure my-proc
704  (lambda (new)
705    (lambda args
706      (printf "~s called with arguments: ~s~%" new args)
707      (apply new args) ) ) )
708</enscript>
709
710
711Previous: [[Unit tcp]]
712
713Next: [[Interface to external functions and variables]]
714
Note: See TracBrowser for help on using the repository browser.