w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

interp.c
Go to the documentation of this file.
1 /*
2  * interp.c
3  *
4  * This file is part of the Oxford Oberon-2 compiler
5  * Copyright (c) 2006--2016 J. M. Spivey
6  * All rights reserved
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  * derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /* This file is the skeleton of the bytecode interpreter; the parts
32  specific to each instruction are inserted from the file
33  'keiko.iset' by the script 'iset.tcl'. There are three places that
34  code is inserted, each marked by two dollar signs. In order of
35  appearance, they are:
36 
37  1. A jump table for quick dispatching (used if JTABLE is defined).
38 
39  2. Macro definitions used in the action routines.
40 
41  3. Action routines for each instruction, forming the cases in a big
42  switch. */
43 
44 #include <math.h>
45 #include <string.h>
46 #include "obx.h"
47 #include "keiko.h"
48 
49 #ifdef HAVE_INDEXED_JUMPS
50 #define JTABLE 1
51 #endif
52 
53 #ifdef TRACE
54 #define DISASS 1
55 #undef JTABLE
56 #define do_find_proc if (dflag > 1) thisproc = find_proc(dsegaddr(cp))
57 #else
58 #define do_find_proc
59 #endif
60 
61 #ifdef PROFILE
62 #undef JTABLE
63 #endif
64 
65 #ifdef UNALIGNED_MEM
66 #define getdbl get_double
67 #define putdbl put_double
68 #define getlong get_long
69 #define putlong put_long
70 #else
71 static inline double getdbl(value *v) {
72  dblbuf dd;
73  dd.n.lo = v[0].i;
74  dd.n.hi = v[1].i;
75  return dd.d;
76 }
77 
78 static inline void putdbl(value *v, double x) {
79  dblbuf dd;
80  dd.d = x;
81  v[0].i = dd.n.lo;
82  v[1].i = dd.n.hi;
83 }
84 
85 static inline longint getlong(value *v) {
86  dblbuf dd;
87  dd.n.lo = v[0].i;
88  dd.n.hi = v[1].i;
89  return dd.q;
90 }
91 
92 static inline void putlong(value *v, longint x) {
93  dblbuf dd;
94  dd.q = x;
95  v[0].i = dd.n.lo;
96  v[1].i = dd.n.hi;
97 }
98 #endif
99 
100 /* Macros used in action routines */
101 
102 #define error(msg, n) runtime_error(msg, n, bp, pc0)
103 
104 #define local(n) ((uchar *) bp + (n))
105 #define parent(a, t) indir(pointer(bp[SL]) + a, t)
106 #define indir(p, t) (* (t *) (p))
107 #define subs(p, n, t) ((t *) (p))[n]
108 #define const(n) cp[CP_CONST+n]
109 #define jump(lab) pc = pc0 + lab
110 
111 #define load(x, t) indir(pointer(x), t)
112 #define store(x, y, t) indir(pointer(y), t) = x
113 #define ldl(a, t) indir(local(a), t)
114 #define stl(a, x, t) indir(local(a), t) = x
115 #define ldg(a, t) indir(pointer(const(a)), t)
116 #define stg(a, x, t) indir(pointer(const(a)), t) = x
117 #define ldn(a, x) indir((char *) pointer(x) + a, int)
118 #define stn(a, x, y) indir((char *) pointer(y) + a, int) = x
119 #define ldi(x, y, t) subs(pointer(x), y.i, t)
120 #define sti(x, y, z, t) subs(pointer(y), z.i, t) = x
121 
122 #define dup(n, sp) sp--; sp[0] = sp[n+1]
123 #define swap(sp) sp[-1] = sp[1]; sp[1] = sp[0]; sp[0] = sp[-1]
124 #define slide(nargs) sp += HEAD + nargs; cond_break();
125 
126 #define ror(a, b) ((((unsigned) a) >> b) | (((unsigned) a) << (32-b)))
127 
128 #define fcmpl(a, b) (a > b ? 1 : a == b ? 0 : -1)
129 #define fcmpg(a, b) (a < b ? -1 : a == b ? 0 : 1)
130 #define lcmp(a, b) (a < b ? -1 : a > b ? 1 : 0)
131 
132 #ifdef WORDS_BIGENDIAN
133 #define alignx(a, n) (a << (32-n))
134 #else
135 #define alignx(a, n) a
136 #endif
137 
138 #ifdef PROFILE
139 #define prof_charge(n) ticks += n
140 #else
141 #define prof_charge(n)
142 #endif
143 
144 #ifdef OBXDEB
145 #define cond_break() \
146  if (one_shot && *pc != K_LNUM_2 && *pc != K_BREAK_2) \
147  debug_break(cp, bp, pc, "stop")
148 #else
149 #define cond_break()
150 #endif
151 
152 /* interp -- main loop of the interpreter */
154  register value *cp = valptr(sp0[CP]);
155  uchar *pc = codeptr(cp[CP_CODE].a);
156  register uchar *pc0 = NULL;
157  register value *sp = sp0;
158  register value *rp = NULL;
159  register uchar ir = 0;
160 #ifdef PROFILE
161  register counter ticks = 0;
162 #endif
163  register value *bp = NULL;
164  value *base = sp0;
165 #ifdef TRACE
166  proc thisproc = NULL;
167 #endif
168 
169 #ifdef JTABLE
170  /* Save time by using gcc's label array feature */
171 #define __o__(op, inst, patt, arg, len) &&lbl_ ## op,
172  static void *jtable[256] = { __OPCODES__(__o__) };
173 #endif
174 
175 #ifdef JTABLE
176 /* Each action ends with an indexed jump to the next */
177 #define ACTION(op) lbl_ ## op:
178 #define ALSO(op)
179 #define DEFAULT
180 #define NEXT goto *jtable[ir = *(pc0 = pc)]
181 #else
182 /* Actions are just cases in a big switch */
183 #define ACTION(op) case K_ ## op:
184 #define ALSO(op) case K_ ## op:
185 #define DEFAULT default:
186 #define NEXT break
187 #endif
188 
189  level++;
190 
191 enter:
192  do_find_proc;
193 
194 #ifdef PROFILE
195  prof_enter(dsegaddr(cp), ticks, PROF_CALL);
196 #endif
197 
198  bp = sp;
199  sp = (value *) ((uchar *) bp - cp[CP_FRAME].i);
200  if ((uchar *) sp < stack + SLIMIT) error(E_STACK, 0);
201 
202  /* Preserve the static link if the routine starts with SAVELINK */
203  memset(sp, 0, (*pc == K_SAVELINK ? cp[CP_FRAME].i - 4 : cp[CP_FRAME].i));
204 
205 #ifdef JTABLE
206  NEXT;
207 #else
208  while (TRUE) {
209 #ifdef TRACE
210  if (dflag > 1) {
211  printf("pc=%s+%ld(%p) sp=%p bp=%p cp=%p",
212  thisproc->p_name,
213  (long) (pc - codeptr(cp[CP_CODE].a)),
214  pc, sp, bp, cp);
215  fflush(stdout);
216  for (int i = 0; i < 8; i++) printf(" %x", sp[i].i);
217  printf("\n");
218  printf("%6ld: %s\n", (long) (pc-imem), fmt_inst(pc));
219  fflush(stdout);
220  }
221 #endif
222 
223 #ifdef PROFILE
224  ticks++;
225 #endif
226 
227  switch (ir = *(pc0 = pc)) {
228 #endif
229 
230 #include "action.c"
231 
232  ACTION(ILLEGAL)
233  DEFAULT
234  panic("*illegal instruction %d", ir);
235  return NULL;
236 #ifndef JTABLE
237  }
238  }
239 #endif
240 }
rp
Definition: action.c:992
bp
Definition: action.c:1035
cp
Definition: action.c:1035
int level
Definition: afm2pl.c:1694
@ TRUE
Definition: dd.h:102
long pc
Definition: disdvi.c:114
int v
Definition: dviconv.c:10
#define fflush
Definition: xxstdio.h:24
int printf()
#define a(n)
Definition: gpos-common.c:148
int base
Definition: gsftopk.c:1502
#define K_SAVELINK
Definition: keiko.h:182
static void panic(const Char *)
Definition: bzip2.c:746
unsigned char uchar
Definition: unzcrash.c:37
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
float x
Definition: cordic.py:15
#define CP_FRAME
Definition: obcommon.h:85
#define E_STACK
Definition: obcommon.h:118
#define CP
Definition: obcommon.h:76
int64_t longint
Definition: obcommon.h:61
#define CP_CODE
Definition: obcommon.h:83
int dflag
#define codeptr(v)
Definition: obx.h:93
#define valptr(v)
Definition: obx.h:57
#define SLIMIT
Definition: obx.h:42
#define dsegaddr(p)
Definition: obx.h:68
uchar * imem
bstring c int memset(void *s, int c, int length)
#define ACTION(op)
static __inline longint getlong(value *v)
Definition: interp.c:85
#define NEXT
#define error(msg, n)
Definition: interp.c:102
#define DEFAULT
static __inline void putdbl(value *v, double x)
Definition: interp.c:78
value * interp(value *sp0)
Definition: interp.c:153
static __inline double getdbl(value *v)
Definition: interp.c:71
static __inline void putlong(value *v, longint x)
Definition: interp.c:92
#define do_find_proc
Definition: interp.c:58
Definition: obx.h:103
const char * p_name
Definition: obx.h:104
Definition: spc_misc.c:56
static struct count_rec * counter
Definition: tex4ht.c:1052
#define sp
Definition: stack.c:11
double d
Definition: obcommon.h:69
longint q
Definition: obcommon.h:70
int lo
Definition: obcommon.h:67
struct dblbuf::@1891 n
int hi
Definition: obcommon.h:67
Definition: obx.h:51
#define ticks
Definition: utmscale.cpp:16