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.
d6f90d2003-10-10Henrik Grubbström (Grubba) || $Id: interpret_functions.h,v 1.160 2003/10/10 14:50:53 grubba Exp $
e576bb2002-10-11Martin Nilsson */
1b10db2002-10-08Martin Nilsson 
67bdb52000-04-18Henrik Grubbström (Grubba) /* * Opcode definitions for the interpreter. */
87c7592000-04-18Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) #include "global.h"
68296f2001-07-07Henrik Grubbström (Grubba) #undef CJUMP #undef AUTO_BIGNUM_LOOP_TEST #undef LOOP #undef COMPARISON #undef MKAPPLY #undef DO_CALL_BUILTIN #undef DO_IF_BIGNUM
610d052001-07-06Henrik Grubbström (Grubba) #ifdef AUTO_BIGNUM #define DO_IF_BIGNUM(CODE) CODE #else /* !AUTO_BIGNUM */ #define DO_IF_BIGNUM(CODE) #endif /* AUTO_BIGNUM */
eff6212001-07-09Henrik Grubbström (Grubba) #undef DO_IF_ELSE_COMPUTED_GOTO #ifdef HAVE_COMPUTED_GOTO #define DO_IF_ELSE_COMPUTED_GOTO(A, B) (A) #else /* !HAVE_COMPUTED_GOTO */ #define DO_IF_ELSE_COMPUTED_GOTO(A, B) (B) #endif /* HAVE_COMPUTED_GOTO */
610d052001-07-06Henrik Grubbström (Grubba) #ifdef GEN_PROTOS /* Used to generate the interpret_protos.h file. */
2bcc0d2002-05-11Martin Stjernholm #define OPCODE0(A, B, F, C) OPCODE0(A, B, F) --- C #define OPCODE1(A, B, F, C) OPCODE1(A, B, F) --- C #define OPCODE2(A, B, F, C) OPCODE2(A, B, F) --- C #define OPCODE0_TAIL(A, B, F, C) OPCODE0_TAIL(A, B, F) --- C #define OPCODE1_TAIL(A, B, F, C) OPCODE1_TAIL(A, B, F) --- C #define OPCODE2_TAIL(A, B, F, C) OPCODE2_TAIL(A, B, F) --- C #define OPCODE0_JUMP(A, B, F, C) OPCODE0_JUMP(A, B, F) --- C #define OPCODE1_JUMP(A, B, F, C) OPCODE1_JUMP(A, B, F) --- C #define OPCODE2_JUMP(A, B, F, C) OPCODE2_JUMP(A, B, F) --- C #define OPCODE0_TAILJUMP(A, B, F, C) OPCODE0_TAILJUMP(A, B, F) --- C #define OPCODE1_TAILJUMP(A, B, F, C) OPCODE1_TAILJUMP(A, B, F) --- C #define OPCODE2_TAILJUMP(A, B, F, C) OPCODE2_TAILJUMP(A, B, F) --- C
f142842003-08-06Martin Stjernholm #define OPCODE0_PTRJUMP(A, B, F, C) OPCODE0_PTRJUMP(A, B, F) --- C #define OPCODE1_PTRJUMP(A, B, F, C) OPCODE1_PTRJUMP(A, B, F) --- C #define OPCODE2_PTRJUMP(A, B, F, C) OPCODE2_PTRJUMP(A, B, F) --- C #define OPCODE0_TAILPTRJUMP(A, B, F, C) OPCODE0_TAILPTRJUMP(A, B, F) --- C #define OPCODE1_TAILPTRJUMP(A, B, F, C) OPCODE1_TAILPTRJUMP(A, B, F) --- C #define OPCODE2_TAILPTRJUMP(A, B, F, C) OPCODE2_TAILPTRJUMP(A, B, F) --- C
2bcc0d2002-05-11Martin Stjernholm #define OPCODE0_RETURN(A, B, F, C) OPCODE0_RETURN(A, B, F) --- C #define OPCODE1_RETURN(A, B, F, C) OPCODE1_RETURN(A, B, F) --- C #define OPCODE2_RETURN(A, B, F, C) OPCODE2_RETURN(A, B, F) --- C #define OPCODE0_TAILRETURN(A, B, F, C) OPCODE0_TAILRETURN(A, B, F) --- C #define OPCODE1_TAILRETURN(A, B, F, C) OPCODE1_TAILRETURN(A, B, F) --- C #define OPCODE2_TAILRETURN(A, B, F, C) OPCODE2_TAILRETURN(A, B, F) --- C
8069c22002-11-02Henrik Grubbström (Grubba) #define OPCODE0_BRANCH(A, B, F, C) OPCODE0_BRANCH(A, B, F) --- C #define OPCODE1_BRANCH(A, B, F, C) OPCODE1_BRANCH(A, B, F) --- C #define OPCODE2_BRANCH(A, B, F, C) OPCODE2_BRANCH(A, B, F) --- C #define OPCODE0_TAILBRANCH(A, B, F, C) OPCODE0_TAILBRANCH(A, B, F) --- C #define OPCODE1_TAILBRANCH(A, B, F, C) OPCODE1_TAILBRANCH(A, B, F) --- C #define OPCODE2_TAILBRANCH(A, B, F, C) OPCODE2_TAILBRANCH(A, B, F) --- C
105be62002-11-10Henrik Grubbström (Grubba) #define OPCODE0_ALIAS(A, B, F, C) OPCODE0_ALIAS(A, B, F, C) --- FOO #define OPCODE1_ALIAS(A, B, F, C) OPCODE1_ALIAS(A, B, F, C) --- FOO #define OPCODE2_ALIAS(A, B, F, C) OPCODE2_ALIAS(A, B, F, C) --- FOO
610d052001-07-06Henrik Grubbström (Grubba) #endif /* GEN_PROTOS */
105be62002-11-10Henrik Grubbström (Grubba) #ifndef OPCODE0_ALIAS #define OPCODE0_ALIAS(A,B,C,D) OPCODE0(A,B,C,{D();}) #endif /* !OPCODE0_ALIAS */ #ifndef OPCODE1_ALIAS #define OPCODE1_ALIAS(A,B,C,D) OPCODE1(A,B,C,{D();}) #endif /* !OPCODE1_ALIAS */ #ifndef OPCODE2_ALIAS #define OPCODE2_ALIAS(A,B,C,D) OPCODE2(A,B,C,{D();}) #endif /* !OPCODE2_ALIAS */
7080882001-07-15Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm /*
7080882001-07-15Fredrik Hübinette (Hubbe) #ifndef PROG_COUNTER #define PROG_COUNTER pc #endif
2bcc0d2002-05-11Martin Stjernholm */
7080882001-07-15Fredrik Hübinette (Hubbe)  #ifndef INTER_ESCAPE_CATCH #define INTER_ESCAPE_CATCH return -2 #endif #ifndef INTER_RETURN #define INTER_RETURN return -1 #endif
8069c22002-11-02Henrik Grubbström (Grubba) /* BRANCH opcodes use these two to indicate whether the * branch should be taken or not. */ #ifndef DO_BRANCH #define DO_BRANCH DOJUMP #endif #ifndef DONT_BRANCH #define DONT_BRANCH SKIPJUMP #endif
f822262001-07-16Fredrik Hübinette (Hubbe) #ifndef OVERRIDE_JUMPS #undef GET_JUMP #undef SKIPJUMP #undef DOJUMP #ifdef PIKE_DEBUG
97ebb32003-01-09Henrik Grubbström (Grubba) #define GET_JUMP() (backlog[backlogp].arg=( \ (Pike_interpreter.trace_level>3 ? \ sprintf(trace_buffer, "- Target = %+ld\n", \ (long)LOW_GET_JUMP()), \ write_to_stderr(trace_buffer,strlen(trace_buffer)) : 0), \
f822262001-07-16Fredrik Hübinette (Hubbe)  LOW_GET_JUMP())) #define SKIPJUMP() (GET_JUMP(), LOW_SKIPJUMP()) #else /* !PIKE_DEBUG */
8f0eac2003-08-13Henrik Grubbström (Grubba) #define GET_JUMP() (/*write_to_stderr("GET_JUMP\n", 9),*/ LOW_GET_JUMP()) #define SKIPJUMP() (/*write_to_stderr("SKIPJUMP\n", 9),*/ LOW_SKIPJUMP())
f822262001-07-16Fredrik Hübinette (Hubbe)  #endif /* PIKE_DEBUG */ #define DOJUMP() do { \
f142842003-08-06Martin Stjernholm  PIKE_OPCODE_T *addr; \
f822262001-07-16Fredrik Hübinette (Hubbe)  INT32 tmp; \
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (addr); \
f822262001-07-16Fredrik Hübinette (Hubbe)  tmp = GET_JUMP(); \
f142842003-08-06Martin Stjernholm  SET_PROG_COUNTER(addr + tmp); \
f822262001-07-16Fredrik Hübinette (Hubbe)  FETCH; \ if(tmp < 0) \ fast_check_threads_etc(6); \ } while(0) #endif /* OVERRIDE_JUMPS */
7080882001-07-15Fredrik Hübinette (Hubbe)  /* WARNING: * The surgeon general has stated that define code blocks * without do{}while() can be hazardous to your health.
e87fe82001-07-26Henrik Grubbström (Grubba)  * However, in these cases it is required to handle break
7080882001-07-15Fredrik Hübinette (Hubbe)  * properly. -Hubbe */
e87fe82001-07-26Henrik Grubbström (Grubba) #undef DO_JUMP_TO #define DO_JUMP_TO(NEWPC) { \ SET_PROG_COUNTER(NEWPC); \ FETCH; \
f142842003-08-06Martin Stjernholm  JUMP_DONE; \
e87fe82001-07-26Henrik Grubbström (Grubba) }
7080882001-07-15Fredrik Hübinette (Hubbe) #undef DO_DUMB_RETURN #define DO_DUMB_RETURN { \ if(Pike_fp -> flags & PIKE_FRAME_RETURN_INTERNAL) \ { \ int f=Pike_fp->flags; \
b23b112001-08-15Fredrik Hübinette (Hubbe)  if(f & PIKE_FRAME_RETURN_POP) \ low_return_pop(); \ else \ low_return(); \ \
fcc65d2003-02-26Martin Stjernholm  DO_IF_DEBUG(if (Pike_interpreter.trace_level > 5) \
3a63472001-07-18Henrik Grubbström (Grubba)  fprintf(stderr, "Returning to 0x%p\n", \
025c0a2001-07-27Fredrik Hübinette (Hubbe)  Pike_fp->pc)); \
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(Pike_fp->pc); \
7080882001-07-15Fredrik Hübinette (Hubbe)  } \
fcc65d2003-02-26Martin Stjernholm  DO_IF_DEBUG(if (Pike_interpreter.trace_level > 5) \
025c0a2001-07-27Fredrik Hübinette (Hubbe)  fprintf(stderr, "Inter return\n")); \
7080882001-07-15Fredrik Hübinette (Hubbe)  INTER_RETURN; \ } #undef DO_RETURN #ifndef PIKE_DEBUG #define DO_RETURN DO_DUMB_RETURN #else #define DO_RETURN { \
51adb82003-01-12Martin Stjernholm  if(d_flag>3) do_gc(NULL, 0); \
7080882001-07-15Fredrik Hübinette (Hubbe)  if(d_flag>4) do_debug(); \ DO_DUMB_RETURN; \ } #endif
f142842003-08-06Martin Stjernholm #ifdef OPCODE_RETURN_JUMPADDR #define DO_JUMP_TO_NEXT do { \ PIKE_OPCODE_T *next_addr; \ JUMP_SET_TO_PC_AT_NEXT (next_addr); \ SET_PROG_COUNTER (next_addr); \ FETCH; \ JUMP_DONE; \ } while (0) #else /* !OPCODE_RETURN_JUMPADDR */ #define JUMP_SET_TO_PC_AT_NEXT(PC) ((PC) = PROG_COUNTER) #define DO_JUMP_TO_NEXT JUMP_DONE #endif /* !OPCODE_RETURN_JUMPADDR */
7080882001-07-15Fredrik Hübinette (Hubbe) #undef DO_INDEX #define DO_INDEX do { \ struct svalue s; \ index_no_free(&s,Pike_sp-2,Pike_sp-1); \
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems(); \
7080882001-07-15Fredrik Hübinette (Hubbe)  *Pike_sp=s; \ Pike_sp++; \
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1); \
7080882001-07-15Fredrik Hübinette (Hubbe)  print_return_value(); \ }while(0)
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_UNDEFINED, "push UNDEFINED", I_UPDATE_SP, {
87c7592000-04-18Fredrik Hübinette (Hubbe)  push_int(0); Pike_sp[-1].subtype=NUMBER_UNDEFINED;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_CONST0, "push 0", I_UPDATE_SP, {
87c7592000-04-18Fredrik Hübinette (Hubbe)  push_int(0);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_CONST1, "push 1", I_UPDATE_SP, {
87c7592000-04-18Fredrik Hübinette (Hubbe)  push_int(1);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
a828932001-08-31Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_MARK_AND_CONST0, "mark & 0", I_UPDATE_SP|I_UPDATE_M_SP, {
a828932001-08-31Fredrik Hübinette (Hubbe)  *(Pike_mark_sp++)=Pike_sp; push_int(0); });
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_MARK_AND_CONST1, "mark & 1", I_UPDATE_SP|I_UPDATE_M_SP, {
a828932001-08-31Fredrik Hübinette (Hubbe)  *(Pike_mark_sp++)=Pike_sp; push_int(1); });
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_CONST_1,"push -1", I_UPDATE_SP, {
87c7592000-04-18Fredrik Hübinette (Hubbe)  push_int(-1);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_BIGNUM, "push 0x7fffffff", I_UPDATE_SP, {
87c7592000-04-18Fredrik Hübinette (Hubbe)  push_int(0x7fffffff);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_NUMBER, "push int", I_UPDATE_SP, {
87c7592000-04-18Fredrik Hübinette (Hubbe)  push_int(arg1);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
35afc12003-01-26Mirar (Pontus Hagland) /* always need to declare this opcode to make working dists */
648a8c2003-01-26Mirar (Pontus Hagland) #if SIZEOF_INT_TYPE > 4
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_NUMBER64, "push 64-bit int", I_UPDATE_SP, {
cf84382003-01-26Mirar (Pontus Hagland)  push_int( (INT_TYPE) (( ((unsigned INT_TYPE)arg1) << 32) | ((unsigned INT32)arg2)) );
648a8c2003-01-26Mirar (Pontus Hagland) });
35afc12003-01-26Mirar (Pontus Hagland) #else
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_NUMBER64, "push 64-bit int", I_UPDATE_SP, {
35afc12003-01-26Mirar (Pontus Hagland)  Pike_error("F_NUMBER64: this opcode should never be used in your system\n"); });
648a8c2003-01-26Mirar (Pontus Hagland) #endif
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_NEG_NUMBER, "push -int", I_UPDATE_SP, {
87c7592000-04-18Fredrik Hübinette (Hubbe)  push_int(-arg1);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_CONSTANT, "constant", I_UPDATE_SP, {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(& Pike_fp->context.prog->constants[arg1].sval);
87c7592000-04-18Fredrik Hübinette (Hubbe)  print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
005bf42001-09-29Fredrik Hübinette (Hubbe)  /* Generic swap instruction: * swaps the arg1 top values with the arg2 values beneath */
2bcc0d2002-05-11Martin Stjernholm OPCODE2(F_REARRANGE,"rearrange",0,{
005bf42001-09-29Fredrik Hübinette (Hubbe)  check_stack(arg2); MEMCPY(Pike_sp,Pike_sp-arg1-arg2,sizeof(struct svalue)*arg2); MEMMOVE(Pike_sp-arg1-arg2,Pike_sp-arg1,sizeof(struct svalue)*arg1); MEMCPY(Pike_sp-arg2,Pike_sp,sizeof(struct svalue)*arg2);
8bef1b2001-09-27Fredrik Hübinette (Hubbe) });
87c7592000-04-18Fredrik Hübinette (Hubbe) /* The rest of the basic 'push value' instructions */
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1_TAIL(F_MARK_AND_STRING, "mark & string", I_UPDATE_SP|I_UPDATE_M_SP, {
87c7592000-04-18Fredrik Hübinette (Hubbe)  *(Pike_mark_sp++)=Pike_sp;
8f0eac2003-08-13Henrik Grubbström (Grubba)  OPCODE1(F_STRING, "string", I_UPDATE_SP, {
610d052001-07-06Henrik Grubbström (Grubba)  copy_shared_string(Pike_sp->u.string,Pike_fp->context.prog->strings[arg1]); Pike_sp->type=PIKE_T_STRING; Pike_sp->subtype=0; Pike_sp++; print_return_value(); }); });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_ARROW_STRING, "->string", I_UPDATE_SP, {
87c7592000-04-18Fredrik Hübinette (Hubbe)  copy_shared_string(Pike_sp->u.string,Pike_fp->context.prog->strings[arg1]); Pike_sp->type=PIKE_T_STRING; Pike_sp->subtype=1; /* Magic */ Pike_sp++; print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_LOOKUP_LFUN, "->lfun", 0, {
286afb2001-02-05Henrik Grubbström (Grubba)  struct svalue tmp; struct object *o;
a5cd6a2001-09-24Henrik Grubbström (Grubba) 
9b150a2002-05-11Martin Nilsson  if ((Pike_sp[-1].type == T_OBJECT) && ((o = Pike_sp[-1].u.object)->prog) &&
286afb2001-02-05Henrik Grubbström (Grubba)  (FIND_LFUN(o->prog, LFUN_ARROW) == -1)) { int id = FIND_LFUN(o->prog, arg1); if ((id != -1) && (!(o->prog->identifier_references[id].id_flags & (ID_STATIC|ID_PRIVATE|ID_HIDDEN)))) { low_object_index_no_free(&tmp, o, id); } else { /* Not found. */ tmp.type = T_INT; tmp.subtype = 1; tmp.u.integer = 0; } } else { struct svalue tmp2; tmp2.type = PIKE_T_STRING; tmp2.u.string = lfun_strings[arg1]; tmp2.subtype = 1; index_no_free(&tmp, Pike_sp-1, &tmp2); } free_svalue(Pike_sp-1); Pike_sp[-1] = tmp; print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
286afb2001-02-05Henrik Grubbström (Grubba) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_JUMP(F_FLOAT, "push float", I_UPDATE_SP, {
7080882001-07-15Fredrik Hübinette (Hubbe)  /* FIXME, this opcode uses 'PROG_COUNTER' which is not allowed.. */
f142842003-08-06Martin Stjernholm  PIKE_OPCODE_T *next_addr; JUMP_SET_TO_PC_AT_NEXT (next_addr); MEMCPY((void *)&Pike_sp->u.float_number, next_addr, sizeof(FLOAT_TYPE));
0996a92001-07-17Henrik Grubbström (Grubba)  Pike_sp->type=PIKE_T_FLOAT;
87c7592000-04-18Fredrik Hübinette (Hubbe)  Pike_sp++;
f142842003-08-06Martin Stjernholm  DO_JUMP_TO((PIKE_OPCODE_T *)(((FLOAT_TYPE *) next_addr) + 1));
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_LFUN, "local function", I_UPDATE_SP, {
c07fe52003-01-16Martin Stjernholm  ref_push_function (Pike_fp->current_object, arg1+Pike_fp->context.identifier_level);
87c7592000-04-18Fredrik Hübinette (Hubbe)  print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_TRAMPOLINE, "trampoline", I_UPDATE_SP, {
87c7592000-04-18Fredrik Hübinette (Hubbe)  struct object *o=low_clone(pike_trampoline_program);
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  struct pike_frame *f=Pike_fp;
5cdf732002-05-15Henrik Grubbström (Grubba)  DO_IF_DEBUG(INT32 arg2_ = arg2); while(arg2--) { DO_IF_DEBUG({ if (!f->scope) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("F_TRAMPOLINE %d, %d: Missing %d levels of scope!\n",
5cdf732002-05-15Henrik Grubbström (Grubba)  arg1, arg2_, arg2+1); } }); f=f->scope; }
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  add_ref( ((struct pike_trampoline *)(o->storage))->frame=f );
87c7592000-04-18Fredrik Hübinette (Hubbe)  ((struct pike_trampoline *)(o->storage))->func=arg1+Pike_fp->context.identifier_level;
c07fe52003-01-16Martin Stjernholm  push_function(o, pike_trampoline_program->lfuns[LFUN_CALL]);
87c7592000-04-18Fredrik Hübinette (Hubbe)  print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe)  /* The not so basic 'push value' instructions */
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1_TAIL(F_MARK_AND_GLOBAL, "mark & global", I_UPDATE_SP|I_UPDATE_M_SP, {
0811472001-07-02Fredrik Hübinette (Hubbe)  *(Pike_mark_sp++)=Pike_sp;
8f0eac2003-08-13Henrik Grubbström (Grubba)  OPCODE1(F_GLOBAL, "global", I_UPDATE_SP, {
610d052001-07-06Henrik Grubbström (Grubba)  low_object_index_no_free(Pike_sp, Pike_fp->current_object, arg1 + Pike_fp->context.identifier_level); Pike_sp++; print_return_value(); }); });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2_TAIL(F_MARK_AND_EXTERNAL, "mark & external", I_UPDATE_SP|I_UPDATE_M_SP, {
32315c2001-06-29Fredrik Hübinette (Hubbe)  *(Pike_mark_sp++)=Pike_sp;
8f0eac2003-08-13Henrik Grubbström (Grubba)  OPCODE2(F_EXTERNAL,"external", I_UPDATE_SP, {
610d052001-07-06Henrik Grubbström (Grubba)  struct external_variable_context loc;
342fef2000-08-23Fredrik Hübinette (Hubbe) 
610d052001-07-06Henrik Grubbström (Grubba)  loc.o=Pike_fp->current_object; loc.parent_identifier=Pike_fp->fun;
28553d2003-08-03Martin Stjernholm  if (loc.o->prog) loc.inherit=INHERIT_FROM_INT(loc.o->prog, loc.parent_identifier);
610d052001-07-06Henrik Grubbström (Grubba)  find_external_context(&loc, arg2);
342fef2000-08-23Fredrik Hübinette (Hubbe) 
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_DEBUG({ TRACE((5,"- Identifier=%d Offset=%d\n", arg1, loc.inherit->identifier_level)); });
342fef2000-08-23Fredrik Hübinette (Hubbe) 
28553d2003-08-03Martin Stjernholm  if (arg1 == IDREF_MAGIC_THIS) /* Special treatment to allow doing Foo::this on destructed * parent objects. */ ref_push_object (loc.o); else { low_object_index_no_free(Pike_sp, loc.o, arg1 + loc.inherit->identifier_level); Pike_sp++; }
610d052001-07-06Henrik Grubbström (Grubba)  print_return_value(); }); });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
32315c2001-06-29Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_EXTERNAL_LVALUE, "& external", I_UPDATE_SP, {
342fef2000-08-23Fredrik Hübinette (Hubbe)  struct external_variable_context loc; loc.o=Pike_fp->current_object; loc.parent_identifier=Pike_fp->fun;
28553d2003-08-03Martin Stjernholm  if (loc.o->prog) loc.inherit=INHERIT_FROM_INT(loc.o->prog, loc.parent_identifier);
342fef2000-08-23Fredrik Hübinette (Hubbe)  find_external_context(&loc, arg2);
28553d2003-08-03Martin Stjernholm  if (!loc.o->prog) Pike_error ("Cannot access variable in destructed parent object.\n");
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_DEBUG({ TRACE((5,"- Identifier=%d Offset=%d\n", arg1, loc.inherit->identifier_level)); });
342fef2000-08-23Fredrik Hübinette (Hubbe)  ref_push_object(loc.o);
a903032003-02-16Martin Stjernholm  Pike_sp->type=T_OBJ_INDEX;
342fef2000-08-23Fredrik Hübinette (Hubbe)  Pike_sp->u.integer=arg1 + loc.inherit->identifier_level;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  Pike_sp++;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_MARK_AND_LOCAL, "mark & local", I_UPDATE_SP|I_UPDATE_M_SP, {
f853ac2000-04-20Henrik Grubbström (Grubba)  *(Pike_mark_sp++) = Pike_sp;
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue( Pike_fp->locals + arg1);
f853ac2000-04-20Henrik Grubbström (Grubba)  print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_LOCAL, "local", I_UPDATE_SP, {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue( Pike_fp->locals + arg1);
f853ac2000-04-20Henrik Grubbström (Grubba)  print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_2_LOCALS, "2 locals", I_UPDATE_SP, {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue( Pike_fp->locals + arg1);
f102d22000-04-19Henrik Grubbström (Grubba)  print_return_value();
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue( Pike_fp->locals + arg2);
f102d22000-04-19Henrik Grubbström (Grubba)  print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE2(F_LOCAL_2_LOCAL, "local = local", 0, {
1986622000-04-20Henrik Grubbström (Grubba)  assign_svalue(Pike_fp->locals + arg1, Pike_fp->locals + arg2);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE2(F_LOCAL_2_GLOBAL, "global = local", 0, {
5571462003-02-15Henrik Grubbström (Grubba)  object_low_set_index(Pike_fp->current_object, arg1 + Pike_fp->context.identifier_level, Pike_fp->locals + arg2);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE2(F_GLOBAL_2_LOCAL, "local = global", 0, {
1986622000-04-20Henrik Grubbström (Grubba)  INT32 tmp = arg1 + Pike_fp->context.identifier_level;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  free_svalue(Pike_fp->locals + arg2); low_object_index_no_free(Pike_fp->locals + arg2,
f102d22000-04-19Henrik Grubbström (Grubba)  Pike_fp->current_object, tmp);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_LOCAL_LVALUE, "& local", I_UPDATE_SP, {
a903032003-02-16Martin Stjernholm  Pike_sp[0].type = T_SVALUE_PTR;
f102d22000-04-19Henrik Grubbström (Grubba)  Pike_sp[0].u.lval = Pike_fp->locals + arg1; Pike_sp[1].type = T_VOID; Pike_sp += 2;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_LEXICAL_LOCAL, "lexical local", I_UPDATE_SP, {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  struct pike_frame *f=Pike_fp; while(arg2--)
f102d22000-04-19Henrik Grubbström (Grubba)  { f=f->scope;
a4a1722000-12-05Per Hedbor  if(!f) Pike_error("Lexical scope error.\n");
f102d22000-04-19Henrik Grubbström (Grubba)  } push_svalue(f->locals + arg1); print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_LEXICAL_LOCAL_LVALUE, "&lexical local", I_UPDATE_SP, {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  struct pike_frame *f=Pike_fp; while(arg2--)
f102d22000-04-19Henrik Grubbström (Grubba)  {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  f=f->scope;
a4a1722000-12-05Per Hedbor  if(!f) Pike_error("Lexical scope error.\n");
f102d22000-04-19Henrik Grubbström (Grubba)  }
a903032003-02-16Martin Stjernholm  Pike_sp[0].type=T_SVALUE_PTR;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  Pike_sp[0].u.lval=f->locals+arg1; Pike_sp[1].type=T_VOID; Pike_sp+=2;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_ARRAY_LVALUE, "[ lvalues ]", I_UPDATE_SP, {
f102d22000-04-19Henrik Grubbström (Grubba)  f_aggregate(arg1*2); Pike_sp[-1].u.array->flags |= ARRAY_LVALUE; Pike_sp[-1].u.array->type_field |= BIT_UNFINISHED | BIT_MIXED; /* FIXME: Shouldn't a ref be added here? */ Pike_sp[0] = Pike_sp[-1]; Pike_sp[-1].type = T_ARRAY_LVALUE;
2026c22000-04-20Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp);
f102d22000-04-19Henrik Grubbström (Grubba)  Pike_sp++;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_CLEAR_2_LOCAL, "clear 2 local", 0, {
b23b112001-08-15Fredrik Hübinette (Hubbe)  free_mixed_svalues(Pike_fp->locals + arg1, 2);
7951942000-04-20Fredrik Hübinette (Hubbe)  Pike_fp->locals[arg1].type = PIKE_T_INT; Pike_fp->locals[arg1].subtype = 0; Pike_fp->locals[arg1].u.integer = 0; Pike_fp->locals[arg1+1].type = PIKE_T_INT; Pike_fp->locals[arg1+1].subtype = 0; Pike_fp->locals[arg1+1].u.integer = 0;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_CLEAR_4_LOCAL, "clear 4 local", 0, {
f102d22000-04-19Henrik Grubbström (Grubba)  int e;
b23b112001-08-15Fredrik Hübinette (Hubbe)  free_mixed_svalues(Pike_fp->locals + arg1, 4);
f102d22000-04-19Henrik Grubbström (Grubba)  for(e = 0; e < 4; e++) {
7951942000-04-20Fredrik Hübinette (Hubbe)  Pike_fp->locals[arg1+e].type = PIKE_T_INT; Pike_fp->locals[arg1+e].subtype = 0; Pike_fp->locals[arg1+e].u.integer = 0;
f102d22000-04-19Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_CLEAR_LOCAL, "clear local", 0, {
7951942000-04-20Fredrik Hübinette (Hubbe)  free_svalue(Pike_fp->locals + arg1); Pike_fp->locals[arg1].type = PIKE_T_INT; Pike_fp->locals[arg1].subtype = 0; Pike_fp->locals[arg1].u.integer = 0;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_INC_LOCAL, "++local", I_UPDATE_SP, {
7951942000-04-20Fredrik Hübinette (Hubbe)  if( (Pike_fp->locals[arg1].type == PIKE_T_INT)
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
7951942000-04-20Fredrik Hübinette (Hubbe)  && (!INT_TYPE_ADD_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
610d052001-07-06Henrik Grubbström (Grubba)  )
f102d22000-04-19Henrik Grubbström (Grubba)  ) {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_int(++(Pike_fp->locals[arg1].u.integer));
f102d22000-04-19Henrik Grubbström (Grubba)  } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(Pike_fp->locals+arg1);
f102d22000-04-19Henrik Grubbström (Grubba)  push_int(1); f_add(2);
7951942000-04-20Fredrik Hübinette (Hubbe)  assign_svalue(Pike_fp->locals+arg1,Pike_sp-1);
f102d22000-04-19Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_POST_INC_LOCAL, "local++", I_UPDATE_SP, {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue( Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  if( (Pike_fp->locals[arg1].type == PIKE_T_INT)
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
cc75b62000-04-21Henrik Grubbström (Grubba)  && (!INT_TYPE_ADD_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
610d052001-07-06Henrik Grubbström (Grubba)  )
cc75b62000-04-21Henrik Grubbström (Grubba)  ) { Pike_fp->locals[arg1].u.integer++; } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  push_int(1); f_add(2);
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_pop_to(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_INC_LOCAL_AND_POP, "++local and pop", 0, {
cc75b62000-04-21Henrik Grubbström (Grubba)  if( (Pike_fp->locals[arg1].type == PIKE_T_INT)
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
cc75b62000-04-21Henrik Grubbström (Grubba)  && (!INT_TYPE_ADD_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
610d052001-07-06Henrik Grubbström (Grubba)  )
cc75b62000-04-21Henrik Grubbström (Grubba)  ) { Pike_fp->locals[arg1].u.integer++; } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue( Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  push_int(1); f_add(2);
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_pop_to(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_DEC_LOCAL, "--local", I_UPDATE_SP, {
7951942000-04-20Fredrik Hübinette (Hubbe)  if( (Pike_fp->locals[arg1].type == PIKE_T_INT)
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
7951942000-04-20Fredrik Hübinette (Hubbe)  && (!INT_TYPE_SUB_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
610d052001-07-06Henrik Grubbström (Grubba)  )
f102d22000-04-19Henrik Grubbström (Grubba)  ) {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_int(--(Pike_fp->locals[arg1].u.integer));
f102d22000-04-19Henrik Grubbström (Grubba)  } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(Pike_fp->locals+arg1);
f102d22000-04-19Henrik Grubbström (Grubba)  push_int(1); o_subtract();
7951942000-04-20Fredrik Hübinette (Hubbe)  assign_svalue(Pike_fp->locals+arg1,Pike_sp-1);
f102d22000-04-19Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_POST_DEC_LOCAL, "local--", I_UPDATE_SP, {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue( Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  if( (Pike_fp->locals[arg1].type == PIKE_T_INT)
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
cc75b62000-04-21Henrik Grubbström (Grubba)  && (!INT_TYPE_SUB_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
610d052001-07-06Henrik Grubbström (Grubba)  )
cc75b62000-04-21Henrik Grubbström (Grubba)  ) { Pike_fp->locals[arg1].u.integer--; } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  push_int(1); o_subtract();
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_pop_to(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  } /* Pike_fp->locals[instr].u.integer--; */
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_DEC_LOCAL_AND_POP, "--local and pop", 0, {
cc75b62000-04-21Henrik Grubbström (Grubba)  if( (Pike_fp->locals[arg1].type == PIKE_T_INT)
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
cc75b62000-04-21Henrik Grubbström (Grubba)  && (!INT_TYPE_SUB_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
610d052001-07-06Henrik Grubbström (Grubba)  )
cc75b62000-04-21Henrik Grubbström (Grubba)  ) { Pike_fp->locals[arg1].u.integer--; } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  push_int(1); o_subtract();
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_pop_to(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_LTOSVAL, "lvalue to svalue", I_UPDATE_SP, {
29cf5b2001-06-28Fredrik Hübinette (Hubbe)  dmalloc_touch_svalue(Pike_sp-2); dmalloc_touch_svalue(Pike_sp-1);
f102d22000-04-19Henrik Grubbström (Grubba)  lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++;
005bf42001-09-29Fredrik Hübinette (Hubbe)  print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_LTOSVAL2, "ltosval2", I_UPDATE_SP, {
29cf5b2001-06-28Fredrik Hübinette (Hubbe)  dmalloc_touch_svalue(Pike_sp-3); dmalloc_touch_svalue(Pike_sp-2); dmalloc_touch_svalue(Pike_sp-1);
f102d22000-04-19Henrik Grubbström (Grubba)  Pike_sp[0] = Pike_sp[-1]; Pike_sp[-1].type = PIKE_T_INT; Pike_sp++; lvalue_to_svalue_no_free(Pike_sp-2, Pike_sp-4); /* this is so that foo+=bar (and similar things) will be faster, this * is done by freeing the old reference to foo after it has been pushed * on the stack. That way foo can have only 1 reference if we are lucky, * and then the low array/multiset/mapping manipulation routines can be * destructive if they like */ if( (1 << Pike_sp[-2].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) { struct svalue s; s.type = PIKE_T_INT; s.subtype = 0; s.u.integer = 0; assign_lvalue(Pike_sp-4, &s); }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_LTOSVAL3, "ltosval3", I_UPDATE_SP, {
b99ff82001-06-07Fredrik Hübinette (Hubbe)  Pike_sp[0] = Pike_sp[-1]; Pike_sp[-1] = Pike_sp[-2]; Pike_sp[-2].type = PIKE_T_INT; Pike_sp++; lvalue_to_svalue_no_free(Pike_sp-3, Pike_sp-5);
15a84d2001-06-07Fredrik Hübinette (Hubbe)  /* this is so that foo=foo[x..y] (and similar things) will be faster, this
b99ff82001-06-07Fredrik Hübinette (Hubbe)  * is done by freeing the old reference to foo after it has been pushed * on the stack. That way foo can have only 1 reference if we are lucky, * and then the low array/multiset/mapping manipulation routines can be * destructive if they like */ if( (1 << Pike_sp[-3].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) { struct svalue s; s.type = PIKE_T_INT; s.subtype = 0; s.u.integer = 0; assign_lvalue(Pike_sp-5, &s); }
610d052001-07-06Henrik Grubbström (Grubba) });
b99ff82001-06-07Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_ADD_TO, "+=", I_UPDATE_SP, {
d2154e2003-04-07Henrik Grubbström (Grubba)  Pike_sp[0]=Pike_sp[-1]; Pike_sp[-1].type=PIKE_T_INT; Pike_sp++; lvalue_to_svalue_no_free(Pike_sp-2,Pike_sp-4); if( Pike_sp[-1].type == PIKE_T_INT && Pike_sp[-2].type == PIKE_T_INT ) { DO_IF_BIGNUM( if(!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, Pike_sp[-2].u.integer)) ) { /* Optimization for a rather common case. Makes it 30% faster. */ INT_TYPE val = (Pike_sp[-1].u.integer += Pike_sp[-2].u.integer); assign_lvalue(Pike_sp-4,Pike_sp-1); Pike_sp-=2; pop_2_elems(); push_int(val); goto add_to_done; } } /* this is so that foo+=bar (and similar things) will be faster, this * is done by freeing the old reference to foo after it has been pushed * on the stack. That way foo can have only 1 reference if we are lucky, * and then the low array/multiset/mapping manipulation routines can be * destructive if they like */ if( (1 << Pike_sp[-2].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) { struct svalue s; s.type=PIKE_T_INT; s.subtype=0; s.u.integer=0; assign_lvalue(Pike_sp-4,&s); } else if (Pike_sp[-2].type == T_OBJECT) { /* One ref in the lvalue, and one on the stack. */ if(Pike_sp[-2].u.object->refs <= 2 && FIND_LFUN(Pike_sp[-2].u.object->prog, LFUN_ADD_EQ) != -1) { apply_lfun(Pike_sp[-2].u.object, LFUN_ADD_EQ, 1);
7ae3422003-04-08Henrik Grubbström (Grubba)  /* NB: The lvalue already contains the object, so * no need to reassign it. */ pop_stack();
0d0bab2003-04-27Martin Stjernholm  stack_pop_2_elems_keep_top();
7ae3422003-04-08Henrik Grubbström (Grubba)  goto add_to_done;
d2154e2003-04-07Henrik Grubbström (Grubba)  } } f_add(2); assign_lvalue(Pike_sp-3,Pike_sp-1);
0d0bab2003-04-27Martin Stjernholm  stack_pop_2_elems_keep_top();
d2154e2003-04-07Henrik Grubbström (Grubba)  add_to_done: ; /* make gcc happy */ });
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_ADD_TO_AND_POP, "+= and pop", I_UPDATE_SP, {
f102d22000-04-19Henrik Grubbström (Grubba)  Pike_sp[0]=Pike_sp[-1]; Pike_sp[-1].type=PIKE_T_INT; Pike_sp++; lvalue_to_svalue_no_free(Pike_sp-2,Pike_sp-4);
b1d0682001-06-16Per Hedbor  if( Pike_sp[-1].type == PIKE_T_INT && Pike_sp[-2].type == PIKE_T_INT ) {
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
b1d0682001-06-16Per Hedbor  if(!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, Pike_sp[-2].u.integer))
610d052001-07-06Henrik Grubbström (Grubba)  )
b1d0682001-06-16Per Hedbor  { /* Optimization for a rather common case. Makes it 30% faster. */ Pike_sp[-1].u.integer += Pike_sp[-2].u.integer; assign_lvalue(Pike_sp-4,Pike_sp-1);
29cf5b2001-06-28Fredrik Hübinette (Hubbe)  Pike_sp-=2;
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
d2154e2003-04-07Henrik Grubbström (Grubba)  goto add_to_and_pop_done;
b1d0682001-06-16Per Hedbor  } }
f102d22000-04-19Henrik Grubbström (Grubba)  /* this is so that foo+=bar (and similar things) will be faster, this * is done by freeing the old reference to foo after it has been pushed * on the stack. That way foo can have only 1 reference if we are lucky, * and then the low array/multiset/mapping manipulation routines can be * destructive if they like */ if( (1 << Pike_sp[-2].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) { struct svalue s; s.type=PIKE_T_INT; s.subtype=0; s.u.integer=0; assign_lvalue(Pike_sp-4,&s);
7ae3422003-04-08Henrik Grubbström (Grubba)  } else if (Pike_sp[-2].type == PIKE_T_OBJECT) {
6af7592003-04-07Henrik Grubbström (Grubba)  /* One ref in the lvalue, and one on the stack. */ if(Pike_sp[-2].u.object->refs <= 2 && FIND_LFUN(Pike_sp[-2].u.object->prog, LFUN_ADD_EQ) != -1) { apply_lfun(Pike_sp[-2].u.object, LFUN_ADD_EQ, 1);
7ae3422003-04-08Henrik Grubbström (Grubba)  /* NB: The lvalue already contains the object, so * no need to reassign it. */ pop_n_elems(4); goto add_to_and_pop_done;
6af7592003-04-07Henrik Grubbström (Grubba)  }
f102d22000-04-19Henrik Grubbström (Grubba)  } f_add(2); assign_lvalue(Pike_sp-3,Pike_sp-1); pop_n_elems(3);
d2154e2003-04-07Henrik Grubbström (Grubba)  add_to_and_pop_done:
b1d0682001-06-16Per Hedbor  ; /* make gcc happy */
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_GLOBAL_LVALUE, "& global", I_UPDATE_SP, {
f7f14e2003-02-15Henrik Grubbström (Grubba)  ref_push_object(Pike_fp->current_object); push_int(arg1 + Pike_fp->context.identifier_level);
a903032003-02-16Martin Stjernholm  Pike_sp[-1].type = T_OBJ_INDEX;
610d052001-07-06Henrik Grubbström (Grubba) });
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_INC, "++x", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_ADD_OVERFLOW(u->integer, 1)
610d052001-07-06Henrik Grubbström (Grubba)  )
bac71b2000-04-19Henrik Grubbström (Grubba)  ) {
5298da2003-01-26Mirar (Pontus Hagland)  INT_TYPE val = ++u->integer;
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
eff6212001-07-09Henrik Grubbström (Grubba)  push_int(val);
bac71b2000-04-19Henrik Grubbström (Grubba)  } else { lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++; push_int(1); f_add(2); assign_lvalue(Pike_sp-3, Pike_sp-1);
0d0bab2003-04-27Martin Stjernholm  stack_pop_2_elems_keep_top();
bac71b2000-04-19Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_DEC, "--x", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_SUB_OVERFLOW(u->integer, 1)
610d052001-07-06Henrik Grubbström (Grubba)  )
bac71b2000-04-19Henrik Grubbström (Grubba)  ) {
5298da2003-01-26Mirar (Pontus Hagland)  INT_TYPE val = --u->integer;
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
eff6212001-07-09Henrik Grubbström (Grubba)  push_int(val);
bac71b2000-04-19Henrik Grubbström (Grubba)  } else { lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++; push_int(1); o_subtract(); assign_lvalue(Pike_sp-3, Pike_sp-1);
0d0bab2003-04-27Martin Stjernholm  stack_pop_2_elems_keep_top();
bac71b2000-04-19Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_DEC_AND_POP, "x-- and pop", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_SUB_OVERFLOW(u->integer, 1)
610d052001-07-06Henrik Grubbström (Grubba)  )
87c7592000-04-18Fredrik Hübinette (Hubbe) )
bac71b2000-04-19Henrik Grubbström (Grubba)  {
eff6212001-07-09Henrik Grubbström (Grubba)  --u->integer;
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
bac71b2000-04-19Henrik Grubbström (Grubba)  }else{ lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++; push_int(1); o_subtract(); assign_lvalue(Pike_sp-3, Pike_sp-1); pop_n_elems(3); }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_INC_AND_POP, "x++ and pop", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_ADD_OVERFLOW(u->integer, 1)
610d052001-07-06Henrik Grubbström (Grubba)  )
bac71b2000-04-19Henrik Grubbström (Grubba)  ) {
eff6212001-07-09Henrik Grubbström (Grubba)  ++u->integer;
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
bac71b2000-04-19Henrik Grubbström (Grubba)  } else { lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++; push_int(1); f_add(2); assign_lvalue(Pike_sp-3, Pike_sp-1); pop_n_elems(3); }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_POST_INC, "x++", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_ADD_OVERFLOW(u->integer, 1)
610d052001-07-06Henrik Grubbström (Grubba)  )
bac71b2000-04-19Henrik Grubbström (Grubba)  ) {
5298da2003-01-26Mirar (Pontus Hagland)  INT_TYPE val = u->integer++;
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
eff6212001-07-09Henrik Grubbström (Grubba)  push_int(val);
bac71b2000-04-19Henrik Grubbström (Grubba)  } else { lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++;
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_dup();
bac71b2000-04-19Henrik Grubbström (Grubba)  push_int(1); f_add(2); assign_lvalue(Pike_sp-4, Pike_sp-1);
ee68462001-03-08Fredrik Hübinette (Hubbe)  pop_stack();
0d0bab2003-04-27Martin Stjernholm  stack_pop_2_elems_keep_top();
ee68462001-03-08Fredrik Hübinette (Hubbe)  print_return_value();
bac71b2000-04-19Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_POST_DEC, "x--", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_SUB_OVERFLOW(u->integer, 1)
610d052001-07-06Henrik Grubbström (Grubba)  )
bac71b2000-04-19Henrik Grubbström (Grubba)  ) {
5298da2003-01-26Mirar (Pontus Hagland)  INT_TYPE val = u->integer--;
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
eff6212001-07-09Henrik Grubbström (Grubba)  push_int(val);
bac71b2000-04-19Henrik Grubbström (Grubba)  } else { lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++;
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_dup();
bac71b2000-04-19Henrik Grubbström (Grubba)  push_int(1); o_subtract(); assign_lvalue(Pike_sp-4, Pike_sp-1);
ee68462001-03-08Fredrik Hübinette (Hubbe)  pop_stack();
0d0bab2003-04-27Martin Stjernholm  stack_pop_2_elems_keep_top();
ee68462001-03-08Fredrik Hübinette (Hubbe)  print_return_value();
bac71b2000-04-19Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_ASSIGN_LOCAL, "assign local", 0, {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  assign_svalue(Pike_fp->locals+arg1,Pike_sp-1);
610d052001-07-06Henrik Grubbström (Grubba) });
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_ASSIGN, "assign", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  assign_lvalue(Pike_sp-3,Pike_sp-1); free_svalue(Pike_sp-3); free_svalue(Pike_sp-2); Pike_sp[-3]=Pike_sp[-1];
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1); dmalloc_touch_svalue(Pike_sp-2);
bac71b2000-04-19Henrik Grubbström (Grubba)  Pike_sp-=2;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_APPLY_ASSIGN_LOCAL_AND_POP, "apply, assign local and pop", I_UPDATE_SP|I_UPDATE_M_SP, {
24c37f2001-05-24Fredrik Hübinette (Hubbe)  apply_svalue(&((Pike_fp->context.prog->constants + arg1)->sval),
e428262001-06-10Henrik Grubbström (Grubba)  DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)));
a96ce92000-04-19Fredrik Hübinette (Hubbe)  free_svalue(Pike_fp->locals+arg2); Pike_fp->locals[arg2]=Pike_sp[-1];
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  Pike_sp--;
610d052001-07-06Henrik Grubbström (Grubba) });
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE2(F_APPLY_ASSIGN_LOCAL, "apply, assign local", I_UPDATE_ALL, {
24c37f2001-05-24Fredrik Hübinette (Hubbe)  apply_svalue(&((Pike_fp->context.prog->constants + arg1)->sval),
e428262001-06-10Henrik Grubbström (Grubba)  DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)));
d0ad0a2000-08-08Henrik Grubbström (Grubba)  assign_svalue(Pike_fp->locals+arg2, Pike_sp-1);
610d052001-07-06Henrik Grubbström (Grubba) });
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_ASSIGN_AND_POP, "assign and pop", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  assign_lvalue(Pike_sp-3, Pike_sp-1); pop_n_elems(3);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_ASSIGN_LOCAL_AND_POP, "assign local and pop", I_UPDATE_SP, {
f853ac2000-04-20Henrik Grubbström (Grubba)  free_svalue(Pike_fp->locals + arg1); Pike_fp->locals[arg1] = Pike_sp[-1];
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
f853ac2000-04-20Henrik Grubbström (Grubba)  Pike_sp--;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_ASSIGN_GLOBAL, "assign global", 0, {
eaf1172003-02-15Henrik Grubbström (Grubba)  object_low_set_index(Pike_fp->current_object, arg1 + Pike_fp->context.identifier_level, Pike_sp-1);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_ASSIGN_GLOBAL_AND_POP, "assign global and pop", I_UPDATE_SP, {
e352f82003-02-15Henrik Grubbström (Grubba)  object_low_set_index(Pike_fp->current_object, arg1 + Pike_fp->context.identifier_level, Pike_sp-1); pop_stack();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) /* Stack machine stuff */
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_POP_VALUE, "pop", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  pop_stack();
610d052001-07-06Henrik Grubbström (Grubba) });
bac71b2000-04-19Henrik Grubbström (Grubba) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_POP_N_ELEMS, "pop_n_elems", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  pop_n_elems(arg1);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_TAIL(F_MARK2, "mark mark", I_UPDATE_M_SP, {
7951942000-04-20Fredrik Hübinette (Hubbe)  *(Pike_mark_sp++)=Pike_sp;
90703d2001-01-31Martin Stjernholm  /* This opcode is only used when running with -d. Identical to F_MARK, * but with a different name to make the debug printouts more clear. */
8f0eac2003-08-13Henrik Grubbström (Grubba)  OPCODE0_TAIL(F_SYNCH_MARK, "synch mark", I_UPDATE_M_SP, {
90703d2001-01-31Martin Stjernholm 
8f0eac2003-08-13Henrik Grubbström (Grubba)  OPCODE0(F_MARK, "mark", I_UPDATE_M_SP, {
610d052001-07-06Henrik Grubbström (Grubba)  *(Pike_mark_sp++)=Pike_sp; }); }); });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_MARK_X, "mark Pike_sp-X", I_UPDATE_M_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  *(Pike_mark_sp++)=Pike_sp-arg1;
610d052001-07-06Henrik Grubbström (Grubba) });
bac71b2000-04-19Henrik Grubbström (Grubba) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_POP_MARK, "pop mark", I_UPDATE_M_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  --Pike_mark_sp;
610d052001-07-06Henrik Grubbström (Grubba) });
bac71b2000-04-19Henrik Grubbström (Grubba) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_POP_TO_MARK, "pop to mark", I_UPDATE_SP|I_UPDATE_M_SP, {
7babb52001-01-15Martin Stjernholm  pop_n_elems(Pike_sp - *--Pike_mark_sp);
610d052001-07-06Henrik Grubbström (Grubba) });
7babb52001-01-15Martin Stjernholm 
90703d2001-01-31Martin Stjernholm /* These opcodes are only used when running with -d. The reason for * the two aliases is mainly to keep the indentation in asm debug * output. */
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_TAIL(F_CLEANUP_SYNCH_MARK, "cleanup synch mark", I_UPDATE_SP|I_UPDATE_M_SP, { OPCODE0(F_POP_SYNCH_MARK, "pop synch mark", I_UPDATE_SP|I_UPDATE_M_SP, {
ecbfc82001-07-18Henrik Grubbström (Grubba)  if (d_flag) { if (Pike_mark_sp <= Pike_interpreter.mark_stack) {
d2361e2003-06-30Martin Stjernholm  Pike_fatal("Mark stack out of synch - %p <= %p.\n", Pike_mark_sp, Pike_interpreter.mark_stack);
ecbfc82001-07-18Henrik Grubbström (Grubba)  } else if (*--Pike_mark_sp != Pike_sp) { ptrdiff_t should = *Pike_mark_sp - Pike_interpreter.evaluator_stack; ptrdiff_t is = Pike_sp - Pike_interpreter.evaluator_stack; if (Pike_sp - *Pike_mark_sp > 0) /* not always same as Pike_sp > *Pike_mark_sp */
610d052001-07-06Henrik Grubbström (Grubba)  /* Some attempt to recover, just to be able to report the backtrace. */
ecbfc82001-07-18Henrik Grubbström (Grubba)  pop_n_elems(Pike_sp - *Pike_mark_sp);
5aad932002-08-15Marcus Comstedt  Pike_fatal("Stack out of synch - should be %ld, is %ld.\n",
ecbfc82001-07-18Henrik Grubbström (Grubba)  DO_NOT_WARN((long)should), DO_NOT_WARN((long)is)); }
610d052001-07-06Henrik Grubbström (Grubba)  } }); });
90703d2001-01-31Martin Stjernholm 
2bcc0d2002-05-11Martin Stjernholm OPCODE0(F_CLEAR_STRING_SUBTYPE, "clear string subtype", 0, {
bac71b2000-04-19Henrik Grubbström (Grubba)  if(Pike_sp[-1].type==PIKE_T_STRING) Pike_sp[-1].subtype=0;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe)  /* Jumps */
e180292002-11-02Henrik Grubbström (Grubba) OPCODE0_BRANCH(F_BRANCH, "branch", 0, { DO_BRANCH();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
e180292002-11-02Henrik Grubbström (Grubba) OPCODE2_BRANCH(F_BRANCH_IF_NOT_LOCAL_ARROW, "branch if !local->x", 0, {
7951942000-04-20Fredrik Hübinette (Hubbe)  struct svalue tmp; tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=1; Pike_sp->type=PIKE_T_INT; Pike_sp++; index_no_free(Pike_sp-1,Pike_fp->locals+arg2, &tmp); print_return_value();
87c7592000-04-18Fredrik Hübinette (Hubbe) 
610d052001-07-06Henrik Grubbström (Grubba)  /* Fall through */
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba)  OPCODE0_TAILBRANCH(F_BRANCH_WHEN_ZERO, "branch if zero", I_UPDATE_SP, {
9f516a2001-12-16Martin Stjernholm  if(!UNSAFE_IS_ZERO(Pike_sp-1))
610d052001-07-06Henrik Grubbström (Grubba)  {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
610d052001-07-06Henrik Grubbström (Grubba)  }else{
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
610d052001-07-06Henrik Grubbström (Grubba)  } pop_stack(); }); });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_BRANCH(F_BRANCH_WHEN_NON_ZERO, "branch if not zero", I_UPDATE_SP, {
9f516a2001-12-16Martin Stjernholm  if(UNSAFE_IS_ZERO(Pike_sp-1))
7951942000-04-20Fredrik Hübinette (Hubbe)  {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
7951942000-04-20Fredrik Hübinette (Hubbe)  }else{
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
7951942000-04-20Fredrik Hübinette (Hubbe)  } pop_stack();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1_BRANCH(F_BRANCH_IF_TYPE_IS_NOT, "branch if type is !=", I_UPDATE_SP, {
d9a93b2001-07-01Fredrik Hübinette (Hubbe) /* fprintf(stderr,"******BRANCH IF TYPE IS NOT***** %s\n",get_name_of_type(arg1)); */ if(Pike_sp[-1].type == T_OBJECT && Pike_sp[-1].u.object->prog) { int fun=FIND_LFUN(Pike_sp[-1].u.object->prog, LFUN__IS_TYPE); if(fun != -1) { /* fprintf(stderr,"******OBJECT OVERLOAD IN TYPEP***** %s\n",get_name_of_type(arg1)); */ push_text(get_name_of_type(arg1)); apply_low(Pike_sp[-2].u.object, fun, 1);
9f516a2001-12-16Martin Stjernholm  arg1=UNSAFE_IS_ZERO(Pike_sp-1) ? T_FLOAT : T_OBJECT ;
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  pop_stack(); } } if(Pike_sp[-1].type == arg1) {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  }else{
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  } pop_stack();
610d052001-07-06Henrik Grubbström (Grubba) });
d9a93b2001-07-01Fredrik Hübinette (Hubbe) 
e180292002-11-02Henrik Grubbström (Grubba) OPCODE1_BRANCH(F_BRANCH_IF_LOCAL, "branch if local", 0, {
9f516a2001-12-16Martin Stjernholm  if(UNSAFE_IS_ZERO(Pike_fp->locals + arg1))
7951942000-04-20Fredrik Hübinette (Hubbe)  {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
7951942000-04-20Fredrik Hübinette (Hubbe)  }else{
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
7951942000-04-20Fredrik Hübinette (Hubbe)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
e180292002-11-02Henrik Grubbström (Grubba) OPCODE1_BRANCH(F_BRANCH_IF_NOT_LOCAL, "branch if !local", 0, {
9f516a2001-12-16Martin Stjernholm  if(!UNSAFE_IS_ZERO(Pike_fp->locals + arg1))
a092ba2001-07-06Henrik Grubbström (Grubba)  {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
a092ba2001-07-06Henrik Grubbström (Grubba)  }else{
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
a092ba2001-07-06Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
68296f2001-07-07Henrik Grubbström (Grubba) #define CJUMP(X, DESC, Y) \
8f0eac2003-08-13Henrik Grubbström (Grubba)  OPCODE0_BRANCH(X, DESC, I_UPDATE_SP, { \
68296f2001-07-07Henrik Grubbström (Grubba)  if(Y(Pike_sp-2,Pike_sp-1)) { \
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH(); \
68296f2001-07-07Henrik Grubbström (Grubba)  }else{ \
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */ \
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH(); \
68296f2001-07-07Henrik Grubbström (Grubba)  } \
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems(); \
68296f2001-07-07Henrik Grubbström (Grubba)  }) CJUMP(F_BRANCH_WHEN_EQ, "branch if ==", is_eq); CJUMP(F_BRANCH_WHEN_NE, "branch if !=", !is_eq); CJUMP(F_BRANCH_WHEN_LT, "branch if <", is_lt); CJUMP(F_BRANCH_WHEN_LE, "branch if <=", !is_gt); CJUMP(F_BRANCH_WHEN_GT, "branch if >", is_gt); CJUMP(F_BRANCH_WHEN_GE, "branch if >=", !is_lt);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
e180292002-11-02Henrik Grubbström (Grubba) OPCODE0_BRANCH(F_BRANCH_AND_POP_WHEN_ZERO, "branch & pop if zero", 0, {
9f516a2001-12-16Martin Stjernholm  if(!UNSAFE_IS_ZERO(Pike_sp-1))
a092ba2001-07-06Henrik Grubbström (Grubba)  {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
a092ba2001-07-06Henrik Grubbström (Grubba)  }else{
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
a092ba2001-07-06Henrik Grubbström (Grubba)  pop_stack(); }
610d052001-07-06Henrik Grubbström (Grubba) });
a092ba2001-07-06Henrik Grubbström (Grubba) 
e180292002-11-02Henrik Grubbström (Grubba) OPCODE0_BRANCH(F_BRANCH_AND_POP_WHEN_NON_ZERO, "branch & pop if !zero", 0, {
9f516a2001-12-16Martin Stjernholm  if(UNSAFE_IS_ZERO(Pike_sp-1))
a092ba2001-07-06Henrik Grubbström (Grubba)  {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
a092ba2001-07-06Henrik Grubbström (Grubba)  }else{
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
a092ba2001-07-06Henrik Grubbström (Grubba)  pop_stack(); }
610d052001-07-06Henrik Grubbström (Grubba) });
a092ba2001-07-06Henrik Grubbström (Grubba) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_BRANCH(F_LAND, "&&", I_UPDATE_SP, {
9f516a2001-12-16Martin Stjernholm  if(!UNSAFE_IS_ZERO(Pike_sp-1))
a092ba2001-07-06Henrik Grubbström (Grubba)  {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
a092ba2001-07-06Henrik Grubbström (Grubba)  pop_stack(); }else{
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
198bcd2003-03-18Henrik Grubbström (Grubba)  pop_stack(); push_int(0);
a092ba2001-07-06Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
a092ba2001-07-06Henrik Grubbström (Grubba) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_BRANCH(F_LOR, "||", I_UPDATE_SP, {
9f516a2001-12-16Martin Stjernholm  if(UNSAFE_IS_ZERO(Pike_sp-1))
a092ba2001-07-06Henrik Grubbström (Grubba)  {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
a092ba2001-07-06Henrik Grubbström (Grubba)  pop_stack(); }else{
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
a092ba2001-07-06Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
a092ba2001-07-06Henrik Grubbström (Grubba) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_BRANCH(F_EQ_OR, "==||", I_UPDATE_SP, {
a092ba2001-07-06Henrik Grubbström (Grubba)  if(!is_eq(Pike_sp-2,Pike_sp-1)) {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
0adead2003-03-25Marcus Comstedt  pop_2_elems();
a092ba2001-07-06Henrik Grubbström (Grubba)  }else{
0adead2003-03-25Marcus Comstedt  DO_BRANCH();
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
a092ba2001-07-06Henrik Grubbström (Grubba)  push_int(1); }
610d052001-07-06Henrik Grubbström (Grubba) });
a092ba2001-07-06Henrik Grubbström (Grubba) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_BRANCH(F_EQ_AND, "==&&", I_UPDATE_SP, {
a092ba2001-07-06Henrik Grubbström (Grubba)  if(is_eq(Pike_sp-2,Pike_sp-1)) {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
0adead2003-03-25Marcus Comstedt  pop_2_elems();
a092ba2001-07-06Henrik Grubbström (Grubba)  }else{
0adead2003-03-25Marcus Comstedt  DO_BRANCH();
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
a092ba2001-07-06Henrik Grubbström (Grubba)  push_int(0); }
610d052001-07-06Henrik Grubbström (Grubba) });
a092ba2001-07-06Henrik Grubbström (Grubba) 
e180292002-11-02Henrik Grubbström (Grubba) /* This instruction can't currently be a branch, since * it has more than two continuation paths. */
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE0_PTRJUMP(F_CATCH, "catch", I_UPDATE_ALL, {
f142842003-08-06Martin Stjernholm  PIKE_OPCODE_T *next_addr; JUMP_SET_TO_PC_AT_NEXT (next_addr);
b23b112001-08-15Fredrik Hübinette (Hubbe)  check_c_stack(8192);
f142842003-08-06Martin Stjernholm  switch (o_catch((PIKE_OPCODE_T *)(((INT32 *)next_addr)+1)))
eff6212001-07-09Henrik Grubbström (Grubba)  {
a092ba2001-07-06Henrik Grubbström (Grubba)  case 1: /* There was a return inside the evaluated code */
7080882001-07-15Fredrik Hübinette (Hubbe)  DO_DUMB_RETURN;
a092ba2001-07-06Henrik Grubbström (Grubba)  case 2:
8069c22002-11-02Henrik Grubbström (Grubba)  /* Escape catch, continue after the escape instruction. */
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(Pike_fp->pc);
a092ba2001-07-06Henrik Grubbström (Grubba)  break; default:
8069c22002-11-02Henrik Grubbström (Grubba)  DOJUMP();
a092ba2001-07-06Henrik Grubbström (Grubba)  }
e180292002-11-02Henrik Grubbström (Grubba)  /* NOT_REACHED in byte-code and computed goto cases. */
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f142842003-08-06Martin Stjernholm OPCODE0_RETURN(F_ESCAPE_CATCH, "escape catch", I_PC_AT_NEXT, { JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc);
7080882001-07-15Fredrik Hübinette (Hubbe)  INTER_ESCAPE_CATCH;
610d052001-07-06Henrik Grubbström (Grubba) });
b7c1ee2001-01-10Martin Stjernholm 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_RETURN(F_EXIT_CATCH, "exit catch", I_PC_AT_NEXT|I_UPDATE_SP, {
9307b42002-09-23Martin Stjernholm  push_undefined();
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc);
9307b42002-09-23Martin Stjernholm  INTER_ESCAPE_CATCH;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1_JUMP(F_SWITCH, "switch", I_UPDATE_ALL, {
bac71b2000-04-19Henrik Grubbström (Grubba)  INT32 tmp;
f142842003-08-06Martin Stjernholm  PIKE_OPCODE_T *addr; JUMP_SET_TO_PC_AT_NEXT (addr);
bac71b2000-04-19Henrik Grubbström (Grubba)  tmp=switch_lookup(Pike_fp->context.prog-> constants[arg1].sval.u.array,Pike_sp-1);
7b2c002001-07-18Henrik Grubbström (Grubba)  addr = DO_IF_ELSE_COMPUTED_GOTO(addr, (PIKE_OPCODE_T *)
d2361e2003-06-30Martin Stjernholm  DO_ALIGN(PTR_TO_INT(addr),
2572762003-01-06Henrik Grubbström (Grubba)  ((ptrdiff_t)sizeof(INT32))));
7b2c002001-07-18Henrik Grubbström (Grubba)  addr = (PIKE_OPCODE_T *)(((INT32 *)addr) + (tmp>=0 ? 1+tmp*2 : 2*~tmp)); if(*(INT32*)addr < 0) fast_check_threads_etc(7);
bac71b2000-04-19Henrik Grubbström (Grubba)  pop_stack();
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(addr + *(INT32*)addr);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1_JUMP(F_SWITCH_ON_INDEX, "switch on index", I_UPDATE_ALL, {
6e36e52000-11-30Fredrik Hübinette (Hubbe)  INT32 tmp; struct svalue s;
f142842003-08-06Martin Stjernholm  PIKE_OPCODE_T *addr; JUMP_SET_TO_PC_AT_NEXT (addr);
6e36e52000-11-30Fredrik Hübinette (Hubbe)  index_no_free(&s,Pike_sp-2,Pike_sp-1); Pike_sp++[0]=s; tmp=switch_lookup(Pike_fp->context.prog-> constants[arg1].sval.u.array,Pike_sp-1); pop_n_elems(3);
7b2c002001-07-18Henrik Grubbström (Grubba)  addr = DO_IF_ELSE_COMPUTED_GOTO(addr, (PIKE_OPCODE_T *)
d2361e2003-06-30Martin Stjernholm  DO_ALIGN(PTR_TO_INT(addr),
78cf2a2003-01-06Henrik Grubbström (Grubba)  ((ptrdiff_t)sizeof(INT32))));
7b2c002001-07-18Henrik Grubbström (Grubba)  addr = (PIKE_OPCODE_T *)(((INT32 *)addr) + (tmp>=0 ? 1+tmp*2 : 2*~tmp)); if(*(INT32*)addr < 0) fast_check_threads_etc(7);
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(addr + *(INT32*)addr);
610d052001-07-06Henrik Grubbström (Grubba) });
6e36e52000-11-30Fredrik Hübinette (Hubbe) 
f142842003-08-06Martin Stjernholm OPCODE2_JUMP(F_SWITCH_ON_LOCAL, "switch on local", 0, {
6e36e52000-11-30Fredrik Hübinette (Hubbe)  INT32 tmp;
f142842003-08-06Martin Stjernholm  PIKE_OPCODE_T *addr; JUMP_SET_TO_PC_AT_NEXT (addr);
6e36e52000-11-30Fredrik Hübinette (Hubbe)  tmp=switch_lookup(Pike_fp->context.prog-> constants[arg2].sval.u.array,Pike_fp->locals + arg1);
7b2c002001-07-18Henrik Grubbström (Grubba)  addr = DO_IF_ELSE_COMPUTED_GOTO(addr, (PIKE_OPCODE_T *)
d2361e2003-06-30Martin Stjernholm  DO_ALIGN(PTR_TO_INT(addr),
9986442003-01-06Henrik Grubbström (Grubba)  ((ptrdiff_t)sizeof(INT32))));
7b2c002001-07-18Henrik Grubbström (Grubba)  addr = (PIKE_OPCODE_T *)(((INT32 *)addr) + (tmp>=0 ? 1+tmp*2 : 2*~tmp)); if(*(INT32*)addr < 0) fast_check_threads_etc(7);
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(addr + *(INT32*)addr);
610d052001-07-06Henrik Grubbström (Grubba) });
6e36e52000-11-30Fredrik Hübinette (Hubbe) 
68296f2001-07-07Henrik Grubbström (Grubba) #ifdef AUTO_BIGNUM #define AUTO_BIGNUM_LOOP_TEST(X,Y) INT_TYPE_ADD_OVERFLOW(X,Y) #else #define AUTO_BIGNUM_LOOP_TEST(X,Y) 0 #endif
87c7592000-04-18Fredrik Hübinette (Hubbe)  /* FIXME: Does this need bignum tests? /Fixed - Hubbe */
dd78ff2001-01-14Henrik Grubbström (Grubba)  /* LOOP(OPCODE, INCREMENT, OPERATOR, IS_OPERATOR) */
68296f2001-07-07Henrik Grubbström (Grubba) #define LOOP(ID, DESC, INC, OP2, OP4) \
e180292002-11-02Henrik Grubbström (Grubba)  OPCODE0_BRANCH(ID, DESC, 0, { \
68296f2001-07-07Henrik Grubbström (Grubba)  union anything *i=get_pointer_if_this_type(Pike_sp-2, T_INT); \
667a5a2003-01-30Henrik Grubbström (Grubba)  if(i && !AUTO_BIGNUM_LOOP_TEST(i->integer,INC) && \ Pike_sp[-3].type == T_INT) \
68296f2001-07-07Henrik Grubbström (Grubba)  { \ i->integer += INC; \ if(i->integer OP2 Pike_sp[-3].u.integer) \ { \
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH(); \
68296f2001-07-07Henrik Grubbström (Grubba)  }else{ \
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("loop\n", 8); */ \
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH(); \
68296f2001-07-07Henrik Grubbström (Grubba)  } \ }else{ \ lvalue_to_svalue_no_free(Pike_sp,Pike_sp-2); Pike_sp++; \ push_int(INC); \ f_add(2); \ assign_lvalue(Pike_sp-3,Pike_sp-1); \ if(OP4 ( Pike_sp-1, Pike_sp-4 )) \ { \
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH(); \
68296f2001-07-07Henrik Grubbström (Grubba)  }else{ \
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("loop\n", 8); */ \
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH(); \
68296f2001-07-07Henrik Grubbström (Grubba)  } \ pop_stack(); \ } \ }) LOOP(F_INC_LOOP, "++Loop", 1, <, is_lt); LOOP(F_DEC_LOOP, "--Loop", -1, >, is_gt); LOOP(F_INC_NEQ_LOOP, "++Loop!=", 1, !=, !is_eq); LOOP(F_DEC_NEQ_LOOP, "--Loop!=", -1, !=, !is_eq);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
dd78ff2001-01-14Henrik Grubbström (Grubba) /* Use like: * * push(loopcnt) * branch(l2) * l1: * sync_mark * code * pop_sync_mark * l2: * loop(l1) */
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_BRANCH(F_LOOP, "loop", I_UPDATE_SP, { /* loopcnt */
77fc8c2001-01-14Henrik Grubbström (Grubba)  /* Use >= and 1 to be able to reuse the 1 for the subtraction. */
dd78ff2001-01-14Henrik Grubbström (Grubba)  push_int(1);
9b150a2002-05-11Martin Nilsson  if (!is_lt(Pike_sp-2, Pike_sp-1)) {
dd78ff2001-01-14Henrik Grubbström (Grubba)  o_subtract();
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
dd78ff2001-01-14Henrik Grubbström (Grubba)  } else {
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
0adead2003-03-25Marcus Comstedt  pop_2_elems();
dd78ff2001-01-14Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
dd78ff2001-01-14Henrik Grubbström (Grubba) 
e180292002-11-02Henrik Grubbström (Grubba) OPCODE0_BRANCH(F_FOREACH, "foreach", 0, { /* array, lvalue, X, i */
dc8f722001-07-08Henrik Grubbström (Grubba)  if(Pike_sp[-4].type != PIKE_T_ARRAY) PIKE_ERROR("foreach", "Bad argument 1.\n", Pike_sp-3, 1); if(Pike_sp[-1].u.integer < Pike_sp[-4].u.array->size) { if(Pike_sp[-1].u.integer < 0) Pike_error("Foreach loop variable is negative!\n"); assign_lvalue(Pike_sp-3, Pike_sp[-4].u.array->item + Pike_sp[-1].u.integer);
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
dc8f722001-07-08Henrik Grubbström (Grubba)  Pike_sp[-1].u.integer++; }else{
8f0eac2003-08-13Henrik Grubbström (Grubba)  /* write_to_stderr("foreach\n", 8); */
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
dc8f722001-07-08Henrik Grubbström (Grubba)  } });
4cdb802001-02-23Fredrik Hübinette (Hubbe) 
eaa55b2003-04-18Martin Stjernholm OPCODE0(F_MAKE_ITERATOR, "get_iterator", 0, {
0dd1bc2003-04-18Martin Stjernholm  f_get_iterator(1);
610d052001-07-06Henrik Grubbström (Grubba) });
4cdb802001-02-23Fredrik Hübinette (Hubbe) 
f139182003-09-05Martin Stjernholm /* Stack is: iterator, index lvalue, value lvalue. */ OPCODE0_BRANCH (F_FOREACH_START, "foreach start", 0, { DO_IF_DEBUG ( if(Pike_sp[-5].type != PIKE_T_OBJECT) Pike_fatal ("Iterator gone from stack.\n"); ); if (foreach_iterate (Pike_sp[-5].u.object, 0)) DONT_BRANCH(); else { DO_BRANCH(); } });
4cdb802001-02-23Fredrik Hübinette (Hubbe) 
f139182003-09-05Martin Stjernholm /* Stack is: iterator, index lvalue, value lvalue. */ OPCODE0_BRANCH(F_FOREACH_LOOP, "foreach loop", 0, { DO_IF_DEBUG ( if(Pike_sp[-5].type != PIKE_T_OBJECT) Pike_fatal ("Iterator gone from stack.\n"); ); if(foreach_iterate(Pike_sp[-5].u.object, 1))
dc8f722001-07-08Henrik Grubbström (Grubba)  {
e180292002-11-02Henrik Grubbström (Grubba)  DO_BRANCH();
dc8f722001-07-08Henrik Grubbström (Grubba)  }else{
e180292002-11-02Henrik Grubbström (Grubba)  DONT_BRANCH();
dc8f722001-07-08Henrik Grubbström (Grubba)  } });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1_RETURN(F_RETURN_LOCAL,"return local", I_UPDATE_SP|I_UPDATE_FP, {
7080882001-07-15Fredrik Hübinette (Hubbe)  DO_IF_DEBUG( /* special case! Pike_interpreter.mark_stack may be invalid at the time we * call return -1, so we must call the callbacks here to * prevent false alarms! /Hubbe */
51adb82003-01-12Martin Stjernholm  if(d_flag>3) do_gc(NULL, 0);
7080882001-07-15Fredrik Hübinette (Hubbe)  if(d_flag>4) do_debug(); ); if(Pike_fp->expendible <= Pike_fp->locals + arg1) { pop_n_elems(Pike_sp-1 - (Pike_fp->locals + arg1)); }else{ push_svalue(Pike_fp->locals + arg1); } DO_DUMB_RETURN; });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_RETURN(F_RETURN_IF_TRUE,"return if true", I_UPDATE_SP|I_UPDATE_FP, {
9f516a2001-12-16Martin Stjernholm  if(!UNSAFE_IS_ZERO(Pike_sp-1)) DO_RETURN;
7080882001-07-15Fredrik Hübinette (Hubbe)  pop_stack();
f142842003-08-06Martin Stjernholm  DO_JUMP_TO_NEXT;
7080882001-07-15Fredrik Hübinette (Hubbe) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_RETURN(F_RETURN_1,"return 1", I_UPDATE_SP|I_UPDATE_FP, {
7080882001-07-15Fredrik Hübinette (Hubbe)  push_int(1); DO_RETURN; });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_RETURN(F_RETURN_0,"return 0", I_UPDATE_SP|I_UPDATE_FP, {
7080882001-07-15Fredrik Hübinette (Hubbe)  push_int(0); DO_RETURN; });
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_RETURN(F_RETURN, "return", I_UPDATE_FP, {
7080882001-07-15Fredrik Hübinette (Hubbe)  DO_RETURN; });
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_RETURN(F_DUMB_RETURN,"dumb return", I_UPDATE_FP, {
7080882001-07-15Fredrik Hübinette (Hubbe)  DO_DUMB_RETURN; });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE0(F_NEGATE, "unary minus", 0, {
bac71b2000-04-19Henrik Grubbström (Grubba)  if(Pike_sp[-1].type == PIKE_T_INT) {
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM( if(INT_TYPE_NEG_OVERFLOW(Pike_sp[-1].u.integer)) { convert_stack_top_to_bignum(); o_negate(); } else )
bac71b2000-04-19Henrik Grubbström (Grubba)  Pike_sp[-1].u.integer =- Pike_sp[-1].u.integer; } else if(Pike_sp[-1].type == PIKE_T_FLOAT) { Pike_sp[-1].u.float_number =- Pike_sp[-1].u.float_number; }else{ o_negate(); }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
4173b12002-11-11Henrik Grubbström (Grubba) OPCODE0_ALIAS(F_COMPL, "~", 0, o_compl);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE0(F_NOT, "!", 0, {
bac71b2000-04-19Henrik Grubbström (Grubba)  switch(Pike_sp[-1].type) { case PIKE_T_INT: Pike_sp[-1].u.integer =! Pike_sp[-1].u.integer; break;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba)  case PIKE_T_FUNCTION: case PIKE_T_OBJECT:
9f516a2001-12-16Martin Stjernholm  if(UNSAFE_IS_ZERO(Pike_sp-1))
bac71b2000-04-19Henrik Grubbström (Grubba)  { pop_stack(); push_int(1); }else{ pop_stack(); push_int(0); } break;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba)  default: free_svalue(Pike_sp-1); Pike_sp[-1].type=PIKE_T_INT; Pike_sp[-1].u.integer=0; }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_ALIAS(F_LSH, "<<", I_UPDATE_SP, o_lsh); OPCODE0_ALIAS(F_RSH, ">>", I_UPDATE_SP, o_rsh);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
68296f2001-07-07Henrik Grubbström (Grubba) #define COMPARISON(ID,DESC,EXPR) \
8f0eac2003-08-13Henrik Grubbström (Grubba)  OPCODE0(ID, DESC, I_UPDATE_SP, { \
eff6212001-07-09Henrik Grubbström (Grubba)  INT32 val = EXPR; \
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems(); \
eff6212001-07-09Henrik Grubbström (Grubba)  push_int(val); \
68296f2001-07-07Henrik Grubbström (Grubba)  }) COMPARISON(F_EQ, "==", is_eq(Pike_sp-2,Pike_sp-1)); COMPARISON(F_NE, "!=", !is_eq(Pike_sp-2,Pike_sp-1)); COMPARISON(F_GT, ">", is_gt(Pike_sp-2,Pike_sp-1)); COMPARISON(F_GE, ">=", !is_lt(Pike_sp-2,Pike_sp-1)); COMPARISON(F_LT, "<", is_lt(Pike_sp-2,Pike_sp-1)); COMPARISON(F_LE, "<=", !is_gt(Pike_sp-2,Pike_sp-1));
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_ADD, "+", I_UPDATE_SP, {
f853ac2000-04-20Henrik Grubbström (Grubba)  f_add(2);
610d052001-07-06Henrik Grubbström (Grubba) });
f853ac2000-04-20Henrik Grubbström (Grubba) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_ADD_INTS, "int+int", I_UPDATE_SP, {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_INT && Pike_sp[-2].type == T_INT
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
17f08c2000-07-06Fredrik Hübinette (Hubbe)  && (!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, Pike_sp[-2].u.integer))
610d052001-07-06Henrik Grubbström (Grubba)  )
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  ) {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-2].u.integer+=Pike_sp[-1].u.integer;
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
17f08c2000-07-06Fredrik Hübinette (Hubbe)  Pike_sp--;
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  }else{ f_add(2); }
610d052001-07-06Henrik Grubbström (Grubba) });
a2b70a2000-04-30Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_ADD_FLOATS, "float+float", I_UPDATE_SP, {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_FLOAT && Pike_sp[-2].type == T_FLOAT)
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-2].u.float_number+=Pike_sp[-1].u.float_number;
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
17f08c2000-07-06Fredrik Hübinette (Hubbe)  Pike_sp--;
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  }else{ f_add(2); }
610d052001-07-06Henrik Grubbström (Grubba) });
a2b70a2000-04-30Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_ALIAS(F_SUBTRACT, "-", I_UPDATE_SP, o_subtract); OPCODE0_ALIAS(F_AND, "&", I_UPDATE_SP, o_and); OPCODE0_ALIAS(F_OR, "|", I_UPDATE_SP, o_or); OPCODE0_ALIAS(F_XOR, "^", I_UPDATE_SP, o_xor); OPCODE0_ALIAS(F_MULTIPLY, "*", I_UPDATE_SP, o_multiply); OPCODE0_ALIAS(F_DIVIDE, "/", I_UPDATE_SP, o_divide); OPCODE0_ALIAS(F_MOD, "%", I_UPDATE_SP, o_mod);
f853ac2000-04-20Henrik Grubbström (Grubba) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_ADD_INT, "add integer", 0, {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_INT
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
17f08c2000-07-06Fredrik Hübinette (Hubbe)  && (!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, arg1))
610d052001-07-06Henrik Grubbström (Grubba)  )
6fd5172000-04-25Fredrik Hübinette (Hubbe)  ) {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-1].u.integer+=arg1;
6fd5172000-04-25Fredrik Hübinette (Hubbe)  }else{ push_int(arg1); f_add(2); }
610d052001-07-06Henrik Grubbström (Grubba) });
f853ac2000-04-20Henrik Grubbström (Grubba) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_ADD_NEG_INT, "add -integer", 0, {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_INT
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_BIGNUM(
17f08c2000-07-06Fredrik Hübinette (Hubbe)  && (!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, -arg1))
610d052001-07-06Henrik Grubbström (Grubba)  )
6fd5172000-04-25Fredrik Hübinette (Hubbe)  ) {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-1].u.integer-=arg1;
6fd5172000-04-25Fredrik Hübinette (Hubbe)  }else{ push_int(-arg1); f_add(2); }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_PUSH_ARRAY, "@", I_UPDATE_SP, {
9b22582000-04-18Henrik Grubbström (Grubba)  switch(Pike_sp[-1].type) { default: PIKE_ERROR("@", "Bad argument.\n", Pike_sp, 1); case PIKE_T_OBJECT: if(!Pike_sp[-1].u.object->prog || FIND_LFUN(Pike_sp[-1].u.object->prog,LFUN__VALUES) == -1) PIKE_ERROR("@", "Bad argument.\n", Pike_sp, 1); apply_lfun(Pike_sp[-1].u.object, LFUN__VALUES, 0); if(Pike_sp[-1].type != PIKE_T_ARRAY)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Bad return type from o->_values() in @\n");
9b22582000-04-18Henrik Grubbström (Grubba)  free_svalue(Pike_sp-2); Pike_sp[-2]=Pike_sp[-1];
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
9b22582000-04-18Henrik Grubbström (Grubba)  Pike_sp--; break; case PIKE_T_ARRAY: break; }
50ea682003-03-14Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp-1);
9b22582000-04-18Henrik Grubbström (Grubba)  Pike_sp--; push_array_items(Pike_sp->u.array);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_LOCAL_LOCAL_INDEX, "local[local]", I_UPDATE_SP, {
9b22582000-04-18Henrik Grubbström (Grubba)  struct svalue *s=Pike_fp->locals+arg1; if(s->type == PIKE_T_STRING) s->subtype=0; Pike_sp++->type=PIKE_T_INT; index_no_free(Pike_sp-1,Pike_fp->locals+arg2,s);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_LOCAL_INDEX, "local index", 0, {
610d052001-07-06Henrik Grubbström (Grubba)  struct svalue tmp; struct svalue *s = Pike_fp->locals+arg1;
9b22582000-04-18Henrik Grubbström (Grubba)  if(s->type == PIKE_T_STRING) s->subtype=0; index_no_free(&tmp,Pike_sp-1,s); free_svalue(Pike_sp-1); Pike_sp[-1]=tmp;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_GLOBAL_LOCAL_INDEX, "global[local]", I_UPDATE_SP, {
610d052001-07-06Henrik Grubbström (Grubba)  struct svalue tmp; struct svalue *s;
9b22582000-04-18Henrik Grubbström (Grubba)  low_object_index_no_free(Pike_sp, Pike_fp->current_object, arg1 + Pike_fp->context.identifier_level); Pike_sp++; s=Pike_fp->locals+arg2; if(s->type == PIKE_T_STRING) s->subtype=0; index_no_free(&tmp,Pike_sp-1,s); free_svalue(Pike_sp-1); Pike_sp[-1]=tmp;
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_LOCAL_ARROW, "local->x", I_UPDATE_SP, {
9b22582000-04-18Henrik Grubbström (Grubba)  struct svalue tmp; tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=1; Pike_sp->type=PIKE_T_INT; Pike_sp++; index_no_free(Pike_sp-1,Pike_fp->locals+arg2, &tmp); print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_ARROW, "->x", 0, {
610d052001-07-06Henrik Grubbström (Grubba)  struct svalue tmp; struct svalue tmp2;
9b22582000-04-18Henrik Grubbström (Grubba)  tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=1; index_no_free(&tmp2, Pike_sp-1, &tmp); free_svalue(Pike_sp-1); Pike_sp[-1]=tmp2; print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_STRING_INDEX, "string index", 0, {
610d052001-07-06Henrik Grubbström (Grubba)  struct svalue tmp; struct svalue tmp2;
372a652000-04-18Henrik Grubbström (Grubba)  tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=0; index_no_free(&tmp2, Pike_sp-1, &tmp); free_svalue(Pike_sp-1); Pike_sp[-1]=tmp2; print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_POS_INT_INDEX, "int index", 0, {
7080882001-07-15Fredrik Hübinette (Hubbe)  push_int(arg1); print_return_value(); DO_INDEX; });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_NEG_INT_INDEX, "-int index", 0, {
7080882001-07-15Fredrik Hübinette (Hubbe)  push_int(-(ptrdiff_t)arg1); print_return_value(); DO_INDEX; });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_INDEX, "index", I_UPDATE_SP, {
7080882001-07-15Fredrik Hübinette (Hubbe)  DO_INDEX; });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_MAGIC_INDEX, "::`[]", I_UPDATE_SP, {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  push_magic_index(magic_index_program, arg2, arg1);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_MAGIC_SET_INDEX, "::`[]=", I_UPDATE_SP, {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  push_magic_index(magic_set_index_program, arg2, arg1);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_MAGIC_INDICES, "::_indices", I_UPDATE_SP, {
cbe1132001-12-16Martin Stjernholm  push_magic_index(magic_indices_program, arg2, arg1); });
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_MAGIC_VALUES, "::_values", I_UPDATE_SP, {
cbe1132001-12-16Martin Stjernholm  push_magic_index(magic_values_program, arg2, arg1); });
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_ALIAS(F_CAST, "cast", I_UPDATE_SP, f_cast);
105be62002-11-10Henrik Grubbström (Grubba) OPCODE0_ALIAS(F_CAST_TO_INT, "cast_to_int", 0, o_cast_to_int); OPCODE0_ALIAS(F_CAST_TO_STRING, "cast_to_string", 0, o_cast_to_string);
7f94c22001-06-17Henrik Grubbström (Grubba) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_SOFT_CAST, "soft cast", I_UPDATE_SP, {
bac71b2000-04-19Henrik Grubbström (Grubba)  /* Stack: type_string, value */
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_DEBUG({ if (Pike_sp[-2].type != T_TYPE) {
5aad932002-08-15Marcus Comstedt  Pike_fatal("Argument 1 to soft_cast isn't a type!\n");
610d052001-07-06Henrik Grubbström (Grubba)  } });
bac71b2000-04-19Henrik Grubbström (Grubba)  if (runtime_options & RUNTIME_CHECK_TYPES) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *sval_type = get_type_of_svalue(Pike_sp-1); if (!pike_types_le(sval_type, Pike_sp[-2].u.type)) {
bac71b2000-04-19Henrik Grubbström (Grubba)  /* get_type_from_svalue() doesn't return a fully specified type * for array, mapping and multiset, so we perform a more lenient * check for them. */ if (!pike_types_le(sval_type, weak_type_string) ||
5320152001-02-20Henrik Grubbström (Grubba)  !match_types(sval_type, Pike_sp[-2].u.type)) {
bac71b2000-04-19Henrik Grubbström (Grubba)  struct pike_string *t1; struct pike_string *t2; char *fname = "__soft-cast"; ONERROR tmp1; ONERROR tmp2; if (Pike_fp->current_object && Pike_fp->context.prog && Pike_fp->current_object->prog) { /* Look up the function-name */ struct pike_string *name = ID_FROM_INT(Pike_fp->current_object->prog, Pike_fp->fun)->name; if ((!name->size_shift) && (name->len < 100)) fname = name->str; }
5320152001-02-20Henrik Grubbström (Grubba)  t1 = describe_type(Pike_sp[-2].u.type);
bac71b2000-04-19Henrik Grubbström (Grubba)  SET_ONERROR(tmp1, do_free_string, t1);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba)  t2 = describe_type(sval_type); SET_ONERROR(tmp2, do_free_string, t2);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(sval_type);
bac71b2000-04-19Henrik Grubbström (Grubba)  bad_arg_error(NULL, Pike_sp-1, 1, 1, t1->str, Pike_sp-1, "%s(): Soft cast failed. Expected %s, got %s\n", fname, t1->str, t2->str); /* NOT_REACHED */ UNSET_ONERROR(tmp2); UNSET_ONERROR(tmp1); free_string(t2); free_string(t1); } }
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(sval_type);
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_DEBUG({ if (d_flag > 2) { struct pike_string *t = describe_type(Pike_sp[-2].u.type); fprintf(stderr, "Soft cast to %s\n", t->str); free_string(t); } });
bac71b2000-04-19Henrik Grubbström (Grubba)  } stack_swap(); pop_stack();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0_ALIAS(F_RANGE, "range", I_UPDATE_SP, o_range);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE0(F_COPY_VALUE, "copy_value", 0, {
372a652000-04-18Henrik Grubbström (Grubba)  struct svalue tmp; copy_svalues_recursively_no_free(&tmp,Pike_sp-1,1,0); free_svalue(Pike_sp-1); Pike_sp[-1]=tmp;
9a498f2003-09-23Henrik Grubbström (Grubba)  print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_INDIRECT, "indirect", I_UPDATE_SP, {
372a652000-04-18Henrik Grubbström (Grubba)  struct svalue s; lvalue_to_svalue_no_free(&s,Pike_sp-2); if(s.type != PIKE_T_STRING) {
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
372a652000-04-18Henrik Grubbström (Grubba)  *Pike_sp=s; Pike_sp++; }else{ struct object *o; o=low_clone(string_assignment_program); ((struct string_assignment_storage *)o->storage)->lval[0]=Pike_sp[-2]; ((struct string_assignment_storage *)o->storage)->lval[1]=Pike_sp[-1]; ((struct string_assignment_storage *)o->storage)->s=s.u.string; Pike_sp-=2; push_object(o); }
610d052001-07-06Henrik Grubbström (Grubba)  print_return_value(); });
372a652000-04-18Henrik Grubbström (Grubba) 
2bcc0d2002-05-11Martin Stjernholm OPCODE0(F_SIZEOF, "sizeof", 0, {
5298da2003-01-26Mirar (Pontus Hagland)  INT_TYPE val = pike_sizeof(Pike_sp-1);
372a652000-04-18Henrik Grubbström (Grubba)  pop_stack();
eff6212001-07-09Henrik Grubbström (Grubba)  push_int(val);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_SIZEOF_LOCAL, "sizeof local", I_UPDATE_SP, {
372a652000-04-18Henrik Grubbström (Grubba)  push_int(pike_sizeof(Pike_fp->locals+arg1));
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1_ALIAS(F_SSCANF, "sscanf", I_UPDATE_SP, o_sscanf);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) #define MKAPPLY(OP,OPCODE,NAME,TYPE, ARG2, ARG3) \
8f0eac2003-08-13Henrik Grubbström (Grubba)  PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT(F_,OPCODE),NAME, \
9a498f2003-09-23Henrik Grubbström (Grubba)  I_PC_AT_NEXT|I_UPDATE_ALL, { \
f142842003-08-06Martin Stjernholm JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); \
f663c92003-04-03Henrik Grubbström (Grubba) if(low_mega_apply(TYPE,DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)), \
70be662001-06-19Fredrik Hübinette (Hubbe)  ARG2, ARG3)) \ { \
2454752001-07-10Henrik Grubbström (Grubba)  Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL; \
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(Pike_fp->pc); \
70be662001-06-19Fredrik Hübinette (Hubbe) } \
f142842003-08-06Martin Stjernholm else { \ DO_JUMP_TO_NEXT; \ } \
610d052001-07-06Henrik Grubbström (Grubba) }); \
70be662001-06-19Fredrik Hübinette (Hubbe)  \
8f0eac2003-08-13Henrik Grubbström (Grubba)  PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT3(F_,OPCODE,_AND_POP),NAME " & pop", \
9a498f2003-09-23Henrik Grubbström (Grubba)  I_PC_AT_NEXT|I_UPDATE_ALL, { \
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); \
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(TYPE, DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)), \
70be662001-06-19Fredrik Hübinette (Hubbe)  ARG2, ARG3)) \ { \
2454752001-07-10Henrik Grubbström (Grubba)  Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP; \
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(Pike_fp->pc); \
70be662001-06-19Fredrik Hübinette (Hubbe)  }else{ \ pop_stack(); \
f142842003-08-06Martin Stjernholm  DO_JUMP_TO_NEXT; \
70be662001-06-19Fredrik Hübinette (Hubbe)  } \
610d052001-07-06Henrik Grubbström (Grubba) }); \
70be662001-06-19Fredrik Hübinette (Hubbe)  \
7997532001-07-27Henrik Grubbström (Grubba) PIKE_CONCAT(OP,_RETURN)(PIKE_CONCAT3(F_,OPCODE,_AND_RETURN), \
8f0eac2003-08-13Henrik Grubbström (Grubba)  NAME " & return", \
9a498f2003-09-23Henrik Grubbström (Grubba)  I_UPDATE_ALL, { \
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(TYPE,DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)), \
70be662001-06-19Fredrik Hübinette (Hubbe)  ARG2,ARG3)) \ { \
e87fe82001-07-26Henrik Grubbström (Grubba)  PIKE_OPCODE_T *addr = Pike_fp->pc; \
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_IF_DEBUG(Pike_fp->next->pc=0); \ unlink_previous_frame(); \
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(addr); \
70be662001-06-19Fredrik Hübinette (Hubbe)  }else{ \
7080882001-07-15Fredrik Hübinette (Hubbe)  DO_DUMB_RETURN; \
70be662001-06-19Fredrik Hübinette (Hubbe)  } \
07835a2003-10-10Henrik Grubbström (Grubba) })
bfe2732001-08-15Fredrik Hübinette (Hubbe)  #define MKAPPLY2(OP,OPCODE,NAME,TYPE, ARG2, ARG3) \ \
d6f90d2003-10-10Henrik Grubbström (Grubba) MKAPPLY(OP,OPCODE,NAME,TYPE, ARG2, ARG3); \
70be662001-06-19Fredrik Hübinette (Hubbe)  \
8f0eac2003-08-13Henrik Grubbström (Grubba) PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT(F_MARK_,OPCODE),"mark, " NAME, \
9a498f2003-09-23Henrik Grubbström (Grubba)  I_PC_AT_NEXT|I_UPDATE_ALL, { \
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); \
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(TYPE, 0, \
610d052001-07-06Henrik Grubbström (Grubba)  ARG2, ARG3)) \ { \
2454752001-07-10Henrik Grubbström (Grubba)  Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL; \
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(Pike_fp->pc); \
610d052001-07-06Henrik Grubbström (Grubba)  } \
f142842003-08-06Martin Stjernholm  else { \ DO_JUMP_TO_NEXT; \ } \
610d052001-07-06Henrik Grubbström (Grubba) }); \
70be662001-06-19Fredrik Hübinette (Hubbe)  \
f142842003-08-06Martin Stjernholm PIKE_CONCAT(OP,_JUMP)(PIKE_CONCAT3(F_MARK_,OPCODE,_AND_POP), \
8f0eac2003-08-13Henrik Grubbström (Grubba)  "mark, " NAME " & pop", \
9a498f2003-09-23Henrik Grubbström (Grubba)  I_PC_AT_NEXT|I_UPDATE_ALL, { \
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc); \
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(TYPE, 0, \
70be662001-06-19Fredrik Hübinette (Hubbe)  ARG2, ARG3)) \ { \
2454752001-07-10Henrik Grubbström (Grubba)  Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP; \
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(Pike_fp->pc); \
70be662001-06-19Fredrik Hübinette (Hubbe)  }else{ \ pop_stack(); \
f142842003-08-06Martin Stjernholm  DO_JUMP_TO_NEXT; \
70be662001-06-19Fredrik Hübinette (Hubbe)  } \
610d052001-07-06Henrik Grubbström (Grubba) }); \
70be662001-06-19Fredrik Hübinette (Hubbe)  \
7997532001-07-27Henrik Grubbström (Grubba) PIKE_CONCAT(OP,_RETURN)(PIKE_CONCAT3(F_MARK_,OPCODE,_AND_RETURN), \
8f0eac2003-08-13Henrik Grubbström (Grubba)  "mark, " NAME " & return", \
9a498f2003-09-23Henrik Grubbström (Grubba)  I_UPDATE_ALL, { \
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(TYPE, 0, \
70be662001-06-19Fredrik Hübinette (Hubbe)  ARG2,ARG3)) \ { \
e87fe82001-07-26Henrik Grubbström (Grubba)  PIKE_OPCODE_T *addr = Pike_fp->pc; \
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_IF_DEBUG(Pike_fp->next->pc=0); \ unlink_previous_frame(); \
c2fc3c2001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(addr); \
70be662001-06-19Fredrik Hübinette (Hubbe)  }else{ \
7080882001-07-15Fredrik Hübinette (Hubbe)  DO_DUMB_RETURN; \
70be662001-06-19Fredrik Hübinette (Hubbe)  } \
610d052001-07-06Henrik Grubbström (Grubba) })
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bfe2732001-08-15Fredrik Hübinette (Hubbe) MKAPPLY2(OPCODE1,CALL_LFUN,"call lfun",APPLY_LOW, Pike_fp->current_object,
530bd72001-09-23Henrik Grubbström (Grubba)  (void *)(ptrdiff_t)(arg1+Pike_fp->context.identifier_level));
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bfe2732001-08-15Fredrik Hübinette (Hubbe) MKAPPLY2(OPCODE1,APPLY,"apply",APPLY_SVALUE_STRICT, &((Pike_fp->context.prog->constants + arg1)->sval),0);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) MKAPPLY(OPCODE0,CALL_FUNCTION,"call function",APPLY_STACK, 0,0);
9ddbf22001-05-10Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1_JUMP(F_CALL_OTHER,"call other", I_PC_AT_NEXT|I_UPDATE_ALL, {
a8aed22001-08-15Fredrik Hübinette (Hubbe)  INT32 args=DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)); struct svalue *s=Pike_sp-args;
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc);
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if(s->type == T_OBJECT) { struct object *o=s->u.object; struct program *p; if((p=o->prog)) { if(FIND_LFUN(p, LFUN_ARROW) == -1) { int fun; fun=find_shared_string_identifier(Pike_fp->context.prog->strings[arg1], p); if(fun >= 0) {
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(APPLY_LOW, args-1, o, (void *)(ptrdiff_t)fun))
a8aed22001-08-15Fredrik Hübinette (Hubbe)  { Pike_fp->save_sp--; Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL; DO_JUMP_TO(Pike_fp->pc); }
0d0bab2003-04-27Martin Stjernholm  stack_pop_keep_top();
f142842003-08-06Martin Stjernholm  DO_JUMP_TO_NEXT;
a8aed22001-08-15Fredrik Hübinette (Hubbe)  } } } } { struct svalue tmp; struct svalue tmp2; tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=1; index_no_free(&tmp2, s, &tmp); free_svalue(s); *s=tmp2; print_return_value();
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(APPLY_STACK, args, 0, 0))
a8aed22001-08-15Fredrik Hübinette (Hubbe)  { Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL; DO_JUMP_TO(Pike_fp->pc); }
f142842003-08-06Martin Stjernholm  else { DO_JUMP_TO_NEXT; }
a8aed22001-08-15Fredrik Hübinette (Hubbe)  } });
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1_JUMP(F_CALL_OTHER_AND_POP,"call other & pop", I_PC_AT_NEXT|I_UPDATE_ALL, {
a8aed22001-08-15Fredrik Hübinette (Hubbe)  INT32 args=DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)); struct svalue *s=Pike_sp-args;
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->pc);
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if(s->type == T_OBJECT) { struct object *o=s->u.object; struct program *p; if((p=o->prog)) { if(FIND_LFUN(p, LFUN_ARROW) == -1) { int fun; fun=find_shared_string_identifier(Pike_fp->context.prog->strings[arg1], p); if(fun >= 0) {
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(APPLY_LOW, args-1, o, (void *)(ptrdiff_t)fun))
a8aed22001-08-15Fredrik Hübinette (Hubbe)  { Pike_fp->save_sp--;
2bcc0d2002-05-11Martin Stjernholm  Pike_fp->flags |=
a8aed22001-08-15Fredrik Hübinette (Hubbe)  PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP; DO_JUMP_TO(Pike_fp->pc); } pop_2_elems();
f142842003-08-06Martin Stjernholm  DO_JUMP_TO_NEXT;
a8aed22001-08-15Fredrik Hübinette (Hubbe)  } } } } { struct svalue tmp; struct svalue tmp2; tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=1; index_no_free(&tmp2, s, &tmp); free_svalue(s); *s=tmp2; print_return_value();
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(APPLY_STACK, args, 0, 0))
a8aed22001-08-15Fredrik Hübinette (Hubbe)  { Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP; DO_JUMP_TO(Pike_fp->pc); }
f142842003-08-06Martin Stjernholm  else { pop_stack(); DO_JUMP_TO_NEXT; }
a8aed22001-08-15Fredrik Hübinette (Hubbe)  } });
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1_JUMP(F_CALL_OTHER_AND_RETURN,"call other & return", I_UPDATE_ALL, {
a8aed22001-08-15Fredrik Hübinette (Hubbe)  INT32 args=DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)); struct svalue *s=Pike_sp-args; if(s->type == T_OBJECT) { struct object *o=s->u.object; struct program *p; if((p=o->prog)) { if(FIND_LFUN(p, LFUN_ARROW) == -1) { int fun; fun=find_shared_string_identifier(Pike_fp->context.prog->strings[arg1], p); if(fun >= 0) {
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(APPLY_LOW, args-1, o, (void *)(ptrdiff_t)fun))
a8aed22001-08-15Fredrik Hübinette (Hubbe)  { PIKE_OPCODE_T *addr = Pike_fp->pc; Pike_fp->save_sp--; DO_IF_DEBUG(Pike_fp->next->pc=0); unlink_previous_frame(); DO_JUMP_TO(addr); }
0d0bab2003-04-27Martin Stjernholm  stack_pop_keep_top();
a8aed22001-08-15Fredrik Hübinette (Hubbe)  DO_DUMB_RETURN; } } } } { struct svalue tmp; struct svalue tmp2; tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=1; index_no_free(&tmp2, s, &tmp); free_svalue(s); *s=tmp2; print_return_value();
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(APPLY_STACK, args, 0, 0))
a8aed22001-08-15Fredrik Hübinette (Hubbe)  { PIKE_OPCODE_T *addr = Pike_fp->pc; DO_IF_DEBUG(Pike_fp->next->pc=0); unlink_previous_frame(); DO_JUMP_TO(addr); } DO_DUMB_RETURN; } });
9ddbf22001-05-10Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) #undef DO_CALL_BUILTIN #ifdef PIKE_DEBUG #define DO_CALL_BUILTIN(ARGS) do { \ int args=(ARGS); \ struct svalue *expected_stack=Pike_sp-args; \ struct svalue *s=&Pike_fp->context.prog->constants[arg1].sval; \
97ebb32003-01-09Henrik Grubbström (Grubba)  if(Pike_interpreter.trace_level>1) \
70be662001-06-19Fredrik Hübinette (Hubbe)  { \ init_buf(); \ describe_svalue(s, 0,0); \ do_trace_call(args); \ } \ (*(s->u.efun->function))(args); \
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  s->u.efun->runs++; \
70be662001-06-19Fredrik Hübinette (Hubbe)  if(Pike_sp != expected_stack + !s->u.efun->may_return_void) \ { \ if(Pike_sp < expected_stack) \
97ebb32003-01-09Henrik Grubbström (Grubba)  Pike_fatal("Function popped too many arguments: %s\n", \
70be662001-06-19Fredrik Hübinette (Hubbe)  s->u.efun->name->str); \ if(Pike_sp>expected_stack+1) \
5aad932002-08-15Marcus Comstedt  Pike_fatal("Function left %d droppings on stack: %s\n", \
121f822001-06-28Fredrik Hübinette (Hubbe)  Pike_sp-(expected_stack+1), \
70be662001-06-19Fredrik Hübinette (Hubbe)  s->u.efun->name->str); \ if(Pike_sp == expected_stack && !s->u.efun->may_return_void) \
97ebb32003-01-09Henrik Grubbström (Grubba)  Pike_fatal("Non-void function returned without return value " \
70be662001-06-19Fredrik Hübinette (Hubbe)  "on stack: %s %d\n", \ s->u.efun->name->str,s->u.efun->may_return_void); \ if(Pike_sp==expected_stack+1 && s->u.efun->may_return_void) \
5aad932002-08-15Marcus Comstedt  Pike_fatal("Void function returned with a value on the stack: %s %d\n", \
70be662001-06-19Fredrik Hübinette (Hubbe)  s->u.efun->name->str, s->u.efun->may_return_void); \ } \
97ebb32003-01-09Henrik Grubbström (Grubba)  if(Pike_interpreter.trace_level>1 && Pike_sp>expected_stack) \ trace_return_value(); \
70be662001-06-19Fredrik Hübinette (Hubbe) }while(0) #else #define DO_CALL_BUILTIN(ARGS) \ (*(Pike_fp->context.prog->constants[arg1].sval.u.efun->function))(ARGS) #endif
87c7592000-04-18Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1(F_CALL_BUILTIN, "call builtin", I_UPDATE_ALL, {
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)));
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1(F_CALL_BUILTIN_AND_POP,"call builtin & pop", I_UPDATE_ALL, {
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp))); pop_stack();
610d052001-07-06Henrik Grubbström (Grubba) });
9ddbf22001-05-10Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1_RETURN(F_CALL_BUILTIN_AND_RETURN,"call builtin & return", I_UPDATE_ALL, {
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)));
7080882001-07-15Fredrik Hübinette (Hubbe)  DO_DUMB_RETURN;
610d052001-07-06Henrik Grubbström (Grubba) });
9ddbf22001-05-10Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1(F_MARK_CALL_BUILTIN, "mark, call builtin", I_UPDATE_ALL, {
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(0);
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE1(F_MARK_CALL_BUILTIN_AND_POP, "mark, call builtin & pop", 0, {
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(0); pop_stack();
610d052001-07-06Henrik Grubbström (Grubba) });
9ddbf22001-05-10Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1_RETURN(F_MARK_CALL_BUILTIN_AND_RETURN, "mark, call builtin & return", I_UPDATE_ALL, {
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(0);
7080882001-07-15Fredrik Hübinette (Hubbe)  DO_DUMB_RETURN;
610d052001-07-06Henrik Grubbström (Grubba) });
6fd5172000-04-25Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1(F_CALL_BUILTIN1, "call builtin 1", I_UPDATE_ALL, {
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(1);
610d052001-07-06Henrik Grubbström (Grubba) });
d9a93b2001-07-01Fredrik Hübinette (Hubbe) 
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1(F_CALL_BUILTIN1_AND_POP, "call builtin1 & pop", I_UPDATE_ALL, {
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(1); pop_stack();
610d052001-07-06Henrik Grubbström (Grubba) });
70be662001-06-19Fredrik Hübinette (Hubbe) 
4686dd2002-11-12Henrik Grubbström (Grubba) #ifndef ENTRY_PROLOGUE_SIZE #define ENTRY_PROLOGUE_SIZE 0 #endif /* !ENTRY_PROLOGUE_SIZE */
b23b112001-08-15Fredrik Hübinette (Hubbe) #define DO_RECUR(XFLAGS) do{ \ PIKE_OPCODE_T *addr; \ register struct pike_frame *new_frame; \ ptrdiff_t args; \ \
e8b1f82003-03-06Henrik Grubbström (Grubba)  DO_IF_SECURITY(CHECK_DATA_SECURITY_OR_ERROR(Pike_fp->current_object, \ SECURITY_BIT_CALL, \ ("Function call permission denied.\n"))); \ \
b23b112001-08-15Fredrik Hübinette (Hubbe)  fast_check_threads_etc(6); \ check_stack(256); \ \ new_frame=alloc_pike_frame(); \ \
50ea682003-03-14Henrik Grubbström (Grubba)  new_frame->refs=1; /* FIXME: Is this needed? */ \
b23b112001-08-15Fredrik Hübinette (Hubbe)  new_frame->next=Pike_fp; \ \
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (addr); \ Pike_fp->pc = (PIKE_OPCODE_T *)(((INT32 *) addr) + 1); \ addr += GET_JUMP(); \
4686dd2002-11-12Henrik Grubbström (Grubba)  \ new_frame->num_locals = READ_INCR_BYTE(addr); \ args = READ_INCR_BYTE(addr); \ addr += ENTRY_PROLOGUE_SIZE; \
b23b112001-08-15Fredrik Hübinette (Hubbe)  \ new_frame->num_args = new_frame->args = args; \ new_frame->locals=new_frame->save_sp=new_frame->expendible=Pike_sp-args; \ new_frame->save_mark_sp = new_frame->mark_sp_base = Pike_mark_sp; \
198bcd2003-03-18Henrik Grubbström (Grubba)  \
4686dd2002-11-12Henrik Grubbström (Grubba)  push_zeroes(new_frame->num_locals - args); \
b23b112001-08-15Fredrik Hübinette (Hubbe)  \ DO_IF_DEBUG({ \
97ebb32003-01-09Henrik Grubbström (Grubba)  if(Pike_interpreter.trace_level > 3) \
b23b112001-08-15Fredrik Hübinette (Hubbe)  fprintf(stderr,"- Allocating %d extra locals.\n", \ new_frame->num_locals - new_frame->num_args); \
a068db2003-10-01Henrik Grubbström (Grubba)  if (Pike_fp && (new_frame->locals < Pike_fp->locals)) { \ fatal("New locals below old locals: %p < %p\n", \ new_frame->locals, Pike_fp->locals); \ } \
b23b112001-08-15Fredrik Hübinette (Hubbe)  }); \ \ \
ef9db52002-09-20Marcus Comstedt  SET_PROG_COUNTER(addr); \
b23b112001-08-15Fredrik Hübinette (Hubbe)  new_frame->fun=Pike_fp->fun; \
4b05702001-08-30Fredrik Hübinette (Hubbe)  DO_IF_PROFILING( new_frame->ident=Pike_fp->ident ); \
b23b112001-08-15Fredrik Hübinette (Hubbe)  new_frame->current_storage=Pike_fp->current_storage; \ if(Pike_fp->scope) add_ref(new_frame->scope=Pike_fp->scope); \ add_ref(new_frame->current_object=Pike_fp->current_object); \ new_frame->context=Pike_fp->context; \ add_ref(new_frame->context.prog); \ if(new_frame->context.parent) \ add_ref(new_frame->context.parent); \ Pike_fp=new_frame; \ new_frame->flags=PIKE_FRAME_RETURN_INTERNAL | XFLAGS; \ \
e8b1f82003-03-06Henrik Grubbström (Grubba)  DO_IF_SECURITY(if(!CHECK_DATA_SECURITY(Pike_fp->current_object, \ SECURITY_BIT_NOT_SETUID)) \ SET_CURRENT_CREDS(Pike_fp->current_object->prot)); \ \
399b3f2002-04-08Marcus Comstedt  FETCH; \
f142842003-08-06Martin Stjernholm  JUMP_DONE; \
b23b112001-08-15Fredrik Hübinette (Hubbe) }while(0)
6fd5172000-04-25Fredrik Hübinette (Hubbe) /* Assume that the number of arguments is correct */
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE1_PTRJUMP(F_COND_RECUR, "recur if not overloaded", I_PC_AT_NEXT|I_UPDATE_ALL, {
daf6492002-11-14Henrik Grubbström (Grubba)  struct program *p = Pike_fp->current_object->prog;
f142842003-08-06Martin Stjernholm  PIKE_OPCODE_T *addr; JUMP_SET_TO_PC_AT_NEXT (addr); Pike_fp->pc = (PIKE_OPCODE_T *)(((INT32 *)addr) + 1);
2bcc0d2002-05-11Martin Stjernholm 
daf6492002-11-14Henrik Grubbström (Grubba)  /* Test if the function is overloaded. * * Note: The second part of the test is sufficient, but * the since first case is much simpler to test and * is common, it should offer a speed improvement.
198bcd2003-03-18Henrik Grubbström (Grubba)  *
daf6492002-11-14Henrik Grubbström (Grubba)  * /grubba 2002-11-14
198bcd2003-03-18Henrik Grubbström (Grubba)  * * Also test if the function uses scoping. DO_RECUR() doesn't * adjust fp->expendible which will make eg RETURN_LOCAL fail. * * /grubba 2003-03-25
a64f6b2001-01-12Martin Stjernholm  */
198bcd2003-03-18Henrik Grubbström (Grubba)  if(((p != Pike_fp->context.prog) && (p->inherits[p->identifier_references[Pike_fp->context.identifier_level +
daf6492002-11-14Henrik Grubbström (Grubba)  arg1].inherit_offset].prog !=
198bcd2003-03-18Henrik Grubbström (Grubba)  Pike_fp->context.prog)) || (ID_FROM_INT(p, arg1+Pike_fp->context.identifier_level)-> identifier_flags & IDENTIFIER_SCOPE_USED))
a64f6b2001-01-12Martin Stjernholm  {
f142842003-08-06Martin Stjernholm  PIKE_OPCODE_T *faddr; ptrdiff_t num_locals; ptrdiff_t args; JUMP_SET_TO_PC_AT_NEXT (faddr); faddr += GET_JUMP(); num_locals = READ_INCR_BYTE(faddr); /* ignored */ args = READ_INCR_BYTE(faddr);
2bcc0d2002-05-11Martin Stjernholm 
f663c92003-04-03Henrik Grubbström (Grubba)  if(low_mega_apply(APPLY_LOW,
b23b112001-08-15Fredrik Hübinette (Hubbe)  args,
105ade2001-05-13Fredrik Hübinette (Hubbe)  Pike_fp->current_object,
530bd72001-09-23Henrik Grubbström (Grubba)  (void *)(ptrdiff_t)(arg1+ Pike_fp->context.identifier_level)))
105ade2001-05-13Fredrik Hübinette (Hubbe)  {
2454752001-07-10Henrik Grubbström (Grubba)  Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL;
e87fe82001-07-26Henrik Grubbström (Grubba)  addr = Pike_fp->pc;
105ade2001-05-13Fredrik Hübinette (Hubbe)  }
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(addr);
a64f6b2001-01-12Martin Stjernholm  }
610d052001-07-06Henrik Grubbström (Grubba)  /* FALL THROUGH */ /* Assume that the number of arguments is correct */
e87fe82001-07-26Henrik Grubbström (Grubba) 
9a498f2003-09-23Henrik Grubbström (Grubba)  OPCODE0_TAILPTRJUMP(F_RECUR, "recur", I_UPDATE_ALL, {
b23b112001-08-15Fredrik Hübinette (Hubbe)  DO_RECUR(0);
610d052001-07-06Henrik Grubbström (Grubba)  }); });
6fd5172000-04-25Fredrik Hübinette (Hubbe) 
f822262001-07-16Fredrik Hübinette (Hubbe) /* Ugly code duplication */
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE0_PTRJUMP(F_RECUR_AND_POP, "recur & pop", I_UPDATE_ALL, {
b23b112001-08-15Fredrik Hübinette (Hubbe)  DO_RECUR(PIKE_FRAME_RETURN_POP);
f822262001-07-16Fredrik Hübinette (Hubbe) });
873ceb2000-04-30Fredrik Hübinette (Hubbe) /* Assume that the number of arguments is correct */
17f08c2000-07-06Fredrik Hübinette (Hubbe) /* FIXME: adjust Pike_mark_sp */
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE0_PTRJUMP(F_TAIL_RECUR, "tail recursion", I_UPDATE_ALL, {
a222992000-08-07Henrik Grubbström (Grubba)  INT32 num_locals;
eff6212001-07-09Henrik Grubbström (Grubba)  PIKE_OPCODE_T *addr;
b23b112001-08-15Fredrik Hübinette (Hubbe)  INT32 args;
6fd5172000-04-25Fredrik Hübinette (Hubbe)  fast_check_threads_etc(6);
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (addr); addr += GET_JUMP();
4686dd2002-11-12Henrik Grubbström (Grubba)  num_locals = READ_INCR_BYTE(addr); args = READ_INCR_BYTE(addr); addr += ENTRY_PROLOGUE_SIZE;
c378ff2002-11-14Marcus Comstedt  SET_PROG_COUNTER(addr);
6fd5172000-04-25Fredrik Hübinette (Hubbe) 
17f08c2000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp-args != Pike_fp->locals)
6fd5172000-04-25Fredrik Hübinette (Hubbe)  {
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_DEBUG({ if (Pike_sp < Pike_fp->locals + args)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Pike_sp (%p) < Pike_fp->locals (%p) + args (%d)\n",
610d052001-07-06Henrik Grubbström (Grubba)  Pike_sp, Pike_fp->locals, args); });
17f08c2000-07-06Fredrik Hübinette (Hubbe)  assign_svalues(Pike_fp->locals, Pike_sp-args, args, BIT_MIXED); pop_n_elems(Pike_sp - (Pike_fp->locals + args));
6fd5172000-04-25Fredrik Hübinette (Hubbe)  }
b23b112001-08-15Fredrik Hübinette (Hubbe)  push_zeroes(num_locals - args);
6fd5172000-04-25Fredrik Hübinette (Hubbe) 
610d052001-07-06Henrik Grubbström (Grubba)  DO_IF_DEBUG({ if(Pike_sp != Pike_fp->locals + Pike_fp->num_locals)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Sp whacked!\n");
610d052001-07-06Henrik Grubbström (Grubba)  });
e87fe82001-07-26Henrik Grubbström (Grubba) 
c378ff2002-11-14Marcus Comstedt  FETCH;
f142842003-08-06Martin Stjernholm  JUMP_DONE;
610d052001-07-06Henrik Grubbström (Grubba) });
d49add2001-04-25Fredrik Hübinette (Hubbe) 
f142842003-08-06Martin Stjernholm #if 0 /* This opcode needs mending if it is to work with machine code. */ OPCODE0_JUMP(F_BREAKPOINT, "breakpoint", 0, {
d49add2001-04-25Fredrik Hübinette (Hubbe)  extern void o_breakpoint(void);
2454752001-07-10Henrik Grubbström (Grubba)  o_breakpoint();
e87fe82001-07-26Henrik Grubbström (Grubba)  DO_JUMP_TO(PROG_COUNTER-1);
610d052001-07-06Henrik Grubbström (Grubba) });
f142842003-08-06Martin Stjernholm #endif
0811472001-07-02Fredrik Hübinette (Hubbe) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE1(F_THIS_OBJECT, "this_object", I_UPDATE_SP, {
0ee38f2002-05-11Martin Stjernholm  struct object *o = Pike_fp->current_object;
aa7e422003-08-03Martin Stjernholm  int level; for (level = 0; level < arg1; level++) {
0ee38f2002-05-11Martin Stjernholm  struct program *p = o->prog; if (!p)
aa7e422003-08-03Martin Stjernholm  Pike_error ("Object %d level(s) up is destructed - cannot get the parent.\n", level); if (!(p->flags & PROGRAM_USES_PARENT)) /* FIXME: Ought to write out the object here. */ Pike_error ("Object %d level(s) up lacks parent reference.\n", level);
0ee38f2002-05-11Martin Stjernholm  o = PARENT_INFO(o)->parent; } ref_push_object(o);
28553d2003-08-03Martin Stjernholm  });
0811472001-07-02Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE0(F_ZERO_TYPE, "zero_type", 0, {
0811472001-07-02Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type != T_INT) {
eaa4da2001-10-04Fredrik Hübinette (Hubbe)  if((Pike_sp[-1].type==T_OBJECT || Pike_sp[-1].type==T_FUNCTION) && !Pike_sp[-1].u.object->prog) { pop_stack(); push_int(NUMBER_DESTRUCTED); }else{ pop_stack(); push_int(0); }
0811472001-07-02Fredrik Hübinette (Hubbe)  }else{ Pike_sp[-1].u.integer=Pike_sp[-1].subtype; Pike_sp[-1].subtype=NUMBER_NUMBER; }
610d052001-07-06Henrik Grubbström (Grubba) });
7080882001-07-15Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm /*
7080882001-07-15Fredrik Hübinette (Hubbe) #undef PROG_COUNTER
2bcc0d2002-05-11Martin Stjernholm */