67bdb52000-04-18Henrik Grubbström (Grubba) /*
121f822001-06-28Fredrik Hübinette (Hubbe)  * $Id: interpret_functions.h,v 1.64 2001/06/29 02:15:12 hubbe Exp $
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"
87c7592000-04-18Fredrik Hübinette (Hubbe) OPCODE0(F_UNDEFINED,"push UNDEFINED") push_int(0); Pike_sp[-1].subtype=NUMBER_UNDEFINED; BREAK; OPCODE0(F_CONST0, "push 0") push_int(0); BREAK; OPCODE0(F_CONST1, "push 1") push_int(1); BREAK; OPCODE0(F_CONST_1,"push -1") push_int(-1); BREAK; OPCODE0(F_BIGNUM, "push 0x7fffffff") push_int(0x7fffffff); BREAK; OPCODE1(F_NUMBER, "push int") push_int(arg1); BREAK; OPCODE1(F_NEG_NUMBER,"push -int") push_int(-arg1); BREAK; OPCODE1(F_CONSTANT,"constant")
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(& Pike_fp->context.prog->constants[arg1].sval);
87c7592000-04-18Fredrik Hübinette (Hubbe)  print_return_value(); BREAK; /* The rest of the basic 'push value' instructions */ OPCODE1_TAIL(F_MARK_AND_STRING,"mark & string") *(Pike_mark_sp++)=Pike_sp; OPCODE1(F_STRING,"string") 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(); BREAK; OPCODE1(F_ARROW_STRING,"->string") 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(); BREAK;
286afb2001-02-05Henrik Grubbström (Grubba) OPCODE1(F_LOOKUP_LFUN, "->lfun") { struct svalue tmp; struct object *o; int id; if ((sp[-1].type == T_OBJECT) && ((o = Pike_sp[-1].u.object)->prog) && (FIND_LFUN(o->prog, LFUN_ARROW) == -1)) { int id = FIND_LFUN(o->prog, arg1); if ((id != -1) && (!(o->prog->identifier_references[id].id_flags & (ID_STATIC|ID_PRIVATE|ID_HIDDEN)))) { low_object_index_no_free(&tmp, o, id); } else { /* Not found. */ tmp.type = T_INT; tmp.subtype = 1; tmp.u.integer = 0; } } else { struct svalue tmp2; tmp2.type = PIKE_T_STRING; tmp2.u.string = lfun_strings[arg1]; tmp2.subtype = 1; index_no_free(&tmp, Pike_sp-1, &tmp2); } free_svalue(Pike_sp-1); Pike_sp[-1] = tmp; print_return_value(); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) OPCODE0(F_FLOAT,"push float") /* FIXME, this opcode uses 'pc' which is not allowed.. */ Pike_sp->type=PIKE_T_FLOAT; MEMCPY((void *)&Pike_sp->u.float_number, pc, sizeof(FLOAT_TYPE)); pc+=sizeof(FLOAT_TYPE); Pike_sp++; BREAK; OPCODE1(F_LFUN, "local function") Pike_sp->u.object=Pike_fp->current_object; add_ref(Pike_fp->current_object); Pike_sp->subtype=arg1+Pike_fp->context.identifier_level; Pike_sp->type=PIKE_T_FUNCTION; Pike_sp++; print_return_value(); BREAK; OPCODE1(F_TRAMPOLINE, "trampoline") { struct object *o=low_clone(pike_trampoline_program); add_ref( ((struct pike_trampoline *)(o->storage))->frame=Pike_fp ); ((struct pike_trampoline *)(o->storage))->func=arg1+Pike_fp->context.identifier_level; push_object(o); /* Make it look like a function. */ Pike_sp[-1].subtype = pike_trampoline_program->lfuns[LFUN_CALL]; Pike_sp[-1].type = T_FUNCTION; print_return_value(); } BREAK; /* The not so basic 'push value' instructions */ OPCODE1(F_GLOBAL,"global") low_object_index_no_free(Pike_sp, Pike_fp->current_object, arg1 + Pike_fp->context.identifier_level); Pike_sp++; print_return_value(); BREAK;
a96ce92000-04-19Fredrik Hübinette (Hubbe) OPCODE2(F_EXTERNAL,"external")
87c7592000-04-18Fredrik Hübinette (Hubbe) {
342fef2000-08-23Fredrik Hübinette (Hubbe)  struct external_variable_context loc; loc.o=Pike_fp->current_object; if(!loc.o->prog)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot access parent of destructed object.\n");
342fef2000-08-23Fredrik Hübinette (Hubbe)  loc.parent_identifier=Pike_fp->fun; loc.inherit=INHERIT_FROM_INT(loc.o->prog, Pike_fp->fun);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
342fef2000-08-23Fredrik Hübinette (Hubbe)  find_external_context(&loc, arg2);
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
342fef2000-08-23Fredrik Hübinette (Hubbe)  TRACE((5,"- Identifier=%d Offset=%d\n", arg1, loc.inherit->identifier_level));
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif
342fef2000-08-23Fredrik Hübinette (Hubbe) 
87c7592000-04-18Fredrik Hübinette (Hubbe)  low_object_index_no_free(Pike_sp,
342fef2000-08-23Fredrik Hübinette (Hubbe)  loc.o, arg1 + loc.inherit->identifier_level);
87c7592000-04-18Fredrik Hübinette (Hubbe)  Pike_sp++; print_return_value(); } BREAK;
a96ce92000-04-19Fredrik Hübinette (Hubbe) OPCODE2(F_EXTERNAL_LVALUE,"& external") {
342fef2000-08-23Fredrik Hübinette (Hubbe)  struct external_variable_context loc; loc.o=Pike_fp->current_object; if(!loc.o->prog)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot access parent of destructed object.\n");
342fef2000-08-23Fredrik Hübinette (Hubbe)  loc.parent_identifier=Pike_fp->fun; loc.inherit=INHERIT_FROM_INT(loc.o->prog, Pike_fp->fun);
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
342fef2000-08-23Fredrik Hübinette (Hubbe)  find_external_context(&loc, arg2); #ifdef PIKE_DEBUG TRACE((5,"- Identifier=%d Offset=%d\n", arg1, loc.inherit->identifier_level)); #endif ref_push_object(loc.o);
a96ce92000-04-19Fredrik Hübinette (Hubbe)  Pike_sp->type=T_LVALUE;
342fef2000-08-23Fredrik Hübinette (Hubbe)  Pike_sp->u.integer=arg1 + loc.inherit->identifier_level;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  Pike_sp++; } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f853ac2000-04-20Henrik Grubbström (Grubba) OPCODE1(F_MARK_AND_LOCAL, "mark & local") *(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(); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f853ac2000-04-20Henrik Grubbström (Grubba) OPCODE1(F_LOCAL, "local")
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue( Pike_fp->locals + arg1);
f853ac2000-04-20Henrik Grubbström (Grubba)  print_return_value(); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE2(F_2_LOCALS, "2 locals")
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(); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe) OPCODE2(F_LOCAL_2_LOCAL, "local = local")
1986622000-04-20Henrik Grubbström (Grubba)  assign_svalue(Pike_fp->locals + arg1, Pike_fp->locals + arg2);
f102d22000-04-19Henrik Grubbström (Grubba) BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
1986622000-04-20Henrik Grubbström (Grubba) OPCODE2(F_LOCAL_2_GLOBAL, "global = local")
f102d22000-04-19Henrik Grubbström (Grubba) { INT32 tmp = arg1 + Pike_fp->context.identifier_level; struct identifier *i;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba)  if(!Pike_fp->current_object->prog)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot access global variables in destructed object.\n");
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba)  i = ID_FROM_INT(Pike_fp->current_object->prog, tmp); if(!IDENTIFIER_IS_VARIABLE(i->identifier_flags))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot assign functions or constants.\n");
2cd8ca2000-07-28Fredrik Hübinette (Hubbe)  if(i->run_time_type == PIKE_T_MIXED)
f102d22000-04-19Henrik Grubbström (Grubba)  { assign_svalue((struct svalue *)GLOBAL_FROM_INT(tmp), Pike_fp->locals + arg2); }else{ assign_to_short_svalue((union anything *)GLOBAL_FROM_INT(tmp), i->run_time_type, Pike_fp->locals + arg2); } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
1986622000-04-20Henrik Grubbström (Grubba) OPCODE2(F_GLOBAL_2_LOCAL,"local = global")
f102d22000-04-19Henrik Grubbström (Grubba) {
1986622000-04-20Henrik Grubbström (Grubba)  INT32 tmp = arg1 + Pike_fp->context.identifier_level;
a96ce92000-04-19Fredrik Hübinette (Hubbe)  free_svalue(Pike_fp->locals + arg2); low_object_index_no_free(Pike_fp->locals + arg2,
f102d22000-04-19Henrik Grubbström (Grubba)  Pike_fp->current_object, tmp); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE1(F_LOCAL_LVALUE, "& local") Pike_sp[0].type = T_LVALUE; Pike_sp[0].u.lval = Pike_fp->locals + arg1; Pike_sp[1].type = T_VOID; Pike_sp += 2; BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe) OPCODE2(F_LEXICAL_LOCAL,"lexical local")
f102d22000-04-19Henrik Grubbström (Grubba) {
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(); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe) OPCODE2(F_LEXICAL_LOCAL_LVALUE,"&lexical local")
f102d22000-04-19Henrik Grubbström (Grubba) {
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)  }
a96ce92000-04-19Fredrik Hübinette (Hubbe)  Pike_sp[0].type=T_LVALUE; Pike_sp[0].u.lval=f->locals+arg1; Pike_sp[1].type=T_VOID; Pike_sp+=2;
f102d22000-04-19Henrik Grubbström (Grubba) } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE1(F_ARRAY_LVALUE, "[ lvalues ]") f_aggregate(arg1*2); Pike_sp[-1].u.array->flags |= ARRAY_LVALUE; Pike_sp[-1].u.array->type_field |= BIT_UNFINISHED | BIT_MIXED; /* FIXME: Shouldn't a ref be added here? */ Pike_sp[0] = Pike_sp[-1]; Pike_sp[-1].type = T_ARRAY_LVALUE;
2026c22000-04-20Henrik Grubbström (Grubba)  dmalloc_touch_svalue(Pike_sp);
f102d22000-04-19Henrik Grubbström (Grubba)  Pike_sp++; BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE1(F_CLEAR_2_LOCAL, "clear 2 local")
7951942000-04-20Fredrik Hübinette (Hubbe)  free_svalues(Pike_fp->locals + arg1, 2, -1); Pike_fp->locals[arg1].type = PIKE_T_INT; Pike_fp->locals[arg1].subtype = 0; Pike_fp->locals[arg1].u.integer = 0; Pike_fp->locals[arg1+1].type = PIKE_T_INT; Pike_fp->locals[arg1+1].subtype = 0; Pike_fp->locals[arg1+1].u.integer = 0;
f102d22000-04-19Henrik Grubbström (Grubba) BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE1(F_CLEAR_4_LOCAL, "clear 4 local") { int e;
7951942000-04-20Fredrik Hübinette (Hubbe)  free_svalues(Pike_fp->locals + arg1, 4, -1);
f102d22000-04-19Henrik Grubbström (Grubba)  for(e = 0; e < 4; e++) {
7951942000-04-20Fredrik Hübinette (Hubbe)  Pike_fp->locals[arg1+e].type = PIKE_T_INT; Pike_fp->locals[arg1+e].subtype = 0; Pike_fp->locals[arg1+e].u.integer = 0;
f102d22000-04-19Henrik Grubbström (Grubba)  } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE1(F_CLEAR_LOCAL, "clear local")
7951942000-04-20Fredrik Hübinette (Hubbe)  free_svalue(Pike_fp->locals + arg1); Pike_fp->locals[arg1].type = PIKE_T_INT; Pike_fp->locals[arg1].subtype = 0; Pike_fp->locals[arg1].u.integer = 0;
f102d22000-04-19Henrik Grubbström (Grubba) BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE1(F_INC_LOCAL, "++local")
7951942000-04-20Fredrik Hübinette (Hubbe)  if( (Pike_fp->locals[arg1].type == PIKE_T_INT)
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
7951942000-04-20Fredrik Hübinette (Hubbe)  && (!INT_TYPE_ADD_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif /* AUTO_BIGNUM */
f102d22000-04-19Henrik Grubbström (Grubba)  ) {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_int(++(Pike_fp->locals[arg1].u.integer));
f102d22000-04-19Henrik Grubbström (Grubba)  } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(Pike_fp->locals+arg1);
f102d22000-04-19Henrik Grubbström (Grubba)  push_int(1); f_add(2);
7951942000-04-20Fredrik Hübinette (Hubbe)  assign_svalue(Pike_fp->locals+arg1,Pike_sp-1);
f102d22000-04-19Henrik Grubbström (Grubba)  } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
cc75b62000-04-21Henrik Grubbström (Grubba) OPCODE1(F_POST_INC_LOCAL, "local++")
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) #ifdef AUTO_BIGNUM && (!INT_TYPE_ADD_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1)) #endif /* AUTO_BIGNUM */ ) { Pike_fp->locals[arg1].u.integer++; } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  push_int(1); f_add(2);
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_pop_to(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
cc75b62000-04-21Henrik Grubbström (Grubba) OPCODE1(F_INC_LOCAL_AND_POP, "++local and pop") if( (Pike_fp->locals[arg1].type == PIKE_T_INT)
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
cc75b62000-04-21Henrik Grubbström (Grubba)  && (!INT_TYPE_ADD_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif /* AUTO_BIGNUM */
cc75b62000-04-21Henrik Grubbström (Grubba)  ) { Pike_fp->locals[arg1].u.integer++; } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue( Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  push_int(1); f_add(2);
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_pop_to(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE1(F_DEC_LOCAL, "--local")
7951942000-04-20Fredrik Hübinette (Hubbe)  if( (Pike_fp->locals[arg1].type == PIKE_T_INT)
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
7951942000-04-20Fredrik Hübinette (Hubbe)  && (!INT_TYPE_SUB_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif /* AUTO_BIGNUM */
f102d22000-04-19Henrik Grubbström (Grubba)  ) {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_int(--(Pike_fp->locals[arg1].u.integer));
f102d22000-04-19Henrik Grubbström (Grubba)  } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(Pike_fp->locals+arg1);
f102d22000-04-19Henrik Grubbström (Grubba)  push_int(1); o_subtract();
7951942000-04-20Fredrik Hübinette (Hubbe)  assign_svalue(Pike_fp->locals+arg1,Pike_sp-1);
f102d22000-04-19Henrik Grubbström (Grubba)  } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
cc75b62000-04-21Henrik Grubbström (Grubba) OPCODE1(F_POST_DEC_LOCAL, "local--")
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) #ifdef AUTO_BIGNUM && (!INT_TYPE_SUB_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1)) #endif /* AUTO_BIGNUM */ ) { Pike_fp->locals[arg1].u.integer--; } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  push_int(1); o_subtract();
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_pop_to(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  } /* Pike_fp->locals[instr].u.integer--; */ BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
cc75b62000-04-21Henrik Grubbström (Grubba) OPCODE1(F_DEC_LOCAL_AND_POP, "--local and pop") if( (Pike_fp->locals[arg1].type == PIKE_T_INT)
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
cc75b62000-04-21Henrik Grubbström (Grubba)  && (!INT_TYPE_SUB_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif /* AUTO_BIGNUM */
cc75b62000-04-21Henrik Grubbström (Grubba)  ) { Pike_fp->locals[arg1].u.integer--; } else {
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_svalue(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  push_int(1); o_subtract();
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_pop_to(Pike_fp->locals + arg1);
cc75b62000-04-21Henrik Grubbström (Grubba)  } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE0(F_LTOSVAL, "lvalue to svalue")
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++; BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE0(F_LTOSVAL2, "ltosval2")
29cf5b2001-06-28Fredrik Hübinette (Hubbe)  dmalloc_touch_svalue(Pike_sp-3); dmalloc_touch_svalue(Pike_sp-2); dmalloc_touch_svalue(Pike_sp-1);
f102d22000-04-19Henrik Grubbström (Grubba)  Pike_sp[0] = Pike_sp[-1]; Pike_sp[-1].type = PIKE_T_INT; Pike_sp++; lvalue_to_svalue_no_free(Pike_sp-2, Pike_sp-4); /* this is so that foo+=bar (and similar things) will be faster, this * is done by freeing the old reference to foo after it has been pushed * on the stack. That way foo can have only 1 reference if we are lucky, * and then the low array/multiset/mapping manipulation routines can be * destructive if they like */ if( (1 << Pike_sp[-2].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) { struct svalue s; s.type = PIKE_T_INT; s.subtype = 0; s.u.integer = 0; assign_lvalue(Pike_sp-4, &s); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
b99ff82001-06-07Fredrik Hübinette (Hubbe) OPCODE0(F_LTOSVAL3, "ltosval3") Pike_sp[0] = Pike_sp[-1]; Pike_sp[-1] = Pike_sp[-2]; Pike_sp[-2].type = PIKE_T_INT; Pike_sp++; lvalue_to_svalue_no_free(Pike_sp-3, Pike_sp-5);
15a84d2001-06-07Fredrik Hübinette (Hubbe)  /* this is so that foo=foo[x..y] (and similar things) will be faster, this
b99ff82001-06-07Fredrik Hübinette (Hubbe)  * is done by freeing the old reference to foo after it has been pushed * on the stack. That way foo can have only 1 reference if we are lucky, * and then the low array/multiset/mapping manipulation routines can be * destructive if they like */ if( (1 << Pike_sp[-3].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) { struct svalue s; s.type = PIKE_T_INT; s.subtype = 0; s.u.integer = 0; assign_lvalue(Pike_sp-5, &s); } BREAK;
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE0(F_ADD_TO_AND_POP, "+= and pop") Pike_sp[0]=Pike_sp[-1]; Pike_sp[-1].type=PIKE_T_INT; Pike_sp++; lvalue_to_svalue_no_free(Pike_sp-2,Pike_sp-4);
b1d0682001-06-16Per Hedbor  if( Pike_sp[-1].type == PIKE_T_INT && Pike_sp[-2].type == PIKE_T_INT ) { #ifdef AUTO_BIGNUM if(!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, Pike_sp[-2].u.integer)) #endif { /* Optimization for a rather common case. Makes it 30% faster. */ Pike_sp[-1].u.integer += Pike_sp[-2].u.integer; assign_lvalue(Pike_sp-4,Pike_sp-1);
29cf5b2001-06-28Fredrik Hübinette (Hubbe)  Pike_sp-=2; pop_n_elems(2);
b1d0682001-06-16Per Hedbor  goto add_and_pop_done; } }
f102d22000-04-19Henrik Grubbström (Grubba)  /* this is so that foo+=bar (and similar things) will be faster, this * is done by freeing the old reference to foo after it has been pushed * on the stack. That way foo can have only 1 reference if we are lucky, * and then the low array/multiset/mapping manipulation routines can be * destructive if they like */ if( (1 << Pike_sp[-2].type) & (BIT_ARRAY | BIT_MULTISET | BIT_MAPPING | BIT_STRING) ) { struct svalue s; s.type=PIKE_T_INT; s.subtype=0; s.u.integer=0; assign_lvalue(Pike_sp-4,&s); } f_add(2); assign_lvalue(Pike_sp-3,Pike_sp-1); pop_n_elems(3);
b1d0682001-06-16Per Hedbor  add_and_pop_done: ; /* make gcc happy */
f102d22000-04-19Henrik Grubbström (Grubba) BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba) OPCODE1(F_GLOBAL_LVALUE, "& global") { struct identifier *i; INT32 tmp=arg1 + Pike_fp->context.identifier_level; if(!Pike_fp->current_object->prog)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot access global variables in destructed object.\n");
f102d22000-04-19Henrik Grubbström (Grubba)  i=ID_FROM_INT(Pike_fp->current_object->prog, tmp);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f102d22000-04-19Henrik Grubbström (Grubba)  if(!IDENTIFIER_IS_VARIABLE(i->identifier_flags))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot re-assign functions or constants.\n");
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2cd8ca2000-07-28Fredrik Hübinette (Hubbe)  if(i->run_time_type == PIKE_T_MIXED)
f102d22000-04-19Henrik Grubbström (Grubba)  { Pike_sp[0].type=T_LVALUE; Pike_sp[0].u.lval=(struct svalue *)GLOBAL_FROM_INT(tmp); }else{ Pike_sp[0].type=T_SHORT_LVALUE; Pike_sp[0].u.short_lval= (union anything *)GLOBAL_FROM_INT(tmp); Pike_sp[0].subtype=i->run_time_type; } Pike_sp[1].type=T_VOID; Pike_sp+=2; } BREAK;
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_INC, "++x") { union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_ADD_OVERFLOW(u->integer, 1)
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif
bac71b2000-04-19Henrik Grubbström (Grubba)  ) { instr=++ u->integer; pop_n_elems(2);
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_int(instr);
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);
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_unlink(2);
bac71b2000-04-19Henrik Grubbström (Grubba)  } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_DEC, "--x") { union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_SUB_OVERFLOW(u->integer, 1)
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif
bac71b2000-04-19Henrik Grubbström (Grubba)  ) { instr=-- u->integer; pop_n_elems(2);
ee68462001-03-08Fredrik Hübinette (Hubbe)  push_int(instr);
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);
ee68462001-03-08Fredrik Hübinette (Hubbe)  stack_unlink(2);
bac71b2000-04-19Henrik Grubbström (Grubba)  } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_DEC_AND_POP, "x-- and pop") { union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_SUB_OVERFLOW(u->integer, 1)
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif )
bac71b2000-04-19Henrik Grubbström (Grubba)  {
ee68462001-03-08Fredrik Hübinette (Hubbe)  -- u->integer;
bac71b2000-04-19Henrik Grubbström (Grubba)  pop_n_elems(2); }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); } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_INC_AND_POP, "x++ and pop") { union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_ADD_OVERFLOW(u->integer, 1)
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif
bac71b2000-04-19Henrik Grubbström (Grubba)  ) { instr=++ u->integer; pop_n_elems(2); } 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); } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_POST_INC, "x++") { union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_ADD_OVERFLOW(u->integer, 1)
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif
bac71b2000-04-19Henrik Grubbström (Grubba)  ) { instr=u->integer ++; pop_n_elems(2); push_int(instr); } 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(); stack_unlink(2); print_return_value();
bac71b2000-04-19Henrik Grubbström (Grubba)  } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_POST_DEC, "x--") { union anything *u=get_pointer_if_this_type(Pike_sp-2, PIKE_T_INT); if(u
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
bac71b2000-04-19Henrik Grubbström (Grubba)  && !INT_TYPE_SUB_OVERFLOW(u->integer, 1)
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif
bac71b2000-04-19Henrik Grubbström (Grubba)  ) { instr=u->integer --; pop_n_elems(2); push_int(instr); } 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(); stack_unlink(2); print_return_value();
bac71b2000-04-19Henrik Grubbström (Grubba)  } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe) OPCODE1(F_ASSIGN_LOCAL,"assign local") assign_svalue(Pike_fp->locals+arg1,Pike_sp-1); BREAK;
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_ASSIGN, "assign") assign_lvalue(Pike_sp-3,Pike_sp-1); free_svalue(Pike_sp-3); free_svalue(Pike_sp-2); Pike_sp[-3]=Pike_sp[-1]; Pike_sp-=2; BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe) OPCODE2(F_APPLY_ASSIGN_LOCAL_AND_POP,"apply, assign local and pop")
24c37f2001-05-24Fredrik Hübinette (Hubbe)  apply_svalue(&((Pike_fp->context.prog->constants + arg1)->sval),
e428262001-06-10Henrik Grubbström (Grubba)  DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)));
a96ce92000-04-19Fredrik Hübinette (Hubbe)  free_svalue(Pike_fp->locals+arg2); Pike_fp->locals[arg2]=Pike_sp[-1]; Pike_sp--; BREAK; OPCODE2(F_APPLY_ASSIGN_LOCAL,"apply, assign local")
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);
a96ce92000-04-19Fredrik Hübinette (Hubbe) BREAK;
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_ASSIGN_AND_POP, "assign and pop") assign_lvalue(Pike_sp-3, Pike_sp-1); pop_n_elems(3); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
f853ac2000-04-20Henrik Grubbström (Grubba) OPCODE1(F_ASSIGN_LOCAL_AND_POP, "assign local and pop") free_svalue(Pike_fp->locals + arg1); Pike_fp->locals[arg1] = Pike_sp[-1]; Pike_sp--; BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE1(F_ASSIGN_GLOBAL, "assign global") { struct identifier *i; INT32 tmp=arg1 + Pike_fp->context.identifier_level; if(!Pike_fp->current_object->prog)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot access global variables in destructed object.\n");
bac71b2000-04-19Henrik Grubbström (Grubba)  i=ID_FROM_INT(Pike_fp->current_object->prog, tmp); if(!IDENTIFIER_IS_VARIABLE(i->identifier_flags))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot assign functions or constants.\n");
2cd8ca2000-07-28Fredrik Hübinette (Hubbe)  if(i->run_time_type == PIKE_T_MIXED)
bac71b2000-04-19Henrik Grubbström (Grubba)  { assign_svalue((struct svalue *)GLOBAL_FROM_INT(tmp), Pike_sp-1); }else{ assign_to_short_svalue((union anything *)GLOBAL_FROM_INT(tmp), i->run_time_type, Pike_sp-1); } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE1(F_ASSIGN_GLOBAL_AND_POP, "assign global and pop") { struct identifier *i; INT32 tmp=arg1 + Pike_fp->context.identifier_level; if(!Pike_fp->current_object->prog)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot access global variables in destructed object.\n");
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba)  i=ID_FROM_INT(Pike_fp->current_object->prog, tmp); if(!IDENTIFIER_IS_VARIABLE(i->identifier_flags))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Cannot assign functions or constants.\n");
87c7592000-04-18Fredrik Hübinette (Hubbe) 
2cd8ca2000-07-28Fredrik Hübinette (Hubbe)  if(i->run_time_type == PIKE_T_MIXED)
bac71b2000-04-19Henrik Grubbström (Grubba)  { struct svalue *s=(struct svalue *)GLOBAL_FROM_INT(tmp); free_svalue(s); Pike_sp--; *s=*Pike_sp; }else{ assign_to_short_svalue((union anything *)GLOBAL_FROM_INT(tmp), i->run_time_type, Pike_sp-1); pop_stack(); } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) /* Stack machine stuff */ OPCODE0(F_POP_VALUE, "pop") pop_stack(); BREAK; OPCODE1(F_POP_N_ELEMS, "pop_n_elems") pop_n_elems(arg1); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
7951942000-04-20Fredrik Hübinette (Hubbe) OPCODE0_TAIL(F_MARK2,"mark mark") *(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. */ OPCODE0_TAIL(F_SYNCH_MARK,"synch mark")
7951942000-04-20Fredrik Hübinette (Hubbe) OPCODE0(F_MARK,"mark") *(Pike_mark_sp++)=Pike_sp; BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
17f08c2000-07-06Fredrik Hübinette (Hubbe) OPCODE1(F_MARK_X, "mark Pike_sp-X")
bac71b2000-04-19Henrik Grubbström (Grubba)  *(Pike_mark_sp++)=Pike_sp-arg1; BREAK; OPCODE0(F_POP_MARK, "pop mark") --Pike_mark_sp; BREAK;
7babb52001-01-15Martin Stjernholm OPCODE0(F_POP_TO_MARK, "pop to mark") pop_n_elems(Pike_sp - *--Pike_mark_sp); BREAK;
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. */ OPCODE0(F_CLEANUP_SYNCH_MARK, "cleanup synch mark") OPCODE0_TAIL(F_POP_SYNCH_MARK, "pop synch mark") if (*--Pike_mark_sp != Pike_sp && d_flag) { 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 */ /* Some attempt to recover, just to be able to report the backtrace. */ pop_n_elems(Pike_sp - *Pike_mark_sp); fatal("Stack out of synch - should be %ld, is %ld.\n",
dcbdc42001-03-19Henrik Grubbström (Grubba)  DO_NOT_WARN((long)should), DO_NOT_WARN((long)is));
90703d2001-01-31Martin Stjernholm  } BREAK;
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_CLEAR_STRING_SUBTYPE, "clear string subtype") if(Pike_sp[-1].type==PIKE_T_STRING) Pike_sp[-1].subtype=0; BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe)  /* Jumps */
7951942000-04-20Fredrik Hübinette (Hubbe) OPCODE0_JUMP(F_BRANCH,"branch") DOJUMP(); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
7951942000-04-20Fredrik Hübinette (Hubbe) OPCODE2(F_BRANCH_IF_NOT_LOCAL_ARROW,"branch if !local->x") { struct svalue tmp; tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=1; Pike_sp->type=PIKE_T_INT; Pike_sp++; index_no_free(Pike_sp-1,Pike_fp->locals+arg2, &tmp); print_return_value(); }
87c7592000-04-18Fredrik Hübinette (Hubbe)  /* Fall through */
7951942000-04-20Fredrik Hübinette (Hubbe) OPCODE0_TAILJUMP(F_BRANCH_WHEN_ZERO,"branch if zero") if(!IS_ZERO(Pike_sp-1)) { SKIPJUMP(); }else{ DOJUMP(); } pop_stack(); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
7951942000-04-20Fredrik Hübinette (Hubbe) OPCODE0_JUMP(F_BRANCH_WHEN_NON_ZERO,"branch if not zero") if(IS_ZERO(Pike_sp-1)) { SKIPJUMP(); }else{ DOJUMP(); } pop_stack(); BREAK
87c7592000-04-18Fredrik Hübinette (Hubbe) 
7951942000-04-20Fredrik Hübinette (Hubbe) OPCODE1_JUMP(F_BRANCH_IF_LOCAL,"branch if local") if(IS_ZERO(Pike_fp->locals + arg1)) { SKIPJUMP(); }else{ DOJUMP(); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe)  CASE(F_BRANCH_IF_NOT_LOCAL); instr=GET_ARG(); if(!IS_ZERO(Pike_fp->locals + instr)) {
7951942000-04-20Fredrik Hübinette (Hubbe)  SKIPJUMP();
87c7592000-04-18Fredrik Hübinette (Hubbe)  }else{ DOJUMP(); } break; CJUMP(F_BRANCH_WHEN_EQ, is_eq); CJUMP(F_BRANCH_WHEN_NE,!is_eq); CJUMP(F_BRANCH_WHEN_LT, is_lt); CJUMP(F_BRANCH_WHEN_LE,!is_gt); CJUMP(F_BRANCH_WHEN_GT, is_gt); CJUMP(F_BRANCH_WHEN_GE,!is_lt); CASE(F_BRANCH_AND_POP_WHEN_ZERO); if(!IS_ZERO(Pike_sp-1)) {
7951942000-04-20Fredrik Hübinette (Hubbe)  SKIPJUMP();
87c7592000-04-18Fredrik Hübinette (Hubbe)  }else{ DOJUMP(); pop_stack(); } break; CASE(F_BRANCH_AND_POP_WHEN_NON_ZERO); if(IS_ZERO(Pike_sp-1)) {
7951942000-04-20Fredrik Hübinette (Hubbe)  SKIPJUMP();
87c7592000-04-18Fredrik Hübinette (Hubbe)  }else{ DOJUMP(); pop_stack(); } break; CASE(F_LAND); if(!IS_ZERO(Pike_sp-1)) {
7951942000-04-20Fredrik Hübinette (Hubbe)  SKIPJUMP();
87c7592000-04-18Fredrik Hübinette (Hubbe)  pop_stack(); }else{ DOJUMP(); } break; CASE(F_LOR); if(IS_ZERO(Pike_sp-1)) {
7951942000-04-20Fredrik Hübinette (Hubbe)  SKIPJUMP();
87c7592000-04-18Fredrik Hübinette (Hubbe)  pop_stack(); }else{ DOJUMP(); } break; CASE(F_EQ_OR); if(!is_eq(Pike_sp-2,Pike_sp-1)) { pop_n_elems(2);
7951942000-04-20Fredrik Hübinette (Hubbe)  SKIPJUMP();
87c7592000-04-18Fredrik Hübinette (Hubbe)  }else{ pop_n_elems(2); push_int(1); DOJUMP(); } break; CASE(F_EQ_AND); if(is_eq(Pike_sp-2,Pike_sp-1)) { pop_n_elems(2);
7951942000-04-20Fredrik Hübinette (Hubbe)  SKIPJUMP();
87c7592000-04-18Fredrik Hübinette (Hubbe)  }else{ pop_n_elems(2); push_int(0); DOJUMP(); } break; CASE(F_CATCH);
b7c1ee2001-01-10Martin Stjernholm  switch (o_catch(pc+sizeof(INT32))) { case 1:
9ddbf22001-05-10Fredrik Hübinette (Hubbe)  /* There was a return inside the evaluated code */ goto do_dumb_return;
b7c1ee2001-01-10Martin Stjernholm  case 2: pc = Pike_fp->pc; break; default:
90703d2001-01-31Martin Stjernholm  pc+=GET_JUMP();
b7c1ee2001-01-10Martin Stjernholm  }
87c7592000-04-18Fredrik Hübinette (Hubbe)  break;
b7c1ee2001-01-10Martin Stjernholm OPCODE0(F_ESCAPE_CATCH, "escape catch") { Pike_fp->pc = pc; return -2; } BREAK;
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_THROW_ZERO, "throw(0)") push_int(0); f_throw(1); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE1(F_SWITCH, "switch") { INT32 tmp; tmp=switch_lookup(Pike_fp->context.prog-> constants[arg1].sval.u.array,Pike_sp-1);
e428262001-06-10Henrik Grubbström (Grubba)  pc=(unsigned char *)DO_ALIGN(pc,((ptrdiff_t)sizeof(INT32)));
bac71b2000-04-19Henrik Grubbström (Grubba)  pc+=(tmp>=0 ? 1+tmp*2 : 2*~tmp) * sizeof(INT32); if(*(INT32*)pc < 0) fast_check_threads_etc(7); pc+=*(INT32*)pc; pop_stack(); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
6e36e52000-11-30Fredrik Hübinette (Hubbe) OPCODE1(F_SWITCH_ON_INDEX, "switch on index") { INT32 tmp; struct svalue s; index_no_free(&s,Pike_sp-2,Pike_sp-1); Pike_sp++[0]=s; tmp=switch_lookup(Pike_fp->context.prog-> constants[arg1].sval.u.array,Pike_sp-1); pop_n_elems(3);
e428262001-06-10Henrik Grubbström (Grubba)  pc=(unsigned char *)DO_ALIGN(pc,((ptrdiff_t)sizeof(INT32)));
6e36e52000-11-30Fredrik Hübinette (Hubbe)  pc+=(tmp>=0 ? 1+tmp*2 : 2*~tmp) * sizeof(INT32); if(*(INT32*)pc < 0) fast_check_threads_etc(7); pc+=*(INT32*)pc; } BREAK; OPCODE2(F_SWITCH_ON_LOCAL, "switch on local") { INT32 tmp; tmp=switch_lookup(Pike_fp->context.prog-> constants[arg2].sval.u.array,Pike_fp->locals + arg1);
e428262001-06-10Henrik Grubbström (Grubba)  pc=(unsigned char *)DO_ALIGN(pc,((ptrdiff_t)sizeof(INT32)));
6e36e52000-11-30Fredrik Hübinette (Hubbe)  pc+=(tmp>=0 ? 1+tmp*2 : 2*~tmp) * sizeof(INT32); if(*(INT32*)pc < 0) fast_check_threads_etc(7); pc+=*(INT32*)pc; } BREAK;
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) */
87c7592000-04-18Fredrik Hübinette (Hubbe)  LOOP(F_INC_LOOP, 1, <, is_lt); LOOP(F_DEC_LOOP, -1, >, is_gt); LOOP(F_INC_NEQ_LOOP, 1, !=, !is_eq); LOOP(F_DEC_NEQ_LOOP, -1, !=, !is_eq);
dd78ff2001-01-14Henrik Grubbström (Grubba) /* Use like: * * push(loopcnt) * branch(l2) * l1: * sync_mark * code * pop_sync_mark * l2: * loop(l1) */ OPCODE0_JUMP(F_LOOP, "loop") /* 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);
77fc8c2001-01-14Henrik Grubbström (Grubba)  if (!is_lt(sp-2, sp-1)) {
dd78ff2001-01-14Henrik Grubbström (Grubba)  o_subtract(); DOJUMP(); } else { pop_n_elems(2); SKIPJUMP(); } } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe)  CASE(F_FOREACH) /* array, lvalue, X, i */ { 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) { fast_check_threads_etc(10);
4cdb802001-02-23Fredrik Hübinette (Hubbe) #if 0
87c7592000-04-18Fredrik Hübinette (Hubbe)  index_no_free(Pike_sp,Pike_sp-4,Pike_sp-1); Pike_sp++; assign_lvalue(Pike_sp-4, Pike_sp-1); free_svalue(Pike_sp-1); Pike_sp--;
4cdb802001-02-23Fredrik Hübinette (Hubbe) #else if(Pike_sp[-1].u.integer < 0) Pike_error("Foreach loop variable is negative!\n"); assign_lvalue(Pike_sp-3, Pike_sp[-4].u.array->item + Pike_sp[-1].u.integer); #endif
90703d2001-01-31Martin Stjernholm  pc+=GET_JUMP();
87c7592000-04-18Fredrik Hübinette (Hubbe)  Pike_sp[-1].u.integer++; }else{
4cdb802001-02-23Fredrik Hübinette (Hubbe) #if 0 pop_n_elems(4); #endif SKIPJUMP(); } break; } OPCODE0(F_MAKE_ITERATOR,"Iterator") { extern void f_Iterator(INT32); f_Iterator(1); } BREAK; CASE(F_NEW_FOREACH) /* iterator, lvalue, lvalue */ { extern int foreach_iterate(struct object *o); if(Pike_sp[-5].type != PIKE_T_OBJECT) PIKE_ERROR("foreach", "Bad argument 1.\n", Pike_sp-3, 1); if(foreach_iterate(Pike_sp[-5].u.object)) { fast_check_threads_etc(10); pc+=GET_JUMP(); }else{
7951942000-04-20Fredrik Hübinette (Hubbe)  SKIPJUMP();
87c7592000-04-18Fredrik Hübinette (Hubbe)  } break; } CASE(F_RETURN_LOCAL); instr=GET_ARG();
931b532000-06-20Fredrik Hübinette (Hubbe) #if defined(PIKE_DEBUG) && defined(GC2)
17f08c2000-07-06Fredrik Hübinette (Hubbe)  /* special case! Pike_interpreter.mark_stack may be invalid at the time we
931b532000-06-20Fredrik Hübinette (Hubbe)  * call return -1, so we must call the callbacks here to * prevent false alarms! /Hubbe */ if(d_flag>3) do_gc(); if(d_flag>4) do_debug(); check_threads_etc(); #endif
87c7592000-04-18Fredrik Hübinette (Hubbe)  if(Pike_fp->expendible <= Pike_fp->locals+instr) { pop_n_elems(Pike_sp-1 - (Pike_fp->locals+instr)); }else{ push_svalue(Pike_fp->locals+instr); } print_return_value();
9ddbf22001-05-10Fredrik Hübinette (Hubbe)  goto do_dumb_return;
87c7592000-04-18Fredrik Hübinette (Hubbe)  CASE(F_RETURN_IF_TRUE);
931b532000-06-20Fredrik Hübinette (Hubbe)  if(!IS_ZERO(Pike_sp-1)) goto do_return;
87c7592000-04-18Fredrik Hübinette (Hubbe)  pop_stack(); break; CASE(F_RETURN_1); push_int(1); goto do_return; CASE(F_RETURN_0); push_int(0); goto do_return; CASE(F_RETURN); do_return: #if defined(PIKE_DEBUG) && defined(GC2) if(d_flag>3) do_gc(); if(d_flag>4) do_debug(); check_threads_etc(); #endif /* fall through */ CASE(F_DUMB_RETURN);
9ddbf22001-05-10Fredrik Hübinette (Hubbe)  do_dumb_return: if(Pike_fp -> flags & PIKE_FRAME_RETURN_INTERNAL) { int f=Pike_fp->flags; low_return(); if(f & PIKE_FRAME_RETURN_POP) pop_stack(); pc=Pike_fp->pc; break; }
87c7592000-04-18Fredrik Hübinette (Hubbe)  return -1;
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_NEGATE, "unary minus") if(Pike_sp[-1].type == PIKE_T_INT) {
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
bac71b2000-04-19Henrik Grubbström (Grubba)  if(INT_TYPE_NEG_OVERFLOW(Pike_sp[-1].u.integer)) { convert_stack_top_to_bignum(); o_negate(); } else
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif /* AUTO_BIGNUM */
bac71b2000-04-19Henrik Grubbström (Grubba)  Pike_sp[-1].u.integer =- Pike_sp[-1].u.integer; } else if(Pike_sp[-1].type == PIKE_T_FLOAT) { Pike_sp[-1].u.float_number =- Pike_sp[-1].u.float_number; }else{ o_negate(); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_COMPL, "~") o_compl(); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_NOT, "!") switch(Pike_sp[-1].type) { case PIKE_T_INT: Pike_sp[-1].u.integer =! Pike_sp[-1].u.integer; break;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba)  case PIKE_T_FUNCTION: case PIKE_T_OBJECT: if(IS_ZERO(Pike_sp-1)) { pop_stack(); push_int(1); }else{ pop_stack(); push_int(0); } break;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba)  default: free_svalue(Pike_sp-1); Pike_sp[-1].type=PIKE_T_INT; Pike_sp[-1].u.integer=0; } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_LSH, "<<") o_lsh(); BREAK; OPCODE0(F_RSH, ">>") o_rsh(); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe)  COMPARISMENT(F_EQ, is_eq(Pike_sp-2,Pike_sp-1)); COMPARISMENT(F_NE,!is_eq(Pike_sp-2,Pike_sp-1)); COMPARISMENT(F_GT, is_gt(Pike_sp-2,Pike_sp-1)); COMPARISMENT(F_GE,!is_lt(Pike_sp-2,Pike_sp-1)); COMPARISMENT(F_LT, is_lt(Pike_sp-2,Pike_sp-1)); COMPARISMENT(F_LE,!is_gt(Pike_sp-2,Pike_sp-1));
f853ac2000-04-20Henrik Grubbström (Grubba) OPCODE0(F_ADD, "+") f_add(2); BREAK;
a2b70a2000-04-30Fredrik Hübinette (Hubbe) OPCODE0(F_ADD_INTS, "int+int")
17f08c2000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_INT && Pike_sp[-2].type == T_INT
a2b70a2000-04-30Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
17f08c2000-07-06Fredrik Hübinette (Hubbe)  && (!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, Pike_sp[-2].u.integer))
a2b70a2000-04-30Fredrik Hübinette (Hubbe) #endif ) {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-2].u.integer+=Pike_sp[-1].u.integer; Pike_sp--;
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  }else{ f_add(2); } BREAK; OPCODE0(F_ADD_FLOATS, "float+float")
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; Pike_sp--;
a2b70a2000-04-30Fredrik Hübinette (Hubbe)  }else{ f_add(2); } BREAK;
f853ac2000-04-20Henrik Grubbström (Grubba) OPCODE0(F_SUBTRACT, "-") o_subtract(); BREAK; OPCODE0(F_AND, "&") o_and(); BREAK; OPCODE0(F_OR, "|") o_or(); BREAK; OPCODE0(F_XOR, "^") o_xor(); BREAK; OPCODE0(F_MULTIPLY, "*") o_multiply(); BREAK; OPCODE0(F_DIVIDE, "/") o_divide(); BREAK; OPCODE0(F_MOD, "%") o_mod(); BREAK; OPCODE1(F_ADD_INT, "add integer")
17f08c2000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_INT
6fd5172000-04-25Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
17f08c2000-07-06Fredrik Hübinette (Hubbe)  && (!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, arg1))
6fd5172000-04-25Fredrik Hübinette (Hubbe) #endif ) {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-1].u.integer+=arg1;
6fd5172000-04-25Fredrik Hübinette (Hubbe)  }else{ push_int(arg1); f_add(2); }
f853ac2000-04-20Henrik Grubbström (Grubba) BREAK; OPCODE1(F_ADD_NEG_INT, "add -integer")
17f08c2000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp[-1].type == T_INT
6fd5172000-04-25Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
17f08c2000-07-06Fredrik Hübinette (Hubbe)  && (!INT_TYPE_ADD_OVERFLOW(Pike_sp[-1].u.integer, -arg1))
6fd5172000-04-25Fredrik Hübinette (Hubbe) #endif ) {
17f08c2000-07-06Fredrik Hübinette (Hubbe)  Pike_sp[-1].u.integer-=arg1;
6fd5172000-04-25Fredrik Hübinette (Hubbe)  }else{ push_int(-arg1); f_add(2); }
f853ac2000-04-20Henrik Grubbström (Grubba) BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
9b22582000-04-18Henrik Grubbström (Grubba) OPCODE0(F_PUSH_ARRAY, "@") switch(Pike_sp[-1].type) { default: PIKE_ERROR("@", "Bad argument.\n", Pike_sp, 1); case PIKE_T_OBJECT: if(!Pike_sp[-1].u.object->prog || FIND_LFUN(Pike_sp[-1].u.object->prog,LFUN__VALUES) == -1) PIKE_ERROR("@", "Bad argument.\n", Pike_sp, 1); apply_lfun(Pike_sp[-1].u.object, LFUN__VALUES, 0); if(Pike_sp[-1].type != PIKE_T_ARRAY)
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Bad return type from o->_values() in @\n");
9b22582000-04-18Henrik Grubbström (Grubba)  free_svalue(Pike_sp-2); Pike_sp[-2]=Pike_sp[-1]; Pike_sp--; break; case PIKE_T_ARRAY: break; } Pike_sp--; push_array_items(Pike_sp->u.array); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
50d1d62000-04-30Fredrik Hübinette (Hubbe) OPCODE2(F_LOCAL_LOCAL_INDEX, "local[local]")
9b22582000-04-18Henrik Grubbström (Grubba) { struct svalue *s=Pike_fp->locals+arg1; if(s->type == PIKE_T_STRING) s->subtype=0; Pike_sp++->type=PIKE_T_INT; index_no_free(Pike_sp-1,Pike_fp->locals+arg2,s); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
9b22582000-04-18Henrik Grubbström (Grubba) OPCODE1(F_LOCAL_INDEX, "local index") {
13cfa82000-04-18Henrik Grubbström (Grubba)  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); Pike_sp[-1]=tmp; } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
9b22582000-04-18Henrik Grubbström (Grubba) OPCODE2(F_GLOBAL_LOCAL_INDEX, "global[local]") { struct svalue tmp,*s; low_object_index_no_free(Pike_sp, Pike_fp->current_object, arg1 + Pike_fp->context.identifier_level); Pike_sp++; s=Pike_fp->locals+arg2; if(s->type == PIKE_T_STRING) s->subtype=0; index_no_free(&tmp,Pike_sp-1,s); free_svalue(Pike_sp-1); Pike_sp[-1]=tmp; } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
9b22582000-04-18Henrik Grubbström (Grubba) OPCODE2(F_LOCAL_ARROW, "local->x") { struct svalue tmp; tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=1; Pike_sp->type=PIKE_T_INT; Pike_sp++; index_no_free(Pike_sp-1,Pike_fp->locals+arg2, &tmp); print_return_value(); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
9b22582000-04-18Henrik Grubbström (Grubba) OPCODE1(F_ARROW, "->x") { struct svalue tmp,tmp2; tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=1; index_no_free(&tmp2, Pike_sp-1, &tmp); free_svalue(Pike_sp-1); Pike_sp[-1]=tmp2; print_return_value(); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
372a652000-04-18Henrik Grubbström (Grubba) OPCODE1(F_STRING_INDEX, "string index") { struct svalue tmp,tmp2; tmp.type=PIKE_T_STRING; tmp.u.string=Pike_fp->context.prog->strings[arg1]; tmp.subtype=0; index_no_free(&tmp2, Pike_sp-1, &tmp); free_svalue(Pike_sp-1); Pike_sp[-1]=tmp2; print_return_value(); } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe)  CASE(F_POS_INT_INDEX); push_int(GET_ARG()); print_return_value(); goto do_index; CASE(F_NEG_INT_INDEX);
e428262001-06-10Henrik Grubbström (Grubba)  push_int(-(ptrdiff_t)GET_ARG());
87c7592000-04-18Fredrik Hübinette (Hubbe)  print_return_value(); CASE(F_INDEX); do_index: { struct svalue s; index_no_free(&s,Pike_sp-2,Pike_sp-1); pop_n_elems(2); *Pike_sp=s; Pike_sp++; } print_return_value(); break;
a96ce92000-04-19Fredrik Hübinette (Hubbe) OPCODE2(F_MAGIC_INDEX, "::`[]") push_magic_index(magic_index_program, arg2, arg1);
372a652000-04-18Henrik Grubbström (Grubba) BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
a96ce92000-04-19Fredrik Hübinette (Hubbe) OPCODE2(F_MAGIC_SET_INDEX, "::`[]=") push_magic_index(magic_set_index_program, arg2, arg1);
372a652000-04-18Henrik Grubbström (Grubba) BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
372a652000-04-18Henrik Grubbström (Grubba) OPCODE0(F_CAST, "cast") f_cast(); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
0232d22001-06-17Henrik Grubbström (Grubba) OPCODE0(F_CAST_TO_INT, "cast_to_int") o_cast_to_int(); BREAK;
7f94c22001-06-17Henrik Grubbström (Grubba) OPCODE0(F_CAST_TO_STRING, "cast_to_string") o_cast_to_string(); BREAK;
bac71b2000-04-19Henrik Grubbström (Grubba) OPCODE0(F_SOFT_CAST, "soft cast") /* Stack: type_string, value */
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b103b32001-02-20Henrik Grubbström (Grubba)  if (Pike_sp[-2].type != T_TYPE) { fatal("Argument 1 to soft_cast isn't a type!\n");
bac71b2000-04-19Henrik Grubbström (Grubba)  }
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif /* PIKE_DEBUG */
bac71b2000-04-19Henrik Grubbström (Grubba)  if (runtime_options & RUNTIME_CHECK_TYPES) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_type *sval_type = get_type_of_svalue(Pike_sp-1); if (!pike_types_le(sval_type, Pike_sp[-2].u.type)) {
bac71b2000-04-19Henrik Grubbström (Grubba)  /* get_type_from_svalue() doesn't return a fully specified type * for array, mapping and multiset, so we perform a more lenient * check for them. */ if (!pike_types_le(sval_type, weak_type_string) ||
5320152001-02-20Henrik Grubbström (Grubba)  !match_types(sval_type, Pike_sp[-2].u.type)) {
bac71b2000-04-19Henrik Grubbström (Grubba)  struct pike_string *t1; struct pike_string *t2; char *fname = "__soft-cast"; ONERROR tmp1; ONERROR tmp2; if (Pike_fp->current_object && Pike_fp->context.prog && Pike_fp->current_object->prog) { /* Look up the function-name */ struct pike_string *name = ID_FROM_INT(Pike_fp->current_object->prog, Pike_fp->fun)->name; if ((!name->size_shift) && (name->len < 100)) fname = name->str; }
5320152001-02-20Henrik Grubbström (Grubba)  t1 = describe_type(Pike_sp[-2].u.type);
bac71b2000-04-19Henrik Grubbström (Grubba)  SET_ONERROR(tmp1, do_free_string, t1);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
bac71b2000-04-19Henrik Grubbström (Grubba)  t2 = describe_type(sval_type); SET_ONERROR(tmp2, do_free_string, t2);
87c7592000-04-18Fredrik Hübinette (Hubbe) 
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(sval_type);
bac71b2000-04-19Henrik Grubbström (Grubba)  bad_arg_error(NULL, Pike_sp-1, 1, 1, t1->str, Pike_sp-1, "%s(): Soft cast failed. Expected %s, got %s\n", fname, t1->str, t2->str); /* NOT_REACHED */ UNSET_ONERROR(tmp2); UNSET_ONERROR(tmp1); free_string(t2); free_string(t1); } }
d68a072001-02-20Henrik Grubbström (Grubba)  free_type(sval_type);
87c7592000-04-18Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
bac71b2000-04-19Henrik Grubbström (Grubba)  if (d_flag > 2) {
d68a072001-02-20Henrik Grubbström (Grubba)  struct pike_string *t = describe_type(Pike_sp[-2].u.type);
bac71b2000-04-19Henrik Grubbström (Grubba)  fprintf(stderr, "Soft cast to %s\n", t->str); free_string(t); }
87c7592000-04-18Fredrik Hübinette (Hubbe) #endif /* PIKE_DEBUG */
bac71b2000-04-19Henrik Grubbström (Grubba)  } stack_swap(); pop_stack(); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
372a652000-04-18Henrik Grubbström (Grubba) OPCODE0(F_RANGE, "range") o_range(); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
372a652000-04-18Henrik Grubbström (Grubba) OPCODE0(F_COPY_VALUE, "copy_value") { struct svalue tmp; copy_svalues_recursively_no_free(&tmp,Pike_sp-1,1,0); free_svalue(Pike_sp-1); Pike_sp[-1]=tmp; } BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
372a652000-04-18Henrik Grubbström (Grubba) OPCODE0(F_INDIRECT, "indirect") { struct svalue s; lvalue_to_svalue_no_free(&s,Pike_sp-2); if(s.type != PIKE_T_STRING) { pop_n_elems(2); *Pike_sp=s; Pike_sp++; }else{ struct object *o; o=low_clone(string_assignment_program); ((struct string_assignment_storage *)o->storage)->lval[0]=Pike_sp[-2]; ((struct string_assignment_storage *)o->storage)->lval[1]=Pike_sp[-1]; ((struct string_assignment_storage *)o->storage)->s=s.u.string; Pike_sp-=2; push_object(o); } } print_return_value(); BREAK; OPCODE0(F_SIZEOF, "sizeof") instr=pike_sizeof(Pike_sp-1); pop_stack(); push_int(instr); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
372a652000-04-18Henrik Grubbström (Grubba) OPCODE1(F_SIZEOF_LOCAL, "sizeof local") push_int(pike_sizeof(Pike_fp->locals+arg1)); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
372a652000-04-18Henrik Grubbström (Grubba) OPCODE1(F_SSCANF, "sscanf") o_sscanf(arg1); BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) #define MKAPPLY(OP,OPCODE,NAME,TYPE, ARG2, ARG3) \ OP(PIKE_CONCAT(F_,OPCODE),NAME) \ if(low_mega_apply(TYPE,DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)), \ ARG2, ARG3)) \ { \ Pike_fp->next->pc=pc; \ Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL; \ pc=Pike_fp->pc; \ } \ BREAK; \ \ OP(PIKE_CONCAT3(F_,OPCODE,_AND_POP),NAME " & pop") \ if(low_mega_apply(TYPE, DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)), \ ARG2, ARG3)) \ { \ Pike_fp->next->pc=pc; \ Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP; \ pc=Pike_fp->pc; \ }else{ \ pop_stack(); \ } \ BREAK; \ \ OP(PIKE_CONCAT3(F_,OPCODE,_AND_RETURN),NAME " & return") \ { \ if(low_mega_apply(TYPE,DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)), \ ARG2,ARG3)) \ { \ DO_IF_DEBUG(Pike_fp->next->pc=0); \ pc=Pike_fp->pc; \ unlink_previous_frame(); \ }else{ \ goto do_dumb_return; \ } \ } \ BREAK \ \ OP(PIKE_CONCAT(F_MARK_,OPCODE),"mark, " NAME) \ if(low_mega_apply(TYPE,0, \ ARG2, ARG3)) \ { \ Pike_fp->next->pc=pc; \ Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL; \ pc=Pike_fp->pc; \ } \ BREAK; \ \ OP(PIKE_CONCAT3(F_MARK_,OPCODE,_AND_POP),"mark, " NAME " & pop") \ if(low_mega_apply(TYPE, 0, \ ARG2, ARG3)) \ { \ Pike_fp->next->pc=pc; \ Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP; \ pc=Pike_fp->pc; \ }else{ \ pop_stack(); \ } \ BREAK; \ \ OP(PIKE_CONCAT3(F_MARK_,OPCODE,_AND_RETURN),"mark, " NAME " & return") \ { \ if(low_mega_apply(TYPE,0, \ ARG2,ARG3)) \ { \ DO_IF_DEBUG(Pike_fp->next->pc=0); \ pc=Pike_fp->pc; \ unlink_previous_frame(); \ }else{ \ goto do_dumb_return; \ } \ } \ BREAK
87c7592000-04-18Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) MKAPPLY(OPCODE1,CALL_LFUN,"call lfun",APPLY_LOW, Pike_fp->current_object, (void *)(arg1+Pike_fp->context.identifier_level));
87c7592000-04-18Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) MKAPPLY(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) 
70be662001-06-19Fredrik Hübinette (Hubbe) #undef DO_CALL_BUILTIN #ifdef PIKE_DEBUG #define DO_CALL_BUILTIN(ARGS) do { \ int args=(ARGS); \ struct svalue *expected_stack=Pike_sp-args; \ struct svalue *s=&Pike_fp->context.prog->constants[arg1].sval; \ if(t_flag>1) \ { \ init_buf(); \ describe_svalue(s, 0,0); \ do_trace_call(args); \ } \ (*(s->u.efun->function))(args); \ if(Pike_sp != expected_stack + !s->u.efun->may_return_void) \ { \ if(Pike_sp < expected_stack) \ fatal("Function popped too many arguments: %s\n", \ s->u.efun->name->str); \ if(Pike_sp>expected_stack+1) \
121f822001-06-28Fredrik Hübinette (Hubbe)  fatal("Function left %d droppings on stack: %s\n", \ 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) \ fatal("Non-void function returned without return value " \ "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) \ fatal("Void function returned with a value on the stack: %s %d\n", \ s->u.efun->name->str, s->u.efun->may_return_void); \ } \ if(t_flag>1 && Pike_sp>expected_stack) trace_return_value(); \ }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) 
70be662001-06-19Fredrik Hübinette (Hubbe) OPCODE1(F_CALL_BUILTIN,"call builtin") { DO_CALL_BUILTIN(DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp))); }
90703d2001-01-31Martin Stjernholm BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) OPCODE1(F_CALL_BUILTIN_AND_POP,"call builtin & pop") { DO_CALL_BUILTIN(DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp))); pop_stack(); } BREAK;
9ddbf22001-05-10Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) OPCODE1(F_CALL_BUILTIN_AND_RETURN,"call builtin & return") { DO_CALL_BUILTIN(DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp))); goto do_dumb_return; }
9ddbf22001-05-10Fredrik Hübinette (Hubbe) BREAK;
70be662001-06-19Fredrik Hübinette (Hubbe)  OPCODE1(F_MARK_CALL_BUILTIN,"mark, call builtin")
9ddbf22001-05-10Fredrik Hübinette (Hubbe) {
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(0);
9ddbf22001-05-10Fredrik Hübinette (Hubbe) }
90703d2001-01-31Martin Stjernholm BREAK;
87c7592000-04-18Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) OPCODE1(F_MARK_CALL_BUILTIN_AND_POP,"mark, call builtin & pop")
9ddbf22001-05-10Fredrik Hübinette (Hubbe) {
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(0); pop_stack();
9ddbf22001-05-10Fredrik Hübinette (Hubbe) }
70be662001-06-19Fredrik Hübinette (Hubbe) BREAK;
9ddbf22001-05-10Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) OPCODE1(F_MARK_CALL_BUILTIN_AND_RETURN,"mark, call builtin & return")
90703d2001-01-31Martin Stjernholm {
70be662001-06-19Fredrik Hübinette (Hubbe)  DO_CALL_BUILTIN(0); goto do_dumb_return;
90703d2001-01-31Martin Stjernholm } BREAK;
6fd5172000-04-25Fredrik Hübinette (Hubbe) 
70be662001-06-19Fredrik Hübinette (Hubbe) 
6fd5172000-04-25Fredrik Hübinette (Hubbe) /* Assume that the number of arguments is correct */
a64f6b2001-01-12Martin Stjernholm OPCODE1_JUMP(F_COND_RECUR,"recur if not overloaded") { /* FIXME: * this test should actually test if this function is * overloaded or not. Currently it only tests if * this context is inherited or not. */ if(Pike_fp->current_object->prog != Pike_fp->context.prog) { pc+=sizeof(INT32);
105ade2001-05-13Fredrik Hübinette (Hubbe)  if(low_mega_apply(APPLY_LOW,
e428262001-06-10Henrik Grubbström (Grubba)  DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp)),
105ade2001-05-13Fredrik Hübinette (Hubbe)  Pike_fp->current_object, (void *)(arg1+Pike_fp->context.identifier_level))) { Pike_fp->next->pc=pc; Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL; pc=Pike_fp->pc; }
a64f6b2001-01-12Martin Stjernholm  DONE; } } /* FALL THROUGH */ /* Assume that the number of arguments is correct */
9ddbf22001-05-10Fredrik Hübinette (Hubbe) /* FIXME: Use new recursion stuff */
a64f6b2001-01-12Martin Stjernholm OPCODE0_TAILJUMP(F_RECUR,"recur")
90703d2001-01-31Martin Stjernholm OPCODE0_TAILJUMP(F_RECUR_AND_POP,"recur & pop")
6fd5172000-04-25Fredrik Hübinette (Hubbe) {
9ddbf22001-05-10Fredrik Hübinette (Hubbe)  int opcode = instr;
c051fc2001-05-11Henrik Grubbström (Grubba)  unsigned char *addr;
9ddbf22001-05-10Fredrik Hübinette (Hubbe)  struct pike_frame *new_frame; fast_check_threads_etc(6); check_c_stack(8192); check_stack(256); new_frame=alloc_pike_frame(); new_frame[0]=Pike_fp[0]; new_frame->refs=1; new_frame->next=Pike_fp; new_frame->save_sp = new_frame->expendible = new_frame->locals = *--Pike_mark_sp;
e428262001-06-10Henrik Grubbström (Grubba)  new_frame->num_args = new_frame->args = DO_NOT_WARN((INT32)(Pike_sp - new_frame->locals));
9ddbf22001-05-10Fredrik Hübinette (Hubbe)  new_frame->save_mark_sp = Pike_mark_sp; new_frame->mark_sp_base = Pike_mark_sp; addr=pc+GET_JUMP(); new_frame->num_locals=EXTRACT_UCHAR(addr-2); #ifdef PIKE_DEBUG if(new_frame->num_args != EXTRACT_UCHAR(addr-1)) fatal("Wrong number of arguments in F_RECUR %d!=%d\n", new_frame->num_args, EXTRACT_UCHAR(addr-1)); if(t_flag > 3) fprintf(stderr,"- Allocating %d extra locals.\n", new_frame->num_locals - new_frame->num_args); #endif clear_svalues(Pike_sp, new_frame->num_locals - new_frame->num_args); Pike_sp += new_frame->num_locals - new_frame->args; if(new_frame->scope) add_ref(new_frame->scope); add_ref(new_frame->current_object); add_ref(new_frame->context.prog); if(new_frame->context.parent) add_ref(new_frame->context.parent); Pike_fp->pc=pc+sizeof(INT32); Pike_fp=new_frame; pc=addr; new_frame->flags=PIKE_FRAME_RETURN_INTERNAL; if (opcode == F_RECUR_AND_POP-F_OFFSET) new_frame->flags|=PIKE_FRAME_RETURN_POP;
6fd5172000-04-25Fredrik Hübinette (Hubbe) } BREAK
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 */
6fd5172000-04-25Fredrik Hübinette (Hubbe) OPCODE0_JUMP(F_TAIL_RECUR,"tail recursion") {
a222992000-08-07Henrik Grubbström (Grubba)  int x; INT32 num_locals;
c051fc2001-05-11Henrik Grubbström (Grubba)  unsigned char *addr;
e428262001-06-10Henrik Grubbström (Grubba)  INT32 args = DO_NOT_WARN((INT32)(Pike_sp - *--Pike_mark_sp));
6fd5172000-04-25Fredrik Hübinette (Hubbe)  fast_check_threads_etc(6);
90703d2001-01-31Martin Stjernholm  addr=pc+GET_JUMP();
873ceb2000-04-30Fredrik Hübinette (Hubbe)  num_locals=EXTRACT_UCHAR(addr-2);
6fd5172000-04-25Fredrik Hübinette (Hubbe)  #ifdef PIKE_DEBUG
873ceb2000-04-30Fredrik Hübinette (Hubbe)  if(args != EXTRACT_UCHAR(addr-1))
a222992000-08-07Henrik Grubbström (Grubba)  fatal("Wrong number of arguments in F_TAIL_RECUR %d != %d\n", args, EXTRACT_UCHAR(addr-1));
6fd5172000-04-25Fredrik Hübinette (Hubbe) #endif
17f08c2000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp-args != Pike_fp->locals)
6fd5172000-04-25Fredrik Hübinette (Hubbe)  {
3723b92001-01-08Martin Stjernholm #ifdef PIKE_DEBUG if (Pike_sp < Pike_fp->locals + args) fatal("Pike_sp (%p) < Pike_fp->locals (%p) + args (%d)\n", Pike_sp, Pike_fp->locals, args); #endif
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)  }
17f08c2000-07-06Fredrik Hübinette (Hubbe)  clear_svalues(Pike_sp, num_locals - args); Pike_sp += num_locals - args;
6fd5172000-04-25Fredrik Hübinette (Hubbe)  #ifdef PIKE_DEBUG
17f08c2000-07-06Fredrik Hübinette (Hubbe)  if(Pike_sp != Pike_fp->locals + Pike_fp->num_locals)
6fd5172000-04-25Fredrik Hübinette (Hubbe)  fatal("Sp whacked!\n"); #endif pc=addr; } BREAK
d49add2001-04-25Fredrik Hübinette (Hubbe)  OPCODE0(F_BREAKPOINT,"breakpoint") { extern void o_breakpoint(void); o_breakpoint(); pc--; } BREAK;