File: pl-incl.h

package info (click to toggle)
swi-prolog 6.6.6-1~bpo70%2B1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy-backports
  • size: 82,312 kB
  • sloc: ansic: 322,250; perl: 245,822; sh: 6,651; java: 5,254; makefile: 4,423; cpp: 4,153; ruby: 1,594; yacc: 843; xml: 82; sed: 12; sql: 6
file content (2176 lines) | stat: -rw-r--r-- 74,187 bytes parent folder | download | duplicates (2)
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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
/*  Part of SWI-Prolog

    Author:        Jan Wielemaker
    E-mail:        J.Wielemaker@cs.vu.nl
    WWW:           http://www.swi-prolog.org
    Copyright (C): 1985-2013, University of Amsterdam,
			      VU University Amsterdam

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
    MA  02110-1301  USA
*/

#ifndef _PL_INCLUDE_H
#define _PL_INCLUDE_H

#define PLNAME "swi"

#ifdef __WINDOWS__
#ifdef WIN64
#include "config/win64.h"
#else
#include "config/win32.h"
#endif
#define PLHOME       "c:/Program Files/pl"
#define DEFSTARTUP   "pl.ini"
#else
#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"
#define C_LDFLAGS    ""
#endif
#include <parms.h>			/* pick from the working dir */
#endif

#define PL_KERNEL		1
#include "pl-builtin.h"

#ifdef HAVE_DMALLOC_H
#include <dmalloc.h>			/* Use www.dmalloc.com debugger */
#endif


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		      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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#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_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_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
#ifdef HAVE_GMP_H
#define O_GMP			1
#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

#if O_LABEL_ADDRESSES && !defined(VMCODE_IS_ADDRESS)
#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_READLINE			/* no readline too */
#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__)
#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*/
#include <assert.h>
#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

#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

#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

#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

#if defined(__STRICT_ANSI__) || defined(NO_ASM_NOP)
#define ASM_NOP { static int nop; nop++; }
#endif

#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		0	/* asserta */
#define CL_END			1	/* 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 BUFFER_RING_SIZE	16	/* foreign buffer ring (pl-fli.c) */
#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 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)	(((n)&~PLMAXTAGGEDINT) == 0 || \
				 ((n)&~PLMAXTAGGEDINT) == ~PLMAXTAGGEDINT)
#define PLMININT		(((int64_t)-1<<(INT64BITSIZE-1)))
#define PLMAXINT		(-(PLMININT+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

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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

#ifndef PL_HAVE_TERM_T
#define PL_HAVE_TERM_T
typedef uintptr_t		term_t;		/* external term-reference */
#endif

typedef uintptr_t		word;		/* Anonymous 4 byte 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 uintptr_t qid_t;		/* external query-id */
typedef uintptr_t PL_fid_t;		/* external foreign context-id */

#define fid_t PL_fid_t			/* avoid AIX name-clash */

		 /*******************************
		 *	    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 same_type_numbers(n1, n2) \
	if ( (n1)->type != (n2)->type ) \
	  make_same_type_numbers(n1, n2)

#define TOINT_CONVERT_FLOAT	0x1	/* toIntegerNumber() */
#define TOINT_TRUNCATE		0x2

#ifdef O_GMP
#define intNumber(n)	((n)->type <=  V_MPZ)
#else
#define intNumber(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 */
} 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	1
#define GF_PROCEDURE	2		/* check for max arity */


		 /*******************************
		 *	       ALERT		*
		 *******************************/

/* See updateAlerted()
*/

#define	ALERT_SIGNAL	 0x01
#define	ALERT_GCREQ	 0x02
#define	ALERT_PROFILE	 0x04
#define	ALERT_EXITREQ	 0x08
#define	ALERT_DEPTHLIMIT 0x10
#define	ALERT_WAKEUP	 0x20
#define ALERT_DEBUG	 0x40


		 /*******************************
		 *	     CLEANUP		*
		 *******************************/

typedef enum
{ CLN_NORMAL = 0,			/* Normal mode */
  CLN_ACTIVE,				/* Started cleanup */
  CLN_FOREIGN,				/* Foreign hooks */
  CLN_PROLOG,				/* Prolog hooks */
  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 false(s, a)		(!true((s), (a)))
#define set(s, a)		((s)->flags |= (a))
#define clear(s, a)		((s)->flags &= ~(a))
#define clearFlags(s)		((s)->flags = 0)

/* Flags on predicates (packed in unsigned int */

#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 NEEDSCLAUSEGC		(0x00400000) /* Holds erased clauses */
#define HIDE_CHILDS		(0x00800000) /* Hide children from tracer */
#define SPY_ME			(0x01000000) /* Spy point placed */
#define TRACE_ME		(0x02000000) /* Can be debugged */
#define TRACE_CALL		(0x04000000) /* Trace calls */
#define TRACE_REDO		(0x08000000) /* Trace redo */
#define TRACE_EXIT		(0x10000000) /* Trace edit */
#define TRACE_FAIL		(0x20000000) /* Trace fail */
#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)

/* Flags on clauses (packed in unsigned flags : 8) */

#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 */

/* Flags on module.  Most of these flags are copied to the read context
   in pl-read.c.
*/

#define M_SYSTEM		(0x0001) /* system module */
#define M_CHARESCAPE		(0x0002) /* module */
#define DBLQ_CHARS		(0x0004) /* "ab" --> ['a', 'b'] */
#define DBLQ_ATOM		(0x0008) /* "ab" --> 'ab' */
#define DBLQ_STRING		(0x0010) /* "ab" --> "ab" */
#define DBLQ_MASK		(DBLQ_CHARS|DBLQ_ATOM|DBLQ_STRING)
#define UNKNOWN_FAIL		(0x0020) /* module */
#define UNKNOWN_WARNING		(0x0040) /* module */
#define UNKNOWN_ERROR		(0x0080) /* module */
#define UNKNOWN_MASK		(UNKNOWN_ERROR|UNKNOWN_WARNING|UNKNOWN_FAIL)

/* Flags on functors */

#define CONTROL_F		(0x0002) /* functor (compiled controlstruct) */
#define ARITH_F			(0x0004) /* functor (arithmetic operator) */

/* Flags on record lists (recorded database keys) */

#define RL_DIRTY		(0x0001) /* recordlist */

/* Flags on recorded database records (also PL_record()) */

#define R_ERASED		(0x0001) /* record: record is erased */
#define R_EXTERNAL		(0x0002) /* record: inline atoms */
#define R_DUPLICATE		(0x0004) /* record: include references */
#define R_NOLOCK		(0x0008) /* record: do not lock atoms */
#define R_DBREF			(0x0010) /* record: has DB-reference */

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Macros for environment frames (local stack frames)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define FR_HIDE_CHILDS		(0x01L)	/* flag of pred after I_DEPART */
#define FR_SKIPPED		(0x02L)	/* We have skipped on this frame */
#define FR_MARKED		(0x04L)	/* GC */
#define FR_MARKED_PRED		(0x08L)	/* GC predicates/clauses */
#define FR_WATCHED		(0x10L)	/* GUI debugger */
#define FR_CATCHED		(0x20L)	/* Frame caught an exception */
#define FR_INBOX		(0x40L) /* Inside box (for REDO in built-in) */
#define FR_CONTEXT		(0x80L)	/* fr->context is set */

#define ARGOFFSET		((int)sizeof(struct localFrame))
#define VAROFFSET(var)		((var)+(ARGOFFSET/(int)sizeof(word)))

#define setLevelFrame(fr, l)	do { (fr)->level = (l); } while(0)
#define levelFrame(fr)		((fr)->level)
#define argFrameP(f, n)		((Word)((f)+1) + (n))
#define argFrame(f, n)		(*argFrameP((f), (n)) )
#define varFrameP(f, n)		((Word)(f) + (n))
#define varFrame(f, n)		(*varFrameP((f), (n)) )
#define refFliP(f, n)		((Word)((f)+1) + (n))
#define parentFrame(f)		((f)->parent ? (f)->parent\
					     : (LocalFrame)varFrame((f), -1))
#define slotsFrame(f)		(true((f)->predicate, P_FOREIGN) ? \
				      (f)->predicate->functor->arity : \
				      (f)->clause->clause->prolog_vars)

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Generations must be 64-bit to  avoid   overflow  in realistic scenarios.
This makes them the only 64-bit value in struct localFrame. Stack frames
mix with variables on the stacks and  are thus word-aligned. We have two
options here. One is to represent a  generation as a struct (used below)
or we must align frame at 8-byte  boundaries. The latter is probably the
best solution, but merely aligning lTop in   I_ENTER  doesn't seem to be
doing the trick: it causes failure of the  test suite for which I failed
to find the reason. Enabling the structure   on x86 causes a slowdown of
about 5%. I'd assume the difference is smaller on real 32-bit hardware.

We enable this  if the alignment  of an int64_t type  is not the same as
the alignment of pointers.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#ifdef O_LOGICAL_UPDATE
typedef uint64_t gen_t;

#if ALIGNOF_INT64_T != ALIGNOF_VOIDP
typedef struct lgen_t
{ uint32_t	gen_l;
  uint32_t	gen_u;
} lgen_t;

#define generationFrame(f) \
	((gen_t)(f)->generation.gen_u<<32 | (gen_t)(f)->generation.gen_l)
#define setGenerationFrame(f, gen) \
	do { (f)->generation.gen_u = (uint32_t)(gen>>32); \
	     (f)->generation.gen_l = (uint32_t)(gen); \
	   } while(0)
#else
typedef uint64_t lgen_t;
#define generationFrame(f)	((f)->generation)
#define setGenerationFrame(f, gen) \
	do { (f)->generation = (gen); } while(0)
#endif
#else /*O_LOGICAL_UPDATE*/
#define generationFrame(f)	(0)
#define setGenerationFrame(f)	(void)0
#endif /*O_LOGICAL_UPDATE*/

#define FR_CLEAR_NEXT	FR_SKIPPED|FR_WATCHED|FR_CATCHED|FR_HIDE_CHILDS
#define setNextFrameFlags(next, fr) \
	do \
	{ (next)->level = (fr)->level+1; \
	  (next)->flags = ((fr)->flags) & ~(FR_CLEAR_NEXT|FR_CONTEXT); \
	} while(0)

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Predicate reference counting. The aim  of   this  mechanism  is to avoid
modifying the predicate structure while  it   has  choicepoints  or (MT)
other threads running the predicate. For dynamic  code we allow to clean
the predicate as the reference-count drops to   zero. For static code we
introduce a garbage collector (TBD).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define enterDefinition(def) \
	if ( unlikely(true(def, P_DYNAMIC)) ) \
	{ LOCKDYNDEF(def); \
	  def->references++; \
	  UNLOCKDYNDEF(def); \
	}
#define leaveDefinition(def) \
	if ( unlikely(true(def, P_DYNAMIC)) ) \
	{ LOCKDYNDEF(def); \
	  if ( --def->references == 0 && \
	       true(def, NEEDSCLAUSEGC) ) \
	  { gcClausesDefinitionAndUnlock(def); \
	  } else \
	  { UNLOCKDYNDEF(def); \
	  } \
	}


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
At times an abort is not allowed because the heap  is  inconsistent  the
programmer  should  call  startCritical  to start such a code region and
endCritical to end it.

MT/TBD: how to handle this gracefully in the multi-threading case.  Does
it mean anything?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define startCritical (void)(LD->critical++)
#define endCritical   ((--(LD->critical) == 0 && LD->alerted) \
				? endCritical__LD(PASS_LD1) : TRUE)

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LIST processing macros.

    isNil(w)		word is the nil list ([]).
    isList(w)		word is a './2' term.
    HeadList(p)		Pointer to the head of list *p (NOT dereferenced).
    TailList(p)		Pointer to the tail of list *p (NOT dereferenced).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define HeadList(p)	(argTermP(*(p), 0) )
#define TailList(p)	(argTermP(*(p), 1) )

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Doubles. To and from are Word pointers pointing to the data of a double,
but generally not  satisfying  the   double  alignment  requirements. We
assume

  sizeof(*to) == sizeof(*from) &&
  sizeof(*to) * n == sizeof(*double)
	with n == 1 or n == 2.

We assume the compiler will optimise this properly.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define cpDoubleData(to, from) \
	{ Word _f = (Word)(from); \
	  switch(WORDS_PER_DOUBLE) \
	  { case 2: \
	      *(to)++ = *_f++; \
	    case 1: \
	      *(to)++ = *_f++; \
	      from = (void *)_f; \
	      break; \
	    default: \
	      assert(0); \
	  } \
	}

#define cpInt64Data(to, from) \
	{ Word _f = (Word)(from); \
	  switch(WORDS_PER_INT64) \
	  { case 2: \
	      *(to)++ = *_f++; \
	    case 1: \
	      *(to)++ = *_f++; \
	      from = (void *)_f; \
	      break; \
	    default: \
	      assert(0); \
	  } \
	}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Structure declarations that must be shared across multiple files.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

struct atom
{ Atom		next;		/* next in chain */
  word		atom;		/* as appearing on the global stack */
#ifdef O_TERMHASH
  unsigned int  hash_value;	/* hash-key value */
#endif
#ifdef O_ATOMGC
  unsigned int	references;	/* reference-count */
#endif
  struct PL_blob_t *type;	/* blob-extension */
  size_t	length;		/* length of the atom */
  char *	name;		/* name associated with atom */
};


typedef struct atom_array
{ Atom *blocks[8*sizeof(void*)];
} atom_array;


#ifdef O_ATOMGC
#define ATOM_MARKED_REFERENCE ((unsigned int)1 << (INTBITSIZE-1))
#ifdef O_DEBUG_ATOMGC
#define PL_register_atom(a) \
	_PL_debug_register_atom(a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define PL_unregister_atom(a) \
	_PL_debug_unregister_atom(a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#undef atomValue
#define atomValue(a) _PL_debug_atom_value(a)
extern Atom _PL_debug_atom_value(atom_t a);
#endif
#else
#define PL_register_atom(a)
#define PL_unregister_atom(a)
#endif

struct functorDef
{ FunctorDef	next;		/* next in chain */
  word		functor;	/* as appearing on the global stack */
  word		name;		/* Name of functor */
  unsigned	arity;		/* arity of functor */
  unsigned      flags;		/* Flag field holding: */
		  /* CONTROL_F	   Compiled control-structure */
		  /* ARITH_F	   Arithmetic function */
};


typedef struct functor_array
{ FunctorDef *blocks[8*sizeof(void*)];
} functor_array;


#ifdef O_LOGICAL_UPDATE
#define visibleClause(cl, gen) \
	((cl)->generation.created <= (gen) && \
	 (cl)->generation.erased   > (gen))
#else
#define visibleClause(cl, gen) false(cl, CL_ERASED)
#endif

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Struct clause must be a  multiple   of  sizeof(word)  for compilation on
behalf  of  I_USERCALL.  This   is   verified    in   an   assertion  in
checkCodeTable().
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define sizeofClause(n) ((char *)&((Clause)NULL)->codes[n] - (char *)NULL)

struct clause
{ Procedure	procedure;		/* procedure we belong to */
#ifdef O_LOGICAL_UPDATE
  struct
  { gen_t created;			/* Generation that created me */
    gen_t erased;			/* Generation I was erased */
  } generation;
#endif /*O_LOGICAL_UPDATE*/
  unsigned int		variables;	/* # of variables for frame */
  unsigned int		prolog_vars;	/* # real Prolog variables */
  unsigned		flags : 8;	/* Flag field holding: */
  unsigned		line_no : 24;	/* Source line-number */
  unsigned short	source_no;	/* Index of source-file */
  unsigned short	owner_no;	/* Index of owning source-file */
  code			code_size;	/* size of ->codes */
  code			codes[1];	/* VM codes of clause */
};

typedef struct clause_list
{ ClauseRef	first_clause;		/* clause list of procedure */
  ClauseRef	last_clause;		/* last clause of list */
  ClauseIndex	clause_indexes;		/* Hash index(es) */
  unsigned int	number_of_clauses;	/* number of associated clauses */
  unsigned int	erased_clauses;		/* number of erased clauses in set */
  unsigned int	number_of_rules;	/* number of real rules */
} clause_list, *ClauseList;

typedef struct clause_ref
{ ClauseRef	next;			/* Next in list */
  word		key;			/* Index key */
  union
  { Clause	clause;			/* Single clause value */
    clause_list	clauses;		/* Clause list (in hash-tables) */
  } value;
} clause_ref;

#define SIZEOF_CREF_CLAUSE	(offsetof(clause_ref, value.clause) + \
				 sizeof(Clause))
#define SIZEOF_CREF_LIST	sizeof(clause_ref)

#define VM_DYNARGC    255	/* compute argcount dynamically */

#define CA1_PROC	1	/* code arg 1 is procedure */
#define CA1_FUNC	2	/* code arg 1 is functor */
#define CA1_DATA	3	/* code arg 2 is prolog data (H_ATOM, H_SMALLINT) */
#define CA1_INTEGER	4	/* intptr_t value */
#define CA1_INT64	5	/* int64 value */
#define CA1_FLOAT	6	/* next WORDS_PER_DOUBLE are double */
#define CA1_STRING	7	/* inlined string */
#define CA1_MODULE	8	/* a module */
#define CA1_VAR		9	/* a variable(-offset) */
#define CA1_FVAR       10	/* a variable(-offset), used as `firstvar' */
#define CA1_CHP	       11	/* ChoicePoint (also variable(-offset)) */
#define CA1_MPZ	       12	/* GNU mpz number */
#define CA1_FOREIGN    13	/* Foreign function pointer */
#define CA1_CLAUSEREF  14	/* Clause reference */
#define CA1_JUMP       15	/* Instructions to skip */
#define CA1_AFUNC      16	/* Number of arithmetic function */

#define VIF_BREAK      0x01	/* Can be a breakpoint */

typedef enum
{ VMI_REPLACE,
  VMI_STEP_ARGUMENT
} vmi_merge_type;

typedef struct
{ vmi		code;		/* Code to merge with */
  vmi_merge_type how;		/* How to merge? */
  vmi		merge_op;	/* Opcode of merge */
  int		merge_ac;	/* #arguments of merged code */
  code		merge_av[1];	/* Argument vector */
} vmi_merge;

typedef struct
{ char	       *name;		/* name of the code */
  vmi		code;		/* number of the code */
  unsigned char flags;		/* Addional flags (VIF_*) */
  unsigned char	arguments;	/* #args code takes (or VM_DYNARGC) */
  char		argtype[4];	/* Argument type(s) code takes */
} code_info;

struct mark
{ TrailEntry	trailtop;	/* top of the trail stack */
  Word		globaltop;	/* top of the global stack */
  Word		saved_bar;	/* saved LD->mark_bar */
};

struct functor
{ word		definition;	/* Tagged definition pointer */
  word		arguments[1];	/* arguments vector */
};

struct clause_bucket
{ ClauseRef	head;
  ClauseRef	tail;
  unsigned int	dirty;			/* # of garbage clauses */
};

#define MAX_MULTI_INDEX 1

struct clause_index
{ unsigned int	 buckets;		/* # entries */
  unsigned int	 size;			/* # clauses */
  unsigned int	 resize_above;		/* consider resize > #clauses */
  unsigned int	 resize_below;		/* consider resize < #clauses */
  unsigned int	 dirty;			/* # chains that are dirty */
  unsigned short args[MAX_MULTI_INDEX];	/* Indexed arguments */
  unsigned	 is_list : 1;		/* Index with lists */
  float		 speedup;		/* Estimated speedup */
  struct bit_vector *tried_better;	/* We tried to access for better hash */
  ClauseIndex	 next;			/* Next index */
  ClauseBucket	 entries;		/* chains holding the clauses */
};

typedef struct clause_index_list
{ ClauseIndex index;
  struct clause_index_list *next;
} clause_index_list, *ClauseIndexList;

#define MAX_BLOCKS 20			/* allows for 2M threads */

typedef struct local_definitions
{ Definition *blocks[MAX_BLOCKS];
  Definition preallocated[7];
} local_definitions;

#ifdef _MSC_VER
typedef __int64 meta_mask;		/* MSVC cannot do typedef of typedef!? */
#else
typedef uint64_t meta_mask;
#endif

struct definition
{ FunctorDef	functor;		/* Name/Arity of procedure */
  Module	module;			/* module of the predicate */
  Code		codes;			/* Executable code */
  union
  { void *	any;			/* has some value */
    clause_list	clauses;		/* (Indexed) list of clauses */
    Func	function;		/* function pointer of procedure */
    LocalDefinitions local;		/* P_THREAD_LOCAL predicates */
  } impl;
#ifdef O_PLMT
  counting_mutex  *mutex;		/* serialize access to dynamic pred */
#endif
  ClauseIndexList old_clause_indexes;	/* Outdated hash indexes */
  struct bit_vector *tried_index;	/* Arguments on which we tried to index */
  meta_mask	meta_info;		/* meta-predicate info */
  int		references;		/* reference count */
  unsigned int  flags;			/* booleans (P_*) */
  unsigned int  shared;			/* #procedures sharing this def */
#ifdef O_PROF_PENTIUM
  int		prof_index;		/* index in profiling */
  char	       *prof_name;		/* name in profiling */
#endif
};

struct definition_chain
{ Definition		definition;	/* chain on definition */
  DefinitionChain	next;		/* next in chain */
};

#define	PROC_WEAK	(0x0001)	/* implicit import */

struct procedure
{ Definition	definition;		/* definition of procedure */
  unsigned int	flags;			/* PROC_WEAK */
};

struct localFrame
{ Code		programPointer;		/* pointer into program */
  LocalFrame	parent;			/* parent local frame */
  ClauseRef	clause;			/* Current clause of frame */
  Definition	predicate;		/* Predicate we are running */
  Module	context;		/* context module of frame */
#ifdef O_PROFILE
  struct call_node *prof_node;		/* Profiling node */
#endif
#ifdef O_LOGICAL_UPDATE
  lgen_t	generation;		/* generation of the database */
#endif
  unsigned int	level;			/* recursion level */
  unsigned int	flags;			/* packed long holding: */
};


typedef enum
{ CHP_JUMP = 0,				/* A jump due to ; */
  CHP_CLAUSE,				/* Next clause of predicate */
  CHP_TOP,				/* First (toplevel) choice */
  CHP_CATCH,				/* $catch initiated choice */
  CHP_DEBUG				/* Enable redo */
} choice_type;

typedef enum
{ DBG_OFF = 0,				/* no debugging */
  DBG_ON,				/* switch on in current environment */
  DBG_ALL				/* switch on globally */
} debug_type;

struct clause_choice
{ ClauseRef	cref;			/* Next clause reference */
  word		key;			/* Search key */
};

struct choice
{ choice_type	type;			/* CHP_* */
  Choice	parent;			/* Alternative if I fail */
  mark		mark;			/* data mark for undo */
  LocalFrame	frame;			/* Frame I am related to */
#ifdef O_PROFILE
  struct call_node *prof_node;		/* Profiling node */
#endif
  union
  { struct clause_choice clause;	/* Next candidate clause */
    Code	PC;			/* Next candidate program counter */
    word        foreign;		/* foreign redo handle */
  } value;
};


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EXCEPTION_GUARDED(code, cleanup) must be used  in environments that need
cleanup  should  a  PL_throw()  happen.  The   most  commpn  reason  for
PL_throw() instead of the nicely   synchronous PL_raise_exception() is a
stack overflow.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define EXCEPTION_GUARDED(code, cleanup) \
	{ exception_frame __throw_env; \
	  __throw_env.parent = LD->exception.throw_environment; \
	  if ( setjmp(__throw_env.exception_jmp_env) != 0 ) \
	  { LD->exception.throw_environment = __throw_env.parent; \
	    cleanup; \
	  } else \
	  { __throw_env.magic = THROW_MAGIC; \
	    LD->exception.throw_environment = &__throw_env; \
	    code; \
	    assert(LD->exception.throw_environment == &__throw_env); \
	    __throw_env.magic = 41414141; \
	    LD->exception.throw_environment = __throw_env.parent; \
	  } \
	}

#define THROW_MAGIC 42424242

typedef struct exception_frame		/* PL_throw exception environments */
{ struct exception_frame *parent;	/* parent frame */
  int		magic;			/* THROW_MAGIC */
  jmp_buf	exception_jmp_env;	/* longjmp environment */
} exception_frame;


#define QF_NODEBUG		0x0001	/* debug-able query */
#define QF_DETERMINISTIC	0x0002	/* deterministic success */
#define	QF_INTERACTIVE		0x0004	/* interactive goal (prolog()) */

struct queryFrame
{ uintptr_t magic;			/* Magic code for security */
  struct				/* Interpreter registers */
  { LocalFrame  fr;
    Word	argp;
    Code	pc;
  } registers;
  LocalFrame	next_environment;	/* See D_BREAK and get_vmi_state() */
#ifdef O_LIMIT_DEPTH
  uintptr_t saved_depth_limit;		/* saved values of these */
  uintptr_t saved_depth_reached;
#endif
#if O_CATCHTHROW
  term_t	exception;		/* Exception term */
#endif
  fid_t		foreign_frame;		/* Frame after PL_next_solution() */
  unsigned int	flags;
  debug_type	debugSave;		/* saved debugstatus.debugging */
  unsigned int	flags_saved;		/* Saved boolean Prolog flags */
  int		solutions;		/* # of solutions produced */
  Word	       *aSave;			/* saved argument-stack */
  Choice	saved_bfr;		/* Saved choice-point */
  LocalFrame	saved_ltop;		/* Saved lTop */
  QueryFrame	parent;			/* Parent queryFrame */
  struct choice	choice;			/* First (dummy) choice-point */
  LocalFrame	saved_environment;	/* Parent local-frame */
					/* Do not put anything between */
					/* or check parentFrame() */
  struct localFrame top_frame;		/* The (dummy) top local frame */
  struct localFrame frame;		/* The initial frame */
};


#define FLI_MAGIC		82649821
#define FLI_MAGIC_CLOSED	42424242

struct fliFrame
{ int		magic;			/* Magic code */
  int		size;			/* # slots on it */
  FliFrame	parent;			/* parent FLI frame */
  mark		mark;			/* data-stack mark */
};

#ifdef O_MAINTENANCE
#define REC_MAGIC 27473244
#endif

struct record
{ int		size;			/* # bytes of the record */
  unsigned      gsize;			/* Size on global stack */
  unsigned	nvars : 27;		/* # variables in the term */
  unsigned	flags : 5;		/* Flags, holding */
					/* R_ERASED */
					/* R_EXTERNAL */
					/* R_DUPLICATE */
					/* R_NOLOCK */
					/* R_DBREF */
#ifdef REC_MAGIC
  int		magic;			/* REC_MAGIC */
#endif
  int		references;		/* PL_duplicate_record() support */
  char		buffer[1];		/* array holding codes */
};

struct recordList
{ RecordRef	firstRecord;		/* first record associated with key */
  RecordRef	lastRecord;		/* last record associated with key */
  struct recordList *next;		/* Next recordList */
  word		key;			/* key of record */
  unsigned int	flags;			/* RL_DIRTY */
  int		references;		/* choicepoints reference count */
};

struct recordRef
{ RecordList	list;			/* list I belong to */
  RecordRef	next;			/* next in list */
  Record	record;			/* the record itself */
};

struct sourceFile
{ atom_t	name;			/* name of source file */
  double	mtime;			/* modification time when loaded */
  ListCell	procedures;		/* List of associated procedures */
  Procedure	current_procedure;	/* currently loading one */
  ListCell	modules;		/* Modules associated to this file */
  int		count;			/* number of times loaded */
  unsigned	index : 24;		/* index number (1,2,...) */
  unsigned	system : 1;		/* system sourcefile: do not reload */
};


struct list_cell
{ void *	value;		/* object in the cell */
  ListCell	next;		/* next in chain */
};


struct module
{ atom_t	name;		/* name of module */
  atom_t	class;		/* class of the module */
  SourceFile	file;		/* file from which module is loaded */
  Table		procedures;	/* predicates associated with module */
  Table		public;		/* public predicates associated */
  Table		operators;	/* local operator declarations */
  ListCell	supers;		/* Import predicates from here */
#ifdef O_PLMT
  counting_mutex *mutex;	/* Mutex to guard procedures */
#endif
#ifdef O_PROLOG_HOOK
  Procedure	hook;		/* Hooked module */
#endif
  int		level;		/* Distance to root (root=0) */
  unsigned int	line_no;	/* Source line-number */
  unsigned int  flags;		/* booleans: */
};

struct trail_entry
{ Word		address;	/* address of the variable */
};

struct gc_trail_entry
{ word		address;	/* address of the variable */
};

		 /*******************************
		 *	   META PREDICATE	*
		 *******************************/

/*0..9*/				/* 0..9: `Extra meta arguments' */
#define MA_META		10		/* : */
#define MA_VAR		11		/* - */
#define MA_ANY		12		/* ? */
#define MA_NONVAR	13		/* + */
#define MA_HAT		14		/* ^ */
#define MA_DCG		15		/* // */

#define MA_INFO(def, n) \
	(((def)->meta_info >> ((n)*4)) & 0xf)
#define MA_SETINFO(def, n, i) \
	((def)->meta_info &= ~((meta_mask)0xf << (n)*4), \
	 (def)->meta_info |= ((meta_mask)(i) << (n)*4))


		 /*******************************
		 *	     MARK/UNDO		*
		 *******************************/

#define setVar(w)	((w) = (word) 0)

#ifdef O_DESTRUCTIVE_ASSIGNMENT

#define Undo(b)		do_undo(&b)

#else /*O_DESTRUCTIVE_ASSIGNMENT*/

#define Undo(b)		do { TrailEntry tt = tTop; \
			     TrailEntry mt = (b).trailtop; \
			     while(tt > mt) \
			     { tt--; \
			       setVar(*tt->address); \
			     } \
			     tTop = tt; \
			     gTop = (LD->frozen_bar > (b).globaltop ? \
			             LD->frozen_bar : (b).globaltop); \
			    } while(0)
#endif /*O_DESTRUCTIVE_ASSIGNMENT*/

#define NO_MARK_BAR	(Word)(~(uintptr_t)0)

#define Mark(b)		do { (b).trailtop  = tTop; \
			     (b).saved_bar = LD->mark_bar; \
			     DEBUG(CHK_SECURE, assert((b).saved_bar >= gBase && \
					   (b).saved_bar <= gTop)); \
			     LD->mark_bar = (b).globaltop = gTop; \
			   } while(0)
#define DiscardMark(b)	do { LD->mark_bar = (LD->frozen_bar > (b).saved_bar ? \
					     LD->frozen_bar : (b).saved_bar); \
			   } while(0)
#define NOT_A_MARK	(TrailEntry)(~(word)0)
#define NoMark(b)	do { (b).trailtop = NOT_A_MARK; \
			   } while(0)
#define isRealMark(b)	((b).trailtop != NOT_A_MARK)


		 /*******************************
		 *	     TRAILING		*
		 *******************************/

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Note that all trail operations demand that   the caller ensures there is
at least one free cell on the trail-stack.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define Trail(p, w) Trail__LD(p, w PASS_LD)
					/* trail local stack pointer */
#define LTrail(p) \
  (void)((tTop++)->address = p)
					/* trail global stack pointer */
#define GTrail(p) \
  do { if ( p < LD->mark_bar ) \
         (tTop++)->address = p; \
     } while(0)


		 /*******************************
		 *	    SUPERVISORS		*
		 *******************************/

#define SUPERVISOR(name)	(&PL_code_data.supervisors.name[1])



		 /*******************************
		 *	   FLI INTERNALS	*
		 *******************************/

#define consTermRef(p)	 ((Word)(p) - (Word)(lBase))
#define valTermRef(r)	 (&((Word)(lBase))[r])

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Temporary store/restore pointers to make them safe over GC/shift
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define TMP_PTR_SIZE	(4)
#define PushPtr(p)	do { int i = LD->tmp.top++; \
			     assert(i<TMP_PTR_SIZE); \
			     *valTermRef(LD->tmp.h[i]) = makeRef(p); \
			   } while(0)
#define PopPtr(p)	do { int i = --LD->tmp.top; \
			     p = unRef(*valTermRef(LD->tmp.h[i])); \
			     setVar(*valTermRef(LD->tmp.h[i])); \
			   } while(0)
#define PushVal(w)	do { int i = LD->tmp.top++; \
			     assert(i<TMP_PTR_SIZE); \
			     *valTermRef(LD->tmp.h[i]) = w; \
			   } while(0)
#define PopVal(w)	do { int i = --LD->tmp.top; \
			     w = *valTermRef(LD->tmp.h[i]); \
			     setVar(*valTermRef(LD->tmp.h[i])); \
			   } while(0)


#define QueryFromQid(qid)	((QueryFrame) valTermRef(qid))
#define QidFromQuery(f)		(consTermRef(f))
#define QID_EXPORT_WAM_TABLE	(qid_t)(-1)

#include "SWI-Prolog.h"


		 /*******************************
		 *	       SIGNALS		*
		 *******************************/

#if HAVE_SIGNAL
#define MAXSIGNAL		64	/* highest system signal number */
#define SIG_PROLOG_OFFSET	32	/* Start of Prolog signals */

typedef RETSIGTYPE (*handler_t)(int);
typedef void *SignalContext;		/* struct sigcontext on sun */

typedef struct
{ handler_t   saved_handler;		/* Original handler */
  handler_t   handler;			/* User signal handler */
  predicate_t predicate;		/* Prolog handler */
  int	      flags;			/* PLSIG_*, defined in pl-setup.c */
} sig_handler, *SigHandler;
#endif /* HAVE_SIGNAL */

#define SIG_EXCEPTION	  (SIG_PROLOG_OFFSET+0)
#ifdef O_ATOMGC
#define SIG_ATOM_GC	  (SIG_PROLOG_OFFSET+1)
#endif
#define SIG_GC		  (SIG_PROLOG_OFFSET+2)
#ifdef O_PLMT
#define SIG_THREAD_SIGNAL (SIG_PROLOG_OFFSET+3)
#endif
#define SIG_FREECLAUSES	  (SIG_PROLOG_OFFSET+4)
#define SIG_PLABORT	  (SIG_PROLOG_OFFSET+5)


		 /*******************************
		 *	      EVENTS		*
		 *******************************/

typedef enum pl_event_type
{ PLEV_ABORT,				/* Execution aborted */
  PLEV_ERASED_CLAUSE,			/* clause was erased */
  PLEV_ERASED_RECORD,			/* record was erased */
  PLEV_DEBUGGING,			/* changed debugging mode */
  PLEV_TRACING,				/* changed tracing mode */
  PLEV_SPY,				/* changed spypoint */
  PLEV_BREAK,				/* a break-point was set */
  PLEV_NOBREAK,				/* a break-point was cleared */
  PLEV_FRAMEFINISHED,			/* A watched frame was discarded */
  PL_EV_THREADFINISHED			/* A thread has finished */
} pl_event_type;



		 /*******************************
		 *	       COMPARE		*
		 *******************************/

/* Results from comparison operations.  Mostly used by compareStandard() */

#define CMP_ERROR  -2			/* Error (out of memory) */
#define CMP_LESS   -1			/* < */
#define CMP_EQUAL   0			/* == */
#define CMP_GREATER 1			/* > */
#define CMP_NOTEQ   2			/* \== */

		/********************************
		*             STACKS            *
		*********************************/

#ifdef small				/* defined by MSVC++ 2.0 windows.h */
#undef small
#endif

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If we have access to the virtual   memory management of the machine, use
this to enlarge the runtime stacks.  Otherwise use the stack-shifter.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define GC_FAST_POLICY 0x1		/* not really used yet */

#define STACK(type) \
	{ type		base;		/* base address of the stack */     \
	  type		top;		/* current top of the stack */      \
	  type		max;		/* allocated maximum */		    \
	  size_t	size_limit;	/* Max size the stack can grow to */\
	  size_t	gced_size;	/* size after last GC */	    \
	  size_t	small;		/* Do not GC below this size */	    \
	  size_t	spare;		/* Current reserved area */	    \
	  size_t	def_spare;	/* Desired reserved area */	    \
	  size_t	min_free;	/* Free left when trimming */	    \
	  bool		gc;		/* Can be GC'ed? */		    \
	  int		factor;		/* How eager we are */		    \
	  int		policy;		/* Time, memory optimization */	    \
	  int	        overflow_id;	/* OVERFLOW_* */		    \
	  const char   *name;		/* Symbolic name of the stack */    \
	}

struct stack STACK(caddress);		/* Anonymous stack */

#define N_STACKS (4)

typedef struct
{ struct STACK(LocalFrame) local;	/* local (environment) stack */
  struct STACK(Word)	   global;	/* local (environment) stack */
  struct STACK(TrailEntry) trail;	/* trail stack */
  struct STACK(Word *)	   argument;	/* argument stack */
} pl_stacks_t;

#define tBase	(LD->stacks.trail.base)
#define tTop	(LD->stacks.trail.top)
#define tMax	(LD->stacks.trail.max)

#define lBase	(LD->stacks.local.base)
#define lTop	(LD->stacks.local.top)
#define lMax	(LD->stacks.local.max)

#define gBase	(LD->stacks.global.base)
#define gTop	(LD->stacks.global.top)
#define gMax	(LD->stacks.global.max)

#define aBase	(LD->stacks.argument.base)
#define aTop	(LD->stacks.argument.top)
#define aMax	(LD->stacks.argument.max)

#define tSpare	(LD->stacks.trail.spare)

#define onStack(name, addr) \
	((char *)(addr) >= (char *)LD->stacks.name.base && \
	 (char *)(addr) <  (char *)LD->stacks.name.top)
#define onStackArea(name, addr) \
	((char *)(addr) >= (char *)LD->stacks.name.base && \
	 (char *)(addr) <  (char *)LD->stacks.name.max)
#define onTrailArea(addr) \
	((char *)(addr) >= (char *)tBase && \
	 (char *)(addr) <  (char *)tMax + tSpare)
#define onGlobalArea(addr) \
	((char *)(addr) >= (char *)gBase && \
	 (char *)(addr) <  (char *)lBase)
#define usedStackP(s) ((intptr_t)((char *)(s)->top - (char *)(s)->base))
#define sizeStackP(s) ((intptr_t)((char *)(s)->max - (char *)(s)->base))
#define roomStackP(s) ((intptr_t)((char *)(s)->max - (char *)(s)->top))
#define spaceStackP(s) (limitStackP(s)-usedStackP(s))
#define limitStackP(s) ((intptr_t)((s)->size_limit))
#define narrowStackP(s) (roomStackP(s) < (intptr_t)(s)->minfree)

#define usedStack(name) usedStackP(&LD->stacks.name)
#define sizeStack(name) sizeStackP(&LD->stacks.name)
#define roomStack(name) roomStackP(&LD->stacks.name)
#define spaceStack(name) spaceStackP(&LD->stacks.name)
#define limitStack(name) limitStackP(&LD->stacks.name)
#define narrowStack(name) narrowStackP(&LD->stacks.name)

#define GROW_TRIM ((size_t)-1)

#define	LOCAL_OVERFLOW	  (-1)
#define	GLOBAL_OVERFLOW	  (-2)
#define	TRAIL_OVERFLOW	  (-3)
#define	ARGUMENT_OVERFLOW (-4)
#define	MEMORY_OVERFLOW   (-5)		/* out of malloc()-heap */

#define ALLOW_NOTHING	0x0
#define ALLOW_GC	0x1
#define ALLOW_SHIFT	0x2
#define ALLOW_CHECKED	0x4

typedef enum
{ STACK_OVERFLOW_RAISE,
  STACK_OVERFLOW_THROW
} stack_overflow_action;

#define pushArgumentStack(p) \
	do { if ( likely(aTop+1 < aMax) ) \
	       *aTop++ = (p); \
	     else \
	       pushArgumentStack__LD((p) PASS_LD); \
	   } while(0)

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
hasGlobalSpace(n) is true if we have enough space to create an object of
size N on the global stack AND  can   use  bindConst()  to bind it to an
(attributed) variable.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define BIND_GLOBAL_SPACE (7)
#define BIND_TRAIL_SPACE (6)
#define hasGlobalSpace(n) \
	(likely(gTop+(n)+BIND_GLOBAL_SPACE <= gMax) && \
	 likely(tTop+BIND_TRAIL_SPACE <= tMax))
#define overflowCode(n) \
	( (gTop+(n)+BIND_GLOBAL_SPACE > gMax) ? GLOBAL_OVERFLOW \
					      : TRAIL_OVERFLOW )


		 /*******************************
		 *	     NUMBERVARS		*
		 *******************************/

typedef enum
{ AV_BIND,
  AV_SKIP,
  AV_ERROR
} av_action;

typedef struct
{ functor_t functor;			/* Functor to use ($VAR/1) */
  av_action on_attvar;			/* How to handle attvars */
  int	    singletons;			/* Write singletons as $VAR('_') */
  int	    numbered_check;		/* Check for already numbered */
} nv_options;

#define BEGIN_NUMBERVARS(save) \
	{ fid_t _savedf; \
	  if ( save ) \
	  { _savedf = LD->var_names.numbervars_frame; \
	    LD->var_names.numbervars_frame = PL_open_foreign_frame(); \
	  }
#define END_NUMBERVARS(save) \
          if ( save ) \
	  { PL_discard_foreign_frame(LD->var_names.numbervars_frame); \
	    LD->var_names.numbervars_frame = _savedf; \
	  } \
	}


		 /*******************************
		 *	      WAKEUP		*
		 *******************************/

#define WAKEUP_STATE_WAKEUP    0x1
#define WAKEUP_STATE_EXCEPTION 0x2
#define WAKEUP_STATE_SKIP_EXCEPTION 0x4

typedef struct wakeup_state
{ fid_t		fid;			/* foreign frame reference */
  int		flags;
} wakeup_state;




		 /*******************************
		 *	    STREAM I/O		*
		 *******************************/

#define REDIR_MAGIC 0x23a9bef3

typedef struct redir_context
{ int		magic;			/* REDIR_MAGIC */
  IOSTREAM     *stream;			/* temporary output */
  int		is_stream;		/* redirect to stream */
  int		redirected;		/* output is redirected */
  term_t	term;			/* redirect target */
  int		out_format;		/* output type */
  int		out_arity;		/* 2 for difference-list versions */
  size_t	size;			/* size of I/O buffer */
  char	       *data;			/* data written */
  char		buffer[1024];		/* fast temporary buffer */
} redir_context;


		/********************************
		*       READ WARNINGS           *
		*********************************/

#define ReadingSource (source_line_no > 0 && \
		       source_file_name != NULL_ATOM)


		/********************************
		*        FAST DISPATCHING	*
		********************************/

#if VMCODE_IS_ADDRESS
#define encode(wam) (wam_table[wam])		/* WAM --> internal */
						/* internal --> WAM */
#define decode(c)   ((code) (dewam_table[(uintptr_t)(c) - \
					 dewam_table_offset]))
#else /* VMCODE_IS_ADDRESS */
#define encode(wam) (wam)
#define decode(wam) (wam)
#endif /* VMCODE_IS_ADDRESS */

		/********************************
		*            STATUS             *
		*********************************/

typedef struct
{ int		blocked;		/* GC is blocked now */
  bool		active;			/* Currently running? */
  long		collections;		/* # garbage collections */
  int64_t	global_gained;		/* global stack bytes collected */
  int64_t	trail_gained;		/* trail stack bytes collected */
  int64_t	global_left;		/* global stack bytes left after GC */
  int64_t	trail_left;		/* trail stack bytes left after GC */
  double	time;			/* time spent in collections */
} pl_gc_status_t;


typedef struct
{ int		blocked;		/* No shifts allowed */
  double	time;			/* time spent in stack shifts */
  int		local_shifts;		/* Shifts of the local stack */
  int		global_shifts;		/* Shifts of the global stack */
  int		trail_shifts;		/* Shifts of the trail stack */
} pl_shift_status_t;


		/********************************
		*            MODULES            *
		*********************************/

#define MODULE_user	(GD->modules.user)
#define MODULE_system	(GD->modules.system)
#define MODULE_parse	(ReadingSource ? LD->modules.source \
				       : MODULE_user)


		/********************************
		*         PREDICATES            *
		*********************************/

#define PROCEDURE_catch3		(GD->procedures.catch3)
#define PROCEDURE_true0			(GD->procedures.true0)
#define PROCEDURE_fail0			(GD->procedures.fail0)
#define PROCEDURE_event_hook1		(GD->procedures.event_hook1)
#define PROCEDURE_print_message2	(GD->procedures.print_message2)
#define PROCEDURE_dcall1		(GD->procedures.dcall1)
#define PROCEDURE_setup_call_catcher_cleanup4 \
				(GD->procedures.setup_call_catcher_cleanup4)
#define PROCEDURE_dwakeup1		(GD->procedures.dwakeup1)
#define PROCEDURE_call_residue_vars2	(GD->procedures.call_residue_vars2)
#define PROCEDURE_dthread_init0		(GD->procedures.dthread_init0)
#define PROCEDURE_exception_hook4	(GD->procedures.exception_hook4)
#define PROCEDURE_dc_call_prolog	(GD->procedures.dc_call_prolog0)

extern const code_info codeTable[]; /* Instruction info (read-only) */

		 /*******************************
		 *	  TEXT PROCESSING	*
		 *******************************/

typedef enum
{ CVT_ok = 0,				/* Conversion ok */
  CVT_wide,				/* Conversion needs wide characters */
  CVT_partial,				/* Input list is partial */
  CVT_nolist,				/* Input list is not a list */
  CVT_nocode,				/* List contains a non-code */
  CVT_nochar				/* List contains a non-char */
} CVT_status;

typedef struct
{ CVT_status status;
  word culprit;				/* for CVT_nocode/CVT_nochar */
} CVT_result;


		/********************************
		*            DEBUGGER           *
		*********************************/

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Tracer communication declarations.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define ACTION_CONTINUE	0
#define ACTION_RETRY	1
#define ACTION_FAIL	2
#define ACTION_IGNORE	3
#define ACTION_AGAIN	4
#define ACTION_ABORT	5		/* only for Prolog interception */

#define CALL_PORT	0x001		/* port masks */
#define EXIT_PORT	0x002
#define FAIL_PORT	0x004
#define REDO_PORT	0x008
#define UNIFY_PORT	0x010
#define CUT_CALL_PORT   0x040
#define CUT_EXIT_PORT   0x080
#define EXCEPTION_PORT	0x100
#define CUT_PORT	(CUT_CALL_PORT|CUT_EXIT_PORT)
#define PORT_MASK	0x1ff

/* keep in sync with style_name/1 in boot/prims.pl */

#define LONGATOM_CHECK	    0x0001	/* read/1: error on intptr_t atoms */
#define SINGLETON_CHECK	    0x0002	/* read/1: check singleton vars */
#define MULTITON_CHECK	    0x0004	/* read/1: check multiton vars */
#define DISCONTIGUOUS_STYLE 0x0008	/* warn on discontiguous predicates */
#define DYNAMIC_STYLE	    0x0010	/* warn on assert/retract active */
#define CHARSET_CHECK	    0x0020	/* warn on unquoted characters */
#define SEMSINGLETON_CHECK  0x0040	/* Semantic singleton checking */
#define NOEFFECT_CHECK	    0x0080	/* Check for meaningless statements */
#define VARBRANCH_CHECK	    0x0100	/* warn on unbalanced variables */
#define MAXNEWLINES	    5		/* maximum # of newlines in atom */

typedef struct debuginfo
{ size_t	skiplevel;		/* current skip level */
  bool		tracing;		/* are we tracing? */
  debug_type	debugging;		/* are we debugging? */
  int		leashing;		/* ports we are leashing */
  int	        visible;		/* ports that are visible */
  bool		showContext;		/* tracer shows context module */
  int		styleCheck;		/* source style checking */
  int		suspendTrace;		/* tracing is suspended now */
  LocalFrame	retryFrame;		/* Frame to retry */
} pl_debugstatus_t;

#define FT_ATOM		0		/* atom feature */
#define FT_BOOL		1		/* boolean feature (true, false) */
#define FT_INTEGER	2		/* integer feature */
#define FT_FLOAT	3		/* float feature */
#define FT_TERM		4		/* term feature */
#define FT_INT64	5		/* passed as int64_t */
#define FT_FROM_VALUE	0x0f		/* Determine type from value */
#define FT_MASK		0x0f		/* mask to get type */

#define PLFLAG_CHARESCAPE	    0x000001 /* handle \ in atoms */
#define PLFLAG_GC		    0x000002 /* do GC */
#define PLFLAG_TRACE_GC		    0x000004 /* verbose gc */
#define PLFLAG_TTY_CONTROL	    0x000008 /* allow for tty control */
#define PLFLAG_READLINE		    0x000010 /* readline is loaded */
#define PLFLAG_DEBUG_ON_ERROR	    0x000020 /* start tracer on error */
#define PLFLAG_REPORT_ERROR	    0x000040 /* print error message */
#define PLFLAG_FILE_CASE	    0x000080 /* file names are case sensitive */
#define PLFLAG_FILE_CASE_PRESERVING 0x000100 /* case preserving file names */
#define PLFLAG_DOS_FILE_NAMES       0x000200 /* dos (8+3) file names */
#define ALLOW_VARNAME_FUNCTOR	    0x000400 /* Read Foo(x) as 'Foo'(x) */
#define PLFLAG_ISO		    0x000800 /* Strict ISO compliance */
#define PLFLAG_OPTIMISE		    0x001000 /* -O: optimised compilation */
#define PLFLAG_FILEVARS		    0x002000 /* Expand $var and ~ in filename */
#define PLFLAG_AUTOLOAD		    0x004000 /* do autoloading */
#define PLFLAG_CHARCONVERSION	    0x008000 /* do character-conversion */
#define PLFLAG_LASTCALL		    0x010000 /* Last call optimization enabled? */
#define PLFLAG_BACKQUOTED_STRING    0x020000 /* `a string` */
#define PLFLAG_SIGNALS		    0x040000 /* Handle signals */
#define PLFLAG_DEBUGINFO	    0x080000 /* generate debug info */
#define PLFLAG_FILEERRORS	    0x100000 /* Edinburgh file errors */
#define PLFLAG_WARN_OVERRIDE_IMPLICIT_IMPORT 0x200000 /* Warn overriding weak symbols */
#define PLFLAG_QUASI_QUOTES	    0x400000 /* Support quasi quotes */

typedef struct
{ unsigned int flags;		/* Fast access to some boolean Prolog flags */
} pl_features_t;

#define truePrologFlag(flag)	  true(&LD->prolog_flag.mask, flag)
#define setPrologFlagMask(flag)	  set(&LD->prolog_flag.mask, flag)
#define clearPrologFlagMask(flag) clear(&LD->prolog_flag.mask, flag)

typedef enum
{ OCCURS_CHECK_FALSE = 0,	/* allow rational trees */
  OCCURS_CHECK_TRUE,		/* fail if rational tree would result */
  OCCURS_CHECK_ERROR		/* exception if rational tree would result */
} occurs_check_t;

typedef enum
{ ACCESS_LEVEL_USER = 0,	/* Default user view */
  ACCESS_LEVEL_SYSTEM		/* Allow low-level access */
} access_level_t;

#define SYSTEM_MODE	    (LD->prolog_flag.access_level == ACCESS_LEVEL_SYSTEM)

#ifdef O_LIMIT_DEPTH
#define DEPTH_NO_LIMIT	(~(uintptr_t)0x0) /* Highest value */
#endif

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Administration of loaded intermediate code files  (see  pl-wic.c).  Used
with the -c option to include all these if necessary.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

typedef struct state * State;

struct state
{ char *	name;			/* name of state */
  State		next;			/* next state loaded */
};

#define QLF_TOPLEVEL 0x1		/* toplevel wic file */
#define QLF_OPTIONS  0x2		/* only load options */
#define QLF_EXESTATE 0x4		/* probe qlf exe state */

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sourcelocation information (should be used at more places).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

typedef struct
{ atom_t	file;			/* name of the file */
  int		line;			/* line number */
} sourceloc, *SourceLoc;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Include debugging info to make it (very) verbose.  SECURE adds  code  to
check  consistency mainly in the WAM interpreter.  Prolog gets VERY slow
if SECURE is  used.   DEBUG  is  not  too  bad  (about  20%  performance
decrease).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define REL(a)		((Word)(a) - (Word)(lBase))

#if defined(_DEBUG) && !defined(O_MAINTENANCE)
#define O_MAINTENANCE
#endif

#include "os/pl-os.h"			/* OS dependencies */

#ifdef SYSLIB_H
#include SYSLIB_H
#endif

#define NULL_ATOM ((atom_t)0)
#define MK_ATOM(n)		((atom_t)((n)<<7|TAG_ATOM|STG_STATIC))
#include "pl-atom.ih"
#include "pl-funct.ih"

#include "pl-alloc.h"			/* Allocation primitives */
#include "pl-init.h"			/* Declarations needed by pl-init.c */
#include "pl-error.h"			/* Exception generation */
#include "pl-thread.h"			/* thread manipulation */
#include "pl-data.h"			/* Access Prolog data */
#include "pl-segstack.h"		/* Segmented stacks */
#include "pl-gmp.h"			/* GNU-GMP support */
#include "os/pl-locale.h"		/* Locale objects */
#include "os/pl-file.h"			/* Stream management */
#include "pl-global.h"			/* global data */
#include "pl-funcs.h"			/* global functions */
#include "pl-ldpass.h"			/* Wrap __LD functions */
#include "pl-inline.h"			/* Inline facilities */
#include "pl-privitf.h"			/* private foreign interface */
#include "os/pl-text.h"			/* text manipulation */
#include "pl-hash.h"			/* Murmurhash function */
#include "os/pl-option.h"		/* Option processing */
#include "os/pl-files.h"		/* File management */
#include "os/pl-string.h"		/* Basic string functions */

#ifdef ATOMIC_INC
#define ATOMIC_REFERENCES 1		/* Use atomic +/- for atom references */
#endif

#ifdef __DECC				/* Dec C-compiler: avoid conflicts */
#undef leave
#undef except
#undef try
#endif

#ifdef DMALLOC
#define DMALLOC_FUNC_CHECK 1
#include <dmalloc.h>
#define allocHeap(n)		malloc(n)
#define allocHeapOrHalt(n)	xmalloc(n)
#define freeHeap(ptr, n)	xfree(ptr)
#endif

#endif /*_PL_INCLUDE_H*/