00001
00002
00003
00004
00005
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
00030 #define DONE do { \
00031 Pike_fp->pc = PROG_COUNTER++; \
00032 goto *instr; \
00033 } while(0)
00034
00035 #endif
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
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
00055 #define LOW_GET_JUMP() EXTRACT_INT(PROG_COUNTER)
00056 #define LOW_SKIPJUMP() (PROG_COUNTER += sizeof(INT32))
00057 #endif
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
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
00081
00082 #endif
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
00095 unsigned INT32 prefix2=0,prefix=0;
00096 #endif
00097
00098
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)
00109
00110 #ifdef HAVE_COMPUTED_GOTO
00111 goto *strap;
00112 normal_strap:
00113 #endif
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
00132 switch(instr)
00133 {
00134
00135
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
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
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
00205
00206
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
00238 }
00239
00240
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
00275
00276
00277
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
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
00368 }