Main Page | Class List | Directories | File List | Class Members | File Members

interpreter.h

Go to the documentation of this file.
00001 /*
00002 || This file is part of Pike. For copyright information see COPYRIGHT.
00003 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
00004 || for more information.
00005 || $Id: interpreter.h,v 1.87 2004/09/22 17:55:29 grubba Exp $
00006 */
00007 
00008 #undef LOW_GET_ARG
00009 #undef LOW_GET_JUMP
00010 #undef LOW_SKIPJUMP
00011 #undef GET_ARG
00012 #undef GET_ARG2
00013 #undef GET_JUMP
00014 #undef SKIPJUMP
00015 #undef DOJUMP
00016 #undef CASE
00017 #undef BREAK
00018 #undef DONE
00019 
00020 #undef JUMP_DONE
00021 #define JUMP_DONE DONE
00022 
00023 #ifdef HAVE_COMPUTED_GOTO
00024 
00025 #define CASE(OP)        PIKE_CONCAT(LABEL_,OP): FETCH
00026 #define FETCH           (instr = PROG_COUNTER[0])
00027 #ifdef PIKE_DEBUG
00028 #define DONE            continue
00029 #else /* !PIKE_DEBUG */
00030 #define DONE            do {    \
00031     Pike_fp->pc = PROG_COUNTER++;               \
00032     goto *instr;                \
00033   } while(0)
00034     
00035 #endif /* PIKE_DEBUG */
00036 
00037 #define LOW_GET_ARG()   ((INT32)(ptrdiff_t)(*(PROG_COUNTER++)))
00038 #define LOW_GET_JUMP()  ((INT32)(ptrdiff_t)(*(PROG_COUNTER)))
00039 #define LOW_SKIPJUMP()  (instr = (++PROG_COUNTER)[0])
00040 
00041 #define GET_ARG()       LOW_GET_ARG()
00042 #define GET_ARG2()      LOW_GET_ARG()
00043 
00044 #else /* !HAVE_COMPUTED_GOTO */
00045 
00046 #define CASE(X)         case (X)-F_OFFSET:
00047 #define DONE            break
00048 #define FETCH
00049 
00050 #define LOW_GET_ARG()   ((PROG_COUNTER++)[0])
00051 #if PIKE_BYTECODE_METHOD == PIKE_BYTECODE_SPARC
00052 #define LOW_GET_JUMP()  (PROG_COUNTER[0])
00053 #define LOW_SKIPJUMP()  (++PROG_COUNTER)
00054 #else /* PIKE_BYTECODE_METHOD != PIKE_BYTECODE_SPARC */
00055 #define LOW_GET_JUMP()  EXTRACT_INT(PROG_COUNTER)
00056 #define LOW_SKIPJUMP()  (PROG_COUNTER += sizeof(INT32))
00057 #endif /* PIKE_BYTECODE_METHOD */
00058 
00059 #ifdef PIKE_DEBUG
00060 
00061 #define GET_ARG() (                                             \
00062   instr=prefix,                                                 \
00063   prefix=0,                                                     \
00064   instr += LOW_GET_ARG(),                                       \
00065   DEBUG_LOG_ARG (instr),                                        \
00066   instr)
00067 
00068 #define GET_ARG2() (                                            \
00069   instr=prefix2,                                                \
00070   prefix2=0,                                                    \
00071   instr += LOW_GET_ARG(),                                       \
00072   DEBUG_LOG_ARG2 (instr),                                       \
00073   instr)
00074 
00075 #else /* !PIKE_DEBUG */
00076 
00077 #define GET_ARG() (instr=prefix,prefix=0,instr+LOW_GET_ARG())
00078 #define GET_ARG2() (instr=prefix2,prefix2=0,instr+LOW_GET_ARG())
00079 
00080 #endif /* PIKE_DEBUG */
00081 
00082 #endif /* HAVE_COMPUTED_GOTO */
00083 
00084 #ifndef STEP_BREAK_LINE
00085 #define STEP_BREAK_LINE
00086 #endif
00087 
00088 static int eval_instruction(PIKE_OPCODE_T *pc)
00089 {
00090   PIKE_INSTR_T instr;
00091 #ifdef HAVE_COMPUTED_GOTO
00092   static void *strap = &&init_strap;
00093   instr = NULL;
00094 #else /* !HAVE_COMPUTED_GOTO */
00095   unsigned INT32 prefix2=0,prefix=0;
00096 #endif /* HAVE_COMPUTED_GOTO */
00097   /* Variables that are commonly used by the various opcodes.
00098    * They are defined here to reduce the size of the stack frame.
00099    */
00100   struct svalue tmp, tmp2;
00101   struct external_variable_context loc;
00102   struct program *p;
00103   struct object *o;
00104   struct svalue *s;
00105   DO_IF_DEBUG(dynamic_buffer save_buf);
00106 
00107 #undef LOCAL_VAR
00108 #define LOCAL_VAR(X)    /* Local variable defined above. */
00109 
00110 #ifdef HAVE_COMPUTED_GOTO
00111   goto *strap;
00112  normal_strap:
00113 #endif /* HAVE_COMPUTED_GOTO */
00114 
00115   debug_malloc_touch(Pike_fp);
00116   while(1)
00117   {
00118     INT32 arg1, arg2;
00119     instr = pc[0];
00120     Pike_fp->pc = pc++;
00121 
00122     STEP_BREAK_LINE
00123 
00124 #ifdef PIKE_DEBUG
00125     if (d_flag || Pike_interpreter.trace_level > 2)
00126       low_debug_instr_prologue (instr);
00127 #endif
00128 
00129 #ifdef HAVE_COMPUTED_GOTO
00130     goto *instr;
00131 #else /* !HAVE_COMPUTED_GOTO */
00132     switch(instr)
00133     {
00134       /* NOTE: The prefix handling is not needed in computed-goto mode. */
00135       /* Support to allow large arguments */
00136       CASE(F_PREFIX_256); prefix+=256; DONE;
00137       CASE(F_PREFIX_512); prefix+=512; DONE;
00138       CASE(F_PREFIX_768); prefix+=768; DONE;
00139       CASE(F_PREFIX_1024); prefix+=1024; DONE;
00140       CASE(F_PREFIX_24BITX256);
00141         prefix += (pc++)[0]<<24;
00142       CASE(F_PREFIX_WORDX256);
00143         prefix += (pc++)[0]<<16;
00144       CASE(F_PREFIX_CHARX256);
00145         prefix += (pc++)[0]<<8;
00146       DONE;
00147 
00148       /* Support to allow large arguments */
00149       CASE(F_PREFIX2_256); prefix2+=256; DONE;
00150       CASE(F_PREFIX2_512); prefix2+=512; DONE;
00151       CASE(F_PREFIX2_768); prefix2+=768; DONE;
00152       CASE(F_PREFIX2_1024); prefix2+=1024; DONE;
00153       CASE(F_PREFIX2_24BITX256);
00154         prefix2 += (pc++)[0]<<24;
00155       CASE(F_PREFIX2_WORDX256);
00156         prefix2 += (pc++)[0]<<16;
00157       CASE(F_PREFIX2_CHARX256);
00158         prefix2 += (pc++)[0]<<8;
00159       DONE;
00160 #endif /* HAVE_COMPUTED_GOTO */
00161 
00162 
00163 #define INTERPRETER
00164 
00165 #define OPCODE0(OP, DESC, FLAGS, CODE) CASE(OP); CODE; DONE
00166 #define OPCODE1(OP, DESC, FLAGS, CODE) CASE(OP); { \
00167     arg1=GET_ARG(); \
00168     FETCH; \
00169     CODE; \
00170   } DONE
00171 
00172 #define OPCODE2(OP, DESC, FLAGS, CODE) CASE(OP); { \
00173     arg1=GET_ARG(); \
00174     arg2=GET_ARG2(); \
00175     FETCH; \
00176     CODE; \
00177   } DONE
00178 
00179 #define OPCODE0_ALIAS(OP, DESC, FLAGS, FUN) OPCODE0(OP, DESC, FLAGS, {FUN();})
00180 #define OPCODE1_ALIAS(OP, DESC, FLAGS, FUN) OPCODE1(OP, DESC, FLAGS, {FUN(arg1);})
00181 #define OPCODE2_ALIAS(OP, DESC, FLAGS, FUN) OPCODE2(OP, DESC, FLAGS, {FUN(arg1, arg2);})
00182 
00183 #define OPCODE0_TAIL(OP, DESC, FLAGS, CODE) CASE(OP); CODE
00184 #define OPCODE1_TAIL(OP, DESC, FLAGS, CODE) CASE(OP); CODE
00185 #define OPCODE2_TAIL(OP, DESC, FLAGS, CODE) CASE(OP); CODE
00186 
00187 #define OPCODE0_JUMP            OPCODE0
00188 #define OPCODE1_JUMP            OPCODE1
00189 #define OPCODE2_JUMP            OPCODE2
00190 #define OPCODE0_TAILJUMP        OPCODE0_TAIL
00191 #define OPCODE1_TAILJUMP        OPCODE1_TAIL
00192 #define OPCODE2_TAILJUMP        OPCODE2_TAIL
00193 
00194 #define OPCODE0_RETURN(OP, DESC, FLAGS, CODE) OPCODE0(OP, DESC, FLAGS, CODE)
00195 #define OPCODE1_RETURN(OP, DESC, FLAGS, CODE) OPCODE1(OP, DESC, FLAGS, CODE)
00196 #define OPCODE2_RETURN(OP, DESC, FLAGS, CODE) OPCODE2(OP, DESC, FLAGS, CODE)
00197 #define OPCODE0_TAILRETURN(OP, DESC, FLAGS, CODE) OPCODE0_TAIL(OP, DESC, FLAGS, CODE)
00198 #define OPCODE1_TAILRETURN(OP, DESC, FLAGS, CODE) OPCODE1_TAIL(OP, DESC, FLAGS, CODE)
00199 #define OPCODE2_TAILRETURN(OP, DESC, FLAGS, CODE) OPCODE2_TAIL(OP, DESC, FLAGS, CODE)
00200 
00201 #define OPCODE0_PTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); CODE; DONE
00202 #define OPCODE0_TAILPTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); CODE
00203 
00204 /* These are something of a special case as they
00205  * requires a POINTER stored explicitly after
00206  * the instruction itself.
00207  */
00208 #define OPCODE1_PTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); { \
00209     arg1=GET_ARG(); \
00210     FETCH; \
00211     CODE; \
00212   } DONE
00213 
00214 #define OPCODE2_PTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); { \
00215     arg1=GET_ARG(); \
00216     arg2=GET_ARG2(); \
00217     FETCH; \
00218     CODE; \
00219   } DONE
00220 
00221 #define OPCODE1_TAILPTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); CODE
00222 #define OPCODE2_TAILPTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); CODE
00223 
00224 #define OPCODE0_BRANCH          OPCODE0_PTRJUMP
00225 #define OPCODE1_BRANCH          OPCODE1_PTRJUMP
00226 #define OPCODE2_BRANCH          OPCODE2_PTRJUMP
00227 #define OPCODE0_TAILBRANCH      OPCODE0_TAILPTRJUMP
00228 #define OPCODE1_TAILBRANCH      OPCODE1_TAILPTRJUMP
00229 #define OPCODE2_TAILBRANCH      OPCODE2_TAILPTRJUMP
00230 
00231 #include "interpret_functions.h"
00232 
00233 #ifndef HAVE_COMPUTED_GOTO      
00234     default:
00235       Pike_fatal("Strange instruction %ld\n",(long)instr);
00236     }
00237 #endif /* !HAVE_COMPUTED_GOTO */
00238   }
00239 
00240   /* NOT_REACHED */
00241 
00242 #ifdef HAVE_COMPUTED_GOTO
00243 
00244 #undef OPCODE0
00245 #undef OPCODE1
00246 #undef OPCODE2
00247 #undef OPCODE0_TAIL
00248 #undef OPCODE1_TAIL
00249 #undef OPCODE2_TAIL
00250 #undef OPCODE0_JUMP
00251 #undef OPCODE1_JUMP
00252 #undef OPCODE2_JUMP
00253 #undef OPCODE0_TAILJUMP
00254 #undef OPCODE1_TAILJUMP
00255 #undef OPCODE2_TAILJUMP
00256 #undef OPCODE0_PTRJUMP
00257 #undef OPCODE1_PTRJUMP
00258 #undef OPCODE2_PTRJUMP
00259 #undef OPCODE0_TAILPTRJUMP
00260 #undef OPCODE1_TAILPTRJUMP
00261 #undef OPCODE2_TAILPTRJUMP
00262 #undef OPCODE0_RETURN
00263 #undef OPCODE1_RETURN
00264 #undef OPCODE2_RETURN
00265 #undef OPCODE0_TAILRETURN
00266 #undef OPCODE1_TAILRETURN
00267 #undef OPCODE2_TAILRETURN
00268 #undef OPCODE0_BRANCH
00269 #undef OPCODE1_BRANCH
00270 #undef OPCODE2_BRANCH
00271 #undef OPCODE0_TAILBRANCH
00272 #undef OPCODE1_TAILBRANCH
00273 #undef OPCODE2_TAILBRANCH
00274   /* NOTE: No need to redefine these.
00275    * #undef OPCODE0_ALIAS
00276    * #undef OPCODE1_ALIAS
00277    * #undef OPCODE2_ALIAS
00278    */
00279 #undef LABEL
00280 #define LABEL(OP)                       &&PIKE_CONCAT(LABEL_,OP)
00281 #define NULL_LABEL(OP)                  NULL
00282 #define OPCODE0(OP,DESC)                LABEL(OP),
00283 #define OPCODE1(OP,DESC)                LABEL(OP),
00284 #define OPCODE2(OP,DESC)                LABEL(OP),
00285 #define OPCODE0_TAIL(OP,DESC)           LABEL(OP),
00286 #define OPCODE1_TAIL(OP,DESC)           LABEL(OP),
00287 #define OPCODE2_TAIL(OP,DESC)           LABEL(OP),
00288 #define OPCODE0_PTRJUMP(OP,DESC)        LABEL(OP),
00289 #define OPCODE1_PTRJUMP(OP,DESC)        LABEL(OP),
00290 #define OPCODE2_PTRJUMP(OP,DESC)        LABEL(OP),
00291 #define OPCODE0_TAILPTRJUMP(OP,DESC)    LABEL(OP),
00292 #define OPCODE1_TAILPTRJUMP(OP,DESC)    LABEL(OP),
00293 #define OPCODE2_TAILPTRJUMP(OP,DESC)    LABEL(OP),
00294 #define OPCODE0_RETURN(OP,DESC)         LABEL(OP),
00295 #define OPCODE1_RETURN(OP,DESC)         LABEL(OP),
00296 #define OPCODE2_RETURN(OP,DESC)         LABEL(OP),
00297 #define OPCODE0_TAILRETURN(OP,DESC)     LABEL(OP),
00298 #define OPCODE1_TAILRETURN(OP,DESC)     LABEL(OP),
00299 #define OPCODE2_TAILRETURN(OP,DESC)     LABEL(OP),
00300 
00301  init_strap:
00302   strap = &&normal_strap;
00303   {
00304     static void *table[] = {
00305       NULL_LABEL(F_OFFSET),
00306 
00307       NULL_LABEL(F_PREFIX_256),
00308       NULL_LABEL(F_PREFIX_512),
00309       NULL_LABEL(F_PREFIX_768),
00310       NULL_LABEL(F_PREFIX_1024),
00311       NULL_LABEL(F_PREFIX_CHARX256),
00312       NULL_LABEL(F_PREFIX_WORDX256),
00313       NULL_LABEL(F_PREFIX_24BITX256),
00314 
00315       NULL_LABEL(F_PREFIX2_256),
00316       NULL_LABEL(F_PREFIX2_512),
00317       NULL_LABEL(F_PREFIX2_768),
00318       NULL_LABEL(F_PREFIX2_1024),
00319       NULL_LABEL(F_PREFIX2_CHARX256),
00320       NULL_LABEL(F_PREFIX2_WORDX256),
00321       NULL_LABEL(F_PREFIX2_24BITX256),
00322 
00323 #include "interpret_protos.h"
00324     };
00325 
00326     static struct op_2_f lookup[] = {
00327 #undef LABEL
00328 #define LABEL(OP)       { &&PIKE_CONCAT(LABEL_, OP), OP }
00329 #undef NULL_LABEL
00330 #define NULL_LABEL(OP)  { NULL, OP }
00331 
00332       NULL_LABEL(F_OFFSET),
00333 
00334       NULL_LABEL(F_PREFIX_256),
00335       NULL_LABEL(F_PREFIX_512),
00336       NULL_LABEL(F_PREFIX_768),
00337       NULL_LABEL(F_PREFIX_1024),
00338       NULL_LABEL(F_PREFIX_CHARX256),
00339       NULL_LABEL(F_PREFIX_WORDX256),
00340       NULL_LABEL(F_PREFIX_24BITX256),
00341 
00342       NULL_LABEL(F_PREFIX2_256),
00343       NULL_LABEL(F_PREFIX2_512),
00344       NULL_LABEL(F_PREFIX2_768),
00345       NULL_LABEL(F_PREFIX2_1024),
00346       NULL_LABEL(F_PREFIX2_CHARX256),
00347       NULL_LABEL(F_PREFIX2_WORDX256),
00348       NULL_LABEL(F_PREFIX2_24BITX256),
00349 
00350 #include "interpret_protos.h"
00351     };
00352 
00353 #ifdef PIKE_DEBUG
00354     if (sizeof(table) != (F_MAX_OPCODE-F_OFFSET)*sizeof(void *))
00355       Pike_fatal("opcode_to_label out of sync: 0x%08lx != 0x%08lx\n",
00356             DO_NOT_WARN((long)sizeof(table)),
00357             DO_NOT_WARN((long)((F_MAX_OPCODE-F_OFFSET)*sizeof(void *))));
00358 #endif /* PIKE_DEBUG */
00359     fcode_to_opcode = table;
00360     opcode_to_fcode = lookup;
00361 
00362     qsort(lookup, F_MAX_OPCODE-F_OFFSET, sizeof(struct op_2_f),
00363           lookup_sort_fun);
00364 
00365     return 0;
00366   }
00367 #endif /* HAVE_COMPUTED_GOTO */
00368 }

Generated on Fri Jul 22 23:44:26 2005 for Pike by  doxygen 1.3.9.1