-
-
Notifications
You must be signed in to change notification settings - Fork 171
/
pl-incl.h
2651 lines (2230 loc) · 89.4 KB
/
pl-incl.h
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
/* Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: J.Wielemaker@vu.nl
WWW: http://www.swi-prolog.org
Copyright (c) 1985-2020, University of Amsterdam,
VU University Amsterdam
CWI, Amsterdam
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PL_INCLUDE_H
#define _PL_INCLUDE_H
#define PLNAME "swi"
#ifdef __WINDOWS__
#ifdef WIN64
#include "config/win64.h"
#define PLHOME "c:/Program Files/swipl"
#else
#include "config/win32.h"
#define PLHOME "c:/Program Files (x86)/swipl"
#endif
#else /*__WINDOWS__*/
#include <config.h>
#endif
#ifdef _MSC_VER
#define C_LIBS ""
#define C_STATICLIBS ""
#define C_CC "cl"
#if (_MSC_VER < 1400)
#define C_CFLAGS "/MD /GX"
#else
#define C_CFLAGS "/MD /EHsc"
#endif
#define C_LDFLAGS ""
#if defined(_DEBUG)
#define C_PLLIB "swiplD.lib"
#else
#define C_PLLIB "swipl.lib"
#endif
#else /* !_MSC_VER */
#ifdef __WINDOWS__ /* I.e., MinGW */
#define C_LIBS ""
#define C_STATICLIBS ""
#define C_CC "gcc"
#define C_CFLAGS ""
#define C_PLLIB "-lswipl" /* Or "libswipl.lib"? */
#define C_LIBPLSO "-lswipl"
#define C_LDFLAGS ""
#else
#include <parms.h> /* pick from the working dir */
#endif
#endif
/* gmp.h must be included PRIOR to SWI-Prolog.h to enable the API prototypes */
#ifdef HAVE_GMP_H
#define O_GMP 1
#endif
#ifdef O_GMP
# ifdef _MSC_VER /* ignore warning in gmp 5.0.2 header */
# pragma warning( disable : 4146 )
# endif
#include <gmp.h>
# ifdef _MSC_VER
# pragma warning( default : 4146 )
# endif
#endif
#define PL_KERNEL 1
/* PL_SO_EXPORT is an optional declaration used by SWI-Prolog.h that
* marks API symbols for being exported from libswipl.so.
*/
#ifdef HAVE_VISIBILITY_ATTRIBUTE
#define PL_SO_EXPORT __attribute__((visibility("default")))
#endif
/* The public API has references to a number of opaque types only
* defined in internal library code. The PL_OPAQUE macro prefixes
* the names with PL_ to avoid cluttering the type namespace, but
* here we want the original names.
*/
#define PL_OPAQUE(type) type
#include "SWI-Prolog.h"
/* Our definition of _PL_get_arg appears in pl-fli.h */
#undef _PL_get_arg
/* This is only here to assist static analysis; undefine this and
* the LDFUNC functions will look like normal definitions, as though
* this were a single-threaded build */
#define USE_LD_MACROS 1
#ifdef __INTELLISENSE__
# undef USE_LD_MACROS
#endif
/* COMMON() was a macro used to mark symbols to be global to the library
* internals but not exported from the shared library. This is now the
* default visibility for library symbols, so it is no longer necessary.
*/
#define COMMON(type) type
#include "pl-builtin.h"
#include "pl-macros.h"
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PROLOG SYSTEM OPTIONS
These are not really options normally. They are there because I use to
add new features conditional using #if ... #endif. In many cases I
leave them in for ducumentation purposes. Notably O_STRING might be
handy for it someone wants to add a data type to the system.
O_STRING
Include data type string. This feature does not rely on any
system feature. It hardly has any consequences for the system.
Because of its experimental nature it is optional. The definition
of the predicates operating on strings might change.
(NOTE: Currently some of the boot files rely on strings. It is NOT
suggested to leave them out).
O_QUASIQUOTATIONS
Support quasi quoted content in read_term/3 and friends.
O_COMPILE_OR
Compile ->/2, ;/2 and |/2 into WAM. This no longer is a real
option. the mechanism to handle cuts without compiling ;/2, etc.
has been taken out.
O_COMPILE_ARITH
Include arithmetic compiler (compiles is/2, >/2, etc. into WAM).
O_COMPILE_IS
Compile Var = Value in the body.
O_CALL_AT_MODULE
Support the Goal@Module control-structure
O_LABEL_ADDRESSES
Means we can pick up the address of a label in a function using
the var = `&&label' construct and jump to it using goto *var;
This construct is known by the GNU-C compiler gcc version 2. It
is buggy in gcc-2.0, but seems to works properly in gcc-2.1.
VMCODE_IS_ADDRESS
Can only be set when O_LABEL_ADDRESSES is set. It causes the
prolog compiler to put the code (= label-) addresses in the
compiled Prolog code rather than the virtual-machine numbers.
This speeds-up the vm instruction dispatching in interpret().
See also pl-comp.c
O_LOGICAL_UPDATE
Use `logical' update-view for dynamic predicates rather then the
`immediate' update-view of older Prolog systems.
O_PLMT
Include support for multi-threading. Too much of the system relies
on this now, so it cannot be disabled without significant work.
O_LARGEFILES
Supports files >2GB on 32-bit systems (if the OS provides it).
O_ATTVAR
Include support for attributes variables.
This option requires O_DESTRUCTIVE_ASSIGNMENT.
O_GVAR
Include support for backtrackable global variables. This option
requires O_DESTRUCTIVE_ASSIGNMENT.
O_CYCLIC
Provide support for cyclic terms.
O_LOCALE
Provide locale support on streams.
O_GMP
Use GNU gmp library for infinite precision arthmetic
O_MITIGATE_SPECTRE
Reduce spectre security risc. Currently reduces timer resolution.
O_PREFER_RATIONALS
Default for the `prefer_rationals` flag.
O_RATIONAL_SYNTAX
Default support for rational syntax (RAT_NATURAL or RAT_COMPAT)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define O_COMPILE_OR 1
#define O_SOFTCUT 1
#define O_COMPILE_ARITH 1
#define O_COMPILE_IS 1
#define O_CALL_AT_MODULE 1
#define O_STRING 1
#define O_RESERVED_SYMBOLS 1
#define O_QUASIQUOTATIONS 1
#define O_CATCHTHROW 1
#define O_DEBUGGER 1
#define O_INTERRUPT 1
#define O_DESTRUCTIVE_ASSIGNMENT 1
#define O_TERMHASH 1
#define O_LIMIT_DEPTH 1
#define O_INFERENCE_LIMIT 1
#define O_SAFE_SIGNALS 1
#define O_LOGICAL_UPDATE 1
#define O_LOCALE 1
#define O_ATOMGC 1
#define O_CLAUSEGC 1
#define O_ATTVAR 1
#define O_CALL_RESIDUE 1
#define O_GVAR 1
#define O_CYCLIC 1
#define O_MITIGATE_SPECTRE 1
#ifndef O_PREFER_RATIONALS
#define O_PREFER_RATIONALS FALSE
#endif
#ifndef O_RATIONAL_SYNTAX
#define O_RATIONAL_SYNTAX RAT_COMPAT
#endif
#if defined(O_PLMT)
#if defined(O_SIGPROF_PROFILE) || defined(__WINDOWS__)
#define O_PROFILE 1
#endif
#endif
#ifdef __WINDOWS__
#define NOTTYCONTROL TRUE
#define O_DDE 1
#define O_DLL 1
#define O_HASDRIVES 1
#define O_HASSHARES 1
#define O_XOS 1
#define O_RLC 1
#endif
#ifndef DOUBLE_TO_LONG_CAST_RAISES_SIGFPE
#ifdef __i386__
#define DOUBLE_TO_LONG_CAST_RAISES_SIGFPE 1
#endif
#endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The ia64 says setjmp()/longjmp() buffer must be aligned at 128 bits
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef JMPBUF_ALIGNMENT
#ifdef __ia64__
#define JMPBUF_ALIGNMENT 128
#else
#if ALIGNOF_DOUBLE != ALIGNOF_VOIDP
#define JMPBUF_ALIGNMENT ALIGNOF_DOUBLE
#endif
#endif
#endif
#ifndef O_LABEL_ADDRESSES
#if __GNUC__ == 2
#define O_LABEL_ADDRESSES 1
#endif
#endif
/* clang as of version 11 performs about 30% worse with this option */
#if O_LABEL_ADDRESSES && !defined(VMCODE_IS_ADDRESS) && !defined(__llvm__)
#define VMCODE_IS_ADDRESS 1
#endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Runtime version. Uses somewhat less memory and has no tracer.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifdef O_RUNTIME
#undef O_PROFILE /* no profiling */
#undef O_DEBUGGER /* no debugging */
#undef O_INTERRUPT /* no interrupts too */
#endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The macros below try to establish a common basis for various compilers,
so we can write most of the real code without having to worry about
compiler limits and differences.
The current version has prototypes defined for all functions. If you
have a very old compiler, try the unprotoize program that comes with
gcc.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __unix__
#if defined(_AIX) || defined(__APPLE__) || defined(__unix) || defined(__BEOS__) || defined(__NetBSD__) || defined(__HAIKU__)
#define __unix__ 1
#endif
#endif
/* AIX requires this to be the first thing in the file. */
#ifdef __GNUC__
# ifndef alloca
# define alloca __builtin_alloca
# endif
#else
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
void *alloca ();
# endif
# endif
# endif
#endif
#if _FILE_OFFSET_BITS == 64 || defined(_LARGE_FILES)
#define O_LARGEFILES 1 /* use for conditional code in Prolog */
#else
#undef O_LARGEFILES
#endif
#include <sys/types.h>
#if __MINGW32__
typedef _sigset_t sigset_t;
#endif
#include <setjmp.h>
#ifdef ASSERT_H_REQUIRES_STDIO_H
#include <stdio.h>
#endif /*ASSERT_H_REQUIRES_STDIO_H*/
#ifdef NO_ASSERT_H /* see pl-assert.c */
#define assert(c) (void)0
#else
#include <assert.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <stdarg.h>
#include <limits.h>
#ifdef HAVE_SIGNAL
#include <signal.h>
#endif
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#else
#ifdef HAVE_SYS_MALLOC_H
#include <sys/malloc.h>
#endif
#endif
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
#if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
/* memory.h and strings.h conflict on some systems. */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
#if OS2 && EMX
#include <process.h>
#include <io.h>
#endif /* OS2 */
/* prepare including BeOS types */
#ifdef __BEOS__
#define bool BOOL
#include <BeBuild.h>
#if (B_BEOS_VERSION <= B_BEOS_VERSION_5)
# include <socket.h> /* include socket.h to get the fd_set structure */
#else
# include <SupportDefs.h> /* not needed for a BONE-based networking stack */
#endif
#include <OS.h>
#undef true
#undef false
#undef bool
#define EMULATE_DLOPEN 1 /* Emulated dlopen() in pl-beos.c */
#endif
/* MAXPATHLEN is an optional POSIX feature (Bug#63). As SWI-Prolog has
no length limits on text except for representing paths, we should
rewrite all file handling code to avoid MAXPATHLEN. For now we just
define it.
*/
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
A common basis for C keywords.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if __GNUC__ && !__STRICT_ANSI__
#define HAVE_INLINE 1
#define HAVE_VOLATILE 1
#define HAVE___BUILTIN_EXPECT 1
#endif
#if !defined(HAVE_INLINE) && !defined(inline)
#define inline
#endif
#if defined(__GNUC__) && !defined(__OPTIMIZE__)
#define _DEBUG 1
#endif
#ifndef HAVE_VOLATILE
#define volatile
#endif
#if defined(__GNUC__) && !defined(NORETURN)
#define NORETURN __attribute__ ((noreturn))
#else
#define NORETURN
#endif
#if defined(__GNUC__) && !defined(MAY_ALIAS)
#define MAY_ALIAS __attribute__ ((__may_alias__))
#else
#define MAY_ALIAS
#endif
#if defined(__GNUC__) && !defined(MAYBE_UNUSED)
#define MAYBE_UNUSED __attribute__ ((unused))
#else
#define MAYBE_UNUSED
#endif
#ifdef HAVE___BUILTIN_EXPECT
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif
#ifdef DMALLOC
#include <dmalloc.h> /* Use www.dmalloc.com debugger */
#define PL_ALLOC_DONE 1
#define DMALLOC_FUNC_CHECK 1
#define allocHeap(n) malloc(n)
#define allocHeapOrHalt(n) xmalloc(n)
#define freeHeap(ptr, n) do { (void)(n); xfree(ptr); } while(0)
#endif /*DMALLOC*/
#define forwards static /* forwards function declarations */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Booleans, addresses, strings and other goodies.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
typedef int bool;
#if __GNUC__ && !__STRICT_ANSI__
#define LocalArray(t, n, s) t n[s]
#else
#define LocalArray(t, n, s) t *n = (t *) alloca((s)*sizeof(t))
#endif
#define TermVector(name, s) LocalArray(Word, name, s)
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define succeed return TRUE
#define fail return FALSE
#define TRY(goal) do { if (!(goal)) return FALSE; } while(0)
#define CL_START ((ClauseRef)1) /* asserta */
#define CL_END ((ClauseRef)2) /* assertz */
typedef void * caddress;
#define EOS ('\0')
#define ESC ((char) 27)
#define streq(s, q) ((strcmp((s), (q)) == 0))
/* n is 2^m !!! */
#define ROUND(p, n) ((((p) + (n) - 1) & ~((n) - 1)))
#define addPointer(p, n) ((void *) ((intptr_t)(p) + (intptr_t)(n)))
#define diffPointers(p1, p2) ((intptr_t)(p1) - (intptr_t)(p2))
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LIMITS
Below are some arbitrary limits on object sizes. Feel free to enlarge
them. Descriptions:
* LINESIZ
Buffer used to store textual info. It is not concerned with
critical things, just things like building an error message,
reading a command for the tracer, etc.
* MAXARITY
Maximum arity of a predicate. May be enarged further, but
wastes stack (4 bytes for each argument) on machines that
use malloc() for allocating the stack as the local and global
stack need to be apart by this amount. Also, an interrupt
skips this amount of stack.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define LINESIZ 1024 /* size of a data line */
#define MAXARITY 1024 /* arity of predicate */
#define MINFOREIGNSIZE 32 /* Minimum term_t in foreign frame */
#define MAXSYMBOLLEN 256 /* max size of foreign symbols */
#define OP_MAXPRIORITY 1200 /* maximum operator priority */
#define SMALLSTACK 32 * 1024 /* GC policy */
#define MAX_PORTRAY_NESTING 100 /* Max recursion in portray */
#define LOCAL_MARGIN ((size_t)argFrameP((LocalFrame)NULL, MAXARITY) + \
sizeof(struct choice))
#define WORDBITSIZE (8 * sizeof(word))
#define LONGBITSIZE (8 * sizeof(long))
#define INTBITSIZE (8 * sizeof(int))
#define INT64BITSIZE (8 * sizeof(int64_t))
#define WORDS_PER_DOUBLE ((sizeof(double)+sizeof(word)-1)/sizeof(word))
#define WORDS_PER_INT64 (sizeof(int64_t)/sizeof(word))
/* Prolog's integer range */
#define PLMINTAGGEDINT (-(intptr_t)((word)1<<(WORDBITSIZE-LMASK_BITS-1)))
#define PLMAXTAGGEDINT (-PLMINTAGGEDINT - 1)
#define PLMINTAGGEDINT32 (-(intptr_t)((word)1<<(32-LMASK_BITS-1)))
#define PLMAXTAGGEDINT32 (-PLMINTAGGEDINT32 - 1)
#define inTaggedNumRange(n) (valInt(consInt(n)) == (n))
#define PLMININT (-PLMAXINT - 1)
#define PLMAXINT ((int64_t)(((uint64_t)1<<(INT64BITSIZE-1)) - 1))
#if SIZEOF_WCHAR_T == 2
#define PLMAXWCHAR (0xffff)
#else
#define PLMAXWCHAR (0x10ffff)
#endif
#if vax
#define MAXREAL (1.701411834604692293e+38)
#else /* IEEE double */
#define MAXREAL (1.79769313486231470e+308)
#endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Macros to handle hash tables. See pl-table.c for details. First the
sizes of the hash tables are defined. Note that these should all be
2^N.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define ATOMHASHSIZE 1024 /* global atom table */
#define FUNCTORHASHSIZE 512 /* global functor table */
#define PROCEDUREHASHSIZE 256 /* predicates in module user */
#define MODULEPROCEDUREHASHSIZE 16 /* predicates in other modules */
#define MODULEHASHSIZE 16 /* global module table */
#define PUBLICHASHSIZE 8 /* Module export table */
#define FLAGHASHSIZE 16 /* global flag/3 table */
#include "os/pl-table.h"
#include "pl-vmi.h"
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Arithmetic comparison
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define LT 1
#define GT 2
#define LE 3
#define GE 4
#define NE 5
#define EQ 6
#define LT_C <
#define GT_C >
#define LE_C <=
#define GE_C >=
#define NE_C !=
#define EQ_C ==
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operator types. NOTE: if you change OP_*, check operatorTypeToAtom()!
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define OP_PREFIX 0
#define OP_INFIX 1
#define OP_POSTFIX 2
#define OP_MASK 0xf
#define OP_FX (0x10|OP_PREFIX)
#define OP_FY (0x20|OP_PREFIX)
#define OP_XF (0x30|OP_POSTFIX)
#define OP_YF (0x40|OP_POSTFIX)
#define OP_XFX (0x50|OP_INFIX)
#define OP_XFY (0x60|OP_INFIX)
#define OP_YFX (0x70|OP_INFIX)
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Magic for assertions.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define StackMagic(n) ((n) | 0x98765000)
#define QID_MAGIC StackMagic(1) /* Query frame */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PROLOG DATA REPRESENTATION
Prolog data objects live on various places:
- In the variable and argument slots of environment frames.
- As arguments to complex terms on the global stack.
- In records (recorda/recorded database) in the heap.
- In variables in foreign language functions.
All Prolog data is packed into a `word'. A word is a 32 bit entity.
The top 3 bits are used to indicate the type; the bottom 2 bits are used
for the garbage collector. The bits for the garbage collector are
always 0 during normal execution. This implies we do not have to care
about them for pointers and as pointers always point to 4 bytes
entities, the range is not harmed by the garbage collection bits.
The remaining 27 bits can hold a unique representation of the value
itself or can be a pointer to the global stack where the real value is
stored. We call the latter type of data `indirect'.
Below is a description of the representation used for each type of
Prolog data:
***TBD*** This is totally out of date. The datatypes are accessed using
macros defined in pl-data.h.
INTEGER
Integers are stored in the 27 remaining bits of a word. This
implies they are limited to +- 2^26.
FLOAT
For a real, the 27 bits are a pointer to a 8 byte unit on the global
stack. For both words of the 8 byte unit, the top 3 and bottom 2
bits are reserved for identification and garbage collection. The
remaining bits hold the exponent and mantisse. See pack_real() and
unpack_real() in pl-alloc.c for details.
ATOM
For atoms, the 27 bits represent a pointer to an atom structure.
Atom structures are cells of a hash table. Equality of the pointer
implies equality of the atoms and visa versa. Atom structures are
not collected by the garbage collector and thus live for the entire
Prolog session.
STRING
For a string, the 27 bits are a pointer to the global stack. The
first word of the string again reserves the top 3 and bottom 2
bits. The remaining bits indicate the lenght of the string. Next
follows a 0 terminated character string. Finally a word exactly the
same as the header word, to allow the garbage collector to traverse
the stack downwards and identify the string.
TERM
For a compound term, the 27 bits are a pointer to the global stack.
the first word there is a pointer to a functordef structure, which
determines the name and arity of the term. functordef structures
are cells of a hash table like atom structures. They to live for
the entire Prolog session. Next, there are just as many words as
the arity of the term, each word representing a normal Prolog data
object.
VARIABLES
An unbound variable is represented by NULL.
REFERENCES
References are the result of sharing variables. If two variables
must share, the one with the shortest livetime is made a reference
pointer to the other. This way a tree of reference pointers can be
constructed. The root of the tree is the variable with the longest
livetime. To bind the entire tree of variables this root is bound.
The others remain reference pointers. This implies that ANY prolog
data object might be a reference pointer to another Prolog data
object, holding the real value. To find the real value, a macro
called deRef() is available.
The direction of reference pointers is critical. It MUST point in
the direction of the longest living variable. If not, the reference
pointer will point into the dark if the other end dies. This
implies that if both cells are part of an environment frame, the one
in the child function (closest to the top of the stack) must point
to the one in the parent function. If one is on the local and one
on the global stack, the pointer must point towards the global
stack. Inside the global stack it is irrelevant. If backtracking
destroys a variable, it also will reset the reference towards it if
there is one.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Common Prolog objects typedefs. Note that code is word-aligned for two
reasons. First of all, we want to get the maximum speed and second, we
must ensure that sizeof(struct clause) is a multiple of sizeof(word) to
place them on the stack (see I_USERCALL).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifdef __GNUC__
#define WORD_ALIGNED __attribute__ ((aligned (sizeof(word))))
#else
#define WORD_ALIGNED
#endif
#if 0
/* The following have all been defined in SWI-Prolog.h, included above,
* and are repeated here only for programmer reference and convenience.
*/
typedef uintptr_t word; /* Anonymous ptr-sized object*/
typedef word atom_t; /* encoded atom */
typedef word functor_t; /* encoded functor */
typedef struct module * module_t; /* a module */
typedef struct procedure * predicate_t; /* a predicate handle */
typedef struct record * record_t; /* handle to a recorded term */
typedef uintptr_t term_t; /* external term-reference */
typedef uintptr_t qid_t; /* external query-id */
typedef uintptr_t PL_fid_t; /* external foreign context-id */
typedef struct foreign_context *control_t; /* non-deterministic control arg */
typedef struct PL_local_data * PL_engine_t; /* handle to an engine */
typedef uintptr_t PL_atomic_t; /* same a word */
typedef uintptr_t foreign_t; /* return type of foreign functions */
typedef wchar_t pl_wchar_t; /* Prolog wide character */
typedef foreign_t (*pl_function_t)(); /* foreign language functions */
typedef uintptr_t buf_mark_t; /* buffer mark handle */
#define fid_t \
PL_fid_t /* avoid AIX name-clash */
#endif
typedef uintptr_t word; /* Anonymous ptr-sized object*/
typedef word * Word; /* a pointer to anything */
typedef word atom_t; /* encoded atom */
typedef word functor_t; /* encoded functor */
typedef uintptr_t code WORD_ALIGNED; /* bytes codes */
typedef code * Code; /* pointer to byte codes */
typedef int Char; /* char that can pass EOF */
typedef word (*Func)(); /* foreign functions */
typedef int (*ArithF)(); /* arithmetic function */
typedef struct atom * Atom; /* atom */
typedef struct functor * Functor; /* complex term */
typedef struct functorDef * FunctorDef; /* name/arity pair */
typedef struct procedure * Procedure; /* predicate */
typedef struct definition * Definition; /* predicate definition */
typedef struct definition_chain *DefinitionChain; /* linked list of defs */
typedef struct clause * Clause; /* compiled clause */
typedef struct clause_ref * ClauseRef; /* reference to a clause */
typedef struct clause_index * ClauseIndex; /* Clause indexing table */
typedef struct clause_bucket * ClauseBucket; /* Bucked in clause-index table */
typedef struct operator * Operator; /* see pl-op.c, pl-read.c */
typedef struct record * Record; /* recorda/3, etc. */
typedef struct recordRef * RecordRef; /* reference to a record */
typedef struct recordList * RecordList; /* list of these */
typedef struct module * Module; /* predicate modules */
typedef struct sourceFile * SourceFile; /* file adminitration */
typedef struct list_cell * ListCell; /* Anonymous list */
typedef struct localFrame * LocalFrame; /* environment frame */
typedef struct local_definitions *LocalDefinitions; /* thread-local preds */
typedef struct choice * Choice; /* Choice-point */
typedef struct clause_choice * ClauseChoice; /* firstClause()/nextClause() */
typedef struct queryFrame * QueryFrame; /* toplevel query frame */
typedef struct fliFrame * FliFrame; /* FLI interface frame */
typedef struct trail_entry * TrailEntry; /* Entry of trail stack */
typedef struct gc_trail_entry * GCTrailEntry; /* Entry of trail stack (GC) */
typedef struct mark mark; /* backtrack mark */
typedef struct stack * Stack; /* machine stack */
typedef struct _varDef * VarDef; /* pl-comp.c */
typedef struct extension_cell * ExtensionCell; /* pl-ext.c */
typedef struct abort_handle * AbortHandle; /* PL_abort_hook() */
typedef struct initialise_handle * InitialiseHandle;
typedef struct canonical_dir * CanonicalDir; /* pl-os.c */
typedef struct on_halt * OnHalt; /* pl-os.c */
typedef struct find_data_tag * FindData; /* pl-trace.c */
typedef struct feature * Feature; /* pl-prims.c */
typedef struct dirty_def_info * DirtyDefInfo;
typedef struct counting_mutex counting_mutex;
typedef struct pl_mutex pl_mutex;
/*******************************
* ARITHMETIC *
*******************************/
/* the numtype enum requires total ordering.
*/
typedef enum
{ V_INTEGER, /* integer (64-bit) value */
#ifdef O_GMP
V_MPZ, /* mpz_t */
V_MPQ, /* mpq_t */
#endif
V_FLOAT /* Floating point number (double) */
} numtype;
typedef struct
{ numtype type; /* type of number */
union { double f; /* value as a floating point number */
int64_t i; /* value as integer */
word w[WORDS_PER_DOUBLE]; /* for packing/unpacking the double */
#ifdef O_GMP
mpz_t mpz; /* GMP integer */
mpq_t mpq; /* GMP rational */
#endif
} value;
} number, *Number;
#define TOINT_CONVERT_FLOAT 0x1 /* toIntegerNumber() */
#define TOINT_TRUNCATE 0x2
#ifdef O_GMP
#define intNumber(n) ((n)->type <= V_MPZ)
#define ratNumber(n) ((n)->type <= V_MPQ)
#else
#define intNumber(n) ((n)->type < V_FLOAT)
#define ratNumber(n) ((n)->type < V_FLOAT)
#endif
#define floatNumber(n) ((n)->type >= V_FLOAT)
typedef enum
{ NUM_ERROR = FALSE, /* Syntax error */
NUM_OK = TRUE, /* Ok */
NUM_FUNDERFLOW = -1, /* Float underflow */
NUM_FOVERFLOW = -2, /* Float overflow */
NUM_IOVERFLOW = -3, /* Integer overflow */
NUM_CONSTRANGE = -4 /* numeric constant out of range */
} strnumstat;
/*******************************
* GET-PROCEDURE *
*******************************/
#define GP_FIND 0 /* find anywhere */
#define GP_FINDHERE 1 /* find in this module */
#define GP_CREATE 2 /* create (in this module) */
#define GP_DEFINE 4 /* define a procedure */
#define GP_RESOLVE 5 /* find defenition */
#define GP_HOW_MASK 0x0ff
#define GP_NAMEARITY 0x100 /* or'ed mask */
#define GP_HIDESYSTEM 0x200 /* hide system module */
#define GP_TYPE_QUIET 0x400 /* don't throw errors on wrong types */
#define GP_EXISTENCE_ERROR 0x800 /* throw error if proc is not found */
#define GP_QUALIFY 0x1000 /* Always module-qualify */
#define GP_NOT_QUALIFIED 0x2000 /* Demand unqualified name/arity */
/* get_functor() */
#define GF_EXISTING 0x1
#define GF_PROCEDURE 0x2 /* check for max arity */
#define GF_NAMEARITY 0x4 /* only accept name/arity */
#define SM_NOCREATE 0x1 /* stripModule(): do not create modules */
/*******************************
* ALERT *
*******************************/
/* See updateAlerted()
*/
#define ALERT_SIGNAL 0x001
#define ALERT_GCREQ 0x002
#define ALERT_PROFILE 0x004
#define ALERT_EXITREQ 0x008
#define ALERT_DEPTHLIMIT 0x010
#define ALERT_INFERENCELIMIT 0x020
#define ALERT_WAKEUP 0x040
#define ALERT_DEBUG 0x080
#define ALERT_BUFFER 0x100
#define ALERT_UNDO 0x200
/*******************************
* CLEANUP *
*******************************/
typedef enum
{ CLN_NORMAL = 0, /* Normal mode */
CLN_PROLOG, /* Prolog hooks */
CLN_FOREIGN, /* Foreign hooks */
CLN_IO, /* Cleaning I/O */
CLN_SHARED, /* Unload shared objects */
CLN_DATA /* Remaining data */
} cleanup_status;
/*******************************
* FLAGS *
*******************************/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Many of the structures have a large number of booleans associated with
them. Early versions defined these using `unsigned <name> : 1' in the
structure definition. When I ported SWI-Prolog to a machine that did
not understand this construct I decided to pack all the flags in a
short. As this allows us to set, clear and test combinations of flags
with one operation, it turns out to be faster as well.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define true(s, a) ((s)->flags & (a))
#define alltrue(s, a) (((s)->flags & (a)) == (a))
#define false(s, a) (!true((s), (a)))
#define set(s, a) ATOMIC_OR(&(s)->flags, (a))
#define clear(s, a) ATOMIC_AND(&(s)->flags, ~(a))
#define clearFlags(s) ((s)->flags = 0)
/* Flags on predicates (packed in unsigned int */
#define P_SSU_DET (0x00000001) /* Single Sided Unification: det */
#define P_CLAUSABLE (0x00000002) /* Clause/2 always works */
#define P_QUASI_QUOTATION_SYNTAX (0x00000004) /* {|Type||Quasi Quote|} */
#define P_NON_TERMINAL (0x00000008) /* Grammar rule (Name//Arity) */
#define P_SHRUNKPOW2 (0x00000010) /* See reconsider_index() */
#define P_FOREIGN (0x00000020) /* Implemented in C */
#define P_NONDET (0x00000040) /* Foreign: nondet */
#define P_VARARG (0x00000080) /* Foreign: use alt calling API */
#define P_FOREIGN_CREF (0x00000100) /* Foreign: ndet ctx is clause */
#define P_DYNAMIC (0x00000200) /* Dynamic predicate */
#define P_THREAD_LOCAL (0x00000400) /* Thread local dynamic predicate */
#define P_VOLATILE (0x00000800) /* Clauses are not saved */
#define P_DISCONTIGUOUS (0x00001000) /* Clauses are not together */
#define P_MULTIFILE (0x00002000) /* Clauses are in multiple files */
#define P_PUBLIC (0x00004000) /* Called from somewhere */
#define P_ISO (0x00008000) /* Part of the ISO standard */
#define P_LOCKED (0x00010000) /* Locked as system predicate */
#define P_NOPROFILE (0x00020000) /* Profile children, not me */
#define P_TRANSPARENT (0x00040000) /* Inherit calling module */
#define P_META (0x00080000) /* Has meta_predicate declaration */
#define P_MFCONTEXT (0x00100000) /* Used for Goal@Module */
#define P_DIRTYREG (0x00200000) /* Part of GD->procedures.dirty */
#define P_ERASED (0x00400000) /* Predicate has been destroyed */
#define HIDE_CHILDS (0x00800000) /* Hide children from tracer */
#define SPY_ME (0x01000000) /* Spy point placed */
#define TRACE_ME (0x02000000) /* Can be debugged */
#define P_DET (0x04000000) /* Predicate is deterministic */
#define P_AUTOLOAD (0x08000000) /* autoload/2 explicit import */
#define P_WAITED_FOR (0x10000000) /* Someone is waiting for this predicate */
#define P_LOCKED_SUPERVISOR (0x20000000) /* Fixed supervisor */
#define FILE_ASSIGNED (0x40000000) /* Is assigned to a file */
#define P_REDEFINED (0x80000000) /* Overrules a definition */
#define PROC_DEFINED (P_DYNAMIC|P_FOREIGN|P_MULTIFILE|\
P_DISCONTIGUOUS|P_LOCKED_SUPERVISOR)
/* flags for p_reload data (reconsult) */
#define P_MODIFIED P_DIRTYREG
#define P_NEW SPY_ME
#define P_NO_CLAUSES TRACE_ME
#define P_CHECK_SSU HIDE_CHILDS
/* Flags on clauses (unsigned int) */
#define CL_ERASED (0x0001) /* clause was erased */
#define UNIT_CLAUSE (0x0002) /* Clause has no body */
#define HAS_BREAKPOINTS (0x0004) /* Clause has breakpoints */
#define GOAL_CLAUSE (0x0008) /* Dummy for meta-calling */
#define COMMIT_CLAUSE (0x0010) /* This clause will commit */
#define DBREF_CLAUSE (0x0020) /* Clause has db-reference */
#define DBREF_ERASED_CLAUSE (0x0040) /* Deleted while referenced */
#define CL_BODY_CONTEXT (0x0080) /* Module context of body is different */
/* from predicate */
#define SSU_COMMIT_CLAUSE (0x0100) /* Head => Body */
#define SSU_CHOICE_CLAUSE (0x0200) /* Head ?=> Body */
#define CL_HEAD_TERMS (0x0400) /* Head contains terms used in body */
#define CLAUSE_TYPE_MASK (UNIT_CLAUSE|SSU_COMMIT_CLAUSE|SSU_CHOICE_CLAUSE)
/* Flags on a DDI (Dirty Definition Info struct */
#define DDI_MARKING 0x0001 /* Actively using the DDI */
#define DDI_INTERVALS 0x0002 /* DDI collects an interval */
/* Flags on module. Most of these flags are copied to the read context
in pl-read.c.
*/
#define M_SYSTEM (0x00000001) /* system module */
#define M_CHARESCAPE (0x00000002) /* module */
#define DBLQ_CHARS (0x00000004) /* "ab" --> ['a', 'b'] */
#define DBLQ_ATOM (0x00000008) /* "ab" --> 'ab' */
#define DBLQ_STRING (0x00000010) /* "ab" --> "ab" */
#define DBLQ_MASK (DBLQ_CHARS|DBLQ_ATOM|DBLQ_STRING)
#define BQ_STRING (0x00000020) /* `ab` --> "ab" */
#define BQ_CODES (0x00000040) /* `ab` --> [97,98] */
#define BQ_CHARS (0x00000080) /* `ab` --> [a,b] */
#define BQ_MASK (BQ_STRING|BQ_CODES|BQ_CHARS)
#define RAT_COMPAT (0)
#define RAT_NATURAL (0x00000100) /* 1/3 */
#define RAT_MASK (RAT_NATURAL)
#define UNKNOWN_FAIL (0x00001000) /* module */
#define UNKNOWN_WARNING (0x00002000) /* module */