Skip to content
Snippets Groups Projects
Select Git revision
  • 5008af05072fd08c7058e8d56a089343daf9035d
  • master default protected
  • 9.0
  • 8.0
  • nt-tools
  • 7.8
  • 7.6
  • 7.4
  • 7.2
  • 7.0
  • 0.6
  • rosuav/latex-markdown-renderer
  • rxnpatch/rxnpatch
  • marcus/gobject-introspection
  • rxnpatch/8.0
  • rosuav/pre-listening-ports
  • rosuav/async-annotations
  • rosuav/pgsql-ssl
  • rxnpatch/rxnpatch-broken/2023-10-06T094250
  • grubba/fdlib
  • grubba/wip/sakura/8.0
  • v8.0.2020
  • v8.0.2018
  • v8.0.2016
  • v8.0.2014
  • v8.0.2012
  • v8.0.2008
  • v8.0.2006
  • v8.0.2004
  • v8.0.2002
  • v8.0.2000
  • v8.0.1998
  • v8.0.1996
  • v8.0.1994
  • v8.0.1992
  • v8.0.1990
  • v8.0.1988
  • v8.0.1986
  • rxnpatch/clusters/8.0/2025-04-29T124414
  • rxnpatch/2025-04-29T124414
  • v8.0.1984
41 results

image.h

Blame
  • apply_low.h 8.72 KiB
    /*
    || 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.
    */
    
        {
          struct program *p;
          struct reference *ref;
          struct pike_frame *new_frame;
          struct identifier *function;
    
    #ifdef PIKE_DEBUG
          if (fun < 0)
    	Pike_fatal ("Invalid function offset: %d.\n", fun);
    #endif
          check_stack(256);
          check_mark_stack(256);
    
    #ifdef PIKE_DEBUG
          {
    	static int counter;
    	switch(d_flag)
    	{
    	  case 0:
    	  case 1:
    	  case 2:
    	    break;
    	  case 3:
    	    if(!((counter++ & 7)))
    	      do_debug();
    	    break;
    	  case 4:
    	  default:
    	    do_debug();
    	}
          }
    #endif
    
          p=o->prog;
          if(!p)
    	PIKE_ERROR("destructed object->function",
    	      "Cannot call functions in destructed objects.\n", Pike_sp, args);
    
          if(!(p->flags & PROGRAM_PASS_1_DONE) || (p->flags & PROGRAM_AVOID_CHECK))
    	PIKE_ERROR("__empty_program() -> function",
    	      "Cannot call functions in unfinished objects.\n", Pike_sp, args);
    	
    
    #ifdef PIKE_SECURITY
          CHECK_DATA_SECURITY_OR_ERROR(o, SECURITY_BIT_CALL,
    				   ("Function call permission denied.\n"));
    
          if(!CHECK_DATA_SECURITY(o, SECURITY_BIT_NOT_SETUID))
    	SET_CURRENT_CREDS(o->prot);
    #endif
    
    
    #ifdef PIKE_DEBUG
          if(fun>=(int)p->num_identifier_references)
          {
    	fprintf(stderr, "Function index out of range. %ld >= %d\n",
    		DO_NOT_WARN((long)fun),
    		(int)p->num_identifier_references);
    	fprintf(stderr,"########Program is:\n");
    	describe(p);
    	fprintf(stderr,"########Object is:\n");
    	describe(o);
    	Pike_fatal("Function index out of range.\n");
          }
    #endif
    
          ref = p->identifier_references + fun;
    #ifdef PIKE_DEBUG
          if(ref->inherit_offset>=p->num_inherits)
    	Pike_fatal("Inherit offset out of range in program.\n");
    #endif
    
          /* init a new evaluation pike_frame */
          new_frame=alloc_pike_frame();
    #ifdef PROFILING
          new_frame->children_base = Pike_interpreter.accounted_time;
          new_frame->start_time = get_cpu_time() - Pike_interpreter.unlocked_time;
    
          /* 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;
          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);
    	});
    #endif
          debug_malloc_touch(new_frame);
    
          new_frame->next = Pike_fp;
          new_frame->current_object = o;
          new_frame->current_program = p;
          new_frame->context = p->inherits + ref->inherit_offset;
    
          function = new_frame->context->prog->identifiers + ref->identifier_offset;
          new_frame->fun = DO_NOT_WARN((unsigned INT16)fun);
    
          
    #ifdef PIKE_DEBUG
    	if(Pike_interpreter.trace_level > 9)
    	{
    	  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",
    		  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,
    		  DO_NOT_WARN((long)new_frame->context->storage_offset),
    		  new_frame->context->name ? new_frame->context->name->str  : "NULL");
    	  if(Pike_interpreter.trace_level>19)
    	  {
    	    describe(new_frame->context->prog);
    	  }
    	}
    #endif
    
    
          new_frame->expendible = new_frame->locals = Pike_sp - args;
          new_frame->args = args;
          new_frame->pc = 0;
          new_frame->scope=scope;
    #ifdef PIKE_DEBUG
          if(scope && new_frame->fun == scope->fun)
          {
    	Pike_fatal("Que? A function cannot be parented by itself!\n");
          }
    #endif
          new_frame->save_sp=save_sp;
    
          add_ref(new_frame->current_object);
          add_ref(new_frame->current_program);
          if(new_frame->scope) add_ref(new_frame->scope);
    #ifdef PIKE_DEBUG
          if (Pike_fp) {
    
    	if (new_frame->locals < Pike_fp->locals) {
    	  fatal("New locals below old locals: %p < %p\n",
    		new_frame->locals, Pike_fp->locals);
    	}
    
    	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++)
    	    if (TYPEOF(l[i]) != PIKE_T_FREE)
    	      debug_check_svalue (l + i);
    	}
          }
    #endif /* PIKE_DEBUG */
    
          Pike_fp = new_frame;
          
          if(Pike_interpreter.trace_level)
          {
    	dynamic_buffer save_buf;
    	char buf[50];
    
    	init_buf(&save_buf);
    	sprintf(buf, "%lx->", DO_NOT_WARN((long) PTR_TO_INT (o)));
    	my_strcat(buf);
    	if (function->name->size_shift)
    	  my_strcat ("[widestring function name]");
    	else
    	  my_strcat(function->name->str);
    	do_trace_call(args, &save_buf);
          }
          if (PIKE_FN_START_ENABLED()) {
    	/* DTrace enter probe
    	   arg0: function name
    	   arg1: object
    	*/
    	dynamic_buffer save_buf;
    	dynbuf_string obj_name;
    	struct svalue obj_sval;
    	SET_SVAL(obj_sval, T_OBJECT, 0, object, o);
    	init_buf(&save_buf);
    	safe_describe_svalue(&obj_sval, 0, NULL);
    	obj_name = complex_free_buf(&save_buf);
    	PIKE_FN_START(function->name->size_shift == 0 ?
    		      function->name->str : "[widestring fn name]",
    		      obj_name.str);
          }
    
    #ifdef PROFILING
          function->num_calls++;
          function->recur_depth++;
    #endif
      
          if(function->func.offset == -1) {
    	new_frame->num_args = args;
    	generic_error(NULL, Pike_sp, args,
    		      "Calling undefined function.\n");
          }
          
          switch(function->identifier_flags & (IDENTIFIER_TYPE_MASK|IDENTIFIER_ALIAS))
          {
          case IDENTIFIER_C_FUNCTION:
    	debug_malloc_touch(Pike_fp);
    	Pike_fp->num_args=args;
    	new_frame->current_storage = o->storage+new_frame->context->storage_offset;
    	new_frame->num_locals=args;
    	FAST_CHECK_THREADS_ON_CALL();
    	(*function->func.c_fun)(args);
    	break;
    	
          case IDENTIFIER_CONSTANT:
          {
    	struct svalue *s=&(Pike_fp->context->prog->
    			   constants[function->func.const_info.offset].sval);
    	debug_malloc_touch(Pike_fp);
    	if(TYPEOF(*s) == T_PROGRAM)
    	{
    	  struct object *tmp;
    	  FAST_CHECK_THREADS_ON_CALL();
    	  Pike_fp->num_args=args;
    	  tmp=parent_clone_object(s->u.program,
    				  o,
    				  fun,
    				  args);
    	  push_object(tmp);
    	  break;
    	}
    	/* Fall through */
          }
    
          case IDENTIFIER_VARIABLE:
          {
    	/* 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++;
    	  MEMMOVE(Pike_sp-args,Pike_sp-args-1,sizeof(struct svalue)*args);
    #ifdef DEBUG_MALLOC
    	  if (args) {
    	    int i;
    	    /* Note: touch the dead svalue too. */
    	    for (i=args+2; i > 0; i--) {
    	      dmalloc_touch_svalue(Pike_sp-i);
    	    }
    	  }
    #endif /* DEBUG_MALLOC */
    	}else{
    	  free_svalue(Pike_sp-args-1);
    	}
    	mark_free_svalue (Pike_sp - args - 1);
    	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);
    	if (PIKE_FN_POPFRAME_ENABLED()) {
    	  /* DTrace adjust frame depth */
    	  PIKE_FN_POPFRAME();
    	}
    	goto apply_svalue;
          }
    
          case IDENTIFIER_PIKE_FUNCTION:
          {
    	int num_args;
    	int num_locals;
    	PIKE_OPCODE_T *pc;
    	FAST_CHECK_THREADS_ON_CALL();
    
    #ifdef PIKE_DEBUG
    	if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_FREE)
    	  Pike_fatal("Pike code called within gc.\n");
        new_frame->num_args = 0;
        new_frame->num_locals = 0;
    #endif
    
    	debug_malloc_touch(Pike_fp);
    	pc=new_frame->context->prog->program + function->func.offset;
    
    	new_frame->save_mark_sp=new_frame->mark_sp_base=Pike_mark_sp;
    	new_frame->pc = pc
    #ifdef ENTRY_PROLOGUE_SIZE
    	  + ENTRY_PROLOGUE_SIZE
    #endif /* ENTRY_PROLOGUE_SIZE */
    	  ;
    
    	return new_frame->pc;
          }
    
          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));
    	  if (PIKE_FN_POPFRAME_ENABLED()) {
    	    /* DTrace adjust frame depth */
    	    PIKE_FN_POPFRAME();
    	  }
    	  goto apply_low;
    	}
    #ifdef PIKE_DEBUG
    	Pike_fatal("Unknown identifier type.\n");
    #endif
          }
          POP_PIKE_FRAME();
        }