e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
7951942000-04-20Fredrik Hübinette (Hubbe) 
eff6212001-07-09Henrik Grubbström (Grubba) #undef LOW_GET_ARG #undef LOW_GET_JUMP #undef LOW_SKIPJUMP
7d7d7e1999-01-31Fredrik Hübinette (Hubbe) #undef GET_ARG #undef GET_ARG2
388f0d2001-01-31Martin Stjernholm #undef GET_JUMP #undef SKIPJUMP
68296f2001-07-07Henrik Grubbström (Grubba) #undef DOJUMP
61e9832001-07-08Henrik Grubbström (Grubba) #undef CASE #undef BREAK #undef DONE
f142842003-08-06Martin Stjernholm #undef JUMP_DONE #define JUMP_DONE DONE
61e9832001-07-08Henrik Grubbström (Grubba) #ifdef HAVE_COMPUTED_GOTO
2454752001-07-10Henrik Grubbström (Grubba) #define CASE(OP) PIKE_CONCAT(LABEL_,OP): FETCH
f822262001-07-16Fredrik Hübinette (Hubbe) #define FETCH (instr = PROG_COUNTER[0])
61e9832001-07-08Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG #define DONE continue #else /* !PIKE_DEBUG */
88149c2001-07-08Henrik Grubbström (Grubba) #define DONE do { \
f822262001-07-16Fredrik Hübinette (Hubbe)  Pike_fp->pc = PROG_COUNTER++; \
88149c2001-07-08Henrik Grubbström (Grubba)  goto *instr; \ } while(0)
13670c2015-05-25Martin Nilsson 
61e9832001-07-08Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
88149c2001-07-08Henrik Grubbström (Grubba) 
f822262001-07-16Fredrik Hübinette (Hubbe) #define LOW_GET_ARG() ((INT32)(ptrdiff_t)(*(PROG_COUNTER++))) #define LOW_GET_JUMP() ((INT32)(ptrdiff_t)(*(PROG_COUNTER))) #define LOW_SKIPJUMP() (instr = (++PROG_COUNTER)[0])
88149c2001-07-08Henrik Grubbström (Grubba) 
eff6212001-07-09Henrik Grubbström (Grubba) #define GET_ARG() LOW_GET_ARG() #define GET_ARG2() LOW_GET_ARG()
61e9832001-07-08Henrik Grubbström (Grubba) #else /* !HAVE_COMPUTED_GOTO */
88149c2001-07-08Henrik Grubbström (Grubba) #define CASE(X) case (X)-F_OFFSET: #define DONE break
2454752001-07-10Henrik Grubbström (Grubba) #define FETCH
88149c2001-07-08Henrik Grubbström (Grubba) 
f822262001-07-16Fredrik Hübinette (Hubbe) #define LOW_GET_ARG() ((PROG_COUNTER++)[0])
98a7752002-04-08Martin Stjernholm #if PIKE_BYTECODE_METHOD == PIKE_BYTECODE_SPARC
c696242001-07-18Henrik Grubbström (Grubba) #define LOW_GET_JUMP() (PROG_COUNTER[0]) #define LOW_SKIPJUMP() (++PROG_COUNTER)
98a7752002-04-08Martin Stjernholm #else /* PIKE_BYTECODE_METHOD != PIKE_BYTECODE_SPARC */
cd93cc2017-07-20Martin Nilsson #define LOW_GET_JUMP() (INT32)get_unaligned32(PROG_COUNTER)
f822262001-07-16Fredrik Hübinette (Hubbe) #define LOW_SKIPJUMP() (PROG_COUNTER += sizeof(INT32))
98a7752002-04-08Martin Stjernholm #endif /* PIKE_BYTECODE_METHOD */
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  #ifdef PIKE_DEBUG
31984c2003-03-20Martin Stjernholm #define GET_ARG() ( \
97ebb32003-01-09Henrik Grubbström (Grubba)  instr=prefix, \ prefix=0, \ instr += LOW_GET_ARG(), \
31984c2003-03-20Martin Stjernholm  DEBUG_LOG_ARG (instr), \ instr)
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
31984c2003-03-20Martin Stjernholm #define GET_ARG2() ( \
97ebb32003-01-09Henrik Grubbström (Grubba)  instr=prefix2, \ prefix2=0, \ instr += LOW_GET_ARG(), \
31984c2003-03-20Martin Stjernholm  DEBUG_LOG_ARG2 (instr), \ instr)
7d7d7e1999-01-31Fredrik Hübinette (Hubbe) 
eff6212001-07-09Henrik Grubbström (Grubba) #else /* !PIKE_DEBUG */ #define GET_ARG() (instr=prefix,prefix=0,instr+LOW_GET_ARG()) #define GET_ARG2() (instr=prefix2,prefix2=0,instr+LOW_GET_ARG()) #endif /* PIKE_DEBUG */ #endif /* HAVE_COMPUTED_GOTO */
d49add2001-04-25Fredrik Hübinette (Hubbe) #ifndef STEP_BREAK_LINE #define STEP_BREAK_LINE #endif
610d052001-07-06Henrik Grubbström (Grubba) static int eval_instruction(PIKE_OPCODE_T *pc)
7d7d7e1999-01-31Fredrik Hübinette (Hubbe) {
31984c2003-03-20Martin Stjernholm  PIKE_INSTR_T instr;
61e9832001-07-08Henrik Grubbström (Grubba) #ifdef HAVE_COMPUTED_GOTO
88149c2001-07-08Henrik Grubbström (Grubba)  static void *strap = &&init_strap;
31984c2003-03-20Martin Stjernholm  instr = NULL;
61e9832001-07-08Henrik Grubbström (Grubba) #else /* !HAVE_COMPUTED_GOTO */
afea002001-07-12Per Hedbor  unsigned INT32 prefix2=0,prefix=0;
61e9832001-07-08Henrik Grubbström (Grubba) #endif /* HAVE_COMPUTED_GOTO */
7c1e422004-09-22Henrik Grubbström (Grubba)  /* Variables that are commonly used by the various opcodes. * They are defined here to reduce the size of the stack frame. */ struct svalue tmp, tmp2; struct external_variable_context loc; struct program *p; struct object *o; struct svalue *s;
0beb332013-08-21Tobias S. Josefowitz  PIKE_OPCODE_T *addr;
2d10fb2016-12-29Arne Goedeke  DO_IF_DEBUG(struct byte_buffer save_buf);
7c1e422004-09-22Henrik Grubbström (Grubba)  #undef LOCAL_VAR #define LOCAL_VAR(X) /* Local variable defined above. */
61e9832001-07-08Henrik Grubbström (Grubba) 
88149c2001-07-08Henrik Grubbström (Grubba) #ifdef HAVE_COMPUTED_GOTO goto *strap; normal_strap: #endif /* HAVE_COMPUTED_GOTO */
a2ad152000-02-16Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_fp);
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  while(1) {
2f816c2004-05-29Henrik Grubbström (Grubba)  INT32 arg1, arg2;
2454752001-07-10Henrik Grubbström (Grubba)  instr = pc[0]; Pike_fp->pc = pc++;
7d7d7e1999-01-31Fredrik Hübinette (Hubbe) 
d49add2001-04-25Fredrik Hübinette (Hubbe)  STEP_BREAK_LINE
610d052001-07-06Henrik Grubbström (Grubba) 
31984c2003-03-20Martin Stjernholm #ifdef PIKE_DEBUG if (d_flag || Pike_interpreter.trace_level > 2)
170ec22003-03-22Henrik Grubbström (Grubba)  low_debug_instr_prologue (instr);
7d7d7e1999-01-31Fredrik Hübinette (Hubbe) #endif
61e9832001-07-08Henrik Grubbström (Grubba) #ifdef HAVE_COMPUTED_GOTO goto *instr; #else /* !HAVE_COMPUTED_GOTO */
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  switch(instr) {
eff6212001-07-09Henrik Grubbström (Grubba)  /* NOTE: The prefix handling is not needed in computed-goto mode. */
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  /* Support to allow large arguments */
61e9832001-07-08Henrik Grubbström (Grubba)  CASE(F_PREFIX_256); prefix+=256; DONE; CASE(F_PREFIX_512); prefix+=512; DONE; CASE(F_PREFIX_768); prefix+=768; DONE; CASE(F_PREFIX_1024); prefix+=1024; DONE;
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  CASE(F_PREFIX_24BITX256);
c1a3ee2014-07-03Arne Goedeke  prefix += (unsigned INT32)(pc++)[0]<<24;
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  CASE(F_PREFIX_WORDX256);
c1a3ee2014-07-03Arne Goedeke  prefix += (unsigned INT32)(pc++)[0]<<16;
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  CASE(F_PREFIX_CHARX256);
61e9832001-07-08Henrik Grubbström (Grubba)  prefix += (pc++)[0]<<8; DONE;
7d7d7e1999-01-31Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe)  /* Support to allow large arguments */
61e9832001-07-08Henrik Grubbström (Grubba)  CASE(F_PREFIX2_256); prefix2+=256; DONE; CASE(F_PREFIX2_512); prefix2+=512; DONE; CASE(F_PREFIX2_768); prefix2+=768; DONE; CASE(F_PREFIX2_1024); prefix2+=1024; DONE;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  CASE(F_PREFIX2_24BITX256);
c1a3ee2014-07-03Arne Goedeke  prefix2 += (unsigned INT32)(pc++)[0]<<24;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  CASE(F_PREFIX2_WORDX256);
c1a3ee2014-07-03Arne Goedeke  prefix2 += (unsigned INT32)(pc++)[0]<<16;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  CASE(F_PREFIX2_CHARX256);
61e9832001-07-08Henrik Grubbström (Grubba)  prefix2 += (pc++)[0]<<8; DONE;
eff6212001-07-09Henrik Grubbström (Grubba) #endif /* HAVE_COMPUTED_GOTO */
7d7d7e1999-01-31Fredrik Hübinette (Hubbe) 
87c7592000-04-18Fredrik Hübinette (Hubbe) #define INTERPRETER
7d7d7e1999-01-31Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm #define OPCODE0(OP, DESC, FLAGS, CODE) CASE(OP); CODE; DONE #define OPCODE1(OP, DESC, FLAGS, CODE) CASE(OP); { \
2f816c2004-05-29Henrik Grubbström (Grubba)  arg1=GET_ARG(); \
2454752001-07-10Henrik Grubbström (Grubba)  FETCH; \
610d052001-07-06Henrik Grubbström (Grubba)  CODE; \
61e9832001-07-08Henrik Grubbström (Grubba)  } DONE
7d7d7e1999-01-31Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm #define OPCODE2(OP, DESC, FLAGS, CODE) CASE(OP); { \
2f816c2004-05-29Henrik Grubbström (Grubba)  arg1=GET_ARG(); \ arg2=GET_ARG2(); \
2454752001-07-10Henrik Grubbström (Grubba)  FETCH; \
610d052001-07-06Henrik Grubbström (Grubba)  CODE; \
61e9832001-07-08Henrik Grubbström (Grubba)  } DONE
7d7d7e1999-01-31Fredrik Hübinette (Hubbe) 
105be62002-11-10Henrik Grubbström (Grubba) #define OPCODE0_ALIAS(OP, DESC, FLAGS, FUN) OPCODE0(OP, DESC, FLAGS, {FUN();}) #define OPCODE1_ALIAS(OP, DESC, FLAGS, FUN) OPCODE1(OP, DESC, FLAGS, {FUN(arg1);}) #define OPCODE2_ALIAS(OP, DESC, FLAGS, FUN) OPCODE2(OP, DESC, FLAGS, {FUN(arg1, arg2);})
2bcc0d2002-05-11Martin Stjernholm #define OPCODE0_TAIL(OP, DESC, FLAGS, CODE) CASE(OP); CODE #define OPCODE1_TAIL(OP, DESC, FLAGS, CODE) CASE(OP); CODE #define OPCODE2_TAIL(OP, DESC, FLAGS, CODE) CASE(OP); CODE
7951942000-04-20Fredrik Hübinette (Hubbe) 
f142842003-08-06Martin Stjernholm #define OPCODE0_JUMP OPCODE0 #define OPCODE1_JUMP OPCODE1 #define OPCODE2_JUMP OPCODE2 #define OPCODE0_TAILJUMP OPCODE0_TAIL #define OPCODE1_TAILJUMP OPCODE1_TAIL #define OPCODE2_TAILJUMP OPCODE2_TAIL
4555f32011-05-11Henrik Grubbström (Grubba) #define OPCODE0_RETURN(OP, DESC, FLAGS, CODE) OPCODE0(OP, DESC, FLAGS | I_RETURN, CODE) #define OPCODE1_RETURN(OP, DESC, FLAGS, CODE) OPCODE1(OP, DESC, FLAGS | I_RETURN, CODE) #define OPCODE2_RETURN(OP, DESC, FLAGS, CODE) OPCODE2(OP, DESC, FLAGS | I_RETURN, CODE) #define OPCODE0_TAILRETURN(OP, DESC, FLAGS, CODE) OPCODE0_TAIL(OP, DESC, FLAGS | I_RETURN, CODE) #define OPCODE1_TAILRETURN(OP, DESC, FLAGS, CODE) OPCODE1_TAIL(OP, DESC, FLAGS | I_RETURN, CODE) #define OPCODE2_TAILRETURN(OP, DESC, FLAGS, CODE) OPCODE2_TAIL(OP, DESC, FLAGS | I_RETURN, CODE)
7997532001-07-27Henrik Grubbström (Grubba) 
f142842003-08-06Martin Stjernholm #define OPCODE0_PTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); CODE; DONE #define OPCODE0_TAILPTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); CODE
7951942000-04-20Fredrik Hübinette (Hubbe)  /* These are something of a special case as they * requires a POINTER stored explicitly after * the instruction itself. */
f142842003-08-06Martin Stjernholm #define OPCODE1_PTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); { \
2f816c2004-05-29Henrik Grubbström (Grubba)  arg1=GET_ARG(); \
2454752001-07-10Henrik Grubbström (Grubba)  FETCH; \
610d052001-07-06Henrik Grubbström (Grubba)  CODE; \
61e9832001-07-08Henrik Grubbström (Grubba)  } DONE
610d052001-07-06Henrik Grubbström (Grubba) 
f142842003-08-06Martin Stjernholm #define OPCODE2_PTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); { \
2f816c2004-05-29Henrik Grubbström (Grubba)  arg1=GET_ARG(); \ arg2=GET_ARG2(); \
2454752001-07-10Henrik Grubbström (Grubba)  FETCH; \
610d052001-07-06Henrik Grubbström (Grubba)  CODE; \
61e9832001-07-08Henrik Grubbström (Grubba)  } DONE
610d052001-07-06Henrik Grubbström (Grubba) 
f142842003-08-06Martin Stjernholm #define OPCODE1_TAILPTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); CODE #define OPCODE2_TAILPTRJUMP(OP, DESC, FLAGS, CODE) CASE(OP); CODE
7951942000-04-20Fredrik Hübinette (Hubbe) 
f142842003-08-06Martin Stjernholm #define OPCODE0_BRANCH OPCODE0_PTRJUMP #define OPCODE1_BRANCH OPCODE1_PTRJUMP #define OPCODE2_BRANCH OPCODE2_PTRJUMP #define OPCODE0_TAILBRANCH OPCODE0_TAILPTRJUMP #define OPCODE1_TAILBRANCH OPCODE1_TAILPTRJUMP #define OPCODE2_TAILBRANCH OPCODE2_TAILPTRJUMP
8069c22002-11-02Henrik Grubbström (Grubba) 
87c7592000-04-18Fredrik Hübinette (Hubbe) #include "interpret_functions.h"
61e9832001-07-08Henrik Grubbström (Grubba) 
13670c2015-05-25Martin Nilsson #ifndef HAVE_COMPUTED_GOTO
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  default:
5aad932002-08-15Marcus Comstedt  Pike_fatal("Strange instruction %ld\n",(long)instr);
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  }
61e9832001-07-08Henrik Grubbström (Grubba) #endif /* !HAVE_COMPUTED_GOTO */
7d7d7e1999-01-31Fredrik Hübinette (Hubbe)  }
7965d72001-01-24Fredrik Hübinette (Hubbe) 
b42e942015-09-28Martin Nilsson  UNREACHABLE();
88149c2001-07-08Henrik Grubbström (Grubba)  #ifdef HAVE_COMPUTED_GOTO #undef OPCODE0 #undef OPCODE1 #undef OPCODE2 #undef OPCODE0_TAIL #undef OPCODE1_TAIL #undef OPCODE2_TAIL #undef OPCODE0_JUMP #undef OPCODE1_JUMP #undef OPCODE2_JUMP #undef OPCODE0_TAILJUMP #undef OPCODE1_TAILJUMP #undef OPCODE2_TAILJUMP
f142842003-08-06Martin Stjernholm #undef OPCODE0_PTRJUMP #undef OPCODE1_PTRJUMP #undef OPCODE2_PTRJUMP #undef OPCODE0_TAILPTRJUMP #undef OPCODE1_TAILPTRJUMP #undef OPCODE2_TAILPTRJUMP
8069c22002-11-02Henrik Grubbström (Grubba) #undef OPCODE0_RETURN #undef OPCODE1_RETURN #undef OPCODE2_RETURN #undef OPCODE0_TAILRETURN #undef OPCODE1_TAILRETURN #undef OPCODE2_TAILRETURN #undef OPCODE0_BRANCH #undef OPCODE1_BRANCH #undef OPCODE2_BRANCH #undef OPCODE0_TAILBRANCH #undef OPCODE1_TAILBRANCH #undef OPCODE2_TAILBRANCH
105be62002-11-10Henrik Grubbström (Grubba)  /* NOTE: No need to redefine these. * #undef OPCODE0_ALIAS * #undef OPCODE1_ALIAS * #undef OPCODE2_ALIAS */
88149c2001-07-08Henrik Grubbström (Grubba) #undef LABEL
eff6212001-07-09Henrik Grubbström (Grubba) #define LABEL(OP) &&PIKE_CONCAT(LABEL_,OP) #define NULL_LABEL(OP) NULL #define OPCODE0(OP,DESC) LABEL(OP), #define OPCODE1(OP,DESC) LABEL(OP), #define OPCODE2(OP,DESC) LABEL(OP), #define OPCODE0_TAIL(OP,DESC) LABEL(OP), #define OPCODE1_TAIL(OP,DESC) LABEL(OP), #define OPCODE2_TAIL(OP,DESC) LABEL(OP),
f142842003-08-06Martin Stjernholm #define OPCODE0_PTRJUMP(OP,DESC) LABEL(OP), #define OPCODE1_PTRJUMP(OP,DESC) LABEL(OP), #define OPCODE2_PTRJUMP(OP,DESC) LABEL(OP), #define OPCODE0_TAILPTRJUMP(OP,DESC) LABEL(OP), #define OPCODE1_TAILPTRJUMP(OP,DESC) LABEL(OP), #define OPCODE2_TAILPTRJUMP(OP,DESC) LABEL(OP),
7997532001-07-27Henrik Grubbström (Grubba) #define OPCODE0_RETURN(OP,DESC) LABEL(OP), #define OPCODE1_RETURN(OP,DESC) LABEL(OP), #define OPCODE2_RETURN(OP,DESC) LABEL(OP), #define OPCODE0_TAILRETURN(OP,DESC) LABEL(OP), #define OPCODE1_TAILRETURN(OP,DESC) LABEL(OP), #define OPCODE2_TAILRETURN(OP,DESC) LABEL(OP),
88149c2001-07-08Henrik Grubbström (Grubba)  init_strap: strap = &&normal_strap; { static void *table[] = {
c9745c2001-07-09Henrik Grubbström (Grubba)  NULL_LABEL(F_OFFSET),
eff6212001-07-09Henrik Grubbström (Grubba)  NULL_LABEL(F_PREFIX_256), NULL_LABEL(F_PREFIX_512), NULL_LABEL(F_PREFIX_768), NULL_LABEL(F_PREFIX_1024), NULL_LABEL(F_PREFIX_CHARX256), NULL_LABEL(F_PREFIX_WORDX256), NULL_LABEL(F_PREFIX_24BITX256), NULL_LABEL(F_PREFIX2_256), NULL_LABEL(F_PREFIX2_512), NULL_LABEL(F_PREFIX2_768), NULL_LABEL(F_PREFIX2_1024), NULL_LABEL(F_PREFIX2_CHARX256), NULL_LABEL(F_PREFIX2_WORDX256), NULL_LABEL(F_PREFIX2_24BITX256),
88149c2001-07-08Henrik Grubbström (Grubba) 
afa1c62001-07-09Henrik Grubbström (Grubba) #include "interpret_protos.h" }; static struct op_2_f lookup[] = { #undef LABEL #define LABEL(OP) { &&PIKE_CONCAT(LABEL_, OP), OP } #undef NULL_LABEL #define NULL_LABEL(OP) { NULL, OP } NULL_LABEL(F_OFFSET), NULL_LABEL(F_PREFIX_256), NULL_LABEL(F_PREFIX_512), NULL_LABEL(F_PREFIX_768), NULL_LABEL(F_PREFIX_1024), NULL_LABEL(F_PREFIX_CHARX256), NULL_LABEL(F_PREFIX_WORDX256), NULL_LABEL(F_PREFIX_24BITX256), NULL_LABEL(F_PREFIX2_256), NULL_LABEL(F_PREFIX2_512), NULL_LABEL(F_PREFIX2_768), NULL_LABEL(F_PREFIX2_1024), NULL_LABEL(F_PREFIX2_CHARX256), NULL_LABEL(F_PREFIX2_WORDX256), NULL_LABEL(F_PREFIX2_24BITX256),
88149c2001-07-08Henrik Grubbström (Grubba) #include "interpret_protos.h" }; #ifdef PIKE_DEBUG
c9745c2001-07-09Henrik Grubbström (Grubba)  if (sizeof(table) != (F_MAX_OPCODE-F_OFFSET)*sizeof(void *))
5aad932002-08-15Marcus Comstedt  Pike_fatal("opcode_to_label out of sync: 0x%08lx != 0x%08lx\n",
bd67392015-10-14Martin Nilsson  (long)sizeof(table), (long)((F_MAX_OPCODE-F_OFFSET)*sizeof(void *)));
88149c2001-07-08Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */ fcode_to_opcode = table;
afa1c62001-07-09Henrik Grubbström (Grubba)  opcode_to_fcode = lookup; qsort(lookup, F_MAX_OPCODE-F_OFFSET, sizeof(struct op_2_f), lookup_sort_fun);
88149c2001-07-08Henrik Grubbström (Grubba)  return 0; } #endif /* HAVE_COMPUTED_GOTO */ }