00001
00002
00003
00004
00005
00006
00007
00008 {
00009 struct program *p;
00010 struct reference *ref;
00011 struct pike_frame *new_frame;
00012 struct identifier *function;
00013
00014 #if 0
00015
00016 if(fun<0)
00017 {
00018 pop_n_elems(Pike_sp-save_sp);
00019 push_undefined();
00020 return 0;
00021 }
00022 #else
00023 #ifdef PIKE_DEBUG
00024 if (fun < 0)
00025 Pike_fatal ("Invalid function offset.\n");
00026 #endif
00027 #endif
00028
00029 check_stack(256);
00030 check_mark_stack(256);
00031
00032 #ifdef PIKE_DEBUG
00033 {
00034 static int counter;
00035 switch(d_flag)
00036 {
00037 case 0:
00038 case 1:
00039 case 2:
00040 break;
00041 case 3:
00042 if(!((counter++ & 7)))
00043 do_debug();
00044 break;
00045 case 4:
00046 default:
00047 do_debug();
00048 }
00049 }
00050 #endif
00051
00052 p=o->prog;
00053 if(!p)
00054 PIKE_ERROR("destructed object->function",
00055 "Cannot call functions in destructed objects.\n", Pike_sp, args);
00056
00057 if(!(p->flags & PROGRAM_PASS_1_DONE) || (p->flags & PROGRAM_AVOID_CHECK))
00058 PIKE_ERROR("__empty_program() -> function",
00059 "Cannot call functions in unfinished objects.\n", Pike_sp, args);
00060
00061
00062 #ifdef PIKE_SECURITY
00063 CHECK_DATA_SECURITY_OR_ERROR(o, SECURITY_BIT_CALL,
00064 ("Function call permission denied.\n"));
00065
00066 if(!CHECK_DATA_SECURITY(o, SECURITY_BIT_NOT_SETUID))
00067 SET_CURRENT_CREDS(o->prot);
00068 #endif
00069
00070
00071 #ifdef PIKE_DEBUG
00072 if(fun>=(int)p->num_identifier_references)
00073 {
00074 fprintf(stderr, "Function index out of range. %ld >= %d\n",
00075 DO_NOT_WARN((long)fun),
00076 (int)p->num_identifier_references);
00077 fprintf(stderr,"########Program is:\n");
00078 describe(p);
00079 fprintf(stderr,"########Object is:\n");
00080 describe(o);
00081 Pike_fatal("Function index out of range.\n");
00082 }
00083 #endif
00084
00085 ref = p->identifier_references + fun;
00086 #ifdef PIKE_DEBUG
00087 if(ref->inherit_offset>=p->num_inherits)
00088 Pike_fatal("Inherit offset out of range in program.\n");
00089 #endif
00090
00091
00092 new_frame=alloc_pike_frame();
00093 #ifdef PROFILING
00094 new_frame->children_base = Pike_interpreter.accounted_time;
00095 new_frame->start_time = get_cpu_time() - Pike_interpreter.unlocked_time;
00096
00097
00098
00099
00100
00101
00102
00103
00104 new_frame->ident = ref->identifier_offset;
00105 DO_IF_PROFILING_DEBUG({
00106 fprintf(stderr, "%p{: Push at %" PRINT_CPU_TIME
00107 " %" PRINT_CPU_TIME "\n",
00108 Pike_interpreter.thread_state, new_frame->start_time,
00109 new_frame->children_base);
00110 });
00111 #endif
00112 debug_malloc_touch(new_frame);
00113
00114 new_frame->next = Pike_fp;
00115 new_frame->current_object = o;
00116 new_frame->context = p->inherits[ ref->inherit_offset ];
00117
00118 function = new_frame->context.prog->identifiers + ref->identifier_offset;
00119 new_frame->fun = DO_NOT_WARN((unsigned INT16)fun);
00120
00121
00122 #ifdef PIKE_DEBUG
00123 if(Pike_interpreter.trace_level > 9)
00124 {
00125 fprintf(stderr,"-- ref: inoff=%d idoff=%d flags=%d\n",
00126 ref->inherit_offset,
00127 ref->identifier_offset,
00128 ref->id_flags);
00129
00130 fprintf(stderr,"-- context: prog->id=%d inlev=%d idlev=%d pi=%d po=%d so=%ld name=%s\n",
00131 new_frame->context.prog->id,
00132 new_frame->context.inherit_level,
00133 new_frame->context.identifier_level,
00134 new_frame->context.parent_identifier,
00135 new_frame->context.parent_offset,
00136 DO_NOT_WARN((long)new_frame->context.storage_offset),
00137 new_frame->context.name ? new_frame->context.name->str : "NULL");
00138 if(Pike_interpreter.trace_level>19)
00139 {
00140 describe(new_frame->context.prog);
00141 }
00142 }
00143 #endif
00144
00145
00146 new_frame->expendible =new_frame->locals = Pike_sp - args;
00147 new_frame->args = args;
00148 new_frame->pc = 0;
00149 #ifdef SCOPE
00150 new_frame->scope=scope;
00151 #ifdef PIKE_DEBUG
00152 if(new_frame->fun == scope->fun)
00153 {
00154 Pike_fatal("Que? A function cannot be parented by itself!\n");
00155 }
00156 #endif
00157 #else
00158 new_frame->scope=0;
00159 #endif
00160 new_frame->save_sp=save_sp;
00161
00162 add_ref(new_frame->current_object);
00163 add_ref(new_frame->context.prog);
00164 if(new_frame->context.parent) add_ref(new_frame->context.parent);
00165 #ifdef SCOPE
00166 if(new_frame->scope) add_ref(new_frame->scope);
00167 #endif
00168
00169 if(Pike_interpreter.trace_level)
00170 {
00171 dynamic_buffer save_buf;
00172 char buf[50];
00173
00174 init_buf(&save_buf);
00175 sprintf(buf, "%lx->", DO_NOT_WARN((long) PTR_TO_INT (o)));
00176 my_strcat(buf);
00177 if (function->name->size_shift)
00178 my_strcat ("[widestring function name]");
00179 else
00180 my_strcat(function->name->str);
00181 do_trace_call(args, &save_buf);
00182 }
00183
00184 #ifdef PIKE_DEBUG
00185 if (Pike_fp && (new_frame->locals < Pike_fp->locals)) {
00186 fatal("New locals below old locals: %p < %p\n",
00187 new_frame->locals, Pike_fp->locals);
00188 }
00189 #endif
00190
00191 Pike_fp = new_frame;
00192
00193 #ifdef PROFILING
00194 function->num_calls++;
00195 #endif
00196
00197 if(function->func.offset == -1) {
00198 new_frame->num_args = args;
00199 generic_error(NULL, Pike_sp, args,
00200 "Calling undefined function.\n");
00201 }
00202
00203 #ifdef PROFILING
00204 new_frame->self_time_base=function->total_time;
00205 #endif
00206
00207 switch(function->identifier_flags & IDENTIFIER_TYPE_MASK)
00208 {
00209 case IDENTIFIER_C_FUNCTION:
00210 debug_malloc_touch(Pike_fp);
00211 Pike_fp->num_args=args;
00212 new_frame->current_storage = o->storage+new_frame->context.storage_offset;
00213 new_frame->num_locals=args;
00214 check_threads_etc();
00215 (*function->func.c_fun)(args);
00216 break;
00217
00218 case IDENTIFIER_CONSTANT:
00219 {
00220 struct svalue *s=&(Pike_fp->context.prog->
00221 constants[function->func.offset].sval);
00222 debug_malloc_touch(Pike_fp);
00223 if(s->type == T_PROGRAM)
00224 {
00225 struct object *tmp;
00226 check_threads_etc();
00227 Pike_fp->num_args=args;
00228 tmp=parent_clone_object(s->u.program,
00229 o,
00230 fun,
00231 args);
00232 push_object(tmp);
00233 break;
00234 }
00235
00236 }
00237
00238 case IDENTIFIER_VARIABLE:
00239 {
00240
00241
00242
00243 debug_malloc_touch(Pike_fp);
00244 debug_malloc_touch(o);
00245 if(Pike_sp-save_sp-args<=0)
00246 {
00247
00248 Pike_sp++;
00249 MEMMOVE(Pike_sp-args,Pike_sp-args-1,sizeof(struct svalue)*args);
00250 #ifdef DEBUG_MALLOC
00251 if (args) {
00252 int i;
00253
00254 for (i=args+2; i > 0; i--) {
00255 dmalloc_touch_svalue(Pike_sp-i);
00256 }
00257 }
00258 #endif
00259 Pike_sp[-args-1].type=T_INT;
00260 }else{
00261 free_svalue(Pike_sp-args-1);
00262 Pike_sp[-args-1].type=T_INT;
00263 }
00264 low_object_index_no_free(Pike_sp-args-1,o,fun);
00265
00266
00267 POP_PIKE_FRAME();
00268
00269 if(Pike_sp-save_sp-args > (args<<2) + 32)
00270 {
00271
00272
00273
00274 assign_svalues(save_sp, Pike_sp-args, args, BIT_MIXED);
00275 pop_n_elems(Pike_sp-save_sp-args);
00276 }
00277 arg1=(void *)(Pike_sp-args-1);
00278 goto apply_svalue;
00279 }
00280
00281 case IDENTIFIER_PIKE_FUNCTION:
00282 {
00283 int num_args;
00284 int num_locals;
00285 PIKE_OPCODE_T *pc;
00286 fast_check_threads_etc(6);
00287
00288 #ifdef PIKE_DEBUG
00289 if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_FREE)
00290 Pike_fatal("Pike code called within gc.\n");
00291 #endif
00292
00293 debug_malloc_touch(Pike_fp);
00294 pc=new_frame->context.prog->program + function->func.offset;
00295
00296
00297
00298
00299
00300
00301 num_locals = READ_INCR_BYTE(pc);
00302
00303 if(function->identifier_flags & IDENTIFIER_SCOPE_USED)
00304 new_frame->expendible+=num_locals;
00305
00306 num_args = READ_INCR_BYTE(pc);
00307
00308 #ifdef PIKE_DEBUG
00309 if(num_locals < num_args)
00310 Pike_fatal("Wrong number of arguments or locals in function def.\n"
00311 "num_locals: %d < num_args: %d\n",
00312 num_locals, num_args);
00313 #endif
00314
00315
00316 if(function->identifier_flags & IDENTIFIER_VARARGS)
00317 {
00318
00319 if(args < num_args)
00320 {
00321 push_undefines(num_args-args);
00322 f_aggregate(0);
00323 }else{
00324 f_aggregate(args - num_args);
00325 }
00326 args = num_args+1;
00327 }else{
00328
00329 if(args < num_args)
00330 push_undefines(num_args-args);
00331 else
00332 pop_n_elems(args - num_args);
00333 args=num_args;
00334 }
00335
00336 if(num_locals > args)
00337 push_zeroes(num_locals-args);
00338
00339 new_frame->num_locals=num_locals;
00340 new_frame->num_args=num_args;
00341 new_frame->save_mark_sp=new_frame->mark_sp_base=Pike_mark_sp;
00342 new_frame->pc = pc
00343 #ifdef ENTRY_PROLOGUE_SIZE
00344 + ENTRY_PROLOGUE_SIZE
00345 #endif
00346 ;
00347 return 1;
00348 }
00349
00350 default:;
00351 #ifdef PIKE_DEBUG
00352 Pike_fatal("Unknown identifier type.\n");
00353 #endif
00354 }
00355
00356 #if 0
00357 #ifdef PIKE_DEBUG
00358 if(Pike_fp!=new_frame)
00359 Pike_fatal("Frame stack out of whack!\n");
00360 #endif
00361 #endif
00362
00363 POP_PIKE_FRAME();
00364 }