aboutsummaryrefslogtreecommitdiff
path: root/src/prog.h
blob: c41746da6214b85f4309bfd8257a80e6fcc8d325 (plain)
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
/* This file is part of Mailfromd.
   Copyright (C) 2006-2024 Sergey Poznyakoff

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

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#define MFL_DATASEG volatile

typedef void *mft_ptr;
typedef char *mft_str;
typedef int mft_int;
typedef unsigned int mft_uint;
typedef long mft_long;
typedef unsigned long mft_ulong;
typedef size_t mft_size;

typedef mft_str mft_string;
typedef mft_long mft_number;

union mf_stkval {
	mft_ptr   v_ptr;
	mft_size  v_size;
	mft_long  v_long;
	mft_ulong v_ulong;
	mft_int   v_int;
	mft_uint  v_uint;
	mft_str   v_str;
};
typedef union mf_stkval STKVAL;

#define mf_cat(a,b) a ## b
#define mf_c_val(x,t) ((x).mf_cat(v_,t))

#define mf_c_cast(x,t) ((STKVAL)(mf_cat(mft_,t))(x))

typedef void (*instr_t) (eval_environ_t env); /* Instruction */
union mf_code_cell {
	instr_t c_instr;
	STKVAL c_value;
};
typedef union mf_code_cell mf_code_cell_t;
#define mf_cell_instr(p) ((p).c_instr)
#define mf_cell_value(p) ((p).c_value)
#define mf_cell_c_value(p,t) mf_c_val(mf_cell_value(p),t)

struct optab {
	char *name;
	instr_t instr;
	void (*dump) (prog_counter_t i);
	unsigned length;
};

/* Code generation and diagnostics functions */
void code_put_stkval(prog_counter_t pos, STKVAL val);
#define code_put(p,v,t) code_put_stkval(p,mf_c_cast(v,t))
mf_code_cell_t code_peek(prog_counter_t pos);
prog_counter_t code_reserve(size_t count);

prog_counter_t code_immediate_stkval(STKVAL value);
#define code_immediate(v,t) code_immediate_stkval(mf_c_cast(v,t))
prog_counter_t code_op(unsigned code);
prog_counter_t code_instr(const instr_t ptr);
prog_counter_t code_exmask(struct exmask *exmask);
prog_counter_t code_get_counter();
void dump_code(prog_counter_t start, prog_counter_t end);
void fixup_code(void);
void run_startup(void);
void run_shutdown(void);

/* Runtime evaluation functions */
struct eval_environ;

#define B2STACK(s) (s + sizeof(STKVAL) - 1) / sizeof(STKVAL)

void runtime_warning(eval_environ_t env, const char *fmt, ...)
	MU_PRINTFLIKE(2, 3);
void runtime_error(eval_environ_t env, const char *fmt, ...)
	MU_PRINTFLIKE(2, 3) ATTRIBUTE_NORETURN;
STKVAL get_arg(eval_environ_t env, unsigned n);
void get_pointer_arg(eval_environ_t env, unsigned n, void * MFL_DATASEG *p);
void get_string_arg(eval_environ_t env, unsigned n, char *MFL_DATASEG *ptr);
void get_numeric_arg(eval_environ_t env, unsigned n, long *np);
void push(eval_environ_t env, STKVAL val);
STKVAL pop(eval_environ_t env);
STKVAL *env_data_ref(eval_environ_t env, size_t off);
size_t heap_reserve(eval_environ_t env, size_t size);
size_t heap_reserve_words(eval_environ_t env, size_t size);
STKVAL heap_tempspace(eval_environ_t env, size_t size);
void heap_obstack_begin(eval_environ_t env);
STKVAL heap_obstack_finish(eval_environ_t env);
void heap_obstack_cancel(eval_environ_t env);
void *heap_obstack_grow(eval_environ_t env, void *MFL_DATASEG ptr, size_t size);
void heap_obstack_reclaim(eval_environ_t env, size_t size);
void heap_obstack_truncate(eval_environ_t env, size_t size);
void *heap_obstack_base(eval_environ_t env);
void heap_obstack_vsprintf(eval_environ_t env, const char *fmt, va_list ap);
void heap_obstack_sprintf(eval_environ_t env, const char *fmt, ...);
void pushs(eval_environ_t env, const char * MFL_DATASEG s);
void advance_pc(eval_environ_t env, long cnt);
void adjust_stack(eval_environ_t env, unsigned cnt);
void unroll_stack(eval_environ_t env, unsigned cnt);
void prog_trace(eval_environ_t env, const char *fmt, ...)
	MU_PRINTFLIKE(2, 3);
void runtime_stack_trace(eval_environ_t env);
void env_var_inc(eval_environ_t env, size_t off);
void env_get_locus(eval_environ_t env, struct mu_locus_range *loc);
STKVAL env_get_reg(eval_environ_t env);
prog_counter_t env_register_read(eval_environ_t env, int what);
char *env_vaptr(eval_environ_t env, size_t off);
int expand_dataseg(eval_environ_t env, size_t count);
void env_save_socket_family(eval_environ_t env, int family);
int env_socket_family(eval_environ_t env);

void *env_get_builtin_priv(eval_environ_t env, int id);
int builtin_priv_register(void *(*init)(void), void (*destroy)(void*),
			  void (*free_capture));
void env_free_captured(eval_environ_t env);


enum cleanup_when {
	CLEANUP_THROW,        /* Cleanup on exception. */
	CLEANUP_RETURN,       /* Cleanup on return from function. */
	CLEANUP_ALWAYS        /* Cleanup always. */
};

void env_function_cleanup_add(eval_environ_t env, int when,
			      void *data,
			      void (*func)(void *));
void env_function_cleanup_del(eval_environ_t env, int when, void *data);
void env_function_cleanup_flush(eval_environ_t env, int when);


void ensure_initialized_variable(const char *name, struct value *val);
void ds_init_variable(const char *name, void *data);

void scan_code(prog_counter_t start, prog_counter_t end,
	       void (*fun)(prog_counter_t pc, struct optab *op, void *d),
	       void *data);

int within_loop(struct literal *lit);
void enter_loop(struct literal *lit,
		prog_counter_t *begptr, prog_counter_t *endptr);
void leave_loop(void);

NODE *alloc_node(enum node_type type, const struct mu_locus_range *locus);
NODE *create_node_variable(struct variable *var, const struct mu_locus_range *locus);
NODE *create_node_argcount(const struct mu_locus_range *locus);
NODE *create_node_arg(long num, const struct mu_locus_range *locus);
NODE *create_node_string(char const *str, struct mu_locus_range const *locus);
NODE *create_node_symbol(struct literal *lit, const struct mu_locus_range *loc);
NODE *create_node_backref(long num, const struct mu_locus_range *locus);
NODE *cast_to(data_type_t type, NODE *node);
void add_xref(struct variable *var, const struct mu_locus_range *locus);

extern mf_code_cell_t *prog;
extern unsigned error_count; 
extern unsigned long prog_trace_option;

extern STKVAL *dataseg;
extern size_t datasize;
extern size_t dvarsize;
#define EXTABIND (datasize - exception_count)

extern size_t *dataseg_reloc;
extern size_t dataseg_reloc_count;

extern size_t exception_count;

extern mu_stream_t mf_strecho;

Return to:

Send suggestions and report system problems to the System administrator.