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. */
1b10db2002-10-08Martin Nilsson 
4b05702001-08-30Fredrik Hübinette (Hubbe)  { struct program *p; struct reference *ref; struct pike_frame *new_frame; struct identifier *function;
bd8fb82004-04-03Martin Stjernholm 
7b0d862003-07-30Martin Stjernholm #ifdef PIKE_DEBUG if (fun < 0)
6cafae2006-03-17Henrik Grubbström (Grubba)  Pike_fatal ("Invalid function offset: %d.\n", fun);
7b0d862003-07-30Martin Stjernholm #endif
4b05702001-08-30Fredrik Hübinette (Hubbe)  check_stack(256); check_mark_stack(256); #ifdef PIKE_DEBUG
5602c72001-09-04Fredrik Hübinette (Hubbe)  { static int counter; switch(d_flag) { case 0: case 1: case 2: break; case 3: if(!((counter++ & 7))) do_debug(); break; case 4:
4853502003-09-08Martin Stjernholm  default:
5602c72001-09-04Fredrik Hübinette (Hubbe)  do_debug(); } }
4b05702001-08-30Fredrik Hübinette (Hubbe) #endif p=o->prog; if(!p) PIKE_ERROR("destructed object->function", "Cannot call functions in destructed objects.\n", Pike_sp, args);
92c73b2001-11-08Fredrik Hübinette (Hubbe)  if(!(p->flags & PROGRAM_PASS_1_DONE) || (p->flags & PROGRAM_AVOID_CHECK))
82c2052001-09-27Fredrik Hübinette (Hubbe)  PIKE_ERROR("__empty_program() -> function", "Cannot call functions in unfinished objects.\n", Pike_sp, args);
4b05702001-08-30Fredrik Hübinette (Hubbe)  #ifdef PIKE_DEBUG if(fun>=(int)p->num_identifier_references) { fprintf(stderr, "Function index out of range. %ld >= %d\n",
bd67392015-10-14Martin Nilsson  (long)fun, (int)p->num_identifier_references);
4b05702001-08-30Fredrik Hübinette (Hubbe)  fprintf(stderr,"########Program is:\n"); describe(p); fprintf(stderr,"########Object is:\n"); describe(o);
5aad932002-08-15Marcus Comstedt  Pike_fatal("Function index out of range.\n");
4b05702001-08-30Fredrik Hübinette (Hubbe)  } #endif ref = p->identifier_references + fun; #ifdef PIKE_DEBUG if(ref->inherit_offset>=p->num_inherits)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Inherit offset out of range in program.\n");
4b05702001-08-30Fredrik Hübinette (Hubbe) #endif /* init a new evaluation pike_frame */ new_frame=alloc_pike_frame(); #ifdef PROFILING new_frame->children_base = Pike_interpreter.accounted_time;
b2630d2004-05-20Henrik Grubbström (Grubba)  new_frame->start_time = get_cpu_time() - Pike_interpreter.unlocked_time;
4b05702001-08-30Fredrik Hübinette (Hubbe)  /* This is mostly for profiling, but * could also be used to find out the name of a function * in a destructed object. -hubbe * * Since it not used for anything but profiling yet, I will * put it here until someone needs it. -Hubbe */ new_frame->ident = ref->identifier_offset;
9a99f72016-02-12Martin Nilsson  W_PROFILING_DEBUG("%p{: Push at %" PRINT_CPU_TIME " %" PRINT_CPU_TIME "\n", Pike_interpreter.thread_state, new_frame->start_time, new_frame->children_base);
4b05702001-08-30Fredrik Hübinette (Hubbe) #endif debug_malloc_touch(new_frame); new_frame->next = Pike_fp; new_frame->current_object = o;
fa93a52008-02-28Henrik Grubbström (Grubba)  new_frame->current_program = p; new_frame->context = p->inherits + ref->inherit_offset;
4b05702001-08-30Fredrik Hübinette (Hubbe) 
fa93a52008-02-28Henrik Grubbström (Grubba)  function = new_frame->context->prog->identifiers + ref->identifier_offset;
bd67392015-10-14Martin Nilsson  new_frame->fun = (unsigned INT16)fun;
4b05702001-08-30Fredrik Hübinette (Hubbe) 
13670c2015-05-25Martin Nilsson 
4b05702001-08-30Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
97ebb32003-01-09Henrik Grubbström (Grubba)  if(Pike_interpreter.trace_level > 9)
4b05702001-08-30Fredrik Hübinette (Hubbe)  { fprintf(stderr,"-- ref: inoff=%d idoff=%d flags=%d\n", ref->inherit_offset, ref->identifier_offset, ref->id_flags); fprintf(stderr,"-- context: prog->id=%d inlev=%d idlev=%d pi=%d po=%d so=%ld name=%s\n",
fa93a52008-02-28Henrik Grubbström (Grubba)  new_frame->context->prog->id, new_frame->context->inherit_level, new_frame->context->identifier_level, new_frame->context->parent_identifier, new_frame->context->parent_offset,
bd67392015-10-14Martin Nilsson  (long)new_frame->context->storage_offset,
fa93a52008-02-28Henrik Grubbström (Grubba)  new_frame->context->name ? new_frame->context->name->str : "NULL");
97ebb32003-01-09Henrik Grubbström (Grubba)  if(Pike_interpreter.trace_level>19)
4b05702001-08-30Fredrik Hübinette (Hubbe)  {
fa93a52008-02-28Henrik Grubbström (Grubba)  describe(new_frame->context->prog);
4b05702001-08-30Fredrik Hübinette (Hubbe)  } } #endif
bca80a2016-07-18Arne Goedeke  new_frame->locals = Pike_sp - args;
4b05702001-08-30Fredrik Hübinette (Hubbe)  new_frame->args = args; new_frame->pc = 0; new_frame->scope=scope;
8c70ba2001-09-28Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
6417722013-06-12Per Hedbor  if(scope && new_frame->fun == scope->fun)
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  {
5aad932002-08-15Marcus Comstedt  Pike_fatal("Que? A function cannot be parented by itself!\n");
8c70ba2001-09-28Fredrik Hübinette (Hubbe)  } #endif
bca80a2016-07-18Arne Goedeke  frame_set_save_sp(new_frame, save_sp);
6417722013-06-12Per Hedbor 
4b05702001-08-30Fredrik Hübinette (Hubbe)  add_ref(new_frame->current_object);
fa93a52008-02-28Henrik Grubbström (Grubba)  add_ref(new_frame->current_program);
4b05702001-08-30Fredrik Hübinette (Hubbe)  if(new_frame->scope) add_ref(new_frame->scope);
6417722013-06-12Per Hedbor #ifdef PIKE_DEBUG
f3b4152008-03-29Martin Stjernholm  if (Pike_fp) {
7dc3e82009-06-06Henrik Grubbström (Grubba) 
f3b4152008-03-29Martin Stjernholm  if (new_frame->locals < Pike_fp->locals) {
a6f2292016-01-29Martin Nilsson  Pike_fatal("New locals below old locals: %p < %p\n", new_frame->locals, Pike_fp->locals);
f3b4152008-03-29Martin Stjernholm  } if (d_flag > 1) { /* Liberal use of variables for debugger convenience. */ size_t i; struct svalue *l = Pike_fp->locals; for (i = 0; l + i < Pike_sp; i++)
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(l[i]) != PIKE_T_FREE)
f3b4152008-03-29Martin Stjernholm  debug_check_svalue (l + i); }
45e7ab2007-12-31Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */
4b05702001-08-30Fredrik Hübinette (Hubbe) 
45e7ab2007-12-31Henrik Grubbström (Grubba)  Pike_fp = new_frame;
13670c2015-05-25Martin Nilsson 
97ebb32003-01-09Henrik Grubbström (Grubba)  if(Pike_interpreter.trace_level)
4b05702001-08-30Fredrik Hübinette (Hubbe)  {
2ff6e72016-12-28Arne Goedeke  do_trace_function_call(o, function, args);
4b05702001-08-30Fredrik Hübinette (Hubbe)  }
cf84342011-05-19Jonas Walldén  if (PIKE_FN_START_ENABLED()) { /* DTrace enter probe arg0: function name arg1: object */
e0cd662016-12-28Arne Goedeke  struct byte_buffer obj_name = BUFFER_INIT();
cf84342011-05-19Jonas Walldén  struct svalue obj_sval;
017b572011-10-28Henrik Grubbström (Grubba)  SET_SVAL(obj_sval, T_OBJECT, 0, object, o);
e0cd662016-12-28Arne Goedeke  safe_describe_svalue(&obj_name, &obj_sval, 0, NULL);
cf84342011-05-19Jonas Walldén  PIKE_FN_START(function->name->size_shift == 0 ? function->name->str : "[widestring fn name]",
e0cd662016-12-28Arne Goedeke  buffer_get_string(&obj_name)); buffer_free(&obj_name);
cf84342011-05-19Jonas Walldén  }
a068db2003-10-01Henrik Grubbström (Grubba) 
4b05702001-08-30Fredrik Hübinette (Hubbe) #ifdef PROFILING function->num_calls++;
5ca7b52012-01-07Jonas Walldén  function->recur_depth++;
4b05702001-08-30Fredrik Hübinette (Hubbe) #endif
13670c2015-05-25Martin Nilsson 
4b05702001-08-30Fredrik Hübinette (Hubbe)  if(function->func.offset == -1) {
fa7f902003-02-24Martin Stjernholm  new_frame->num_args = args;
4b05702001-08-30Fredrik Hübinette (Hubbe)  generic_error(NULL, Pike_sp, args, "Calling undefined function.\n"); }
13670c2015-05-25Martin Nilsson 
45e7ab2007-12-31Henrik Grubbström (Grubba)  switch(function->identifier_flags & (IDENTIFIER_TYPE_MASK|IDENTIFIER_ALIAS))
6417722013-06-12Per Hedbor  {
4b05702001-08-30Fredrik Hübinette (Hubbe)  case IDENTIFIER_C_FUNCTION: debug_malloc_touch(Pike_fp); Pike_fp->num_args=args;
fa93a52008-02-28Henrik Grubbström (Grubba)  new_frame->current_storage = o->storage+new_frame->context->storage_offset;
4b05702001-08-30Fredrik Hübinette (Hubbe)  new_frame->num_locals=args;
51d7d82008-11-18Martin Stjernholm  FAST_CHECK_THREADS_ON_CALL();
4b05702001-08-30Fredrik Hübinette (Hubbe)  (*function->func.c_fun)(args); break;
13670c2015-05-25Martin Nilsson 
4b05702001-08-30Fredrik Hübinette (Hubbe)  case IDENTIFIER_CONSTANT: {
fa93a52008-02-28Henrik Grubbström (Grubba)  struct svalue *s=&(Pike_fp->context->prog->
89378b2010-11-23Henrik Grubbström (Grubba)  constants[function->func.const_info.offset].sval);
4b05702001-08-30Fredrik Hübinette (Hubbe)  debug_malloc_touch(Pike_fp);
017b572011-10-28Henrik Grubbström (Grubba)  if(TYPEOF(*s) == T_PROGRAM)
4b05702001-08-30Fredrik Hübinette (Hubbe)  { struct object *tmp;
51d7d82008-11-18Martin Stjernholm  FAST_CHECK_THREADS_ON_CALL();
89a6022002-11-21Henrik Grubbström (Grubba)  Pike_fp->num_args=args;
4b05702001-08-30Fredrik Hübinette (Hubbe)  tmp=parent_clone_object(s->u.program, o, fun, args); push_object(tmp); break; } }
5f50842018-02-12Marcus Comstedt  /* FALLTHRU */
c278f72003-08-03Martin Stjernholm  case IDENTIFIER_VARIABLE:
4b05702001-08-30Fredrik Hübinette (Hubbe)  { /* FIXME: * Use new-style tail-recursion instead */ debug_malloc_touch(Pike_fp); debug_malloc_touch(o); if(Pike_sp-save_sp-args<=0) { /* Create an extra svalue for tail recursion style call */ Pike_sp++;
68c0a82014-09-03Martin Nilsson  memmove(Pike_sp-args,Pike_sp-args-1,sizeof(struct svalue)*args);
50ea682003-03-14Henrik Grubbström (Grubba) #ifdef DEBUG_MALLOC
f588b42003-03-15Henrik Grubbström (Grubba)  if (args) {
50ea682003-03-14Henrik Grubbström (Grubba)  int i; /* Note: touch the dead svalue too. */ for (i=args+2; i > 0; i--) { dmalloc_touch_svalue(Pike_sp-i); } }
1ab4ac2008-01-26Martin Stjernholm #endif /* DEBUG_MALLOC */
4b05702001-08-30Fredrik Hübinette (Hubbe)  }else{ free_svalue(Pike_sp-args-1); }
1ab4ac2008-01-26Martin Stjernholm  mark_free_svalue (Pike_sp - args - 1);
4b05702001-08-30Fredrik Hübinette (Hubbe)  low_object_index_no_free(Pike_sp-args-1,o,fun); /* No profiling code for calling variables - Hubbe */ POP_PIKE_FRAME(); if(Pike_sp-save_sp-args > (args<<2) + 32) { /* The test above assures these two areas * are not overlapping */ assign_svalues(save_sp, Pike_sp-args, args, BIT_MIXED); pop_n_elems(Pike_sp-save_sp-args); } arg1=(void *)(Pike_sp-args-1);
cf84342011-05-19Jonas Walldén  if (PIKE_FN_POPFRAME_ENABLED()) { /* DTrace adjust frame depth */ PIKE_FN_POPFRAME(); }
4b05702001-08-30Fredrik Hübinette (Hubbe)  goto apply_svalue; } case IDENTIFIER_PIKE_FUNCTION: { int num_args; int num_locals; PIKE_OPCODE_T *pc;
51d7d82008-11-18Martin Stjernholm  FAST_CHECK_THREADS_ON_CALL();
4b05702001-08-30Fredrik Hübinette (Hubbe)  #ifdef PIKE_DEBUG if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_FREE)
5aad932002-08-15Marcus Comstedt  Pike_fatal("Pike code called within gc.\n");
b843342012-06-28Per Hedbor  new_frame->num_args = 0; new_frame->num_locals = 0;
4b05702001-08-30Fredrik Hübinette (Hubbe) #endif debug_malloc_touch(Pike_fp);
8752f62016-09-05Arne Goedeke  new_frame->current_storage = o->storage+new_frame->context->storage_offset;
fa93a52008-02-28Henrik Grubbström (Grubba)  pc=new_frame->context->prog->program + function->func.offset;
4b05702001-08-30Fredrik Hübinette (Hubbe) 
1fd4232016-07-09Arne Goedeke  new_frame->save_mark_sp=Pike_mark_sp;
4b05702001-08-30Fredrik Hübinette (Hubbe)  new_frame->pc = pc #ifdef ENTRY_PROLOGUE_SIZE + ENTRY_PROLOGUE_SIZE #endif /* ENTRY_PROLOGUE_SIZE */ ;
6cafae2006-03-17Henrik Grubbström (Grubba) 
5909f92013-08-15Per Hedbor  return new_frame->pc;
4b05702001-08-30Fredrik Hübinette (Hubbe)  }
c278f72003-08-03Martin Stjernholm 
45e7ab2007-12-31Henrik Grubbström (Grubba)  default: if (IDENTIFIER_IS_ALIAS(function->identifier_flags)) { POP_PIKE_FRAME(); do { struct external_variable_context loc; loc.o = o; loc.inherit = INHERIT_FROM_INT(p, fun); loc.parent_identifier = 0; find_external_context(&loc, function->func.ext_ref.depth); fun = function->func.ext_ref.id; p = (o = loc.o)->prog; function = ID_FROM_INT(p, fun); } while (IDENTIFIER_IS_ALIAS(function->identifier_flags));
cf84342011-05-19Jonas Walldén  if (PIKE_FN_POPFRAME_ENABLED()) { /* DTrace adjust frame depth */ PIKE_FN_POPFRAME(); }
45e7ab2007-12-31Henrik Grubbström (Grubba)  goto apply_low; }
c278f72003-08-03Martin Stjernholm #ifdef PIKE_DEBUG Pike_fatal("Unknown identifier type.\n"); #endif
4b05702001-08-30Fredrik Hübinette (Hubbe)  } POP_PIKE_FRAME(); }