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.
902cc92007-06-11Henrik Grubbström (Grubba) || $Id: interpret_functions.h,v 1.194 2007/06/11 16:13:27 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_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
7c1e422004-09-22Henrik Grubbström (Grubba) #ifndef LOCAL_VAR #define LOCAL_VAR(X) X #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", \
e055572004-03-12Martin Stjernholm  Pike_fp->return_addr)); \ DO_JUMP_TO(Pike_fp->return_addr); \
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 { \
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); \ index_no_free(&tmp,Pike_sp-2,Pike_sp-1); \ pop_2_elems(); \
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp, &tmp); \
7c1e422004-09-22Henrik Grubbström (Grubba)  Pike_sp++; \ print_return_value(); \ }while(0)
7080882001-07-15Fredrik Hübinette (Hubbe) 
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, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o); LOCAL_VAR(struct svalue tmp);
fa002a2004-12-18Henrik Grubbström (Grubba)  LOCAL_VAR(struct program *p);
a5cd6a2001-09-24Henrik Grubbström (Grubba) 
fa002a2004-12-18Henrik Grubbström (Grubba)  if ((Pike_sp[-1].type == T_OBJECT) && (p = (o = Pike_sp[-1].u.object)->prog) && (FIND_LFUN(p = o->prog->inherits[Pike_sp[-1].subtype].prog, LFUN_ARROW) == -1)) { int id = FIND_LFUN(p, arg1);
286afb2001-02-05Henrik Grubbström (Grubba)  if ((id != -1) &&
fa002a2004-12-18Henrik Grubbström (Grubba)  (!(p->identifier_references[id].id_flags &
286afb2001-02-05Henrik Grubbström (Grubba)  (ID_STATIC|ID_PRIVATE|ID_HIDDEN)))) {
08549a2004-12-18Henrik Grubbström (Grubba)  id += o->prog->inherits[Pike_sp[-1].subtype].identifier_level;
286afb2001-02-05Henrik Grubbström (Grubba)  low_object_index_no_free(&tmp, o, id); } else { /* Not found. */ tmp.type = T_INT;
eaaac12004-10-06Martin Stjernholm  tmp.subtype = NUMBER_UNDEFINED;
286afb2001-02-05Henrik Grubbström (Grubba)  tmp.u.integer = 0; } } else {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp2);
286afb2001-02-05Henrik Grubbström (Grubba)  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);
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp - 1, &tmp);
286afb2001-02-05Henrik Grubbström (Grubba)  print_return_value();
610d052001-07-06Henrik Grubbström (Grubba) });
286afb2001-02-05Henrik Grubbström (Grubba) 
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, {
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  struct pike_frame *f=Pike_fp;
275bca2004-09-23Henrik Grubbström (Grubba)  DO_IF_DEBUG(INT32 arg2_ = arg2;)
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o); o = low_clone(pike_trampoline_program);
5cdf732002-05-15Henrik Grubbström (Grubba)  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, {
aea67f2004-12-04Henrik Grubbström (Grubba)  low_index_current_object_no_free(Pike_sp, arg1);
610d052001-07-06Henrik Grubbström (Grubba)  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, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(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) 
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE2(F_EXTERNAL_LVALUE, "& external", I_UPDATE_SP, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct external_variable_context loc);
342fef2000-08-23Fredrik Hübinette (Hubbe)  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);
4ece762005-06-20Henrik Grubbström (Grubba)  push_obj_index(arg1 + loc.inherit->identifier_level);
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, {
a96ce92000-04-19Fredrik Hübinette (Hubbe)  free_svalue(Pike_fp->locals + arg2);
aea67f2004-12-04Henrik Grubbström (Grubba)  low_index_current_object_no_free(Pike_fp->locals + arg2, arg1);
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? */
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp, Pike_sp - 1);
f102d22000-04-19Henrik Grubbström (Grubba)  Pike_sp[-1].type = T_ARRAY_LVALUE; 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;
eaaac12004-10-06Martin Stjernholm  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER;
7951942000-04-20Fredrik Hübinette (Hubbe)  Pike_fp->locals[arg1].u.integer = 0; Pike_fp->locals[arg1+1].type = PIKE_T_INT;
eaaac12004-10-06Martin Stjernholm  Pike_fp->locals[arg1+1].subtype = NUMBER_NUMBER;
7951942000-04-20Fredrik Hübinette (Hubbe)  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;
eaaac12004-10-06Martin Stjernholm  Pike_fp->locals[arg1+e].subtype = NUMBER_NUMBER;
7951942000-04-20Fredrik Hübinette (Hubbe)  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;
eaaac12004-10-06Martin Stjernholm  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER;
7951942000-04-20Fredrik Hübinette (Hubbe)  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));
eaaac12004-10-06Martin Stjernholm  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
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++;
eaaac12004-10-06Martin Stjernholm  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
cc75b62000-04-21Henrik Grubbström (Grubba)  } 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++;
eaaac12004-10-06Martin Stjernholm  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
cc75b62000-04-21Henrik Grubbström (Grubba)  } 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));
eaaac12004-10-06Martin Stjernholm  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
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--;
eaaac12004-10-06Martin Stjernholm  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
cc75b62000-04-21Henrik Grubbström (Grubba)  } 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) 
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--;
eaaac12004-10-06Martin Stjernholm  Pike_fp->locals[arg1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
cc75b62000-04-21Henrik Grubbström (Grubba)  } 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);
408a1e2004-10-30Martin Stjernholm 
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp, Pike_sp - 1);
f102d22000-04-19Henrik Grubbström (Grubba)  Pike_sp[-1].type = PIKE_T_INT; Pike_sp++; lvalue_to_svalue_no_free(Pike_sp-2, Pike_sp-4);
eaaac12004-10-06Martin Stjernholm  /* This is so that foo+=bar (and similar things) will be faster. * It's 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.
f102d22000-04-19Henrik Grubbström (Grubba)  */ if( (1 << Pike_sp[-2].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); tmp.type = PIKE_T_INT;
eaaac12004-10-06Martin Stjernholm  tmp.subtype = NUMBER_NUMBER;
7c1e422004-09-22Henrik Grubbström (Grubba)  tmp.u.integer = 0; assign_lvalue(Pike_sp-4, &tmp);
f102d22000-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_LTOSVAL3, "ltosval3", I_UPDATE_SP, {
408a1e2004-10-30Martin Stjernholm  dmalloc_touch_svalue(Pike_sp-4); dmalloc_touch_svalue(Pike_sp-3); dmalloc_touch_svalue(Pike_sp-2); dmalloc_touch_svalue(Pike_sp-1);
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp, Pike_sp - 1); move_svalue (Pike_sp - 1, Pike_sp - 2);
b99ff82001-06-07Fredrik Hübinette (Hubbe)  Pike_sp[-2].type = PIKE_T_INT; Pike_sp++; lvalue_to_svalue_no_free(Pike_sp-3, Pike_sp-5);
eaaac12004-10-06Martin Stjernholm  /* This is so that foo=foo[x..y] (and similar things) will be faster. * It's 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.
b99ff82001-06-07Fredrik Hübinette (Hubbe)  */ if( (1 << Pike_sp[-3].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); tmp.type = PIKE_T_INT;
eaaac12004-10-06Martin Stjernholm  tmp.subtype = NUMBER_NUMBER;
7c1e422004-09-22Henrik Grubbström (Grubba)  tmp.u.integer = 0; assign_lvalue(Pike_sp-5, &tmp);
b99ff82001-06-07Fredrik Hübinette (Hubbe)  }
610d052001-07-06Henrik Grubbström (Grubba) });
b99ff82001-06-07Fredrik Hübinette (Hubbe) 
408a1e2004-10-30Martin Stjernholm OPCODE0(F_LTOSVAL1, "ltosval1", I_UPDATE_SP, { dmalloc_touch_svalue(Pike_sp-2); dmalloc_touch_svalue(Pike_sp-1); lvalue_to_svalue_no_free(Pike_sp, Pike_sp-2); Pike_sp++; /* See ltosval3. This opcode is used e.g. in foo = foo[..] where no * bound arguments are pushed on the stack. */ if( (1 << Pike_sp[-1].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) { LOCAL_VAR(struct svalue tmp); tmp.type = PIKE_T_INT; tmp.subtype = NUMBER_NUMBER; tmp.u.integer = 0; assign_lvalue(Pike_sp-3, &tmp); } });
8f0eac2003-08-13Henrik Grubbström (Grubba) OPCODE0(F_ADD_TO, "+=", I_UPDATE_SP, {
902cc92007-06-11Henrik Grubbström (Grubba)  ONERROR uwp;
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp, Pike_sp - 1);
d2154e2003-04-07Henrik Grubbström (Grubba)  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);
eaaac12004-10-06Martin Stjernholm  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
d2154e2003-04-07Henrik Grubbström (Grubba)  assign_lvalue(Pike_sp-4,Pike_sp-1); Pike_sp-=2; pop_2_elems(); push_int(val); goto add_to_done; } }
eaaac12004-10-06Martin Stjernholm  /* This is so that foo+=bar (and similar things) will be faster. * It's 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.
d2154e2003-04-07Henrik Grubbström (Grubba)  */ if( (1 << Pike_sp[-2].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); tmp.type=PIKE_T_INT;
eaaac12004-10-06Martin Stjernholm  tmp.subtype=NUMBER_NUMBER;
7c1e422004-09-22Henrik Grubbström (Grubba)  tmp.u.integer=0; assign_lvalue(Pike_sp-4, &tmp);
d2154e2003-04-07Henrik Grubbström (Grubba)  } else if (Pike_sp[-2].type == T_OBJECT) { /* One ref in the lvalue, and one on the stack. */
fb72c92003-11-10Martin Stjernholm  int i;
fa002a2004-12-18Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o); LOCAL_VAR(struct program *p); if((o = Pike_sp[-2].u.object)->refs <= 2 && (p = o->prog) && (i = FIND_LFUN(p->inherits[Pike_sp[-2].subtype].prog, LFUN_ADD_EQ)) != -1)
d2154e2003-04-07Henrik Grubbström (Grubba)  {
08549a2004-12-18Henrik Grubbström (Grubba)  apply_low(o, i + p->inherits[Pike_sp[-2].subtype].identifier_level, 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)  } }
902cc92007-06-11Henrik Grubbström (Grubba)  /* NOTE: Pike_sp-4 is the lvalue, Pike_sp-2 is the original value. * If an error gets thrown, the original value will thus be restored. * If f_add() succeeds, Pike_sp-2 will hold the result. */ SET_ONERROR(uwp, o_assign_lvalue, Pike_sp-4);
d2154e2003-04-07Henrik Grubbström (Grubba)  f_add(2);
902cc92007-06-11Henrik Grubbström (Grubba)  CALL_AND_UNSET_ONERROR(uwp); /* 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, {
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp, Pike_sp - 1);
f102d22000-04-19Henrik Grubbström (Grubba)  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;
eaaac12004-10-06Martin Stjernholm  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
b1d0682001-06-16Per Hedbor  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  } }
eaaac12004-10-06Martin Stjernholm  /* This is so that foo+=bar (and similar things) will be faster. * It's 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.
f102d22000-04-19Henrik Grubbström (Grubba)  */ if( (1 << Pike_sp[-2].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); tmp.type=PIKE_T_INT;
eaaac12004-10-06Martin Stjernholm  tmp.subtype=NUMBER_NUMBER;
7c1e422004-09-22Henrik Grubbström (Grubba)  tmp.u.integer=0; assign_lvalue(Pike_sp-4, &tmp);
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. */
fb72c92003-11-10Martin Stjernholm  int i;
fa002a2004-12-18Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o); LOCAL_VAR(struct program *p); if((o = Pike_sp[-2].u.object)->refs <= 2 && (p = o->prog) && (i = FIND_LFUN(p->inherits[Pike_sp[-2].subtype].prog, LFUN_ADD_EQ)) != -1)
6af7592003-04-07Henrik Grubbström (Grubba)  {
08549a2004-12-18Henrik Grubbström (Grubba)  apply_low(o, i + p->inherits[Pike_sp[-2].subtype].identifier_level, 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);
2673dd2005-06-20Henrik Grubbström (Grubba)  push_obj_index(arg1 + Pike_fp->context.identifier_level);
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);
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp - 3, Pike_sp - 1);
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);
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_fp->locals + arg2, 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);
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_fp->locals + arg1, 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, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp);
7951942000-04-20Fredrik Hübinette (Hubbe)  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)); */
fa002a2004-12-18Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o);
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_OBJECT &&
fa002a2004-12-18Henrik Grubbström (Grubba)  (o = Pike_sp[-1].u.object)->prog)
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  {
fa002a2004-12-18Henrik Grubbström (Grubba)  int fun = FIND_LFUN(o->prog->inherits[Pike_sp[-1].subtype].prog, LFUN__IS_TYPE);
d9a93b2001-07-01Fredrik Hübinette (Hubbe)  if(fun != -1) { /* fprintf(stderr,"******OBJECT OVERLOAD IN TYPEP***** %s\n",get_name_of_type(arg1)); */ push_text(get_name_of_type(arg1));
ffd2e22004-12-18Henrik Grubbström (Grubba)  apply_low(o, fun + o->prog->inherits[Pike_sp[-2].subtype].identifier_level, 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);
f5971b2004-11-27Martin Stjernholm CJUMP(F_BRANCH_WHEN_LE, "branch if <=", is_le);
68296f2001-07-07Henrik Grubbström (Grubba) CJUMP(F_BRANCH_WHEN_GT, "branch if >", is_gt);
f5971b2004-11-27Martin Stjernholm CJUMP(F_BRANCH_WHEN_GE, "branch if >=", is_ge);
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) 
24b1132006-03-09Henrik Grubbström (Grubba) #ifndef ENTRY_PROLOGUE_SIZE #define ENTRY_PROLOGUE_SIZE 0 #endif
ca176b2006-02-27Martin Stjernholm /* Ideally this ought to be an OPCODE0_PTRRETURN but I don't fancy * adding that variety to this macro hell. At the end of the day there * wouldn't be any difference anyway afaics. /mast */
9a498f2003-09-23Henrik Grubbström (Grubba) OPCODE0_PTRJUMP(F_CATCH, "catch", I_UPDATE_ALL, {
ca176b2006-02-27Martin Stjernholm  PIKE_OPCODE_T *addr;
eff6212001-07-09Henrik Grubbström (Grubba)  {
ca176b2006-02-27Martin Stjernholm  struct catch_context *new_catch_ctx = alloc_catch_context(); DO_IF_REAL_DEBUG ( new_catch_ctx->frame = Pike_fp; init_recovery (&new_catch_ctx->recovery, 0, 0, PERR_LOCATION()); ); DO_IF_NOT_REAL_DEBUG ( init_recovery (&new_catch_ctx->recovery, 0); ); new_catch_ctx->save_expendible = Pike_fp->expendible; JUMP_SET_TO_PC_AT_NEXT (addr);
a38a222006-03-15Henrik Grubbström (Grubba)  new_catch_ctx->continue_reladdr = GET_JUMP() /* We need to run the entry prologue... */ - ENTRY_PROLOGUE_SIZE;
ca176b2006-02-27Martin Stjernholm  new_catch_ctx->next_addr = addr; new_catch_ctx->prev = Pike_interpreter.catch_ctx; Pike_interpreter.catch_ctx = new_catch_ctx;
002f3b2006-03-10Henrik Grubbström (Grubba)  DO_IF_DEBUG({ TRACE((3,"- Pushed catch context %p\n", new_catch_ctx)); });
ca176b2006-02-27Martin Stjernholm  } Pike_fp->expendible = Pike_fp->locals + Pike_fp->num_locals;
fe970b2006-03-07Henrik Grubbström (Grubba)  /* Need to adjust next_addr by sizeof(INT32) to skip past the jump * address to the continue position after the catch block. */ addr = (PIKE_OPCODE_T *) ((INT32 *) addr + 1);
ca176b2006-02-27Martin Stjernholm  if (Pike_interpreter.catching_eval_jmpbuf) { /* There's already a catching_eval_instruction around our * eval_instruction, so we can just continue. */ debug_malloc_touch_named (Pike_interpreter.catch_ctx, "(1)");
a38a222006-03-15Henrik Grubbström (Grubba)  /* Skip past the entry prologue... */
fe970b2006-03-07Henrik Grubbström (Grubba)  addr += ENTRY_PROLOGUE_SIZE; SET_PROG_COUNTER(addr); FETCH;
002f3b2006-03-10Henrik Grubbström (Grubba)  DO_IF_DEBUG({ TRACE((3,"- In active catch; continuing at %p\n", addr)); });
fe970b2006-03-07Henrik Grubbström (Grubba)  JUMP_DONE;
ca176b2006-02-27Martin Stjernholm  } else { debug_malloc_touch_named (Pike_interpreter.catch_ctx, "(2)"); check_c_stack(8192); while (1) { /* Loop here every time an exception is caught. Once we've * gotten here and set things up to run eval_instruction from * inside catching_eval_instruction, we keep doing it until it's * time to return. */
e7dc1c2006-04-25David Hedbor  int res;
002f3b2006-03-10Henrik Grubbström (Grubba)  DO_IF_DEBUG({ TRACE((3,"- Activating catch; calling %p in context %p\n", addr, Pike_interpreter.catch_ctx)); });
e7dc1c2006-04-25David Hedbor  res = catching_eval_instruction (addr);
ca176b2006-02-27Martin Stjernholm 
a38a222006-03-15Henrik Grubbström (Grubba)  DO_IF_DEBUG({ TRACE((3,"- catching_eval_instruction(%p) returned %d\n", addr, res)); });
ca176b2006-02-27Martin Stjernholm  if (res != -3) { /* There was an inter return inside the evaluated code. Just * propagate it. */
002f3b2006-03-10Henrik Grubbström (Grubba)  DO_IF_DEBUG ({ TRACE((3,"- Returning from catch.\n")); if (res != -1) Pike_fatal ("Unexpected return value from " "catching_eval_instruction: %d\n", res); });
ca176b2006-02-27Martin Stjernholm  break; } else { /* Caught an exception. */ struct catch_context *cc = Pike_interpreter.catch_ctx;
002f3b2006-03-10Henrik Grubbström (Grubba)  DO_IF_DEBUG ({ TRACE((3,"- Caught exception. catch context: %p\n", cc)); if (!cc) Pike_fatal ("Catch context dropoff.\n"); if (cc->frame != Pike_fp) Pike_fatal ("Catch context doesn't belong to this frame.\n"); });
ca176b2006-02-27Martin Stjernholm  debug_malloc_touch_named (cc, "(3)"); UNSETJMP (cc->recovery); Pike_fp->expendible = cc->save_expendible; move_svalue (Pike_sp++, &throw_value); throw_value.type=T_INT; low_destruct_objects_to_destruct(); if (cc->continue_reladdr < 0) fast_check_threads_etc(6); addr = cc->next_addr + cc->continue_reladdr;
002f3b2006-03-10Henrik Grubbström (Grubba)  DO_IF_DEBUG({ TRACE((3,"- Popping catch context %p ==> %p\n", cc, cc->prev)); if (!addr) Pike_fatal ("Unexpected null continue addr.\n"); });
ca176b2006-02-27Martin Stjernholm  Pike_interpreter.catch_ctx = cc->prev; really_free_catch_context (cc); } } INTER_RETURN;
a092ba2001-07-06Henrik Grubbström (Grubba)  }
610d052001-07-06Henrik Grubbström (Grubba) });
87c7592000-04-18Fredrik Hübinette (Hubbe) 
ca176b2006-02-27Martin Stjernholm OPCODE0(F_ESCAPE_CATCH, "escape catch", 0, { POP_CATCH_CONTEXT;
610d052001-07-06Henrik Grubbström (Grubba) });
b7c1ee2001-01-10Martin Stjernholm 
ca176b2006-02-27Martin Stjernholm OPCODE0(F_EXIT_CATCH, "exit catch", I_UPDATE_SP, {
9307b42002-09-23Martin Stjernholm  push_undefined();
ca176b2006-02-27Martin Stjernholm  POP_CATCH_CONTEXT;
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;
f142842003-08-06Martin Stjernholm  PIKE_OPCODE_T *addr;
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp2);
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (addr);
7c1e422004-09-22Henrik Grubbström (Grubba)  index_no_free(&tmp2, Pike_sp-2, Pike_sp-1);
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp++, &tmp2);
6e36e52000-11-30Fredrik Hübinette (Hubbe)  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) 
eaaac12004-10-06Martin Stjernholm OPCODE0_BRANCH(F_FOREACH, "foreach", 0, { /* array, lvalue, 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)
eaaac12004-10-06Martin Stjernholm  /* Isn't this an internal compiler error? /mast */
dc8f722001-07-08Henrik Grubbström (Grubba)  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++;
eaaac12004-10-06Martin Stjernholm  DO_IF_DEBUG ( if (Pike_sp[-1].subtype) Pike_fatal ("Got unexpected subtype in loop variable.\n"); );
dc8f722001-07-08Henrik Grubbström (Grubba)  }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"); );
fa002a2004-12-18Henrik Grubbström (Grubba)  /* FIXME: object subtype. */
f139182003-09-05Martin Stjernholm  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"); );
fa002a2004-12-18Henrik Grubbström (Grubba)  /* FIXME: object subtype. */
f139182003-09-05Martin Stjernholm  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
eaaac12004-10-06Martin Stjernholm  ) {
bac71b2000-04-19Henrik Grubbström (Grubba)  Pike_sp[-1].u.integer =- Pike_sp[-1].u.integer;
eaaac12004-10-06Martin Stjernholm  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */ }
bac71b2000-04-19Henrik Grubbström (Grubba)  } 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;
eaaac12004-10-06Martin Stjernholm  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
bac71b2000-04-19Henrik Grubbström (Grubba)  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;
eaaac12004-10-06Martin Stjernholm  Pike_sp[-1].subtype = NUMBER_NUMBER;
bac71b2000-04-19Henrik Grubbström (Grubba)  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));
f5971b2004-11-27Martin Stjernholm COMPARISON(F_GE, ">=", is_ge(Pike_sp-2,Pike_sp-1));
68296f2001-07-07Henrik Grubbström (Grubba) COMPARISON(F_LT, "<", is_lt(Pike_sp-2,Pike_sp-1));
f5971b2004-11-27Martin Stjernholm COMPARISON(F_LE, "<=", is_le(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;
eaaac12004-10-06Martin Stjernholm  Pike_sp[-2].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
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;
eaaac12004-10-06Martin Stjernholm  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
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;
eaaac12004-10-06Martin Stjernholm  Pike_sp[-1].subtype = NUMBER_NUMBER; /* Could have UNDEFINED there before. */
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, {
fa002a2004-12-18Henrik Grubbström (Grubba)  int i;
08549a2004-12-18Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o);
fa002a2004-12-18Henrik Grubbström (Grubba)  LOCAL_VAR(struct program *p);
9b22582000-04-18Henrik Grubbström (Grubba)  switch(Pike_sp[-1].type) { default: PIKE_ERROR("@", "Bad argument.\n", Pike_sp, 1); case PIKE_T_OBJECT:
08549a2004-12-18Henrik Grubbström (Grubba)  if(!(p = (o = Pike_sp[-1].u.object)->prog) ||
fa002a2004-12-18Henrik Grubbström (Grubba)  (i = FIND_LFUN(p->inherits[Pike_sp[-1].subtype].prog, LFUN__VALUES)) == -1)
9b22582000-04-18Henrik Grubbström (Grubba)  PIKE_ERROR("@", "Bad argument.\n", Pike_sp, 1);
08549a2004-12-18Henrik Grubbström (Grubba)  apply_low(o, i + p->inherits[Pike_sp[-1].subtype].identifier_level, 0);
9b22582000-04-18Henrik Grubbström (Grubba)  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);
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp - 2, 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, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue *s); s = Pike_fp->locals + arg1;
9b22582000-04-18Henrik Grubbström (Grubba)  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, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue *s); LOCAL_VAR(struct svalue tmp); 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);
b13d222004-09-30Martin Stjernholm  move_svalue (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, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue *s); LOCAL_VAR(struct svalue tmp);
aea67f2004-12-04Henrik Grubbström (Grubba)  low_index_current_object_no_free(Pike_sp, arg1);
9b22582000-04-18Henrik Grubbström (Grubba)  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);
b13d222004-09-30Martin Stjernholm  move_svalue (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, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp);
9b22582000-04-18Henrik Grubbström (Grubba)  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, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); LOCAL_VAR(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);
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp - 1, &tmp2);
9b22582000-04-18Henrik Grubbström (Grubba)  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, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); LOCAL_VAR(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);
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp - 1, &tmp2);
372a652000-04-18Henrik Grubbström (Grubba)  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, {
fe970b2006-03-07Henrik Grubbström (Grubba)  push_int((ptrdiff_t)(int)arg1);
7080882001-07-15Fredrik Hübinette (Hubbe)  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) {
257fcd2006-08-15Henrik Grubbström (Grubba)  o_check_soft_cast(Pike_sp-1, Pike_sp[-2].u.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) 
408a1e2004-10-30Martin Stjernholm OPCODE1_ALIAS(F_RANGE, "range", I_UPDATE_SP, o_range2);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2bcc0d2002-05-11Martin Stjernholm OPCODE0(F_COPY_VALUE, "copy_value", 0, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp);
372a652000-04-18Henrik Grubbström (Grubba)  copy_svalues_recursively_no_free(&tmp,Pike_sp-1,1,0); free_svalue(Pike_sp-1);
b13d222004-09-30Martin Stjernholm  move_svalue (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, {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); lvalue_to_svalue_no_free(&tmp, Pike_sp-2); if(tmp.type != PIKE_T_STRING)
372a652000-04-18Henrik Grubbström (Grubba)  {
b23b112001-08-15Fredrik Hübinette (Hubbe)  pop_2_elems();
b13d222004-09-30Martin Stjernholm  move_svalue (Pike_sp, &tmp);
372a652000-04-18Henrik Grubbström (Grubba)  Pike_sp++; }else{
af7f162004-10-01Henrik Grubbström (Grubba)  struct string_assignment_storage *s;
cf22d72004-10-01Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o);
372a652000-04-18Henrik Grubbström (Grubba)  o=low_clone(string_assignment_program);
b13d222004-09-30Martin Stjernholm  s = (struct string_assignment_storage *)o->storage; move_svalue (s->lval, Pike_sp - 2); move_svalue (s->lval + 1, Pike_sp - 1); s->s=tmp.u.string;
372a652000-04-18Henrik Grubbström (Grubba)  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, \
e055572004-03-12Martin Stjernholm  I_UPDATE_ALL, { \ JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \
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", \
e055572004-03-12Martin Stjernholm  I_UPDATE_ALL, { \ JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \
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, \
e055572004-03-12Martin Stjernholm  I_UPDATE_ALL, { \ JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \
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", \
e055572004-03-12Martin Stjernholm  I_UPDATE_ALL, { \ JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr); \
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) 
e055572004-03-12Martin Stjernholm OPCODE1_JUMP(F_CALL_OTHER,"call other", I_UPDATE_ALL, {
a8aed22001-08-15Fredrik Hübinette (Hubbe)  INT32 args=DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp));
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue *s); s = Pike_sp-args;
e055572004-03-12Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if(s->type == T_OBJECT) {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o); LOCAL_VAR(struct program *p); o = s->u.object;
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if((p=o->prog)) {
fa002a2004-12-18Henrik Grubbström (Grubba)  p = p->inherits[s->subtype].prog;
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if(FIND_LFUN(p, LFUN_ARROW) == -1) { int fun; fun=find_shared_string_identifier(Pike_fp->context.prog->strings[arg1], p); if(fun >= 0) {
08549a2004-12-18Henrik Grubbström (Grubba)  fun += o->prog->inherits[s->subtype].identifier_level;
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)  } } } } {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); LOCAL_VAR(struct svalue tmp2);
a8aed22001-08-15Fredrik Hübinette (Hubbe)  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);
b13d222004-09-30Martin Stjernholm  move_svalue (s, &tmp2);
a8aed22001-08-15Fredrik Hübinette (Hubbe)  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)  } });
e055572004-03-12Martin Stjernholm OPCODE1_JUMP(F_CALL_OTHER_AND_POP,"call other & pop", I_UPDATE_ALL, {
a8aed22001-08-15Fredrik Hübinette (Hubbe)  INT32 args=DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp));
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue *s); s = Pike_sp-args;
e055572004-03-12Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if(s->type == T_OBJECT) {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o); LOCAL_VAR(struct program *p); o = s->u.object;
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if((p=o->prog)) {
fa002a2004-12-18Henrik Grubbström (Grubba)  p = p->inherits[s->subtype].prog;
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if(FIND_LFUN(p, LFUN_ARROW) == -1) { int fun; fun=find_shared_string_identifier(Pike_fp->context.prog->strings[arg1], p); if(fun >= 0) {
08549a2004-12-18Henrik Grubbström (Grubba)  fun += o->prog->inherits[s->subtype].identifier_level;
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)  } } } } {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); LOCAL_VAR(struct svalue tmp2);
a8aed22001-08-15Fredrik Hübinette (Hubbe)  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);
b13d222004-09-30Martin Stjernholm  move_svalue (s, &tmp2);
a8aed22001-08-15Fredrik Hübinette (Hubbe)  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));
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue *s); s = Pike_sp - args;
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if(s->type == T_OBJECT) {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o); LOCAL_VAR(struct program *p); o = s->u.object;
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if((p=o->prog)) {
fa002a2004-12-18Henrik Grubbström (Grubba)  p = p->inherits[s->subtype].prog;
a8aed22001-08-15Fredrik Hübinette (Hubbe)  if(FIND_LFUN(p, LFUN_ARROW) == -1) { int fun; fun=find_shared_string_identifier(Pike_fp->context.prog->strings[arg1], p); if(fun >= 0) {
08549a2004-12-18Henrik Grubbström (Grubba)  fun += o->prog->inherits[s->subtype].identifier_level;
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; } } } } {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue tmp); LOCAL_VAR(struct svalue tmp2);
a8aed22001-08-15Fredrik Hübinette (Hubbe)  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);
b13d222004-09-30Martin Stjernholm  move_svalue (s, &tmp2);
a8aed22001-08-15Fredrik Hübinette (Hubbe)  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; \
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct svalue *s); \ s = &Pike_fp->context.prog->constants[arg1].sval; \
bd8fb82004-04-03Martin Stjernholm  if(Pike_interpreter.trace_level) \
70be662001-06-19Fredrik Hübinette (Hubbe)  { \
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(dynamic_buffer save_buf); \
9fa0ee2003-11-09Martin Stjernholm  init_buf(&save_buf); \
bd8fb82004-04-03Martin Stjernholm  if (s->u.efun->name->size_shift) \ my_strcat ("[widestring function name]"); \ else \ my_strcat (s->u.efun->name->str); \
9fa0ee2003-11-09Martin Stjernholm  do_trace_call(args, &save_buf); \
70be662001-06-19Fredrik Hübinette (Hubbe)  } \ (*(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) \
2d76f22005-05-20Martin Stjernholm  Pike_fatal("Function left %"PRINTPTRDIFFT"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); \ } \
bd8fb82004-04-03Martin Stjernholm  if(Pike_interpreter.trace_level>1) { \
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(dynamic_buffer save_buf); \
bd8fb82004-04-03Martin Stjernholm  init_buf(&save_buf); \ if (s->u.efun->name->size_shift) \ my_strcat ("[widestring function name]"); \ else \ my_strcat (s->u.efun->name->str); \ my_strcat ("() "); \ do_trace_return (Pike_sp>expected_stack, &save_buf); \ } \
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); \
e055572004-03-12Martin Stjernholm  Pike_fp->return_addr = (PIKE_OPCODE_T *)(((INT32 *) addr) + 1); \
f142842003-08-06Martin Stjernholm  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); \
b2630d2004-05-20Henrik Grubbström (Grubba)  \ DO_IF_PROFILING({ \ new_frame->start_time = \ get_cpu_time() - Pike_interpreter.unlocked_time; \ new_frame->ident = Pike_fp->ident; \ new_frame->children_base = Pike_interpreter.accounted_time; \ new_frame->context.prog->identifiers[new_frame->ident].num_calls++; \ DO_IF_PROFILING_DEBUG({ \ fprintf(stderr, "%p{: Push at %" PRINT_CPU_TIME \ " %" PRINT_CPU_TIME "\n", \ Pike_interpreter.thread_state, new_frame->start_time, \ new_frame->children_base); \ }); \ }); \ \
b23b112001-08-15Fredrik Hübinette (Hubbe)  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 */
e055572004-03-12Martin Stjernholm OPCODE1_PTRJUMP(F_COND_RECUR, "recur if not overloaded", I_UPDATE_ALL, {
f142842003-08-06Martin Stjernholm  PIKE_OPCODE_T *addr;
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct program *p); p = Pike_fp->current_object->prog;
f142842003-08-06Martin Stjernholm  JUMP_SET_TO_PC_AT_NEXT (addr);
e055572004-03-12Martin Stjernholm  Pike_fp->return_addr = (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, {
aa7e422003-08-03Martin Stjernholm  int level;
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct object *o); o = Pike_fp->current_object;
aa7e422003-08-03Martin Stjernholm  for (level = 0; level < arg1; level++) {
7c1e422004-09-22Henrik Grubbström (Grubba)  LOCAL_VAR(struct program *p); p = o->prog;
0ee38f2002-05-11Martin Stjernholm  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) 
e965d02004-08-26Henrik Grubbström (Grubba) OPCODE0(F_SWAP,"swap",0,{ stack_swap(); }); OPCODE0(F_DUP,"dup",I_UPDATE_SP,{ stack_dup(); });
c403392004-12-18Henrik Grubbström (Grubba) OPCODE2(F_THIS, "this", I_UPDATE_SP, { LOCAL_VAR(struct external_variable_context loc); loc.o = Pike_fp->current_object; loc.parent_identifier = Pike_fp->fun; if (loc.o->prog) loc.inherit = INHERIT_FROM_INT(loc.o->prog, loc.parent_identifier); find_external_context(&loc, arg1); DO_IF_DEBUG({ TRACE((5,"- Identifier=%d Offset=%d\n", arg1, loc.inherit->identifier_level)); });
a781482004-12-19Henrik Grubbström (Grubba)  if (loc.o->prog && arg2) { /* FIXME: Might want to be able refer to the non overloaded object * (ie arg2 == 0) in the future. * /grubba 2004-12-19 */
c403392004-12-18Henrik Grubbström (Grubba)  ref_push_object_inherit(loc.o, (loc.inherit - loc.o->prog->inherits) + arg2); } else {
a781482004-12-19Henrik Grubbström (Grubba)  /* Destructed or top-level. */
c403392004-12-18Henrik Grubbström (Grubba)  ref_push_object(loc.o); } print_return_value(); });
2bcc0d2002-05-11Martin Stjernholm /*
7080882001-07-15Fredrik Hübinette (Hubbe) #undef PROG_COUNTER
2bcc0d2002-05-11Martin Stjernholm */