emudef.h

00001 /* File:      emudef.h
00002 ** Author(s): Warren, Swift, Xu, Sagonas
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
00006 ** Copyright (C) ECRC, Germany, 1990
00007 ** 
00008 ** XSB is free software; you can redistribute it and/or modify it under the
00009 ** terms of the GNU Library General Public License as published by the Free
00010 ** Software Foundation; either version 2 of the License, or (at your option)
00011 ** any later version.
00012 ** 
00013 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00014 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00015 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00016 ** more details.
00017 ** 
00018 ** You should have received a copy of the GNU Library General Public License
00019 ** along with XSB; if not, write to the Free Software Foundation,
00020 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00021 **
00022 ** $Id: emudef.h,v 1.59 2006/02/06 20:20:03 tswift Exp $
00023 ** 
00024 */
00025 
00026 #include "debugs/debug_attv.h"
00027 
00028 #ifndef MULTI_THREAD
00029 /* Argument Registers
00030    ------------------ */
00031 Cell reg[MAX_REGS];
00032 
00033 
00034 /* Special Registers
00035    ----------------- */
00036 CPtr ereg;              /* last activation record       */
00037 CPtr breg;              /* last choice point            */
00038 CPtr hreg;              /* top of heap                  */
00039 CPtr *trreg;            /* top of trail stack           */
00040 CPtr hbreg;             /* heap back track point        */
00041 CPtr sreg;              /* current build or unify field */
00042 byte *cpreg;            /* return point register        */
00043 byte *pcreg;            /* program counter              */
00044 CPtr ebreg;             /* breg into environment stack  */
00045 #ifdef CP_DEBUG
00046 Psc pscreg;
00047 #endif
00048 
00049 CPtr efreg;
00050 CPtr bfreg;
00051 CPtr hfreg;
00052 CPtr *trfreg;
00053 
00054 CPtr pdlreg;
00055 CPtr openreg;
00056 
00057 /* TLS 08/05: Root address is the address of the first tabled choice
00058    point on the thread's stack.  It is used to reclaim freeze
00059    registers, but could be removed, I think. */
00060 CPtr root_address;      
00061 
00062 CPtr ptcpreg = NULL;
00063 CPtr delayreg;
00064 
00065 #ifdef DEMAND
00066 /* demand-freeze registers */
00067 CPtr edfreg;
00068 CPtr bdfreg;
00069 CPtr hdfreg;
00070 CPtr *trdfreg;
00071 #endif
00072 
00073 VarString *tsgLBuff1;
00074 VarString *tsgLBuff2;
00075 VarString *tsgSBuff1;
00076 VarString *tsgSBuff2;
00077 
00078 /*
00079  * interrupt_reg points to interrupt_counter, which stores the number of
00080  * interrupts in the interrupt chain for attributed variables.
00081  */
00082 Cell interrupt_counter;
00083 CPtr interrupt_reg = &interrupt_counter;
00084 
00085 #endif /* MULTI_THREAD */
00086 
00087 /*
00088  * Ptr to the beginning of instr. array
00089  */ 
00090 byte *inst_begin_gl;
00091 
00092 char *nil_string, *true_string;
00093 
00094 Pair list_pscPair;
00095 
00096 Psc list_psc, comma_psc, true_psc, if_psc, colon_psc;
00097 Psc tnot_psc, delay_psc;
00098 Psc box_psc;
00099 
00100 /*
00101  * Ret PSC's are used to store substitution factors for subgoal calls
00102  * or answers.  A psc with a new arity will be created when needed,
00103  * except that ret_psc[0] stores the pointer to STRING "ret" and is
00104  * initialized when the system is started.
00105  */
00106 Psc ret_psc[MAX_ARITY];
00107 
00108 /* TLS: changed name to accord with new global conventions. */
00109 char *list_dot_string;
00110 
00111 #ifndef MULTI_THREAD
00112 int asynint_code = 0;
00113 int asynint_val = 0;
00114 #endif
00115 
00116 int next_free_code = 0;
00117 unsigned long enc[16] = {0xffffffff,0xffffffff,0xffffffff,0xffffffff,
00118                          0xffffffff,0xffffffff,0xffffffff,0xffffffff,
00119                          0xffffffff,0xffffffff,0xffffffff,0xffffffff,
00120                          0xffffffff,0xffffffff,0xffffffff,0xffffffff};
00121 unsigned long dec[8] = {0xffffffff,0xffffffff,0xffffffff,0xffffffff,
00122                         0xffffffff,0xffffffff,0xffffffff,0xffffffff};
00123 
00124 /* Replacements for labelled code in emusubs.i */
00125 
00126 #define nunify_with_nil(op)                                             \
00127   XSB_Deref(op);                                                        \
00128   if (isref(op)) {                                                      \
00129     /* op is FREE */                                                    \
00130     bind_nil((CPtr)(op));                                               \
00131   }                                                                     \
00132   else if (isnil(op)) {XSB_Next_Instr();} /* op == [] */                \
00133   else if (isattv(op)) {                                                \
00134     xsb_dbgmsg((LOG_ATTV,">>>> ATTV nunify_with_nil, interrupt needed\n"));     \
00135     /* add_interrupt(op, makenil);      */                              \
00136     add_interrupt(CTXTc cell(((CPtr)dec_addr(op1) + 1)),makenil);               \
00137     bind_copy((CPtr)dec_addr(op1), makenil);                            \
00138   }                                                                     \
00139   else Fail1;   /* op is LIST, INT, or FLOAT */
00140 
00141 /*======================================================================*/
00142 
00143 #define nunify_with_con(OP1,OP2)                                        \
00144   XSB_Deref(OP1);                                                       \
00145   if (isref(OP1)) {                                                     \
00146     /* op1 is FREE */                                                   \
00147     bind_string((CPtr)(OP1), (char *)OP2);                              \
00148   }                                                                     \
00149   else if (isstring(OP1)) {                                             \
00150     if (string_val(OP1) == (char *)OP2) {XSB_Next_Instr();} else Fail1; \
00151   }                                                                     \
00152   else if (isattv(OP1)) {                                               \
00153     xsb_dbgmsg((LOG_ATTV,">>>> ATTV nunify_with_con, interrupt needed\n"));     \
00154     /* add_interrupt(OP1, makestring((char *)OP2)); */                  \
00155     add_interrupt(CTXTc cell(((CPtr)dec_addr(op1) + 1)),makestring((char *)OP2));       \
00156     bind_string((CPtr)dec_addr(op1),(char *)OP2);       \
00157   }                                                                     \
00158   else Fail1;
00159 
00160 
00161 /*======================================================================*/
00162 
00163 #define nunify_with_num(OP1,OP2)                                        \
00164   /* op1 is general, op2 has number (untagged) */                       \
00165   XSB_Deref(OP1);                                                       \
00166   if (isref(OP1)) {                                                     \
00167     /* op1 is FREE */                                                   \
00168     bind_oint((CPtr)(OP1), (Integer)OP2);                                       \
00169   }                                                                     \
00170   else if (isinteger(OP1)) {                                            \
00171     if (oint_val(OP1) == (Integer)OP2) {XSB_Next_Instr();} else Fail1;          \
00172   }                                                                     \
00173   else if (isattv(OP1)) {                                               \
00174     xsb_dbgmsg((LOG_ATTV,">>>> ATTV nunify_with_num, interrupt needed\n"));     \
00175     /* add_interrupt(OP1, OP2); */                                      \
00176     add_interrupt(CTXTc cell(((CPtr)dec_addr(op1) + 1)),makeint(OP2));  \
00177     bind_oint((CPtr)dec_addr(op1), (Integer)OP2);                               \
00178   }                                                                     \
00179   else Fail1;   /* op1 is STRING, FLOAT, STRUCT, or LIST */
00180 
00181 /*======================================================================*/
00182 
00183 #define nunify_with_float(OP1,OP2)                                      \
00184   XSB_Deref(OP1);                                                       \
00185   if (isref(OP1)) {                                                     \
00186     /* op1 is FREE */                                                   \
00187     bind_float_tagged(vptr(OP1), makefloat(OP2));                       \
00188   }                                                                     \
00189   else if (isofloat(OP1)) {                                             \
00190     if ( (float)ofloat_val(OP1) == OP2) {                               \
00191       XSB_Next_Instr();                                                 \
00192     }                                                                   \
00193     else Fail1;                                                         \
00194   }                                                                     \
00195   else if (isattv(OP1)) {                                               \
00196     xsb_dbgmsg((LOG_ATTV,">>>> ATTV nunify_with_float, interrupt needed\n"));   \
00197     /* add_interrupt(OP1, OP2); */                                      \
00198     add_interrupt(CTXTc cell(((CPtr)dec_addr(op1) + 1)),makefloat(OP2)); \
00199     bind_float_tagged((CPtr)dec_addr(op1), makefloat(OP2));             \
00200   }                                                                     \
00201   else Fail1;   /* op1 is INT, STRING, STRUCT, or LIST */ 
00202 
00203 /*======================================================================*/
00204 
00205 #define nunify_with_float_get(OP1,OP2)                                  \
00206   XSB_Deref(OP1);                                                       \
00207   if (isref(OP1)) {                                                     \
00208     /* op1 is FREE */                                                   \
00209       bind_boxedfloat(vptr(OP1), OP2);                                  \
00210   }                                                                     \
00211   else if (isofloat(OP1)) {                                             \
00212     if ( (float)ofloat_val(OP1) == OP2) {                               \
00213       XSB_Next_Instr();                                                 \
00214     }                                                                   \
00215     else Fail1;                                                         \
00216   }                                                                     \
00217   else if (isattv(OP1)) {                                               \
00218     xsb_dbgmsg((LOG_ATTV,">>>> ATTV nunify_with_float, interrupt needed\n"));   \
00219     /* add_interrupt(OP1, OP2); */                                      \
00220     add_interrupt(CTXTc cell(((CPtr)dec_addr(op1) + 1)),makefloat(OP2)); \
00221     bind_boxedfloat((CPtr)dec_addr(op1), OP2);                          \
00222   }                                                                     \
00223   else Fail1;   /* op1 is INT, STRING, STRUCT, or LIST */ 
00224 
00225 /*======================================================================*/
00226 
00227 #define nunify_with_str(OP1,OP2)                                        \
00228   /* struct psc_rec *str_ptr; using op2 */                              \
00229   XSB_Deref(OP1);                                                       \
00230   if (isref(OP1)) {                                                     \
00231     /* op1 is FREE */                                                   \
00232     bind_cs((CPtr)(OP1), (Pair)hreg);                                   \
00233     new_heap_functor(hreg, (Psc)OP2);                                   \
00234     flag = WRITE;                                                       \
00235   }                                                                     \
00236   else if (isconstr(OP1)) {                                             \
00237     OP1 = (Cell)(cs_val(OP1));                                          \
00238     if (*((Psc *)OP1) == (Psc)OP2) {                                    \
00239       flag = READFLAG;                                                  \
00240       sreg = (CPtr)OP1 + 1;                                             \
00241     }                                                                   \
00242     else Fail1;                                                         \
00243   }                                                                     \
00244   else if ((Psc)OP2 == box_psc) {                                       \
00245     Cell ignore_addr;                                                   \
00246     if (isfloat(OP1))                                                   \
00247       bld_boxedfloat(CTXTc &ignore_addr, float_val(OP1));               \
00248     else if (isinteger(OP1))                                            \
00249       {bld_oint(&ignore_addr, int_val(OP1));}                           \
00250     flag = READFLAG;                                                    \
00251     sreg = hreg - 3;                                                    \
00252   } else if (isattv(OP1)) {                                             \
00253     xsb_dbgmsg((LOG_ATTV,">>>> ATTV nunify_with_str, interrupt needed\n"));     \
00254     /* add_interrupt(OP1, makecs(hreg)); */                             \
00255     add_interrupt(CTXTc cell(((CPtr)dec_addr(op1) + 1)),makecs(hreg));  \
00256     bind_copy((CPtr)dec_addr(op1), makecs(hreg));                       \
00257     new_heap_functor(hreg, (Psc)OP2);                                   \
00258     flag = WRITE;                                                       \
00259   }                                                                     \
00260   else Fail1;
00261 
00262 /*======================================================================*/
00263 
00264 #define nunify_with_list_sym(OP1)                                       \
00265   XSB_Deref(OP1);                                                       \
00266   if (isref(OP1)) {                                                     \
00267     /* op1 is FREE */                                                   \
00268     bind_list((CPtr)(OP1), hreg);                                       \
00269     flag = WRITE;                                                       \
00270   }                                                                     \
00271   else if (islist(OP1)) {                                               \
00272     sreg = clref_val(OP1);                                              \
00273     flag = READFLAG;                                                    \
00274   }                                                                     \
00275   else if (isattv(OP1)) {                                               \
00276     xsb_dbgmsg((LOG_ATTV,">>>> ATTV nunify_with_list_sym, interrupt needed\n"));        \
00277     /* add_interrupt(OP1, makelist(hreg)); */                           \
00278     add_interrupt(CTXTc cell(((CPtr)dec_addr(op1) + 1)),makelist(hreg));\
00279     bind_copy((CPtr)dec_addr(op1), makelist(hreg));                     \
00280     flag = WRITE;                                                       \
00281   }                                                                     \
00282   else Fail1;
00283 
00284 /*======================================================================*/
00285 
00286 /*
00287  * In getattv, the flag will always be WRITE.  The unification will be
00288  * done here...
00289  * This operation is used in the getattv instruction, emitted for
00290  * asserted code with attributed variables.
00291  *
00292  * The way to do it:
00293  * 
00294  * href      ->  Op1   
00295  * href + 1  ->  _
00296  *
00297  * Put [reference to href + 1|X] in the interrupt queue.
00298  *
00299  * Set the WRITE flag to have the next instructions put the attribute
00300  * at href + 1.
00301  *
00302  * The interrupt should not be handled before the attribute is created.
00303  */
00304 #define nunify_with_attv(OP1) {                                 \
00305   XSB_Deref(OP1);                                               \
00306   if (isref(OP1)) {                                             \
00307     bind_attv((CPtr)(OP1), hreg);                               \
00308     new_heap_free(hreg);        /* the VAR part of the attv */  \
00309   }                                                             \
00310   else {                                                        \
00311     xsb_dbgmsg((LOG_ATTV,">>>> nunify_with_attv, interrupt needed\n")); \
00312     /* add_interrupt(makeattv(hreg), OP1); */                   \
00313     *hreg = OP1; hreg++;                                        \
00314     add_interrupt(CTXTc (Integer)hreg, OP1);                    \
00315   }                                                             \
00316   flag = WRITE;                                                 \
00317 }
00318 
00319 /*======================================================================*/
00320 
00321 /* TLS: refactored to support Thread Cancellation */
00322 
00323 #define call_sub(PSC) {                                                 \
00324   if ( !(asynint_val) & !int_val(cell(interrupt_reg)) ) {               \
00325     lpcreg = (pb)get_ep(PSC);                                           \
00326   } else {                                                              \
00327     if (asynint_val) {                                                  \
00328       if (asynint_val & KEYINT_MARK) {                                  \
00329         synint_proc(CTXTc PSC, MYSIG_KEYB);                             \
00330         lpcreg = pcreg;                                                 \
00331         asynint_val = asynint_val & ~KEYINT_MARK;                       \
00332         asynint_code = 0;                                               \
00333       } else if (asynint_val & PROFINT_MARK) {                          \
00334         asynint_val &= ~PROFINT_MARK;                                   \
00335         log_prog_ctr(lpcreg);                                           \
00336         lpcreg = (byte *)get_ep(PSC);                                   \
00337       } else if (asynint_val & MSGINT_MARK) {                           \
00338         pcreg = (byte *)get_ep(PSC);                                    \
00339         intercept(CTXTc PSC);                                           \
00340         lpcreg = pcreg;                                                 \
00341       } else if (asynint_val & THREADINT_MARK) {                        \
00342         printf("Entered thread cancel: call_sub\n");                    \
00343         synint_proc(CTXTc PSC, THREADSIG_CANCEL);                       \
00344         lpcreg = pcreg;                                                 \
00345         asynint_val = 0;                                                \
00346         asynint_code = 0;                                               \
00347       } else {                                                          \
00348         lpcreg = (byte *)get_ep(PSC);                                   \
00349         asynint_val = 0;                                                \
00350       }                                                                 \
00351     } else if (int_val(cell(interrupt_reg))) {                          \
00352         synint_proc(CTXTc PSC, MYSIG_ATTV);                             \
00353         lpcreg = pcreg;                                                 \
00354     }                                                                   \
00355   }                                                                     \
00356 }
00357 
00358 #define proceed_sub {                                                   \
00359   if ( !(asynint_val) & !int_val(cell(interrupt_reg)) ) {               \
00360      lpcreg = cpreg;                                                    \
00361   } else {                                                              \
00362     if (asynint_val) {                                                  \
00363      if (asynint_val & KEYINT_MARK) {                                   \
00364         synint_proc(CTXTc true_psc, MYSIG_KEYB);                        \
00365         lpcreg = pcreg;                                                 \
00366         asynint_val = asynint_val & ~KEYINT_MARK;                       \
00367         asynint_code = 0;                                               \
00368      } else if (asynint_val & MSGINT_MARK) {                            \
00369        lpcreg = cpreg;  /* ignore MSGINT in proceed */                  \
00370      } else if (asynint_val & PROFINT_MARK) {                           \
00371        asynint_val &= ~PROFINT_MARK;                                    \
00372        log_prog_ctr(lpcreg);                                            \
00373        lpcreg = cpreg;                                                  \
00374        asynint_code = 0;                                                \
00375      } else if (asynint_val & THREADINT_MARK) {                         \
00376        printf("Entered thread cancel: proceed\n");                      \
00377         synint_proc(CTXTc true_psc, THREADSIG_CANCEL);                  \
00378         lpcreg = pcreg;                                                 \
00379         asynint_val = 0;                                                \
00380         asynint_code = 0;                                               \
00381      } else {                                                           \
00382         lpcreg = cpreg;                                                 \
00383         asynint_code = 0;                                               \
00384      }                                                                  \
00385     } else if (int_val(cell(interrupt_reg))) {                          \
00386         synint_proc(CTXTc true_psc, MYSIG_ATTV);                        \
00387         lpcreg = pcreg;                                                 \
00388     }                                                                   \
00389   }                                                                     \
00390 }
00391 

Generated on Wed Jul 26 13:30:40 2006 for XSB by  doxygen 1.4.5