4 /* -----------------------------------------------------------------------------
7 * Copyright (c) 1994-2000.
9 * $RCSfile: Interpreter.c,v $
11 * $Date: 2000/12/19 16:48:35 $
12 * ---------------------------------------------------------------------------*/
22 #include "SchedAPI.h" /* for createGenThread */
23 #include "Schedule.h" /* for context_switch */
24 #include "Bytecodes.h"
25 #include "ForeignCall.h"
26 #include "PrimOps.h" /* for __{encode,decode}{Float,Double} */
29 #include "Evaluator.h"
30 #include "sainteger.h"
34 #include "Disassembler.h"
39 #include <math.h> /* These are for primops */
40 #include <limits.h> /* These are for primops */
41 #include <float.h> /* These are for primops */
43 #include <ieee754.h> /* These are for primops */
50 int /*StgThreadReturnCode*/ interpretBCO ( void* /* Capability* */ cap )
52 fprintf(stderr, "Greetings, earthlings. I am not yet implemented. Bye!\n");
57 /* --------------------------------------------------------------------------
58 * The new bytecode interpreter
59 * ------------------------------------------------------------------------*/
61 /* Sp points to the lowest live word on the stack. */
63 #define StackWord(n) ((W_*)iSp)[n]
64 #define BCO_NEXT bco_instrs[bciPtr++]
65 #define BCO_PTR(n) bco_ptrs[n]
68 StgThreadReturnCode interpretBCO ( Capability* cap )
70 /* On entry, the closure to interpret is on the top of the
73 /* Use of register here is primarily to make it clear to compilers
74 that these entities are non-aliasable.
76 register StgPtr iSp; /* local state -- stack pointer */
77 register StgUpdateFrame* iSu; /* local state -- frame pointer */
78 register StgPtr iSpLim; /* local state -- stack lim pointer */
79 register StgClosure* obj;
81 iSp = cap->rCurrentTSO->sp;
82 iSu = cap->rCurrentTSO->su;
83 iSpLim = cap->rCurrentTSO->stack + RESERVED_STACK_WORDS;
88 "\n---------------------------------------------------------------\n");
89 fprintf(stderr,"Entering: ",); printObj(obj);
90 fprintf(stderr,"xSp = %p\txSu = %p\n", xSp, xSu);
91 fprintf(stderr, "\n" );
92 printStack(iSp,cap->rCurrentTSO->stack+cap->rCurrentTSO->stack_size,iSu);
93 fprintf(stderr, "\n\n");
96 /* Main object-entering loop. Object to be entered is on top of
100 obj = StackWord(0); iSp++;
102 switch ( get_itbl(obj)->type ) {
104 barf("Invalid object %p",obj);
108 /* ---------------------------------------------------- */
109 /* Start of the bytecode interpreter */
110 /* ---------------------------------------------------- */
112 register StgWord8* bciPtr; /* instruction pointer */
113 register StgBCO* bco = (StgBCO*)obj;
114 if (doYouWantToGC()) {
115 iSp--; StackWord(0) = bco;
121 ASSERT((StgWord)(PC) < bco->n_instrs);
123 fprintf(stderr,"Sp = %p\tSu = %p\tpc = %d\t", xSp, xSu, PC);
126 fprintf(stderr,"\n");
127 for (i = 8; i >= 0; i--)
128 fprintf(stderr, "%d %p\n", i, (StgPtr)(*(gSp+i)));
130 fprintf(stderr,"\n");
137 StackWord(-1) = StackWord(o1);
144 StackWord(-1) = StackWord(o1);
145 StackWord(-2) = StackWord(o2);
153 StackWord(-1) = StackWord(o1);
154 StackWord(-2) = StackWord(o2);
155 StackWord(-3) = StackWord(o3);
161 StackWord(-1) = BCO_PTR(o1);
166 int o_bco = BCO_NEXT;
167 int o_itbl = BCO_NEXT;
168 StackWord(-1) = BCO_LIT(o_itbl);
169 StackWord(-2) = BCO_PTR(o_bco);
174 W_ tag = (W_)(BCO_NEXT);
181 StackWord(-1) = BCO_LIT(o);
188 ASSERT(Sp+n+by <= (StgPtr)xSu);
189 /* a_1, .. a_n, b_1, .. b_by, s => a_1, .. a_n, s */
191 StackWord(n+by) = StackWord(n);
197 int n_payload = BCO_NEXT;
198 P_ p = allocate(AP_sizeW(n_payload));
205 int n_payload = BCO_NEXT - 1;
206 StgAP_UPD* ap = StackWord(off);
207 ap->n_args = n_payload;
208 ap->fun = (StgClosure*)StackWord(0);
209 for (i = 0; i < n_payload; i++)
210 ap->payload[i] = StackWord(i+1);
215 /* Unpack N ptr words from t.o.s constructor */
216 /* The common case ! */
217 int n_words = BCO_NEXT;
218 StgClosure* con = StackWord(0);
220 for (i = 0; i < n_words; i++)
221 StackWord(i) = con->payload[i];
224 case bci_UNPACK_BX: {
225 /* Unpack N (non-ptr) words from offset M in the
226 constructor K words down the stack, and then push
227 N as a tag, on top of it. Slow but general; we
228 hope it will be the rare case. */
229 int n_words = BCO_NEXT;
230 int con_off = BCO_NEXT;
231 int stk_off = BCO_NEXT;
232 StgClosure* con = StackWord(stk_off);
234 for (i = 0; i < n_words; i++)
235 StackWord(i) = con->payload[con_off + i];
237 StackWord(0) = n_words;
251 /* Control-flow ish things */
260 } /* switch on opcode */
264 /* ---------------------------------------------------- */
265 /* End of the bytecode interpreter */
266 /* ---------------------------------------------------- */
269 /* Can't handle this object; yield to sched. */
270 fprintf(stderr, "entering unknown closure -- yielding to sched\n");
272 cap->rCurrentTSO->what_next = ThreadEnterGHC;
273 iSp--; StackWord(0) = obj;
274 return ThreadYielding;
276 } /* switch on object kind */
278 barf("fallen off end of switch in enter()");