summaryrefslogtreecommitdiff
path: root/include/interp.h
blob: e0571de1c0c3550a93d955955afaba257166961b (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
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
typedef uchar		BYTE;		/* 8  bits */
typedef int		WORD;		/* 32 bits */
typedef unsigned int	UWORD;		/* 32 bits */
typedef vlong		LONG;		/* 64 bits */
typedef uvlong		ULONG;		/* 64 bits */
typedef double		REAL;		/* 64 double IEEE754 */
typedef short		SHORT;		/* 16 bits */
typedef float		SREAL;		/* 32 float IEEE754 */

enum ProgState
{
	Palt,				/* blocked in alt instruction */
	Psend,				/* waiting to send */
	Precv,				/* waiting to recv */
	Pdebug,				/* debugged */
	Pready,				/* ready to be scheduled */
	Prelease,			/* interpreter released */
	Pexiting,			/* exit because of kill or error */
	Pbroken,			/* thread crashed */
};

enum
{
	propagator	= 3,		/* gc marking color */

	PRNSIZE	= 1024,
	BIHASH	= 23,
	PQUANTA	= 2048,	/* prog time slice */

	/* STRUCTALIGN is the unit to which the compiler aligns structs. */
	/* It really should be defined somewhere else */
	STRUCTALIGN = sizeof(int)	/* must be >=2 because of Strings */
};

enum
{
	Ppropagate = 1<<0,
	Pnotifyleader = 1<<1,
	Prestrict = 1<<2,
	Prestricted = 1<<3,
	Pkilled = 1<<4
};

typedef struct Alt	Alt;
typedef struct Channel	Channel;
typedef struct Progq	Progq;
typedef struct Import	Import;
typedef struct Inst	Inst;
typedef struct Module	Module;
typedef struct Modlink	Modlink;
typedef struct Modl	Modl;
typedef struct Type	Type;
typedef struct Prog	Prog;
typedef struct Progs	Progs;
typedef struct Heap	Heap;
typedef struct Link	Link;
typedef struct List	List;
typedef struct Array	Array;
typedef struct String	String;
typedef union  Linkpc	Linkpc;
typedef struct REG	REG;
typedef struct Frame	Frame;
typedef union  Stkext	Stkext;
typedef struct Atidle	Atidle;
typedef struct Altc	Altc;
typedef struct Except Except;
typedef struct Handler Handler;

struct Frame
{
	Inst*		lr;	/* REGLINK isa.h */
	uchar*		fp;	/* REGFP */
	Modlink*	mr;	/* REGMOD */
	Type*		t;	/* REGTYPE */
};

union Stkext
{
	uchar	stack[1];
	struct {
		Type*	TR;
		uchar*	SP;
		uchar*	TS;
		uchar*	EX;
		union {
			uchar	fu[1];
			Frame	fr[1];
		} tos;
	} reg;
};

struct Array
{
	WORD	len;
	Type*	t;
	Array*	root;
	uchar*	data;
};

struct List
{
	List*	tail;
	Type*	t;
	WORD	data[1];
};

struct Channel
{
	Array*	buf;		/* For buffered channels - must be first */
	Progq*	send;		/* Queue of progs ready to send */
	Progq*	recv;		/* Queue of progs ready to receive */
	void*	aux;		/* Rock for devsrv */
	void	(*mover)(void);	/* Data mover */
	union {
		WORD	w;
		Type*	t;
	} mid;
	int	front;	/* Front of buffered queue */
	int	size;		/* Number of data items in buffered queue */
};

struct Progq
{
	Prog*	prog;
	Progq*	next;
};
	
struct String
{
	int	len;		/* string length */
	int	max;		/* maximum length in representation */
	char*	tmp;
	union {
	#define	Sascii	data.ascii
	#define Srune	data.runes
		char	ascii[STRUCTALIGN];	/* string.c relies on having extra space (eg, in string2c) */
		Rune	runes[1];
	}data;	
};

union Linkpc
{
	void	(*runt)(void*);
	Inst*	pc;
};

struct Link
{
	int	sig;
	Type*	frame;
	Linkpc	u;
	char	*name;
};

typedef union	Adr	Adr;
union Adr
{
	WORD	imm;
	WORD	ind;
	Inst*	ins;
	struct {
		ushort	f;	/* First indirection */	
		ushort	s;	/* Second indirection */
	} i;
};

struct Inst
{
	uchar	op;
	uchar	add;
	ushort	reg;
	Adr	s;
	Adr	d;
};

struct Altc
{
	Channel*	c;
	void*		ptr;
};

struct Alt
{
	int	nsend;
	int	nrecv;
	Altc	ac[1];
};

struct Type
{
	int	ref;
	void	(*free)(Heap*, int);
	void	(*mark)(Type*, void*);
	int	size;
	int	np;
	void*	destroy;
	void*	initialize;
	uchar	map[STRUCTALIGN];
};

struct REG
{
	Inst*		PC;		/* Program counter */
	uchar*		MP;		/* Module data */
	uchar*		FP;		/* Frame pointer */
	uchar*		SP;		/* Stack pointer */
	uchar*		TS;		/* Top of allocated stack */
	uchar*		EX;		/* Extent register */
	Modlink*	M;		/* Module */
	int		IC;		/* Instruction count for this quanta */
	Inst*		xpc;		/* Saved program counter */
	void*		s;		/* Source */
	void*		d;		/* Destination */
	void*		m;		/* Middle */
	WORD		t;		/* Middle temporary */
	WORD		st;		/* Source temporary */
	WORD		dt;		/* Destination temporary */
};

struct Progs
{
	int	id;
	int	flags;
	Progs*	parent;
	Progs*	child;
	Progs*	sib;
	Prog*	head;	/* live group leader is at head */
	Prog*	tail;
};

struct Prog
{
	REG		R;		/* Register set */
	Prog*		link;		/* Run queue */
	Channel*		chan;	/* Channel pointer */
	void*		ptr;		/* Channel data pointer */
	enum ProgState	state;		/* Scheduler state */
	char*		kill;		/* Set if prog should error */
	char*		killstr;	/* kill string buffer when needed */
	int		pid;		/* unique Prog id */
	int		quanta;		/* time slice */
	ulong	ticks;		/* time used */
	int		flags;		/* error recovery flags */
	Prog*		prev;
	Prog*		next;
	Prog*	pidlink;	/* next in pid hash chain */
	Progs*	group;	/* process group */
	Prog*	grpprev;	/* previous group member */
	Prog*	grpnext;	/* next group member */
	void*	exval;	/* current exception */
	char*	exstr;	/* last exception */
	void		(*addrun)(Prog*);
	void		(*xec)(Prog*);

	void*		osenv;
};

struct Module
{
	int	ref;		/* Use count */
	int	compiled;	/* Compiled into native assembler */
	ulong	ss;		/* Stack size */
	ulong	rt;		/* Runtime flags */
	ulong	mtime;		/* Modtime of dis file */
	Qid		qid;		/* Qid of dis file */
	ushort	dtype;		/* type of dis file's server*/
	uint	dev;	/* subtype of dis file's server */
	int	nprog;		/* number of instructions */
	Inst*	prog;		/* text segment */
	uchar*	origmp;		/* unpolluted Module data */
	int	ntype;		/* Number of type descriptors */
	Type**	type;		/* Type descriptors */
	Inst*	entry;		/* Entry PC */
	Type*	entryt;		/* Entry frame */
	char*	name;	/* Implements type */
	char*	path;		/* File module loaded from */
	Module*	link;		/* Links */
	Link*	ext;		/* External dynamic links */
	Import**	ldt;	/* Internal linkage descriptor tables */
	Handler*	htab;	/* Exception handler table */
	ulong*	pctab;	/* dis pc to code pc when compiled */
	void*	dlm;		/* dynamic C module */
};

struct Modl
{
	Linkpc	u;		/* PC of Dynamic link */
	Type*	frame;		/* Frame type for this entry */
};

struct Modlink
{
	uchar*	MP;		/* Module data for this instance */
	Module*	m;		/* The real module */
	int	compiled;	/* Compiled into native assembler */
	Inst*	prog;		/* text segment */
	Type**	type;		/* Type descriptors */
	uchar*	data;		/* for dynamic C modules */
	int	nlinks;		/* ?apparently required by Java */
	Modl	links[1];
};

struct Heap
{
	int	color;		/* Allocation color */
	ulong	ref;
	Type*	t;
	ulong	pad;	/* ensure double alignment; also used for heap profiling */
};

struct	Atidle
{
	int	(*fn)(void*);
	void*	arg;
	Atidle*	link;
};

struct Import
{
	int	sig;
	char*	name;
};

struct Except
{
	char*	s;
	ulong	pc;
};

struct Handler
{
	ulong	pc1;
	ulong	pc2;
	ulong	eoff;
	ulong	ne;
	Type*	t;
	Except*	etab;
};

#define H2D(t, x)	((t)(((uchar*)(x))+sizeof(Heap)))
#define D2H(x)		((Heap*)(((uchar*)(x))-sizeof(Heap)))
#define H		((void*)(-1))
#define SEXTYPE(f)	((Stkext*)((uchar*)(f)-OA(Stkext, reg.tos.fu)))
#define Setmark(h)	if((h)->color!=mutator) { (h)->color = propagator; nprop=1; }
#define gclock()	gchalt++
#define gcunlock()	gchalt--
#define gcruns()	(gchalt == 0)

extern	int	bflag;
extern	int	cflag;
extern	int	nproc;
extern	Type	Tarray;
extern	Type	Tstring;
extern	Type	Tchannel;
extern	Type	Tlist;
extern	Type	Tmodlink;
extern	Type*	TImage;
extern	Type	Tptr;
extern	Type	Tbyte;
extern	Type Tword;
extern	Type Tlong;
extern	Type Treal;
extern	REG	R;
extern	String	snil;
extern	void	(*optab[256])(void);
extern	void	(*comvec)(void);
extern	void	(*dec[])(void);
extern	Module*	modules;
extern	int	mutator;
extern	int	nprop;
extern	int	gchalt;
extern	int	gccolor;
extern	int	minvalid;

extern	int		Dconv(Fmt*);
extern	void		acquire(void);
extern	void		addrun(Prog*);
extern	void		altdone(Alt*, Prog*, Channel*, int);
extern	void		altgone(Prog*);
extern	Array*		allocimgarray(Heap*, Heap*);
extern	Module*	builtinmod(char*, void*, int);
extern	void		cblock(Prog*);
extern	void		cmovw(void*, void*);
extern	Channel*	cnewc(Type*, void (*)(void), int);
extern	int		compile(Module*, int, Modlink*);
extern	void		cqadd(Progq**, Prog*);
extern	void		cqdel(Progq**);
extern	void		cqdelp(Progq**, Prog*);
extern	void		crecv(Channel*, void*);
extern	void		csend(Channel*, void*);
extern	int		csendalt(Channel*, void*, Type *, int);
extern	Prog*		currun(void);
extern	void		dbgexit(Prog*, int, char*);
extern	void		dbgxec(Prog*);
extern	void		delprog(Prog*, char*);
extern	Prog*		delrun(int);
extern	void		delrunq(Prog*);
extern	Prog*		delruntail(int);
extern	void		destroy(void*);
extern	void		destroyimage(ulong);
extern	void		destroylinks(Module*);
extern	void		destroystack(REG*);
extern	void		drawmodinit(void);
extern	int		dynldable(int);
extern	void		loadermodinit(void);
extern	Type*		dtype(void (*)(Heap*, int), int, uchar*, int);
extern	Module*		dupmod(Module*);
extern	void		error(char*);
extern	void		errorf(char*, ...);
extern	void		extend(void);
extern	void		freedyncode(Module*);
extern	void		freedyndata(Modlink*);
extern	void		freemod(Module*);
extern	void		freeheap(Heap*, int);
extern	void		freeptrs(void*, Type*);
extern	void		freestring(Heap*, int);
extern	void		freetype(Type*);
extern	void		freetypemodinit(void);
extern	long	getdbreg();
extern	int		gfltconv(Fmt*);
extern	void		go(Module*);
extern	int		handler(char*);
extern	Heap*	heap(Type*);
extern	Heap*	heaparray(Type*, int);
extern	void		(*heapmonitor)(int, void*, ulong);
extern	int		heapref(void*);
extern	Heap*		heapz(Type*);
extern	int		hmsize(void*);
extern	void		incmem(void*, Type*);
extern	void		initarray(Type*, Array*);
extern	void		initmem(Type*, void*);
extern	void		irestore(Prog*);
extern	Prog*		isave(void);
extern	void		keyringmodinit(void);
extern	void		killcomm(Progq **p);
extern	int		killprog(Prog*, char*);
extern	int		killgrp(Prog*, char*);
extern	Modlink*	linkmod(Module*, Import*, int);
extern	Modlink*	mklinkmod(Module*, int);
extern	Module*		load(char*);
extern	Module*		lookmod(char*);
extern	long	magic(void);
extern	void		markarray(Type*, void*);
extern	void		markchan(Type*, void*);
extern	void		markheap(Type*, void*);
extern	void		marklist(Type*, void*);
extern	void		markmodl(Type*, void*);
extern	void		mathmodinit(void);
extern	Array*		mem2array(void*, int);
extern	void		mlink(Module*, Link*, uchar*, int, int, Type*);
extern	void		modinit(void);
extern	WORD		modstatus(REG*, char*, int);
extern	void		movp(void);
extern	void		movtmp(void);
extern	void		movtmpsafe(void);
extern	int			mustbesigned(char*, uchar*, ulong, Dir*);
extern	Module*		newmod(char*);
extern	Module*		newdyncode(int, char*, Dir*);
extern	void		newdyndata(Modlink*);
extern	void	newgrp(Prog*);
extern	void		newmp(void*, void*, Type*);
extern	Prog*		newprog(Prog*, Modlink*);
extern	void		newstack(Prog*);
extern	Heap*		nheap(int);
extern	void		noptrs(Type*, void*);
extern	int		nprog(void);
extern	void		opinit(void);
extern	Module*		parsemod(char*, uchar*, ulong, Dir*);
extern	Module*		parsedmod(char*, int, ulong, Qid);
extern	void		prefabmodinit(void);
extern	Prog*		progn(int);
extern	Prog*		progpid(int);
extern	void		ptradd(Heap*);
extern	void		ptrdel(Heap*);
extern	void		pushrun(Prog*);
extern	Module*		readmod(char*, Module*, int);
extern	void		irecv(void);
extern	void		release(void);
extern	void		releasex(void);
extern	void		retnstr(char*, int, String**);
extern	void		retstr(char*, String**);
extern	void		rungc(Prog*);
extern	void		runtime(Module*, Link*, char*, int, void(*)(void*), Type*);
extern	void		safemem(void*, Type*, void (*)(void*));
extern	int		segflush(void *, ulong);
extern	void		isend(void);
extern	void	setdbreg(uchar*);
extern	uchar*	setdbloc(uchar*);
extern	void		seterror(char*, ...);
extern	void		sethints(String*, int);
extern	String*		splitc(String**, int);
extern	uchar*		stack(Frame*);
extern	int		stringblen(String*);
extern	int		stringcmp(String*, String*);
extern	String*		stringdup(String*);
extern	String*		stringheap(int, int, int, int);
extern	char*		syserr(char*, char*, Prog*);
extern	void		sysinit(void);
extern	void		sysmodinit(void);
extern	void		tellsomeone(Prog*, char*);
extern	void		tkmodinit(void);
extern	void		unextend(Frame*);
extern	void		unframe(void);
extern	void		unload(Module*);
extern	int		verifysigner(uchar*, int, uchar*, ulong);
extern	void		xec(Prog*);
extern	void		xecalt(int);
extern	int		xprint(Prog*, void*, void*, String*, char*, int);
extern	int		bigxprint(Prog*, void*, void*, String*, char**, int);
extern	void		iyield(void);
extern	String*		newrunes(int);
extern	String*		newstring(int);
extern	int		runeslen(Rune*, int);
extern	String*		c2string(char*, int);
extern	char*		string2c(String*);
extern	List*		cons(ulong, List**);
extern	String*		slicer(ulong, ulong, String*);
extern	String*		addstring(String*, String*, int);
extern	int		brpatch(Inst*, Module*);
extern	void		readimagemodinit(void);

#define	O(t,e)		((long)(&((t*)0)->e))
#define	OA(t,e)		((long)(((t*)0)->e))

#pragma	varargck	type	"D"	Inst*
#pragma varargck argpos errorf 1