1 /* repint.h -- Main include file for library internal objects
2    Copyright (C) 1993, 1994 John Harper <john@dcs.warwick.ac.uk>
3    $Id$
4 
5    This file is part of Jade.
6 
7    Jade is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11 
12    Jade is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with Jade; see the file COPYING.  If not, write to
19    the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20    Boston, MA 02110-1301 USA */
21 
22 #ifndef REPINT_H
23 #define REPINT_H
24 
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 
29 /* Maximum/minimum macros. Don't use when X or Y have side-effects! */
30 #ifdef __OpenBSD__
31     /* MAX and MIN these are defined in <sys/param.h> on OpenBSD
32      * We include that here as sometimes it's included in other
33      * places and sometimes not - this ensures we don't redefine
34      * these two macros */
35 # include <sys/param.h>
36 #else
37 # define MAX(x,y) (((x) > (y)) ? (x) : (y))
38 # define MIN(x,y) (((x) < (y)) ? (x) : (y))
39 #endif
40 #define POS(x)   MAX(x, 0)
41 #define ABS(x)   MAX(x, -(x))
42 
43 #define rep_INTERNAL 1
44 #include "rep.h"
45 
46 #ifndef ENABLE_BROKEN_DUMPING
47   /* No point incurring the overhead if it's unnecessary */
48 # undef rep_CONS_WRITABLE_P
49 # define rep_CONS_WRITABLE_P(x) rep_TRUE
50 #endif
51 
52 #ifdef rep_HAVE_UNIX
53 # include "unix_defs.h"
54 #else
55 # error "Need an operating system definition"
56 #endif
57 
58 enum file_ops {
59     op_file_name_absolute_p = 0,
60     op_expand_file_name,
61     op_local_file_name,
62     op_canonical_file_name,
63     op_file_name_nondirectory,
64     op_file_name_directory,
65     op_file_name_as_directory,
66     op_directory_file_name,
67     op_open_file,
68     op_close_file,
69     op_flush_file,
70     op_seek_file,
71     op_write_buffer_contents,		/* these three for jade */
72     op_read_file_contents,
73     op_insert_file_contents,
74     op_delete_file,
75     op_rename_file,
76     op_make_directory,
77     op_delete_directory,
78     op_copy_file,
79     op_copy_file_to_local_fs,
80     op_copy_file_from_local_fs,
81     op_file_readable_p,
82     op_file_writable_p,
83     op_file_executable_p,
84     op_file_exists_p,
85     op_file_regular_p,
86     op_file_directory_p,
87     op_file_symlink_p,
88     op_file_owner_p,
89     op_file_gid,
90     op_file_uid,
91     op_file_nlinks,
92     op_file_size,
93     op_file_modes,
94     op_set_file_modes,
95     op_file_modes_as_string,
96     op_file_modtime,
97     op_directory_files,
98     op_read_symlink,
99     op_make_symlink,
100 
101     op_MAX
102 };
103 
104 struct blocked_op {
105     struct blocked_op *next;
106     repv handler;
107 };
108 
109 extern struct blocked_op *rep_blocked_ops[op_MAX];
110 
111 
112 /* module system */
113 
114 typedef struct rep_struct_node_struct rep_struct_node;
115 struct rep_struct_node_struct {
116     rep_struct_node *next;
117     repv symbol;
118     repv binding;
119     unsigned int is_constant : 1;
120     unsigned int is_exported : 1;
121 };
122 
123 /* structure encapsulating a single namespace */
124 typedef struct rep_struct_struct rep_struct;
125 struct rep_struct_struct {
126     repv car;
127     rep_struct *next;
128   repv name; /* symbol, not string */
129     repv inherited;	/* exported symbols that have no local binding */
130     int total_buckets, total_bindings;
131     rep_struct_node **buckets;
132     repv imports;
133     repv accessible;
134 
135     /* A list of the special variables that may be accessed in this
136        environment, or Qt to denote all specials. */
137     repv special_env;
138 
139     /* Bytecode interpreter to use when calling functions defined here.
140        If null, call rep_apply_bytecode  */
141     repv (*apply_bytecode) (repv subr, int nargs, repv *args);
142 };
143 
144 extern int rep_structure_type;
145 
146 #define rep_STRUCTUREP(v) rep_CELL16_TYPEP(v, rep_structure_type)
147 #define rep_STRUCTURE(v)  ((rep_struct *) rep_PTR(v))
148 
149 /* If set, currently recursively searching this module for a binding */
150 #define rep_STF_EXCLUSION	(1 << (rep_CELL16_TYPE_BITS + 0))
151 
152 /* If set, all (local) bindings are exported by default. */
153 #define rep_STF_EXPORT_ALL	(1 << (rep_CELL16_TYPE_BITS + 1))
154 
155 /* If set, bindings can be created by setq et al. */
156 #define rep_STF_SET_BINDS	(1 << (rep_CELL16_TYPE_BITS + 2))
157 
158 #define rep_SPECIAL_ENV   (rep_STRUCTURE(rep_structure)->special_env)
159 
160 #define rep_STRUCT_HASH(x,n) (((x) >> 3) % (n))
161 
162 
163 /* binding tracking */
164 
165 #define rep_MARK_LEX_BINDING(x)		(x + (1 << rep_VALUE_INT_SHIFT))
166 #define rep_MARK_SPEC_BINDING(x)	(x + (1 << (16 + rep_VALUE_INT_SHIFT)))
167 #define rep_LEX_BINDINGS(x)		(rep_INT(x) & 0xffff)
168 #define rep_SPEC_BINDINGS(x)		(rep_INT(x) >> 16)
169 #define rep_NEW_FRAME			rep_MAKE_INT(0)
170 
171 #define rep_USE_FUNARG(f)				\
172     do {						\
173 	rep_env = rep_FUNARG(f)->env;			\
174 	rep_structure = rep_FUNARG(f)->structure;	\
175     } while (0)
176 
177 #define rep_USE_DEFAULT_ENV			\
178     do {					\
179 	rep_env = Qnil;				\
180 	rep_structure = rep_default_structure;	\
181     } while (0)
182 
183 
184 /* call history */
185 
186 /* Keeps a backtrace of all lisp functions called. */
187 struct rep_Call {
188     struct rep_Call *next;
189     repv fun;
190     repv args;
191     repv current_form;			/* used for debugging, set by progn */
192     repv saved_env;
193     repv saved_structure;
194 };
195 
196 #define rep_PUSH_CALL(lc)		\
197     do {				\
198 	(lc).current_form = rep_NULL;	\
199 	(lc).saved_env = rep_env;	\
200 	(lc).saved_structure = rep_structure; \
201 	(lc).next = rep_call_stack;	\
202 	rep_call_stack = &(lc);		\
203     } while (0)
204 
205 #define rep_POP_CALL(lc)		\
206     do {				\
207 	rep_env = (lc).saved_env;	\
208 	rep_structure = (lc).saved_structure; \
209 	rep_call_stack = (lc).next;	\
210     } while (0)
211 
212 
213 /* guardians */
214 
215 typedef struct rep_guardian_struct {
216     repv car;
217     struct rep_guardian_struct *next;
218     repv accessible;
219     repv inaccessible;
220 } rep_guardian;
221 
222 
223 /* cons' */
224 
225 #define rep_CONSBLK_SIZE	1022		/* ~8k */
226 
227 /* Structure of cons allocation blocks */
228 typedef struct rep_cons_block_struct {
229     union {
230 	struct rep_cons_block_struct *p;
231 	/* ensure that the following cons cell is aligned to at
232 	   least sizeof (rep_cons) (for the dcache) */
233 	rep_cons dummy;
234     } next;
235     rep_cons cons[rep_CONSBLK_SIZE];
236 } rep_cons_block;
237 
238 
239 /* prototypes */
240 
241 #include "repint_subrs.h"
242 
243 /* If using GCC, make inline_Fcons be Fcons that only takes a procedure
244    call when the heap needs to grow. */
245 
246 #if defined __GNUC__ && defined __OPTIMIZE__
247 static __inline__ repv inline_Fcons (repv x, repv y);
248 static __inline__ repv
inline_Fcons(repv x,repv y)249 inline_Fcons (repv x, repv y)
250 {
251     rep_cons *c = rep_cons_freelist;
252     if (c == 0)
253 	c = rep_allocate_cons ();
254     rep_cons_freelist = rep_CONS (c->cdr);
255     rep_used_cons++;
256     rep_data_after_gc += sizeof(rep_cons);
257 
258     c->car = (x);
259     c->cdr = (y);
260     return rep_CONS_VAL (c);
261 }
262 #else
263 # define inline_Fcons Fcons
264 #endif
265 
266 #endif /* REPINT_H */
267