forked from shirok/Gauche
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgauche-dev.texi
4077 lines (3244 loc) · 151 KB
/
gauche-dev.texi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
@c EN
\input texinfo @c -*- mode: texinfo; coding: utf-8; -*-
@c JP
\input texinfo-ja @c -*- mode: texinfo; coding: utf-8; -*-
@c COMMON
@comment %**start of header
@documentencoding UTF-8
@c EN
@documentlanguage en
@setfilename gauche-deve.info
@settitle Gauche Developers' Reference
@dircategory The Algorithmic Language Scheme
@direntry
* Gauche Developers' Reference: (gauche-deve.info). Internals of Gauche
@end direntry
@c JP
@documentlanguage ja
@setfilename gauche-devj.info
@settitle Gauche Developers' Reference
@dircategory The Algorithmic Language Scheme
@direntry
* Gauche Developers' Reference (ja): (gauche-devj.info). Internals of Gauche
@end direntry
@c COMMON
@comment %**end of header
@titlepage
@c EN
@title Gauche Developers' Reference
@c JP
@title Gauche Developers' Reference
@c COMMON
@subtitle version @VERSION@
@author Shiro Kawai (shiro@@acm.org)
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 2009-2024 Shiro Kawai <shiro@@acm.org>
@end titlepage
@node Top, Introduction, (dir), (dir)
@ifnottex
This document explains the internal guts of Gauche
for developers who want to extend Gauche functionality in C,
or to embed Gauche to other applications.
This manual is for version @VERSION@.
@end ifnottex
@menu
* Introduction::
* Getting started::
* Fundamental concepts::
* Real-life examples::
* C API reference::
* Creating new Scheme datatypes::
* Helper program reference::
* Indices::
@end menu
@c ======================================================================
@node Introduction, Getting started, Top, Top
@chapter Introduction
The core part of the Gauche runtime is written in C and provided
as a library, @file{libgauche}. This document explains how to
use it from C. Using C API, you can extend Gauche's
functionality (e.g. providing bindinds to the existing C library),
and also link @file{libgauche} to your application, making
Gauche as an embedded scripting language.
Gauche's C API is designed for efficiency, consistency,
simplicity and safety, roughly in this order of precedence.
That is, sometimes we omit a safety net for efficiency, or we provide
several different APIs, each of which is efficient for a particular
purpose, rather than simple generic interface with overhead.
By saying efficiency over safety doesn't mean Gauche has security
holes, but we do assume you know what you're doing. If you need
safety nets, you can write in Scheme and call it from C.
That said, it won't be too difficult to use Gauche's C API
as far as you know some fundamental design concepts.
We intend this document to serve both a programmer's guide
that explains such design concepts, and a programmer's reference
that describes every C API in detail.
The guide part begins with @ref{Getting started}, that shows
how to write a simple Gauche extension in C, as well as
a simple application that embeds Gauche. It gives an overview
of the whole process.
The following chapter, @ref{Fundamental concepts}, describes
the design behind the API. We strongly recommend you to
understand this chapter before trying to use Gauche C API
seriously. As we mentioned above, it is very easy to break
something without knowing those concepts.
The guide part concludes with @ref{Real-life examples}, that
explains pitfalls in the practical situations using excerpt
of the actual Gauche extension code.
The reference part consists of two chapters: @ref{C API reference}
lists all the public C API. @ref{Helper program reference}
explains several programs installed as a part of Gauche Scheme
system to help program development.
@c ======================================================================
@node Getting started, Fundamental concepts, Introduction, Top
@chapter Getting started
This chapter explains the basics of how to use Gauche C API
by several simple examples.
Although each example is too small to be practical value,
we try to present working code for each example, so that you
can actually play with it. We recommend you to read through
all examples, for we introduce new concepts in each step.
We deal with the advanced topics that arise in the practical
situation in @ref{Real-life examples}.
The prerequisites for building Gauche extension, besides
the basic compiler chain, are the followings. We assume
these are installed in your system.
@itemize @bullet
@item
Gauche 0.9.10 or later
@item
A compiler suite compatible to the one used to build @file{libgauche}.
@end itemize
@menu
* A trivial extension::
* Simple readline binding::
@end menu
@node A trivial extension, Simple readline binding, Getting started, Getting started
@section A trivial extension
@menu
* Generating skeletons::
* Building the trivial module::
* The templates explained::
* Introduction of the stub file::
@end menu
@node Generating skeletons, Building the trivial module, A trivial extension, A trivial extension
@subsection Generating skeletons
Let's create a Gauche extension that does nothing.
Gauche can generate a skeleton of the extension code
by @code{gauche-package generate} command. You give the
package name to the command-line argument (here we pick @code{trivial}).
@smallexample
% @b{ls trivial}
ls: trivial: No such file or directory
% @b{gauche-package generate trivial}
% @b{ls trivial}
configure package.scm trivial.c triviallib.stub
Makefile.in test.scm trivial.h trivial.scm
@end smallexample
The @code{gauche-package} command creates a directory @file{trivial},
and populates it with template files. The role of each file is shown
below.
@table @emph
@item Package description (@file{package.scm})
This file contains metainformation about the extension,
such as version, dependency, license or repository URL.
@item Glue code (@file{trivial.c} and @file{trivial.h})
If what you want to do is just to write C functions and make it
available from Scheme, the function definitions and declarations
would go to these files.
Even if what you want to do is just to write bindings to
an existing library, it is typical that you need small amount
of auxiliary management code, such as initializing the library
and allocating/freeing library-side data structures.
@item Stub file (@file{triviallib.stub})
This file is the bridge between C world and Scheme world.
You have to list C functions you want to make it visible from
Scheme world. Because of its nature, this file looks like
a mixture of Scheme code and C code fragments.
When the package is compiled, Gauche's helper scripts generate
a C file from a stub file, and compile it with other glue code
to generate a dynamically loadable object code, called DLL
(dynamically loadable library) or SO (shared object), depending
on the platform.
(Note: We're in middle of the process of retiring @file{*.stub} file;
instead, you'll be able to mix Scheme and C code in @file{*.scm} file
that will be compiled into DSO. The extensions bundled with the Gauche
distribution, and several Gauche extensions, have already been switched;
you can take a peek and maybe start trying it. The detailed specification
of this @emph{precompilation}, or ahead-of-time compilation, is still
fluid and may be changed in incompatible way, though.)
@item Module file (@file{trivial.scm})
This file typically defines Gauche modules and sets exported
symbols, and dynamically loads the compiled object code.
You may put auxiliary Scheme code in it.
@item Makefile template (@file{Makefile.in})
Gauche relies on the traditional build workflow---you run @file{configure}
script to generate @file{Makefile} that is tailored for your system.
Sticking to good old @code{make} makes it easy to incorporate
third party libraries.
@item Configure script (@file{configure})
This is a script that generates @file{Makefile} from @file{Makefile.in}.
Edit this if you need other files to be tailored, or need to test
other features on the platform.
We used to use GNU @code{autoconf} to generate @file{configure},
but we're moving away from it. GNU @code{autoconf} is a fine tool
with lots of practical knowledge had put into development, but its
premise is that you have limited set of tools on the platform where
you compile the software, and that limitation makes the pipeline
complicated.
When you build Gauche extension, we already know you have Gauche
installed, so we can use Gauche's features to do configuration
work instead of relying on shell and other limited set of command-line
tools. It is especially handy since we no longer need an extra
pass to generate @file{configure} from @file{configure.ac}. With
the power of Gauche you can write @file{configure} file directly,
and you can check it in to VCS. The users won't need @code{autoconf}
to build from the (unpreprocessed) source tree.
We try to match the interface of @file{configure} script to
@code{autoconf}-generated ones; it accepts most of the standard
options such as @code{--prefix}.
@item Unit test (@file{test.scm})
It is strongly encouraged to include unit test in your package,
and this file contains the skeleton of it. The package user
can run the test by @code{make check}.
@end table
@node Building the trivial module, The templates explained, Generating skeletons, A trivial extension
@subsection Building, testing and installing the trivial module
These auto-generated files are already buildable.
First, you need to
run the @file{configure} script to
generate @file{Makefile}, then run @code{make}.
@smallexample
% @b{cd trivial}
% @b{./configure}
checking for gosh... /usr/bin/gosh
checking for gauche-config... /usr/bin/gauche-config
checking for gauche-package... /usr/bin/gauche-package
checking for gauche-install... /usr/bin/gauche-install
checking for gauche-cesconv... /usr/bin/gauche-cesconv
configure: creating trivial.gpd
configure: creating Makefile
% @b{make}
/usr/bin/gauche-package compile --verbose trivial trivial.c triviallib.stub
@i{(... message truncated ...)}
% @b{ls}
Makefile config.log trivial.c trivial.o triviallib.o
Makefile.in configure trivial.gpd trivial.scm triviallib.stub
VERSION test.scm trivial.h trivial.so
@end smallexample
The build process creates @file{trivial.so}, the dynamically loadable
object file (the actual suffix may differ on some OSes).
Now it's ready to load the extension into Gauche. The skeleton code
defines a Scheme function @code{test-trivial}, which just returns
a string. Run the Gauche interpreter, load the @code{trivial} module,
and call @code{test-trivial} function. Note that you need to give
@code{-I.} option to @code{gosh}, so that Gauche can find the @file{trivial}
module files.
@smallexample
% @b{gosh -I.}
gosh> @b{(use trivial)}
gosh> @b{(test-trivial)}
"trivial is working"
gosh>
@end smallexample
You may have noticed a file @file{trivial.gpd}. The unfamiliar
suffix @code{gpd} stands for ``Gauche package description''.
It is created by @file{configure}, and records the name and version
of the package, and the configure options. It is installed as a part
of the package and will be used by @code{gauche-package} script
(e.g. @code{gauche-package list} lists the installed packages).
You can also run a unit test by @code{make check}.
@smallexample
% make check
/usr/bin/gosh -I. test.scm > test.log
Testing trivial ... passed.
@end smallexample
For now, it just checks if the compiled extension can be loaded,
and the integrity of the module. As you add APIs in the extension,
you're expected to add tests as well.
Finally, you can install the extension by @code{make install}.
@smallexample
% make install
/usr/bin/gauche-install -m 444 -T /usr/lib/gauche/site/include
/usr/bin/gauche-install -m 444 -T /usr/share/gauche/site/lib trivial.scm
/usr/bin/gauche-install -m 555 -T /usr/lib/gauche/site/0.8.8/i686-pc-linux-gnu trivial.so
/usr/bin/gauche-install -m 444 -T /usr/share/gauche/site/lib/.packages trivial.gpd
@end smallexample
By default, the files are installed in the site-specific area
reserved within the installed Gauche.
If you want to change the install location, you can do the
same as typical autoconfigured softwares; e.g. giving
@code{--prefix} option to the @code{configure} script.
@node The templates explained, Introduction of the stub file, Building the trivial module, A trivial extension
@subsection The templates explained
@node Introduction of the stub file, , The templates explained, A trivial extension
@subsection Introduction of the stub file
@node Simple readline binding, , A trivial extension, Getting started
@section Simple readline binding
@c ======================================================================
@node Fundamental concepts, Real-life examples, Getting started, Top
@chapter Fundamental concepts
@menu
* Naming convention::
* Scheme types and C types::
* Memories::
* The VM::
* CPS API::
@end menu
@node Naming convention, Scheme types and C types, Fundamental concepts, Fundamental concepts
@section Naming convention
@c Memo:
@c Scm_XXXXSet(XXXX xxxx, ...) - operation to modify xxxx.
@c Scm_SetXXXX(...) - operation to modify some global (or per-vm) value.
@node Scheme types and C types, Memories, Naming convention, Fundamental concepts
@section Scheme types and C types
@node Memories, The VM, Scheme types and C types, Fundamental concepts
@section Memories
@node The VM, CPS API, Memories, Fundamental concepts
@section The VM
@node CPS API, , The VM, Fundamental concepts
@section CPS API
@c ======================================================================
@node Real-life examples, C API reference, Fundamental concepts, Top
@chapter Real-life examples
To be written. Meanwhile have a look at @file{examples/mqueue-cpp/README.adoc}
in the Gauche source tree.
@c ======================================================================
@node C API reference, Creating new Scheme datatypes, Real-life examples, Top
@chapter C API reference
In this chapter we describe most of public C APIs provided by
libgauche. We say `most' because the features to let you create
a new Scheme datatype requires dedicated chapter,
@ref{Creating new Scheme datatypes}.
@menu
* Representation of Scheme objects::
* Initialization and cleanup::
* Memory allocation and GC::
* Booleans::
* Numbers::
* Pairs and lists::
* Symbols::
* Glocs::
* Modules::
* Characters::
* Character sets::
* Strings::
* Regular expressions::
* Vectors::
* Dictionaries::
* Weak pointers::
* Exceptions::
* Calling back to Scheme::
* Input and output::
* Loading programs::
* System interface::
@end menu
@node Representation of Scheme objects, Initialization and cleanup, C API reference, C API reference
@section Representation of Scheme objects
@deftp {Type} ScmObj
Scheme objects are uniformly treated as of type @code{ScmObj},
which may be either a tagged pointer to a heap allocated object
or a tagged immediate value.
Most Scheme objects are heap allocated, and except Scheme pairs,
heap allocated Scheme object has a fixed header. We don't go
into more details here, but we'll revisit this topic in
@ref{Creating new Scheme datatypes}. Certain frequently used
Scheme objects, such as boolean values, small exact integers
and characters, are encoded in a word without allocating
objects in heap, and we call them @emph{immediate values}.
Querying the type of a Scheme object and accessing its fields
should be done via provided macros or APIs. The user code must
treat @code{ScmObj} as an opaque word, since the internal
representation may change.
The standard way to treat @code{ScmObj} value is (1) check to see
if its type matches what you expect, and (2) cast @code{ScmObj} to
the actual type and use it, as the following example shows.
@example
void your_C_function(ScmObj arg)
@{
if (SCM_STRINGP(arg)) @{ /* check */
ScmString *s = SCM_STRING(arg); /* cast */
do_whatever_you_like_with_scheme_string(s);
@} else @{
SCM_TYPE_ERROR(arg, "a string");
@}
@}
@end example
The @code{SCM_TYPE_ERROR} macro raises an error reporting
"a string is required for arg, but got ...". That's a convenient
way to report the wrong type argument. See @ref{Exceptions}
for more details of reporting errors.
Although it is not always checked explicitly, the programmer should
keep in mind that C's @code{NULL} is never a valid value for @code{ScmObj}.
If a C API requires @code{ScmObj} as an argument, you shouldn't pass
@code{NULL} to it. Also if your function returns @code{ScmObj},
you should make sure it will never return @code{NULL}.
@end deftp
@deftypefn {Macro} ScmObj SCM_OBJ (void *@var{obj})
Typecast @var{obj} to @code{ScmObj}. @var{Obj} must be
a pointer to an actual Scheme object.
@end deftypefn
We describe a few special constant Scheme objects here:
@deftypevr {Macro} ScmObj SCM_EOF
The Scheme's @code{#<eof>} object.
@end deftypevr
@deftypevr {Macro} ScmObj SCM_UNDEFINED
The Gauche's @code{#<undef>} object. In Gauche, it is used as a
placeholder where the value itself doesn't matter. At the time of
writing this document, there's a discussion in the next Scheme standard
to define @emph{the `unspecified' value} for this purpose, and it is
likely that this value will become such a value.
@end deftypevr
@deftypevr {Macro} ScmObj SCM_UNBOUND
This is a special value only seen in C world, and used to indicate
that a variable hasn't got a Scheme value assigned. For example,
if a Scheme procedure with an optional argument is defined in C,
and no value is passed to the optional argument, @code{SCM_UNBOUND}
is given in C world. This value should never be leaked out to
Scheme world.
@end deftypevr
@deftypefn {Macro} int SCM_EOFP (ScmObj @var{obj})
@deftypefnx {Macro} int SCM_UNDEFINEDP (ScmObj @var{obj})
@deftypefnx {Macro} int SCM_UNBOUNDP (ScmObj @var{obj})
Predicates to check whether the given @var{obj} is @code{SCM_EOF},
@code{SCM_UNDEFINED}, or @code{SCM_UNBOUND}, respectively.
@end deftypefn
@node Initialization and cleanup, Memory allocation and GC, Representation of Scheme objects, C API reference
@section Initialization and cleanup
This section explains how to initialize Gauche scheme runtime,
and how to clean it up.
These functions are for the applications that uses Gauche as
an embedded Scheme engine; when you're writing Gauche extensions,
you don't (and shouldn't) use these functions.
@subsubheading Initialization
@deftypefun void Scm_Init (const char *@var{signature})
Initializes the runtime. Must be called before any other
Gauche API call.
To @var{signature}, you should always
pass a macro @code{GAUCHE_SIGNATURE}. It is used to check a
proper version of Gauche shared library is linked. If you
have several version of Gauche libraries (e.g. different
encoding or thread configuration), accidentally linking
unintended version would cause mysterious runtime crash.
If the signature doesn't match the library's, this function
exits the process with a message explaining it.
@end deftypefun
@subsubheading Cleanup and termination
@deftypefun void Scm_Exit (int @var{code})
Exits the process with @var{code} as the exit code.
Calling @code{Scm_Exit} is the easiest way to terminate Gauche
application safely. It runs pending dynamic handlers,
registered cleanup handlers (see below), flushes output ports,
then calls @code{exit(2)} to exit.
Directly calling @code{exit(2)} would skip all those cleanup
process.
@end deftypefun
@deftypefun void Scm_Cleanup (void)
Cleans up the Scheme runtime just like @code{Scm_Exit()},
but does not call @code{exit(2)} at the end. This is useful
for applications that want to shut down Gauche runtime but
need to continue running.
Once you call @code{Scm_Cleanup()}, you shouldn't use any
other Gauche functions.
It is harmless to call @code{Scm_Cleanup()} more than once;
it becomes no-op from the second time and after.
@end deftypefun
@deftypefun void Scm_Panic (const char *@var{msg}, @dots{})
The @var{msg} and other arguments are treated like @code{printf(3)}.
Formats and displays the formatted message, then exits the process
by calling @code{_exit(2)} with exit code 1. No cleanup is done.
This is called when a serious defect is detected in the Gauche
runtime and cannot continue normal operation in any way.
@end deftypefun
@deftypefun void Scm_Abort (const char *@var{msg})
Writes @var{msg} to file descriptor 2, and exits the process
by calling @code{_exit(2)} with exit code 1. No cleanup is done.
This is the last resort of emergency exit, where you cannot
even call @code{malloc} reliably.
@end deftypefun
@subsubheading Cleanup handlers
You can register functions to be called when Gauche runtime
is shut down. The registered functions are called by
@code{Scm_Exit()} or @code{Scm_Cleanup()} in the reverse
order of their registration.
@deftypefun {void *} Scm_AddCleanupHandler (void (*@var{h})(void *), void *@var{d})
Adds a function @var{h} to the cleanup handler chain, with an opaque
data pointer @var{d}. At the cleanup time, @var{h} is called
with @var{d} as the single argument.
Returns an opaque handle, which can be passed to DeleteCleanupHandler.
@end deftypefun
@deftypefun void Scm_DeleteCleanupHandler (void *@var{handle})
Delete cleanup handler. The @var{handle} argument should be an opaque pointer
returned from @code{Scm_AddCleanupHandler}. (But it won't complain if
other pointer is given; it just does nothing.)
@end deftypefun
@node Memory allocation and GC, Booleans, Initialization and cleanup, C API reference
@section Memory allocation and GC
Memories allocated by using the following macros are owned
by Gauche runtime and managed by the garbage collector.
@subsubheading Allocator macros
There's two kind of allocators; ordinary ones and
@emph{atomic} ones. Here the term @emph{atomic} means
the allocated memory would never contain pointers
the collector needs to trace. For example, when you
allocate memory for a character string, you can use
atomic allocator since the memory won't contain any
pointers.
It is important to use atomic versions whenever possible.
Gauche's GC is conservative, which means if there's a
word that looks like a pointer in a live object, the collector assumes
it is a pointer and retains the memory chunk pointed by it.
If it is not really a pointer, the collector may retain
unnecessary memory chunks. It is called false pointers.
Telling the collector that a chunk of memory never contains
traceable pointer you can reduce the chance of false pointers.
It is OK for the atomic memory chunk to contain a pointer,
as far as the pointed chunk is reachable by other means,
or you can allow the pointed chunk to be collected (like
weak pointers).
Note: The term @emph{atomic} here probably came from the
fact that such a memory chunk is a terminal node, or an atom,
in the graph the collector traverses. It has nothing to
do with the atomic operations.
@deftypefn {Macro} {@var{TYPE} *} SCM_NEW (@var{TYPE})
@deftypefnx {Macro} {@var{TYPE} *} SCM_NEW_ATOMIC (@var{TYPE})
Allocates memory for datatype @var{TYPE} and returns its pointer.
@code{ATOMIC} version allocates the memory as an atomic chunk.
@end deftypefn
@deftypefn {Macro} {@var{TYPE} *} SCM_NEW_ARRAY (@var{TYPE}, size_t @var{nelts})
@deftypefnx {Macro} {@var{TYPE} *} SCM_NEW_ATOMIC_ARRAY (@var{TYPE}, size_t @var{nelts})
Allocates memory for an array of size @var{nelts} of datatype @var{TYPE},
and returns its pointer.
@end deftypefn
@deftypefn {Macro} {@var{TYPE} *} SCM_NEW2 (@var{TYPE}, size_t @var{size})
@deftypefnx {Macro} {@var{TYPE} *} SCM_NEW_ATOMIC2 (@var{TYPE}, size_t @var{size})
Allocates memory of @var{size} bytes, and returns it as a pointer to
the datatype @var{TYPE}.
@end deftypefn
Note: to allocate a Scheme object for the class that is inheritable
from Scheme, you should use @code{SCM_ALLOCATE} macro to do some
extra initialization. It is described in @ref{Creating new Scheme datatypes}.
You don't need to worry about it as far as you uses provided set
of Scheme datatypes, for each of them have a special "make" function
such as @code{Scm_MakeString}, @code{Scm_MakeVector}, etc.
@subsubheading Garbage collection
The garbage collector runs implicitly whenever it is necessary.
However, you can run it explicitly by this function:
@deftypefun void Scm_GC (void)
Triggers full GC.
@end deftypefun
@subsubheading Finalizers
@deftypefun void Scm_RegisterFinalizer (ScmObj @var{obj}, ScmFinalizerProc @var{finalizer}, void *@var{data})
Register the function @var{finalizer} to be called by the garbage
collector after the object @var{obj} is determined as dead. The function will
be given two arguments, the object and @var{data}.
GC works as this: After sweeping phase it has a set of unreachable objects.
If an unreachable object has a finalizer, it queues the object
in ``to-be-finalized'' list. Gauche's VM checks the queue occasionally
and processes them if it's not empty.
You should consider a finalizer as an asynchronous callback, much like
Scheme-level signal handlers. It is guaranteed to be called when VM
state is consistent (thus you can call back Gauche API safely from
the finalizer) and outside of GC (thus you can allocate inside
the finalizer), but you can't assume much more.
If @var{obj} points to another objects that's also being garbage collected,
that objects might already be finalized when @var{obj}'s finalizer
is called. So you have to make finalizers set the objects to harmless
state, and you also have to check the case
objects referred from @var{obj} are in such state.
You can't choose which thread will call the finalizer. Any thread that
allocates may call the finalizer.
You can resurrect @var{obj} by storing a pointer to it in some root set.
GC doesn't immediately put back @var{obj} to a free memor pool
after the finalizer is run; basically
it leaves @var{obj}'s fate to the finalizer. If the finalizer doesn't keep
references to @var{obj}, then @var{obj} will be reclaimed in @emph{next}
GC cycle, for it isn't pointed from live objects.
Note that GC unregisters finalizer of @var{obj} when it
chains @var{obj} to ``to-be-finalized'' list. So when the finalizer
is called, @var{obj} no longer has a finalizer.
Last but not least, there's no guarantee that the finalizer is called
promptly after @var{obj} lost all live references,
or whether it is called at all. There might be an indefinite delay
between the point when @var{obj} becomes a garbage and the finalizer is run.
You should think finalizers as a safety-net, rather than a guaranteed clean-up
mechanism. If your object requires explicit clean-up, ask users to do it
explicitly (possibly wrapping it with @code{call-with-*} style procedure).
Finalizers are for back up when the user fails to do so.
@end deftypefun
@deftypefun void Scm_UnregisterFinalizer (ScmObj @var{obj})
@end deftypefun
@node Booleans, Numbers, Memory allocation and GC, C API reference
@section Booleans
@deftypevr {Macro} ScmObj SCM_TRUE
@deftypevrx {Macro} ScmObj SCM_FALSE
Scheme's @code{#t} and @code{#f}.
@end deftypevr
@deftypefn {Macro} int SCM_TRUEP (ScmObj @var{obj})
@deftypefnx {Macro} int SCM_FALSEP (ScmObj @var{obj})
Predicates to check whether the given @var{obj} is @code{SCM_TRUE} or
@code{SCM_FALSE}, respectively. Note that @code{!SCM_FALSEP(obj)}
is different from @code{SCM_TRUEP(obj)}. Since Scheme treats anything
other than @code{#f} as a true value, usually what you need is
@code{SCM_FALSEP}. You use @code{SCM_TRUEP} only iff you want
to make sure the object is @code{#t}.
@end deftypefn
@deftypefn {Macro} int SCM_BOOLP (ScmObj @var{obj})
Returns @code{TRUE} iff @var{obj} is either @code{SCM_FALSE} or
@code{SCM_TRUE}.
@end deftypefn
@deftypefn {Macro} int SCM_BOOL_VALUE (ScmObj @var{obj})
Converts Scheme value to C boolean value. Returns @code{FALSE}
iff @var{obj} is @code{#f}.
@end deftypefn
@deftypefn {Macro} ScmObj SCM_MAKE_BOOL (@var{obj})
Converts C boolean value to a Scheme boolean value.
Returns @code{SCM_FALSE} if @var{obj} is @code{FALSE},
and @code{SCM_TRUE} for any other values.
@end deftypefn
@deftypefn {Macro} int SCM_EQ (ScmObj @var{x}, ScmObj @var{y})
Compares two Scheme objects are the same, in the sense of
Scheme's @code{eq?}. You should always use this macro
instead of comparing two Scheme objects by @code{==}.
@end deftypefn
@deftypefun int Scm_EqP (ScmObj @var{x}, ScmObj @var{y})
A function version of @code{SCM_EQ}.
@end deftypefun
@deftypefun int Scm_EqvP (ScmObj @var{x}, ScmObj @var{y})
Scheme's @code{eqv?}.
@end deftypefun
@deftypefun int Scm_EqualP (ScmObj @var{x}, ScmObj @var{y})
Scheme's @code{equal?}. Note: this function may call back VM recursively.
@end deftypefun
@deftypefun int Scm_EqualM (ScmObj @var{x}, ScmObj @var{y}, int @var{mode})
A convenient function to write functions with parameterized
equivalence procedure. @var{Mode} may be one of the following
constants:
@table @code
@item SCM_CMP_EQ
Compare using @code{eq?}
@item SCM_CMP_EQV
Compare using @code{eqv?}
@item SCM_CMP_EQUAL
Compare using @code{equal?}
@end table
@end deftypefun
@node Numbers, Pairs and lists, Booleans, C API reference
@section Numbers
@menu
* Scheme number objects::
* Number predicates::
* Converting C and Scheme numbers::
* Generic arithmetics::
* Subtype-specific number operations::
* Reading and writing numbers::
@end menu
@node Scheme number objects, Number predicates, Numbers, Numbers
@subsection Scheme number objects
@subsubheading C representation of numbers
Gauche uses several different structures to represent Scheme
numbers. Because of this polymorphic nature, the Scheme numbers
are almost always passed as @code{ScmObj}, except special occasions.
In Scheme level you usually don't need to think much
about different types of numbers, for Gauche automatically
converts them as needed. There are C routines that accept
generic Scheme numbers like Scheme, but from time to time
you need to check the actual type of the number and cast it
from @code{ScmObj} to the actual structure.
Currently Gauche has the following C-level representations.
@table @emph
@item Fixnum
For small Scheme exact integers (30 or 62 bit signed integer
in 32 or 64 bit
architectures, respectively), we encode its immediate value into
a machine word.
@item Bignum
If a Scheme exact integer doesn't fit in fixnum, it is represented
as a bignum, by a @code{ScmBignum} structure.
@item Ratnum
A Scheme exact non-integral number is represented as a ratnum,
by a @code{ScmRatnum} structure.
@item Flonum
Scheme real numbers are represented as flonum, by @code{ScmFlonum}
structure.
@item Compnum
Scheme complex numbers are represented as compnum, by
a @code{ScmCompnum} structure.
@end table
It is important to not confuse these @emph{representations} and
Scheme numeric hierarchy: A Scheme real number can be represented
in either flonum, ratnum, bignum or fixnum, for example.
For each possible Scheme numeric type and exactness, the possible
C representation is shown in the table below:
@example
| exact | inexact |
--------+----------------------+---------------+
integer |fixnum, bignum |flonum |
| | |
rational|fixnum, bignum, ratnum|flonum |
| | |
real |fixnum, bignum, ratnum|flonum |
| | |
complex |fixnum, bignum, ratnum|flonum, compnum|
________|______________________|_______________|
@end example
(Note: Exact real and exact complex are supported in a sense
that exact rational number is always a real and complex number
as well.)
@subsubheading Normalized form
One Scheme number may be represented by more than
one C types; for example, an exact integer can also
be represented in ratnum with its denominator as 1.
To make things simple and clean, there's one important
rule C-routine writers should know:
If your routine returns a Scheme number, it must be in
a @emph{normalized} form, i.e.:
@itemize @bullet
@item
If the number is an exact integer, it should be either
fixnum or bignum; if the value fits in fixnum, it should be
fixnum.
@item
Denominator of ratnum is always greater than 1. That is,
the sign of ratnum is the sign of its numerator.
@item
If the imaginary part of the number is 0.0, it must be
in flonum, rather than compnum.
@end itemize
(Note: here we use the term @emph{normalized} and @emph{denormalized}
in the sense that Scheme numbers should be represented in a simplest
possible C structure. It is unrelated to the term in
IEEE floating point number.)
Most C APIs expect normalized numbers, and return normalized one.
As far as you're using those APIs, you don't need to care about
normalization, or even how the number is represented in Scheme.
If you ever need to peek into the representation, or deal with
denormalized numbers, see @ref{Subtype-specific number operations}.
Carrying around a denormalized Scheme number should be limited
for intermediate results, and only when you find the overhead of
conversion is a problem. Generally such overhead is negligible
compared to other overheads. If you use denormalized numbers,
make sure normalize them before passing it back to the rest
of the world, or bad things will happen.
@subsubheading Conversions and clamping
Converting a Scheme number to a C number is a
tricky business. It's always possible that the Scheme number
you got may not fit into the desired C variable. There are several
options you can choose.
@itemize @bullet
@item
Error: Throws an error.
@item
Clamp: If the Scheme value falls out of the supported range
of C variable, use the closest representable value.
@item
Convert only when possible. If conversion is not possible, use
the Scheme value as-is. It is useful to provide a shortcut path
to improve performance.
@end itemize
Some C APIs take @var{clamp} argument to specify the behavior. The value
can be one of the following enums.
@deftp {Enum} ScmClampMode
@table @code
@item SCM_CLAMP_ERROR
An error is thrown if the given Scheme number doesn't fit
to the resulting C number.
@item SCM_CLAMP_HI
If the given Scheme number is too large to fit in the
resulting C number, the largest possible C number in the
result type is returned instead. If the given Scheme number
is too small, an error is signalled.
@item SCM_CLAMP_LO
If the given Scheme number is too small to fit in the
resulting C number, the smallest possible C number in the
result type is returned instead. If the given Scheme number
is too large, an error is signalled.
@item SCM_CLAMP_BOTH
Clamp both sides; with this argument, the API won't throw
an out-of-range error.
@item SCM_CLAMP_NONE
If the given Scheme number is out of the range, no conversion
is performed (an extra output argument tells you whether
it has happened or not).
@end table
@end deftp
See @var{Scm_GetIntegerClamp} below for a concrete example.
@node Number predicates, Converting C and Scheme numbers, Scheme number objects, Numbers
@subsection Number predicates
@deftypefn {Macro} int SCM_INTEGERP (ScmObj @var{obj})
Returns @code{TRUE} if @var{obj} is a Scheme exact integer; that is,
@var{obj} is either a fixnum or a bignum.
(The name is somewhat misleading. This is @emph{not} Scheme's @code{integer?}.
To check whether @var{obj} is an integer, regardless of exact or
inexact, use @code{Scm_IntegerP} below).
@end deftypefn
@deftypefn {Macro} int SCM_RATIONALP (ScmObj @var{obj})
Returns @code{TRUE} iff @var{obj} is a Scheme exact rational number; that is,
@var{obj} is either one of fixnum, bignum or ratnum.
@end deftypefn
@deftypefn {Macro} int SCM_REALP (ScmObj @var{obj})
Returns @code{TRUE} iff @var{obj} is a Scheme real number; that is,
@var{obj} is either one of fixnum, bignum, ratnum or flonum.
@end deftypefn
@deftypefn {Macro} int SCM_NUMBERP (ScmObj @var{obj})
Returns @code{TRUE} iff @var{obj} is a Scheme number,
that is, either a fixnum, bignum, ratnum, flonum, or compnum.
@end deftypefn
@deftypefun int Scm_IntegerP (ScmObj @var{num})
Returns @code{TRUE} iff @var{num} is (exact or inexact) integer.
Note: If @var{num} is a flonum with exponent larger than certain value,
@code{Scm_IntegerP} always returns @code{TRUE}, because of its limited
precision of mantissa.
@end deftypefun
@deftypefun int Scm_OddP (ScmObj @var{num})
Returns @code{TRUE} iff a Scheme (exact or inexact) integer is
an odd number. This throws an error if @var{num} is not an integer.
@end deftypefun
@deftypefun int Scm_FiniteP (ScmObj @var{obj})
@deftypefunx int Scm_IniniteP (ScmObj @var{obj})
@deftypefunx int Scm_NanP (ScmObj @var{obj})
Returns @code{TRUE} iff @var{obj} is a finite number,
an infinite number, or a NaN, respectively. It is an error if
@var{obj} is not a Scheme number object.
@end deftypefun