f6f02d1995-10-16Fredrik Hübinette (Hubbe) /*\
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License)
f6f02d1995-10-16Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
acbf0a1999-02-20Henrik Grubbström (Grubba) /**/
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
69ee4b2000-04-06Fredrik Hübinette (Hubbe) RCSID("$Id: program.c,v 1.221 2000/04/06 20:17:05 hubbe Exp $");
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "program.h" #include "object.h" #include "dynamic_buffer.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "pike_types.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "stralloc.h" #include "las.h" #include "language.h" #include "lex.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "fsort.h" #include "error.h" #include "docode.h" #include "interpret.h" #include "hashtable.h"
2acdd31995-10-29Fredrik Hübinette (Hubbe) #include "main.h"
624d091996-02-24Fredrik Hübinette (Hubbe) #include "gc.h"
07513e1996-10-04Fredrik Hübinette (Hubbe) #include "threads.h"
0683be1997-01-26Fredrik Hübinette (Hubbe) #include "constants.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "operators.h"
3eb19a1998-01-30Henrik Grubbström (Grubba) #include "builtin_functions.h"
1994981998-04-07Fredrik Hübinette (Hubbe) #include "stuff.h"
05590d1998-04-23Fredrik Hübinette (Hubbe) #include "mapping.h" #include "cyclic.h"
7e97c31999-01-21Fredrik Hübinette (Hubbe) #include "security.h"
51059b1999-12-26Henrik Grubbström (Grubba) #include "pike_types.h"
8aeeb21996-11-19Fredrik Hübinette (Hubbe)  #include <errno.h>
5267b71995-08-09Fredrik Hübinette (Hubbe) #include <fcntl.h>
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  #undef ATTRIBUTE #define ATTRIBUTE(X)
1549c61999-07-02Henrik Grubbström (Grubba) /* #define COMPILER_DEBUG */
a786431999-11-18Martin Stjernholm /* #define PROGRAM_BUILD_DEBUG */
b6f8c31999-07-01Henrik Grubbström (Grubba)  #ifdef COMPILER_DEBUG #define CDFPRINTF(X) fprintf X #else /* !COMPILER_DEBUG */ #define CDFPRINTF(X) #endif /* COMPILER_DEBUG */
189fd01997-01-28Fredrik Hübinette (Hubbe) /* * Define the size of the cache that is used for method lookup. */ #define FIND_FUNCTION_HASHSIZE 4711
5c8e891995-10-29Fredrik Hübinette (Hubbe) #define STRUCT #include "compilation.h" #define DECLARE #include "compilation.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5580691996-06-21Fredrik Hübinette (Hubbe) 
9e26861999-12-31Martin Stjernholm struct pike_string *this_program_string=0;
5580691996-06-21Fredrik Hübinette (Hubbe) char *lfun_names[] = { "__INIT", "create", "destroy", "`+", "`-", "`&", "`|", "`^", "`<<", "`>>", "`*", "`/", "`%", "`~", "`==", "`<", "`>", "__hash", "cast", "`!",
774b061996-08-03Fredrik Hübinette (Hubbe)  "`[]", "`[]=",
dffa011997-01-15Fredrik Hübinette (Hubbe)  "`->", "`->=",
0683be1997-01-26Fredrik Hübinette (Hubbe)  "_sizeof", "_indices", "_values", "`()",
1b89ad1997-10-10Fredrik Hübinette (Hubbe)  "``+", "``-", "``&", "``|", "``^", "``<<", "``>>", "``*", "``/", "``%",
ee37801999-02-09Fredrik Hübinette (Hubbe)  "`+=",
aa73fc1999-10-21Fredrik Hübinette (Hubbe)  "_is_type", "_sprintf",
2ba9191999-10-23Fredrik Hübinette (Hubbe)  "_equal",
5580691996-06-21Fredrik Hübinette (Hubbe) };
51059b1999-12-26Henrik Grubbström (Grubba) /* mapping(string:type) */ static struct mapping *lfun_types; static char *raw_lfun_types[] = { tFuncV(tNone,tVoid,tVoid), /* "__INIT", */ tFuncV(tNone,tZero,tVoid), /* "create", */ tFuncV(tNone,tVoid,tVoid), /* "destroy", */ tFuncV(tNone,tZero,tMix), /* "`+", */ tFuncV(tNone,tZero,tMix), /* "`-", */ tFuncV(tNone,tZero,tMix), /* "`&", */ tFuncV(tNone,tZero,tMix), /* "`|", */ tFuncV(tNone,tZero,tMix), /* "`^", */ tFuncV(tZero,tVoid,tMix), /* "`<<", */ tFuncV(tZero,tVoid,tMix), /* "`>>", */ tFuncV(tNone,tZero,tMix), /* "`*", */ tFuncV(tNone,tZero,tMix), /* "`/", */ tFuncV(tNone,tZero,tMix), /* "`%", */ tFuncV(tNone,tVoid,tMix), /* "`~", */ tFuncV(tMix,tVoid,tInt), /* "`==", */ tFuncV(tMix,tVoid,tInt), /* "`<", */ tFuncV(tMix,tVoid,tInt), /* "`>", */ tFuncV(tNone,tVoid,tInt), /* "__hash", */ tFuncV(tString,tVoid,tMix), /* "cast", */ tFuncV(tNone,tVoid,tInt), /* "`!", */ tFuncV(tZero,tVoid,tMix), /* "`[]", */ tFuncV(tZero tSetvar(0,tZero),tVoid,tVar(0)), /* "`[]=", */ tFuncV(tStr,tVoid,tMix), /* "`->", */ tFuncV(tStr tSetvar(0,tZero),tVoid,tVar(0)), /* "`->=", */ tFuncV(tNone,tVoid,tInt), /* "_sizeof", */ tFuncV(tNone,tVoid,tArray), /* "_indices", */ tFuncV(tNone,tVoid,tArray), /* "_values", */ tFuncV(tNone,tZero,tMix), /* "`()", */ tFuncV(tNone,tZero,tMix), /* "``+", */ tFuncV(tNone,tZero,tMix), /* "``-", */ tFuncV(tNone,tZero,tMix), /* "``&", */ tFuncV(tNone,tZero,tMix), /* "``|", */ tFuncV(tNone,tZero,tMix), /* "``^", */ tFuncV(tZero,tVoid,tMix), /* "``<<", */ tFuncV(tZero,tVoid,tMix), /* "``>>", */ tFuncV(tNone,tZero,tMix), /* "``*", */ tFuncV(tNone,tZero,tMix), /* "``/", */ tFuncV(tNone,tZero,tMix), /* "``%", */ tFuncV(tZero,tVoid,tMix), /* "`+=", */ tFuncV(tStr,tVoid,tInt), /* "_is_type", */
d8bfc01999-12-27Henrik Grubbström (Grubba)  tFuncV(tInt tOr(tMap(tStr,tInt),tVoid),tVoid,tStr), /* "_sprintf", */
51059b1999-12-26Henrik Grubbström (Grubba)  tFuncV(tMix,tVoid,tInt), /* "_equal", */ };
5267b71995-08-09Fredrik Hübinette (Hubbe) struct program *first_program = 0;
8524151999-12-14Fredrik Hübinette (Hubbe) static int current_program_id=0x10000;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) struct program *new_program=0;
6d22541998-01-28Fredrik Hübinette (Hubbe) struct object *fake_object=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) struct program *malloc_size_program=0;
10e16f1999-11-04Henrik Grubbström (Grubba) struct object *error_handler=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) int compiler_pass; int compilation_depth;
48cffa1998-01-22Henrik Grubbström (Grubba) long local_class_counter;
9649491998-02-27Fredrik Hübinette (Hubbe) int catch_level;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) struct compiler_frame *compiler_frame=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) static INT32 last_line = 0; static INT32 last_pc = 0;
06983f1996-09-22Fredrik Hübinette (Hubbe) static struct pike_string *last_file = 0;
591c0c1997-01-19Fredrik Hübinette (Hubbe) dynamic_buffer used_modules;
05590d1998-04-23Fredrik Hübinette (Hubbe) INT32 num_used_modules; static struct mapping *resolve_cache=0; static struct mapping *module_index_cache=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1016021999-10-28Fredrik Hübinette (Hubbe) int get_small_number(char **q);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* So what if we don't have templates? / Hubbe */
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define CHECK_FOO(NUMTYPE,TYPE,NAME) \ if(malloc_size_program-> PIKE_CONCAT(num_,NAME) < new_program-> PIKE_CONCAT(num_,NAME)) \ fatal("new_program->num_" #NAME " is out of order\n"); \ if(new_program->flags & PROGRAM_OPTIMIZED) \ fatal("Tried to reallocate fixed program.\n") #else #define CHECK_FOO(NUMTYPE,TYPE,NAME) #endif #define FOO(NUMTYPE,TYPE,NAME) \
d429a71998-02-24Fredrik Hübinette (Hubbe) void PIKE_CONCAT(add_to_,NAME) (TYPE ARG) { \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  CHECK_FOO(NUMTYPE,TYPE,NAME); \
d429a71998-02-24Fredrik Hübinette (Hubbe)  if(malloc_size_program->PIKE_CONCAT(num_,NAME) == \ new_program->PIKE_CONCAT(num_,NAME)) { \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  void *tmp; \
d429a71998-02-24Fredrik Hübinette (Hubbe)  malloc_size_program->PIKE_CONCAT(num_,NAME) *= 2; \ malloc_size_program->PIKE_CONCAT(num_,NAME)++; \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  tmp=realloc((char *)new_program->NAME, \ sizeof(TYPE) * \
d429a71998-02-24Fredrik Hübinette (Hubbe)  malloc_size_program->PIKE_CONCAT(num_,NAME)); \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!tmp) fatal("Out of memory.\n"); \ new_program->NAME=tmp; \ } \
d429a71998-02-24Fredrik Hübinette (Hubbe)  new_program->NAME[new_program->PIKE_CONCAT(num_,NAME)++]=(ARG); \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) } #include "program_areas.h"
d429a71998-02-24Fredrik Hübinette (Hubbe) #define FOO(NUMTYPE,TYPE,NAME) \ void PIKE_CONCAT(low_add_to_,NAME) (struct program_state *state, \ TYPE ARG) { \ if(state->malloc_size_program->PIKE_CONCAT(num_,NAME) == \ state->new_program->PIKE_CONCAT(num_,NAME)) { \ void *tmp; \ state->malloc_size_program->PIKE_CONCAT(num_,NAME) *= 2; \ state->malloc_size_program->PIKE_CONCAT(num_,NAME)++; \ tmp=realloc((char *)state->new_program->NAME, \ sizeof(TYPE) * \ state->malloc_size_program->PIKE_CONCAT(num_,NAME)); \ if(!tmp) fatal("Out of memory.\n"); \ state->new_program->NAME=tmp; \ } \ state->new_program->NAME[state->new_program->PIKE_CONCAT(num_,NAME)++]=(ARG); \ } #include "program_areas.h"
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void ins_int(INT32 i, void (*func)(char tmp)) { int e; for(e=0;e<(long)sizeof(i);e++) func(EXTRACT_UCHAR(((char *)&i)+e)); } void ins_short(INT16 i, void (*func)(char tmp)) { int e; for(e=0;e<(long)sizeof(i);e++) func(EXTRACT_UCHAR(((char *)&i)+e)); }
5f8eb71997-02-18Fredrik Hübinette (Hubbe) 
591c0c1997-01-19Fredrik Hübinette (Hubbe) void use_module(struct svalue *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
a1e8821998-11-05Fredrik Hübinette (Hubbe)  if( (1<<s->type) & (BIT_MAPPING | BIT_OBJECT | BIT_PROGRAM))
5c0a101997-02-06Fredrik Hübinette (Hubbe)  {
05590d1998-04-23Fredrik Hübinette (Hubbe)  num_used_modules++;
5c0a101997-02-06Fredrik Hübinette (Hubbe)  assign_svalue_no_free((struct svalue *) low_make_buf_space(sizeof(struct svalue), &used_modules), s);
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(module_index_cache) { free_mapping(module_index_cache); module_index_cache=0; }
5c0a101997-02-06Fredrik Hübinette (Hubbe)  }else{ yyerror("Module is neither mapping nor object"); }
591c0c1997-01-19Fredrik Hübinette (Hubbe) }
05590d1998-04-23Fredrik Hübinette (Hubbe) void unuse_modules(INT32 howmany) { if(!howmany) return;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(howmany *sizeof(struct svalue) > used_modules.s.len) fatal("Unusing too many modules.\n"); #endif num_used_modules-=howmany; low_make_buf_space(-sizeof(struct svalue)*howmany, &used_modules); free_svalues((struct svalue *)low_make_buf_space(0, &used_modules), howmany,
a1e8821998-11-05Fredrik Hübinette (Hubbe)  BIT_MAPPING | BIT_OBJECT | BIT_PROGRAM);
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(module_index_cache) { free_mapping(module_index_cache); module_index_cache=0; } }
b8cda21997-01-21Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) int low_find_shared_string_identifier(struct pike_string *name, struct program *prog);
4d7b181999-12-07Fredrik Hübinette (Hubbe) static struct node_s *index_modules(struct pike_string *ident, struct mapping **module_index_cache, int num_used_modules, struct svalue *modules)
591c0c1997-01-19Fredrik Hübinette (Hubbe) {
05590d1998-04-23Fredrik Hübinette (Hubbe)  struct node_s *ret;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  JMP_BUF tmp;
05590d1998-04-23Fredrik Hübinette (Hubbe) 
4d7b181999-12-07Fredrik Hübinette (Hubbe)  if(*module_index_cache)
05590d1998-04-23Fredrik Hübinette (Hubbe)  {
4d7b181999-12-07Fredrik Hübinette (Hubbe)  struct svalue *tmp=low_mapping_string_lookup(*module_index_cache,ident);
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(tmp) { if(!(IS_ZERO(tmp) && tmp->subtype==1)) return mksvaluenode(tmp); return 0; } }
8aae6d1999-08-19Fredrik Hübinette (Hubbe) /* fprintf(stderr,"index_module: %s\n",ident->str); */
5c0a101997-02-06Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(SETJMP(tmp))
591c0c1997-01-19Fredrik Hübinette (Hubbe)  { ONERROR tmp; SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); assign_svalue_no_free(sp++, & throw_value); APPLY_MASTER("handle_error", 1); pop_stack(); UNSET_ONERROR(tmp); yyerror("Couldn't index module."); }else{
4d7b181999-12-07Fredrik Hübinette (Hubbe)  int e=num_used_modules; modules-=num_used_modules;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  while(--e>=0) { push_svalue(modules+e);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  ref_push_string(ident);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  f_index(2);
27ae842000-02-07Per Hedbor 
5c0a101997-02-06Fredrik Hübinette (Hubbe)  if(!IS_UNDEFINED(sp-1))
591c0c1997-01-19Fredrik Hübinette (Hubbe)  { UNSETJMP(tmp);
4d7b181999-12-07Fredrik Hübinette (Hubbe)  if(!*module_index_cache) *module_index_cache=allocate_mapping(10); mapping_string_insert(*module_index_cache, ident, sp-1);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  ret=mksvaluenode(sp-1); pop_stack(); return ret;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  }
5c0a101997-02-06Fredrik Hübinette (Hubbe)  pop_stack();
591c0c1997-01-19Fredrik Hübinette (Hubbe)  } } UNSETJMP(tmp);
b8cda21997-01-21Fredrik Hübinette (Hubbe) 
8aae6d1999-08-19Fredrik Hübinette (Hubbe) /* fprintf(stderr,"***Undefined.\n"); */
05590d1998-04-23Fredrik Hübinette (Hubbe)  return 0; }
4d7b181999-12-07Fredrik Hübinette (Hubbe) 
2816052000-03-30Fredrik Hübinette (Hubbe) struct node_s *find_module_identifier(struct pike_string *ident, int see_inherit)
05590d1998-04-23Fredrik Hübinette (Hubbe) { struct node_s *ret;
4d7b181999-12-07Fredrik Hübinette (Hubbe)  struct svalue *modules=(struct svalue *) (used_modules.s.str + used_modules.s.len);
05590d1998-04-23Fredrik Hübinette (Hubbe) 
4d7b181999-12-07Fredrik Hübinette (Hubbe)  if((ret=index_modules(ident, &module_index_cache, num_used_modules, modules))) return ret; modules-=num_used_modules;
27ae842000-02-07Per Hedbor 
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  struct program_state *p=previous_program_state; int n; for(n=0;n<compilation_depth;n++,p=p->previous)
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
2816052000-03-30Fredrik Hübinette (Hubbe)  int i; if(see_inherit)
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
2816052000-03-30Fredrik Hübinette (Hubbe)  i=really_low_find_shared_string_identifier(ident, p->new_program, SEE_STATIC); if(i!=-1) { struct identifier *id; id=ID_FROM_INT(p->new_program, i); return mkexternalnode(n, i, id); }
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
4d7b181999-12-07Fredrik Hübinette (Hubbe)  if((ret=index_modules(ident, &p->module_index_cache, p->num_used_modules, modules))) return ret; modules-=p->num_used_modules; #ifdef PIKE_DEBUG if( ((char *)modules ) < used_modules.s.str) fatal("Modules out of whack!\n"); #endif
05590d1998-04-23Fredrik Hübinette (Hubbe)  } }
1b67072000-03-09Henrik Grubbström (Grubba)  /* Handle this_program */ if (ident == this_program_string) { struct svalue s; s.type=T_PROGRAM; s.u.program=new_program; return mkconstantsvaluenode(&s); }
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(resolve_cache) { struct svalue *tmp=low_mapping_string_lookup(resolve_cache,ident); if(tmp) { if(!(IS_ZERO(tmp) && tmp->subtype==1)) return mkconstantsvaluenode(tmp); return 0; } } if(!num_parse_error && get_master())
27ae842000-02-07Per Hedbor  {
05590d1998-04-23Fredrik Hübinette (Hubbe)  DECLARE_CYCLIC(); node *ret=0; if(BEGIN_CYCLIC(ident, lex.current_file)) { my_yyerror("Recursive module dependency in %s.", ident->str); }else{
d555692000-03-10Fredrik Hübinette (Hubbe)  int i;
05590d1998-04-23Fredrik Hübinette (Hubbe)  SET_CYCLIC_RET(1); ref_push_string(ident); ref_push_string(lex.current_file);
d555692000-03-10Fredrik Hübinette (Hubbe)  if(error_handler && (i=find_identifier("resolv",error_handler->prog))!=-1) { safe_apply_low(error_handler, i, 2); }else{ SAFE_APPLY_MASTER("resolv", 2); }
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(throw_value.type == T_STRING) { if(compiler_pass==2) my_yyerror("%s",throw_value.u.string->str); } else { if(!resolve_cache)
aed42d1999-12-29Martin Stjernholm  resolve_cache=dmalloc_touch(struct mapping *, allocate_mapping(10));
05590d1998-04-23Fredrik Hübinette (Hubbe)  mapping_string_insert(resolve_cache,ident,sp-1);
27ae842000-02-07Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(!(IS_ZERO(sp-1) && sp[-1].subtype==1))
b8cda21997-01-21Fredrik Hübinette (Hubbe)  {
05590d1998-04-23Fredrik Hübinette (Hubbe)  ret=mkconstantsvaluenode(sp-1);
b8cda21997-01-21Fredrik Hübinette (Hubbe)  } }
05590d1998-04-23Fredrik Hübinette (Hubbe)  pop_stack(); END_CYCLIC();
b8cda21997-01-21Fredrik Hübinette (Hubbe)  }
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(ret) return ret;
b8cda21997-01-21Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
b8cda21997-01-21Fredrik Hübinette (Hubbe)  return 0; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) struct program *parent_compilation(int level) { int n; struct program_state *p=previous_program_state; for(n=0;n<level;n++) { if(n>=compilation_depth) return 0; p=p->previous; if(!p) return 0; } return p->new_program; } #define ID_TO_PROGRAM_CACHE_SIZE 512 struct program *id_to_program_cache[ID_TO_PROGRAM_CACHE_SIZE];
b8cda21997-01-21Fredrik Hübinette (Hubbe) struct program *id_to_program(INT32 id) { struct program *p;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  INT32 h; if(!id) return 0; h=id & (ID_TO_PROGRAM_CACHE_SIZE-1); if((p=id_to_program_cache[h]))
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(p->id==id) return p;
27ae842000-02-07Per Hedbor  if(id)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  { for(p=first_program;p;p=p->next) { if(id==p->id) { id_to_program_cache[h]=p; return p; } } }
591c0c1997-01-19Fredrik Hübinette (Hubbe)  return 0; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* Here starts routines which are used to build new programs */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* Re-allocate all the memory in the program in one chunk. because: * 1) The individual blocks are munch bigger than they need to be * 2) cuts down on malloc overhead (maybe) * 3) localizes memory access (decreases paging)
5267b71995-08-09Fredrik Hübinette (Hubbe)  */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void optimize_program(struct program *p) { SIZE_T size=0; char *data; /* Already done (shouldn't happen, but who knows?) */ if(p->flags & PROGRAM_OPTIMIZED) return; #define FOO(NUMTYPE,TYPE,NAME) \
1994981998-04-07Fredrik Hübinette (Hubbe)  size=DO_ALIGN(size, ALIGNOF(TYPE)); \ size+=p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #include "program_areas.h" data=malloc(size); if(!data) return; /* We are out of memory, but we don't care! */ size=0; #define FOO(NUMTYPE,TYPE,NAME) \
1994981998-04-07Fredrik Hübinette (Hubbe)  size=DO_ALIGN(size, ALIGNOF(TYPE)); \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  MEMCPY(data+size,p->NAME,p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0])); \
424d9c1999-05-02Fredrik Hübinette (Hubbe)  dmfree((char *)p->NAME); \
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  p->NAME=(TYPE *)(data+size); \
1994981998-04-07Fredrik Hübinette (Hubbe)  size+=p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #include "program_areas.h" p->total_size=size + sizeof(struct program); p->flags |= PROGRAM_OPTIMIZED;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* internal function to make the index-table */
05590d1998-04-23Fredrik Hübinette (Hubbe) int program_function_index_compare(const void *a,const void *b)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) { return my_order_strcmp(ID_FROM_INT(new_program, *(unsigned short *)a)->name, ID_FROM_INT(new_program, *(unsigned short *)b)->name); } void fixate_program(void) { INT32 i,e,t; if(new_program->flags & PROGRAM_FIXED) return;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(new_program->flags & PROGRAM_OPTIMIZED) fatal("Cannot fixate optimized program\n"); #endif /* Ok, sort for binsearch */ for(e=i=0;i<(int)new_program->num_identifier_references;i++) { struct reference *funp; struct identifier *fun; funp=new_program->identifier_references+i; if(funp->id_flags & (ID_HIDDEN|ID_STATIC)) continue; if(funp->id_flags & ID_INHERITED) { if(funp->id_flags & ID_PRIVATE) continue; fun=ID_FROM_PTR(new_program, funp); /* if(fun->func.offset == -1) continue; * prototype */
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  /* check for multiple definitions */ for(t=i+1;t>=0 && t<(int)new_program->num_identifier_references;t++) { struct reference *funpb; struct identifier *funb;
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  funpb=new_program->identifier_references+t; if(funpb->id_flags & (ID_HIDDEN|ID_STATIC)) continue; funb=ID_FROM_PTR(new_program,funpb); /* if(funb->func.offset == -1) continue; * prototype */ if(fun->name==funb->name) t=-10; } if(t<0) continue; } add_to_identifier_index(i); } fsort((void *)new_program->identifier_index, new_program->num_identifier_index,
05590d1998-04-23Fredrik Hübinette (Hubbe)  sizeof(unsigned short),(fsortfun)program_function_index_compare);
27ae842000-02-07Per Hedbor 
a5787d1999-03-03Fredrik Hübinette (Hubbe)  /* Yes, it is supposed to start at 1 /Hubbe */
87d5c52000-02-16Henrik Grubbström (Grubba)  for(i=1;i<NUM_LFUNS;i++) { new_program->lfuns[i] = low_find_lfun(new_program, i);
2c17091999-06-22Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  new_program->flags |= PROGRAM_FIXED; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe) struct program *low_allocate_program(void) { struct program *p; p=ALLOC_STRUCT(program); MEMSET(p, 0, sizeof(struct program));
90e9781999-01-31Fredrik Hübinette (Hubbe)  p->alignment_needed=1;
27ae842000-02-07Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  GC_ALLOC(); p->refs=1; p->id=++current_program_id;
27ae842000-02-07Per Hedbor 
05590d1998-04-23Fredrik Hübinette (Hubbe)  if((p->next=first_program)) first_program->prev=p; first_program=p; GETTIMEOFDAY(& p->timestamp);
7e97c31999-01-21Fredrik Hübinette (Hubbe)  INITIALIZE_PROT(p);
05590d1998-04-23Fredrik Hübinette (Hubbe)  return p; }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * Start building a new program */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void low_start_new_program(struct program *p,
993ba72000-02-15Fredrik Hübinette (Hubbe)  struct pike_string *name, int flags, int *idp)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
6d22541998-01-28Fredrik Hübinette (Hubbe)  int e,id=0;
993ba72000-02-15Fredrik Hübinette (Hubbe)  struct svalue tmp;
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
27ae842000-02-07Per Hedbor #if 0
f807f01999-11-11Henrik Grubbström (Grubba) #ifdef SHARED_NODES if (!node_hash.table) { node_hash.table = malloc(sizeof(node *)*16411); if (!node_hash.table) { fatal("Out of memory!\n"); } MEMSET(node_hash.table, 0, sizeof(node *)*16411); node_hash.size = 16411; } #endif /* SHARED_NODES */ #endif /* 0 */
58544f1998-07-17Henrik Grubbström (Grubba)  /* We don't want to change thread, but we don't want to * wait for the other threads to complete. */ low_init_threads_disable();
a91ca01998-07-10Henrik Grubbström (Grubba) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  compilation_depth++;
e0837a1999-07-01Fredrik Hübinette (Hubbe)  CDFPRINTF((stderr, "th(%ld) low_start_new_program() pass=%d: compilation_depth:%d\n", (long)th_self(),compilation_depth,compiler_pass));
ea32c11998-04-13Henrik Grubbström (Grubba) 
993ba72000-02-15Fredrik Hübinette (Hubbe)  tmp.type=T_PROGRAM;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!p) {
05590d1998-04-23Fredrik Hübinette (Hubbe)  p=low_allocate_program();
993ba72000-02-15Fredrik Hübinette (Hubbe)  if(name) { tmp.u.program=p; id=add_constant(name, &tmp, flags & ~ID_EXTERN); }
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  e=1;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }else{
993ba72000-02-15Fredrik Hübinette (Hubbe)  tmp.u.program=p;
8c83371998-04-16Fredrik Hübinette (Hubbe)  add_ref(p);
993ba72000-02-15Fredrik Hübinette (Hubbe)  if(name) { struct identifier *i; id=isidentifier(name); if (id < 0) fatal("Program constant disappeared in second pass.\n"); i=ID_FROM_INT(new_program, id); free_string(i->type); i->type=get_type_of_svalue(&tmp); }
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  e=2;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
993ba72000-02-15Fredrik Hübinette (Hubbe)  if(idp) *idp=id;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
fb2f661998-11-05Fredrik Hübinette (Hubbe)  init_type_stack();
5c8e891995-10-29Fredrik Hübinette (Hubbe) #define PUSH #include "compilation.h"
b8cda21997-01-21Fredrik Hübinette (Hubbe) 
e37a3e1999-10-09Fredrik Hübinette (Hubbe)  compiler_pass=e;
05590d1998-04-23Fredrik Hübinette (Hubbe)  num_used_modules=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(p && (p->flags & PROGRAM_FINISHED))
0683be1997-01-26Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  yyerror("Pass2: Program already done"); p=0; } malloc_size_program = ALLOC_STRUCT(program);
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
6d22541998-01-28Fredrik Hübinette (Hubbe)  fake_object=(struct object *)xalloc(sizeof(struct object) + 256*sizeof(struct svalue)); /* Stipple to find illegal accesses */ MEMSET(fake_object,0x55,sizeof(struct object) + 256*sizeof(struct svalue)); #else fake_object=ALLOC_STRUCT(object); #endif
a3c6ad1998-01-29Fredrik Hübinette (Hubbe)  GC_ALLOC();
6d22541998-01-28Fredrik Hübinette (Hubbe)  fake_object->next=fake_object; fake_object->prev=fake_object; fake_object->refs=1; fake_object->parent=0; fake_object->parent_identifier=0; fake_object->prog=p;
3aa0db1999-10-22Henrik Grubbström (Grubba)  add_ref(p);
7e97c31999-01-21Fredrik Hübinette (Hubbe) #ifdef PIKE_SECURITY fake_object->prot=0; #endif
6d22541998-01-28Fredrik Hübinette (Hubbe)  if(name) { if((fake_object->parent=previous_program_state->fake_object))
8c83371998-04-16Fredrik Hübinette (Hubbe)  add_ref(fake_object->parent);
6d22541998-01-28Fredrik Hübinette (Hubbe)  fake_object->parent_identifier=id; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  new_program=p;
a786431999-11-18Martin Stjernholm #ifdef PROGRAM_BUILD_DEBUG if (name) { fprintf (stderr, "%.*sstarting program %d (pass=%d): ", compilation_depth, " ", new_program->id, compiler_pass); push_string (name); print_svalue (stderr, --sp); putc ('\n', stderr); } else fprintf (stderr, "%.*sstarting program %d (pass=%d)\n", compilation_depth, " ", new_program->id, compiler_pass); #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(new_program->program) { #define FOO(NUMTYPE,TYPE,NAME) \ malloc_size_program->PIKE_CONCAT(num_,NAME)=new_program->PIKE_CONCAT(num_,NAME); #include "program_areas.h"
1016021999-10-28Fredrik Hübinette (Hubbe)  { INT32 line=0, off=0; char *file=0; char *cnt=new_program->linenumbers;
27ae842000-02-07Per Hedbor 
1016021999-10-28Fredrik Hübinette (Hubbe)  while(cnt < new_program->linenumbers + new_program->num_linenumbers) { if(*cnt == 127) { file=cnt+1; cnt=file+strlen(file)+1; } off+=get_small_number(&cnt); line+=get_small_number(&cnt); } last_line=line; last_pc=off; if(file) { if(last_file) free_string(last_file); last_file=make_shared_string(file); } }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }else{ static struct pike_string *s; struct inherit i; #define START_SIZE 64 #define FOO(NUMTYPE,TYPE,NAME) \ malloc_size_program->PIKE_CONCAT(num_,NAME)=START_SIZE; \ new_program->NAME=(TYPE *)xalloc(sizeof(TYPE) * START_SIZE); #include "program_areas.h" i.prog=new_program; i.identifier_level=0; i.storage_offset=0; i.inherit_level=0; i.parent=0; i.parent_identifier=0;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  i.parent_offset=1;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  i.name=0; add_to_inherits(i);
0683be1997-01-26Fredrik Hübinette (Hubbe)  }
2acdd31995-10-29Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  init_node=0;
0683be1997-01-26Fredrik Hübinette (Hubbe)  num_parse_error=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
4218011999-01-31Fredrik Hübinette (Hubbe)  push_compiler_frame(0);
73406b1999-02-14Fredrik Hübinette (Hubbe)  add_ref(compiler_frame->current_return_type=void_type_string);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
bcd5741999-03-17Fredrik Hübinette (Hubbe) void debug_start_new_program(PROGRAM_LINE_ARGS)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) {
b6f8c31999-07-01Henrik Grubbström (Grubba)  CDFPRINTF((stderr,
e0837a1999-07-01Fredrik Hübinette (Hubbe)  "th(%ld) start_new_program(): threads_disabled:%d, compilation_depth:%d\n", (long)th_self(),threads_disabled, compilation_depth));
b6f8c31999-07-01Henrik Grubbström (Grubba) 
993ba72000-02-15Fredrik Hübinette (Hubbe)  low_start_new_program(0,0,0,0);
bcd5741999-03-17Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG { struct pike_string *s=make_shared_string(file); store_linenumber(line,s); free_string(s);
8975b81999-10-18Fredrik Hübinette (Hubbe)  debug_malloc_name(new_program, file, line);
bcd5741999-03-17Fredrik Hübinette (Hubbe)  } #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) } void really_free_program(struct program *p)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
5c8e891995-10-29Fredrik Hübinette (Hubbe)  unsigned INT16 e;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(id_to_program_cache[p->id & (ID_TO_PROGRAM_CACHE_SIZE-1)]==p) id_to_program_cache[p->id & (ID_TO_PROGRAM_CACHE_SIZE-1)]=0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(p->strings) for(e=0; e<p->num_strings; e++) if(p->strings[e]) free_string(p->strings[e]);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(p->identifiers)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
05590d1998-04-23Fredrik Hübinette (Hubbe)  for(e=0; e<p->num_identifiers; e++) { if(p->identifiers[e].name) free_string(p->identifiers[e].name); if(p->identifiers[e].type) free_string(p->identifiers[e].type); }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(p->constants)
43fc171999-09-19Fredrik Hübinette (Hubbe)  {
454d541999-09-18Fredrik Hübinette (Hubbe)  for(e=0;e<p->num_constants;e++)
43fc171999-09-19Fredrik Hübinette (Hubbe)  {
454d541999-09-18Fredrik Hübinette (Hubbe)  free_svalue(& p->constants[e].sval);
43fc171999-09-19Fredrik Hübinette (Hubbe)  if(p->constants[e].name) free_string(p->constants[e].name); } }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(p->inherits) for(e=0; e<p->num_inherits; e++)
3c0c281998-01-26Fredrik Hübinette (Hubbe)  {
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(p->inherits[e].name) free_string(p->inherits[e].name); if(e) { if(p->inherits[e].prog) free_program(p->inherits[e].prog); } if(p->inherits[e].parent) free_object(p->inherits[e].parent);
3c0c281998-01-26Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(p->prev) p->prev->next=p->next; else first_program=p->next;
27ae842000-02-07Per Hedbor 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(p->next) p->next->prev=p->prev;
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(p->flags & PROGRAM_OPTIMIZED)
05590d1998-04-23Fredrik Hübinette (Hubbe)  { if(p->program)
424d9c1999-05-02Fredrik Hübinette (Hubbe)  dmfree(p->program);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define FOO(NUMTYPE,TYPE,NAME) p->NAME=0; #include "program_areas.h"
05590d1998-04-23Fredrik Hübinette (Hubbe)  }else{
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define FOO(NUMTYPE,TYPE,NAME) \
424d9c1999-05-02Fredrik Hübinette (Hubbe)  if(p->NAME) { dmfree((char *)p->NAME); p->NAME=0; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #include "program_areas.h"
05590d1998-04-23Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
7e97c31999-01-21Fredrik Hübinette (Hubbe)  FREE_PROT(p);
424d9c1999-05-02Fredrik Hübinette (Hubbe)  dmfree((char *)p);
27ae842000-02-07Per Hedbor 
624d091996-02-24Fredrik Hübinette (Hubbe)  GC_FREE();
5267b71995-08-09Fredrik Hübinette (Hubbe) }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
2acdd31995-10-29Fredrik Hübinette (Hubbe) void dump_program_desc(struct program *p) { int e,d,q; /* fprintf(stderr,"Program '%s':\n",p->name->str); */ fprintf(stderr,"All inherits:\n"); for(e=0;e<p->num_inherits;e++) { for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," ");
5f05c11999-12-27Fredrik Hübinette (Hubbe)  fprintf(stderr,"%3d:\n",e);
b8896b2000-02-10Fredrik Hübinette (Hubbe)  for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"inherited program: %d\n",p->inherits[e].prog->id);
5f05c11999-12-27Fredrik Hübinette (Hubbe)  if(p->inherits[e].name) { for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"name : %s\n",p->inherits[e].name->str); } for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"inherit_level: %d\n",p->inherits[e].inherit_level); for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"identifier_level: %d\n",p->inherits[e].identifier_level); for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"parent_identifier: %d\n",p->inherits[e].parent_identifier); for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"parent_offset: %d\n",p->inherits[e].parent_offset); for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"storage_offset: %d\n",p->inherits[e].storage_offset); for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"parent: %p\n",p->inherits[e].parent); if(p->inherits[e].parent && p->inherits[e].parent->prog && p->inherits[e].parent->prog->num_linenumbers>1) { for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"parent: %s\n",p->inherits[e].parent->prog->linenumbers+1); }
2acdd31995-10-29Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fprintf(stderr,"All identifiers:\n");
2acdd31995-10-29Fredrik Hübinette (Hubbe)  for(e=0;e<(int)p->num_identifier_references;e++) { fprintf(stderr,"%3d:",e); for(d=0;d<INHERIT_FROM_INT(p,e)->inherit_level;d++) fprintf(stderr," ");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fprintf(stderr,"%s;\n",ID_FROM_INT(p,e)->name->str);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  } fprintf(stderr,"All sorted identifiers:\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  for(q=0;q<(int)p->num_identifier_index;q++)
2acdd31995-10-29Fredrik Hübinette (Hubbe)  { e=p->identifier_index[q]; fprintf(stderr,"%3d (%3d):",e,q); for(d=0;d<INHERIT_FROM_INT(p,e)->inherit_level;d++) fprintf(stderr," ");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fprintf(stderr,"%s;\n", ID_FROM_INT(p,e)->name->str);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  } } #endif
be478c1997-08-30Henrik Grubbström (Grubba) static void toss_compilation_resources(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
a3c6ad1998-01-29Fredrik Hübinette (Hubbe)  if(fake_object) { free_program(fake_object->prog); fake_object->prog=0; free_object(fake_object); fake_object=0; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  free_program(new_program); new_program=0;
591c0c1997-01-19Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(malloc_size_program)
591c0c1997-01-19Fredrik Hübinette (Hubbe)  {
424d9c1999-05-02Fredrik Hübinette (Hubbe)  dmfree((char *)malloc_size_program);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  malloc_size_program=0;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  }
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(module_index_cache) { free_mapping(module_index_cache); module_index_cache=0; }
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  while(compiler_frame) pop_compiler_frame();
591c0c1997-01-19Fredrik Hübinette (Hubbe)  if(last_file) { free_string(last_file); last_file=0; }
05590d1998-04-23Fredrik Hübinette (Hubbe)  unuse_modules(num_used_modules);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
e964ae1998-04-08Fredrik Hübinette (Hubbe) int sizeof_variable(int run_time_type)
1994981998-04-07Fredrik Hübinette (Hubbe) { switch(run_time_type) { case T_FUNCTION: case T_MIXED: return sizeof(struct svalue); case T_FLOAT: return sizeof(FLOAT_TYPE);
2ba9191999-10-23Fredrik Hübinette (Hubbe)  case T_INT: return sizeof(INT_TYPE);
1994981998-04-07Fredrik Hübinette (Hubbe)  default: return sizeof(char *); } } static int alignof_variable(int run_time_type) { switch(run_time_type) { case T_FUNCTION:
90e9781999-01-31Fredrik Hübinette (Hubbe)  case T_MIXED: return ALIGNOF(struct svalue);
1994981998-04-07Fredrik Hübinette (Hubbe)  case T_FLOAT: return ALIGNOF(FLOAT_TYPE);
2ba9191999-10-23Fredrik Hübinette (Hubbe)  case T_INT: return ALIGNOF(INT_TYPE);
1994981998-04-07Fredrik Hübinette (Hubbe)  default: return ALIGNOF(char *); } }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
e51d101999-09-15Fredrik Hübinette (Hubbe) 
624d091996-02-24Fredrik Hübinette (Hubbe) void check_program(struct program *p)
0d202a1995-10-20Fredrik Hübinette (Hubbe) {
3c58e51999-09-22Henrik Grubbström (Grubba)  INT32 size; unsigned INT32 checksum, e;
68b6951999-09-15Fredrik Hübinette (Hubbe)  int variable_positions[1024];
8ba59a2000-03-26Fredrik Hübinette (Hubbe)  if(p->flags & PROGRAM_AVOID_CHECK) return;
68b6951999-09-15Fredrik Hübinette (Hubbe)  for(e=0;e<NELEM(variable_positions);e++) variable_positions[e]=-1;
0d202a1995-10-20Fredrik Hübinette (Hubbe) 
636e471998-04-15Fredrik Hübinette (Hubbe)  if(p->id > current_program_id) fatal("Program id is out of sync! (p->id=%d, current_program_id=%d)\n",p->id,current_program_id);
0d202a1995-10-20Fredrik Hübinette (Hubbe)  if(p->refs <=0) fatal("Program has zero refs.\n"); if(p->next && p->next->prev != p) fatal("Program ->next->prev != program.\n"); if(p->prev) { if(p->prev->next != p) fatal("Program ->prev->next != program.\n"); }else{ if(first_program != p) fatal("Program ->prev == 0 but first_program != program.\n"); }
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(p->id > current_program_id || p->id <= 0)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  fatal("Program id is wrong.\n"); if(p->storage_needed < 0) fatal("Program->storage_needed < 0.\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(p->num_identifier_index > p->num_identifier_references) fatal("Too many identifier index entries in program!\n");
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_constants;e++)
454d541999-09-18Fredrik Hübinette (Hubbe)  { check_svalue(& p->constants[e].sval); if(p->constants[e].name) check_string(p->constants[e].name); }
0d202a1995-10-20Fredrik Hübinette (Hubbe) 
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_strings;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  check_string(p->strings[e]);
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_inherits;e++)
e51d101999-09-15Fredrik Hübinette (Hubbe)  {
ce277e2000-03-25Fredrik Hübinette (Hubbe)  if(!p->inherits[e].prog) {
e05acb2000-03-25Fredrik Hübinette (Hubbe)  /* This inherit is not yet initialized, ignore rest of tests.. */ return;
ce277e2000-03-25Fredrik Hübinette (Hubbe)  }
e51d101999-09-15Fredrik Hübinette (Hubbe)  if(p->inherits[e].storage_offset < 0) fatal("Inherit->storage_offset is wrong.\n");
1f5bfe1999-09-28Fredrik Hübinette (Hubbe)  if(p->inherits[e].prog && p->inherits[e].storage_offset + STORAGE_NEEDED(p->inherits[e].prog) > p->storage_needed) fatal("Not enough room allocated by inherit!\n");
e51d101999-09-15Fredrik Hübinette (Hubbe)  if(e) {
27ae842000-02-07Per Hedbor  if(p->inherits[e-1].storage_offset >
e51d101999-09-15Fredrik Hübinette (Hubbe)  p->inherits[e].storage_offset) fatal("Overlapping inherits! (1)\n");
27ae842000-02-07Per Hedbor 
e51d101999-09-15Fredrik Hübinette (Hubbe)  if(p->inherits[e-1].prog &&
27ae842000-02-07Per Hedbor  p->inherits[e-1].inherit_level >= p->inherits[e].inherit_level &&
1f5bfe1999-09-28Fredrik Hübinette (Hubbe)  ( p->inherits[e-1].storage_offset + STORAGE_NEEDED(p->inherits[e-1].prog)) > p->inherits[e].storage_offset) fatal("Overlapping inherits! (3)\n");
e51d101999-09-15Fredrik Hübinette (Hubbe)  } }
29338d1999-09-29Henrik Grubbström (Grubba) 
7066e11999-09-14Fredrik Hübinette (Hubbe)  if(p->flags & PROGRAM_FINISHED)
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_identifiers;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  { check_string(p->identifiers[e].name); check_string(p->identifiers[e].type);
97f6282000-03-07Fredrik Hübinette (Hubbe)  if(p->identifiers[e].identifier_flags & ~IDENTIFIER_MASK)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  fatal("Unknown flags in identifier flag field.\n"); if(p->identifiers[e].run_time_type!=T_MIXED) check_type(p->identifiers[e].run_time_type);
2f1b9e1998-04-06Fredrik Hübinette (Hubbe)  if(IDENTIFIER_IS_VARIABLE(p->identifiers[e].identifier_flags)) {
68b6951999-09-15Fredrik Hübinette (Hubbe)  if( (p->identifiers[e].func.offset + OFFSETOF(object,storage)) &
1994981998-04-07Fredrik Hübinette (Hubbe)  (alignof_variable(p->identifiers[e].run_time_type)-1))
2f1b9e1998-04-06Fredrik Hübinette (Hubbe)  {
1994981998-04-07Fredrik Hübinette (Hubbe)  fatal("Variable %s offset is not properly aligned (%d).\n",p->identifiers[e].name->str,p->identifiers[e].func.offset);
2f1b9e1998-04-06Fredrik Hübinette (Hubbe)  } }
0d202a1995-10-20Fredrik Hübinette (Hubbe)  }
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_identifier_references;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  {
68b6951999-09-15Fredrik Hübinette (Hubbe)  struct identifier *i;
0d202a1995-10-20Fredrik Hübinette (Hubbe)  if(p->identifier_references[e].inherit_offset > p->num_inherits) fatal("Inherit offset is wrong!\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
513ece1999-09-09Fredrik Hübinette (Hubbe)  if(!p->inherits[p->identifier_references[e].inherit_offset].prog) { if(!(p->flags & PROGRAM_FINISHED)) continue; fatal("p->inherit[%d].prog = NULL!\n",p->identifier_references[e].inherit_offset); }
0d202a1995-10-20Fredrik Hübinette (Hubbe)  if(p->identifier_references[e].identifier_offset > p->inherits[p->identifier_references[e].inherit_offset].prog->num_identifiers) fatal("Identifier offset is wrong!\n");
68b6951999-09-15Fredrik Hübinette (Hubbe)  i=ID_FROM_INT(p, e); if( !(i->identifier_flags & (IDENTIFIER_FUNCTION | IDENTIFIER_CONSTANT))) {
3c58e51999-09-22Henrik Grubbström (Grubba)  unsigned int q, size;
68b6951999-09-15Fredrik Hübinette (Hubbe)  /* Variable */ int offset = INHERIT_FROM_INT(p, e)->storage_offset+i->func.offset;
e51d101999-09-15Fredrik Hübinette (Hubbe)  size=sizeof_variable(i->run_time_type);
3c58e51999-09-22Henrik Grubbström (Grubba)  if((offset+size > (unsigned int)p->storage_needed) || offset<0)
e51d101999-09-15Fredrik Hübinette (Hubbe)  fatal("Variable outside storage! (%s)\n",i->name->str); for(q=0;q<size;q++)
68b6951999-09-15Fredrik Hübinette (Hubbe)  { if(offset+q >= NELEM(variable_positions)) break; if(variable_positions[offset+q] != -1) { if(ID_FROM_INT(p,variable_positions[offset+q])->run_time_type != i->run_time_type) { fatal("Variable '%s' and '%s' overlap\n", ID_FROM_INT(p,variable_positions[offset+q])->name->str, i->name->str); } } variable_positions[offset+q]=e; } }
0d202a1995-10-20Fredrik Hübinette (Hubbe)  }
3c58e51999-09-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_identifier_index;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  { if(p->identifier_index[e] > p->num_identifier_references) fatal("Program->identifier_indexes[%ld] is wrong\n",(long)e); } } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) struct program *end_first_pass(int finish)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
0ffa001998-01-13Fredrik Hübinette (Hubbe)  int e;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct program *prog;
0ffa001998-01-13Fredrik Hübinette (Hubbe)  struct pike_string *s; MAKE_CONSTANT_SHARED_STRING(s,"__INIT"); /* Collect references to inherited __INIT functions */
ae7ee51998-04-10Henrik Grubbström (Grubba)  for(e=new_program->num_inherits-1;e;e--)
0ffa001998-01-13Fredrik Hübinette (Hubbe)  { int id; if(new_program->inherits[e].inherit_level!=1) continue;
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  id=low_reference_inherited_identifier(0, e, s, SEE_STATIC);
0ffa001998-01-13Fredrik Hübinette (Hubbe)  if(id!=-1) {
3d78821999-11-06Henrik Grubbström (Grubba)  init_node=mknode(F_COMMA_EXPR,
0ffa001998-01-13Fredrik Hübinette (Hubbe)  mkcastnode(void_type_string,
87c9d21998-04-09Fredrik Hübinette (Hubbe)  mkapplynode(mkidentifiernode(id),0)), init_node);
0ffa001998-01-13Fredrik Hübinette (Hubbe)  } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* * Define the __INIT function, but only if there was any code * to initialize. */
0ffa001998-01-13Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(init_node)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { union idptr tmp;
a5787d1999-03-03Fredrik Hübinette (Hubbe)  e=dooptcode(s,
3d78821999-11-06Henrik Grubbström (Grubba)  mknode(F_COMMA_EXPR,
a5787d1999-03-03Fredrik Hübinette (Hubbe)  init_node,mknode(F_RETURN,mkintnode(0),0)), function_type_string, ID_STATIC);
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  init_node=0;
a5787d1999-03-03Fredrik Hübinette (Hubbe)  }else{ e=-1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
a5787d1999-03-03Fredrik Hübinette (Hubbe)  new_program->lfuns[LFUN___INIT]=e;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  free_string(s);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  pop_compiler_frame(); /* Pop __INIT local variables */ if(num_parse_error > 0)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { prog=0; }else{
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  prog=new_program;
8c83371998-04-16Fredrik Hübinette (Hubbe)  add_ref(prog);
5580691996-06-21Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
624d091996-02-24Fredrik Hübinette (Hubbe)  check_program(prog);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  if(l_flag) dump_program_desc(prog);
0d202a1995-10-20Fredrik Hübinette (Hubbe) #endif
5580691996-06-21Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  new_program->flags |= PROGRAM_PASS_1_DONE; if(finish) { fixate_program(); optimize_program(new_program); new_program->flags |= PROGRAM_FINISHED; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
a786431999-11-18Martin Stjernholm  #ifdef PROGRAM_BUILD_DEBUG fprintf (stderr, "%.*sfinishing program %d (pass=%d)\n", compilation_depth, " ", new_program->id, compiler_pass); #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  toss_compilation_resources();
5267b71995-08-09Fredrik Hübinette (Hubbe) 
aed42d1999-12-29Martin Stjernholm  CDFPRINTF((stderr, "th(%ld),end_first_pass(): compilation_depth:%d, compiler_pass:%d\n", (long)th_self(), compilation_depth, compiler_pass)); if(!compiler_frame && (compiler_pass==2 || !prog) && resolve_cache) { free_mapping(dmalloc_touch(struct mapping *, resolve_cache)); resolve_cache=0; }
f807f01999-11-11Henrik Grubbström (Grubba) #ifdef SHARED_NODES /* free(node_hash.table); */ #endif /* SHARED_NODES */
5c8e891995-10-29Fredrik Hübinette (Hubbe) #define POP #include "compilation.h"
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
fb2f661998-11-05Fredrik Hübinette (Hubbe)  exit_type_stack();
05590d1998-04-23Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  compilation_depth--;
a91ca01998-07-10Henrik Grubbström (Grubba)  exit_threads_disable(NULL);
ea32c11998-04-13Henrik Grubbström (Grubba) 
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  free_all_nodes();
5f05c11999-12-27Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  return prog; } /*
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  * Finish this program, returning the newly built program */
3c0c281998-01-26Fredrik Hübinette (Hubbe) struct program *debug_end_program(void)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) { return end_first_pass(1); } /*
5267b71995-08-09Fredrik Hübinette (Hubbe)  * Allocate needed for this program in the object structure. * An offset to the data is returned. */
fbef2a1999-09-15Fredrik Hübinette (Hubbe) SIZE_T low_add_storage(SIZE_T size, SIZE_T alignment, int modulo_orig)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b1c8031999-09-15Fredrik Hübinette (Hubbe)  long offset;
9473791999-09-15Fredrik Hübinette (Hubbe)  int modulo;
2ad3c01999-09-16Fredrik Hübinette (Hubbe)  if(!size) return new_program->storage_needed;
90e9781999-01-31Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG if(alignment <=0 || (alignment & (alignment-1)) || alignment > 256) fatal("Alignment must be 1,2,4,8,16,32,64,128 or 256 not %d\n",alignment); #endif
fbef2a1999-09-15Fredrik Hübinette (Hubbe)  modulo=( modulo_orig+OFFSETOF(object,storage) ) % alignment;
b1c8031999-09-15Fredrik Hübinette (Hubbe)  offset=DO_ALIGN(new_program->storage_needed-modulo,alignment)+modulo;
90e9781999-01-31Fredrik Hübinette (Hubbe) 
29338d1999-09-29Henrik Grubbström (Grubba)  if(!new_program->storage_needed) {
eb071e1999-09-28Fredrik Hübinette (Hubbe)  /* Shouldn't new_program->storage_needed be set here?
29338d1999-09-29Henrik Grubbström (Grubba)  * Otherwise the debug code below ought to be trigged. * But since it isn't, I guess this is dead code? * /grubba 1999-09-28
eb071e1999-09-28Fredrik Hübinette (Hubbe)  * * No, the below offset represents the storage in the beginning * of obj->storage which is not used because of alignment constraints. * However, for historical reasons, prog->storage_offset needs to * contain this unused space as well. This means that the real * space used by all variables in an object is really: * o->prog->storage_needed - o->prog->inherits[0].storage_offset, * This can also be written as STORAGE_NEEDED(o->prog) * STORAGE_NEEDED() is defined in program.h. * /Hubbe 1999-09-29
0ee2331999-09-29Henrik Grubbström (Grubba)  * * Oops, seems I read the test below the wrong way around. * /grubba 1999-09-29
29338d1999-09-29Henrik Grubbström (Grubba)  */
90e9781999-01-31Fredrik Hübinette (Hubbe)  new_program->inherits[0].storage_offset=offset;
29338d1999-09-29Henrik Grubbström (Grubba)  }
90e9781999-01-31Fredrik Hübinette (Hubbe)  if(new_program->alignment_needed<alignment) new_program->alignment_needed=alignment;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1c8031999-09-15Fredrik Hübinette (Hubbe)  if(offset < new_program->storage_needed)
1994981998-04-07Fredrik Hübinette (Hubbe)  fatal("add_storage failed horribly!\n");
b1c8031999-09-15Fredrik Hübinette (Hubbe) 
a7d9261999-09-15Fredrik Hübinette (Hubbe)  if( (offset + OFFSETOF(object,storage) - modulo_orig ) % alignment )
454d541999-09-18Fredrik Hübinette (Hubbe)  fatal("add_storage failed horribly(2) %ld %ld %ld %ld!\n", (long)offset, (long)OFFSETOF(object,storage), (long)modulo_orig, (long)alignment
a7d9261999-09-15Fredrik Hübinette (Hubbe)  );
27ae842000-02-07Per Hedbor 
1994981998-04-07Fredrik Hübinette (Hubbe) #endif
b1c8031999-09-15Fredrik Hübinette (Hubbe) 
9386f71999-09-15Fredrik Hübinette (Hubbe)  new_program->storage_needed = offset + size;
b1c8031999-09-15Fredrik Hübinette (Hubbe)  return (SIZE_T) offset;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
1994981998-04-07Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * set a callback used to initialize clones of this program * the init function is called at clone time */
06983f1996-09-22Fredrik Hübinette (Hubbe) void set_init_callback(void (*init)(struct object *))
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  new_program->init=init;
5267b71995-08-09Fredrik Hübinette (Hubbe) } /* * set a callback used to de-initialize clones of this program * the exit function is called at destruct */
06983f1996-09-22Fredrik Hübinette (Hubbe) void set_exit_callback(void (*exit)(struct object *))
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  new_program->exit=exit;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
d4828c1997-07-17Fredrik Hübinette (Hubbe) /* * This callback is called to allow the object to mark all internal * structures as 'used'. */ void set_gc_mark_callback(void (*m)(struct object *)) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  new_program->gc_marked=m;
d4828c1997-07-17Fredrik Hübinette (Hubbe) }
f0c3d31998-04-05Fredrik Hübinette (Hubbe) /* * Called for all objects and inherits in first pass of gc() */ void set_gc_check_callback(void (*m)(struct object *)) { new_program->gc_check=m; }
d429a71998-02-24Fredrik Hübinette (Hubbe) int low_reference_inherited_identifier(struct program_state *q, int e,
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  struct pike_string *name, int flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
d429a71998-02-24Fredrik Hübinette (Hubbe)  struct program *np=q?q->new_program:new_program;
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct reference funp; struct program *p; int i,d;
d429a71998-02-24Fredrik Hübinette (Hubbe)  p=np->inherits[e].prog;
5267b71995-08-09Fredrik Hübinette (Hubbe)  i=find_shared_string_identifier(name,p);
c0e4461998-06-23Fredrik Hübinette (Hubbe)  if(i==-1) {
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  i=really_low_find_shared_string_identifier(name,p, flags);
c0e4461998-06-23Fredrik Hübinette (Hubbe)  if(i==-1) return -1; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  if(p->identifier_references[i].id_flags & ID_HIDDEN)
5267b71995-08-09Fredrik Hübinette (Hubbe)  return -1;
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  if(p->identifier_references[i].id_flags & ID_PRIVATE) if(!(flags & SEE_PRIVATE)) return -1;
5267b71995-08-09Fredrik Hübinette (Hubbe)  funp=p->identifier_references[i];
0d202a1995-10-20Fredrik Hübinette (Hubbe)  funp.inherit_offset+=e;
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  funp.id_flags|=ID_HIDDEN;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
d429a71998-02-24Fredrik Hübinette (Hubbe)  for(d=0;d<(int)np->num_identifier_references;d++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { struct reference *fp;
d429a71998-02-24Fredrik Hübinette (Hubbe)  fp=np->identifier_references+d;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!MEMCMP((char *)fp,(char *)&funp,sizeof funp)) return d; }
d429a71998-02-24Fredrik Hübinette (Hubbe)  if(q) low_add_to_identifier_references(q,funp); else add_to_identifier_references(funp); return np->num_identifier_references -1;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
a005eb1999-03-04Fredrik Hübinette (Hubbe) node *reference_inherited_identifier(struct pike_string *super_name, struct pike_string *function_name)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
a005eb1999-03-04Fredrik Hübinette (Hubbe)  int n,e,id; struct program_state *state=previous_program_state; struct program *p;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(function_name!=debug_findstring(function_name)) fatal("reference_inherited_function on nonshared string.\n"); #endif
a005eb1999-03-04Fredrik Hübinette (Hubbe)  p=new_program;
d429a71998-02-24Fredrik Hübinette (Hubbe)  for(e=p->num_inherits-1;e>0;e--)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
d429a71998-02-24Fredrik Hübinette (Hubbe)  if(p->inherits[e].inherit_level!=1) continue; if(!p->inherits[e].name) continue;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(super_name)
d429a71998-02-24Fredrik Hübinette (Hubbe)  if(super_name != p->inherits[e].name)
5267b71995-08-09Fredrik Hübinette (Hubbe)  continue;
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  id=low_reference_inherited_identifier(0, e, function_name, SEE_STATIC);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(id!=-1) return mkidentifiernode(id);
d429a71998-02-24Fredrik Hübinette (Hubbe) 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(ISCONSTSTR(function_name,"`->") || ISCONSTSTR(function_name,"`[]")) {
f807f01999-11-11Henrik Grubbström (Grubba)  return mknode(F_MAGIC_INDEX,mknewintnode(e),mknewintnode(0));
a005eb1999-03-04Fredrik Hübinette (Hubbe)  }
d429a71998-02-24Fredrik Hübinette (Hubbe) 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(ISCONSTSTR(function_name,"`->=") || ISCONSTSTR(function_name,"`[]=")) {
f807f01999-11-11Henrik Grubbström (Grubba)  return mknode(F_MAGIC_SET_INDEX,mknewintnode(e),mknewintnode(0));
a005eb1999-03-04Fredrik Hübinette (Hubbe)  } } for(n=0;n<compilation_depth;n++,state=state->previous)
d429a71998-02-24Fredrik Hübinette (Hubbe)  {
a005eb1999-03-04Fredrik Hübinette (Hubbe)  struct program *p=state->new_program;
27ae842000-02-07Per Hedbor 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  for(e=p->num_inherits-1;e>0;e--) { if(p->inherits[e].inherit_level!=1) continue; if(!p->inherits[e].name) continue;
27ae842000-02-07Per Hedbor 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(super_name) if(super_name != p->inherits[e].name) continue;
27ae842000-02-07Per Hedbor 
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  id=low_reference_inherited_identifier(state,e,function_name,SEE_STATIC);
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(id!=-1) return mkexternalnode(n,id,ID_FROM_INT(state->new_program, id)); if(ISCONSTSTR(function_name,"`->") || ISCONSTSTR(function_name,"`[]")) {
55aa4a2000-01-27Fredrik Hübinette (Hubbe)  return mknode(F_MAGIC_INDEX, mknewintnode(e),mknewintnode(n+1));
a005eb1999-03-04Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
a005eb1999-03-04Fredrik Hübinette (Hubbe)  if(ISCONSTSTR(function_name,"`->=") || ISCONSTSTR(function_name,"`[]=")) {
55aa4a2000-01-27Fredrik Hübinette (Hubbe)  return mknode(F_MAGIC_SET_INDEX, mknewintnode(e),mknewintnode(n+1));
a005eb1999-03-04Fredrik Hübinette (Hubbe)  } }
d429a71998-02-24Fredrik Hübinette (Hubbe)  } return 0; }
06983f1996-09-22Fredrik Hübinette (Hubbe) void rename_last_inherit(struct pike_string *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(new_program->inherits[new_program->num_inherits].name) free_string(new_program->inherits[new_program->num_inherits].name); copy_shared_string(new_program->inherits[new_program->num_inherits].name, n);
5267b71995-08-09Fredrik Hübinette (Hubbe) } /* * make this program inherit another program */
61e9a01998-01-25Fredrik Hübinette (Hubbe) void low_inherit(struct program *p, struct object *parent, int parent_identifier, int parent_offset, INT32 flags, struct pike_string *name)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int e, inherit_offset, storage_offset; struct inherit inherit;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!p) { yyerror("Illegal program pointer."); return; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1994251999-09-06Fredrik Hübinette (Hubbe)  if(p->flags & PROGRAM_USES_PARENT) { if(!parent && !parent_offset) { yyerror("Parent pointer lost, cannot inherit!");
b1dd8f1999-09-06Henrik Grubbström (Grubba)  /* We inherit it anyway, to avoid causing more errors */
1994251999-09-06Fredrik Hübinette (Hubbe)  } } /* parent offset was increased by one for above test.. */
3139891999-09-06Henrik Grubbström (Grubba)  if(parent_offset) parent_offset--;
1994251999-09-06Fredrik Hübinette (Hubbe) 
bcf9461998-01-27Fredrik Hübinette (Hubbe)  if(!(p->flags & (PROGRAM_FINISHED | PROGRAM_PASS_1_DONE))) { yyerror("Cannot inherit program which is not fully compiled yet."); return; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  inherit_offset = new_program->num_inherits;
90e9781999-01-31Fredrik Hübinette (Hubbe)  /* alignment magic */
9386f71999-09-15Fredrik Hübinette (Hubbe)  storage_offset=p->inherits[0].storage_offset % p->alignment_needed;
1f5bfe1999-09-28Fredrik Hübinette (Hubbe)  storage_offset=low_add_storage(STORAGE_NEEDED(p),
90e9781999-01-31Fredrik Hübinette (Hubbe)  p->alignment_needed,
b1c8031999-09-15Fredrik Hübinette (Hubbe)  storage_offset);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
1f5bfe1999-09-28Fredrik Hübinette (Hubbe)  /* Without this, the inherit becomes skewed */
27ae842000-02-07Per Hedbor  storage_offset-=p->inherits[0].storage_offset;
1f5bfe1999-09-28Fredrik Hübinette (Hubbe) 
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=0; e<(int)p->num_inherits; e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { inherit=p->inherits[e];
8c83371998-04-16Fredrik Hübinette (Hubbe)  add_ref(inherit.prog);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  inherit.identifier_level += new_program->num_identifier_references;
5267b71995-08-09Fredrik Hübinette (Hubbe)  inherit.storage_offset += storage_offset; inherit.inherit_level ++;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!e) {
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(parent)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  {
9e52381998-03-01Fredrik Hübinette (Hubbe)  if(parent->next == parent) { struct object *o; for(o=fake_object->parent;o!=parent;o=o->parent) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
9e52381998-03-01Fredrik Hübinette (Hubbe)  if(!o) fatal("low_inherit with odd fake_object as parent!\n"); #endif inherit.parent_offset++; } }else{ inherit.parent=parent; inherit.parent_identifier=parent_identifier; inherit.parent_offset=0; }
61e9a01998-01-25Fredrik Hübinette (Hubbe)  }else{ inherit.parent_offset+=parent_offset;
bcd5741999-03-17Fredrik Hübinette (Hubbe)  inherit.parent_identifier=parent_identifier;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
1994981998-04-07Fredrik Hübinette (Hubbe)  }else{
5f05c11999-12-27Fredrik Hübinette (Hubbe)  if(!inherit.parent)
1994981998-04-07Fredrik Hübinette (Hubbe)  {
5f05c11999-12-27Fredrik Hübinette (Hubbe)  if(parent && parent->next != parent && inherit.parent_offset)
1994981998-04-07Fredrik Hübinette (Hubbe)  {
5f05c11999-12-27Fredrik Hübinette (Hubbe)  struct object *par=parent; int e,pid=parent_identifier; for(e=1;e<inherit.parent_offset;e++)
1994981998-04-07Fredrik Hübinette (Hubbe)  {
5f05c11999-12-27Fredrik Hübinette (Hubbe)  struct inherit *in; if(!par->prog) { par=0; pid=0; break; }
27ae842000-02-07Per Hedbor 
5f05c11999-12-27Fredrik Hübinette (Hubbe)  in=INHERIT_FROM_INT(par->prog, pid); if(in->parent_offset) { pid=par->parent_identifier; par=par->parent; e-=in->parent_offset-1; }else{ pid=in->parent_identifier; par=in->parent; }
1994981998-04-07Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
5f05c11999-12-27Fredrik Hübinette (Hubbe)  inherit.parent=par; inherit.parent_offset=0; }else{ inherit.parent_offset+=parent_offset;
1994981998-04-07Fredrik Hübinette (Hubbe)  } }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
8c83371998-04-16Fredrik Hübinette (Hubbe)  if(inherit.parent) add_ref(inherit.parent);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(name) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(e==0) {
3c0c281998-01-26Fredrik Hübinette (Hubbe)  copy_shared_string(inherit.name,name);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  } else if(inherit.name) { struct pike_string *s; s=begin_shared_string(inherit.name->len + name->len + 2); MEMCPY(s->str,name->str,name->len); MEMCPY(s->str+name->len,"::",2); MEMCPY(s->str+name->len+2,inherit.name->str,inherit.name->len); inherit.name=end_shared_string(s); } else { inherit.name=0; } }else{ inherit.name=0;
d2c6081996-11-07Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_inherits(inherit);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for (e=0; e < (int)p->num_identifier_references; e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { struct reference fun;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *name;
5267b71995-08-09Fredrik Hübinette (Hubbe)  fun = p->identifier_references[e]; /* Make a copy */ name=ID_FROM_PTR(p,&fun)->name; fun.inherit_offset += inherit_offset;
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  if (fun.id_flags & ID_NOMASK)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { int n; n = isidentifier(name);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if (n != -1 && ID_FROM_INT(new_program,n)->func.offset != -1)
5267b71995-08-09Fredrik Hübinette (Hubbe)  my_yyerror("Illegal to redefine 'nomask' function/variable \"%s\"",name->str); }
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  if(fun.id_flags & ID_PRIVATE) fun.id_flags|=ID_HIDDEN;
5580691996-06-21Fredrik Hübinette (Hubbe) 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  if (fun.id_flags & ID_PUBLIC) fun.id_flags |= flags & ~ID_PRIVATE;
5267b71995-08-09Fredrik Hübinette (Hubbe)  else
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  fun.id_flags |= flags;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  fun.id_flags |= ID_INHERITED;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_identifier_references(fun);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } }
61e9a01998-01-25Fredrik Hübinette (Hubbe) void do_inherit(struct svalue *s, INT32 flags, struct pike_string *name) { struct program *p=program_from_svalue(s); low_inherit(p, s->type == T_FUNCTION ? s->u.object : 0, s->subtype, 0, flags, name); } void compiler_do_inherit(node *n, INT32 flags, struct pike_string *name) {
086acc1999-09-11Fredrik Hübinette (Hubbe)  struct program *p; struct identifier *i; INT32 numid, offset;
27ae842000-02-07Per Hedbor 
2416d81998-01-27Fredrik Hübinette (Hubbe)  if(!n) { yyerror("Unable to inherit"); return; }
61e9a01998-01-25Fredrik Hübinette (Hubbe)  switch(n->token) {
086acc1999-09-11Fredrik Hübinette (Hubbe)  case F_IDENTIFIER: p=new_program; offset=0;
f807f01999-11-11Henrik Grubbström (Grubba)  numid=n->u.id.number;
086acc1999-09-11Fredrik Hübinette (Hubbe)  goto continue_inherit;
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  case F_EXTERNAL:
086acc1999-09-11Fredrik Hübinette (Hubbe)  p=parent_compilation(n->u.integer.a); offset=n->u.integer.a; numid=n->u.integer.b;
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(!p) { yyerror("Failed to resolv external constant.\n"); return; }
086acc1999-09-11Fredrik Hübinette (Hubbe)  continue_inherit:
61e9a01998-01-25Fredrik Hübinette (Hubbe)  i=ID_FROM_INT(p, numid);
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(IDENTIFIER_IS_CONSTANT(i->identifier_flags)) {
454d541999-09-18Fredrik Hübinette (Hubbe)  struct svalue *s=&PROG_FROM_INT(p, numid)-> constants[i->func.offset].sval;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(s->type != T_PROGRAM) {
2416d81998-01-27Fredrik Hübinette (Hubbe)  do_inherit(s,flags,name);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  return; }else{ p=s->u.program; } }else{ yyerror("Inherit identifier is not a constant program"); return; } low_inherit(p, 0,
bcd5741999-03-17Fredrik Hübinette (Hubbe)  numid,
086acc1999-09-11Fredrik Hübinette (Hubbe)  offset+1,
61e9a01998-01-25Fredrik Hübinette (Hubbe)  flags, name); break; default:
086acc1999-09-11Fredrik Hübinette (Hubbe)  resolv_class(n);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  do_inherit(sp-1, flags, name); pop_stack(); } }
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void simple_do_inherit(struct pike_string *s, INT32 flags, struct pike_string *name)
5267b71995-08-09Fredrik Hübinette (Hubbe) { reference_shared_string(s); push_string(s);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  ref_push_string(lex.current_file);
5267b71995-08-09Fredrik Hübinette (Hubbe)  SAFE_APPLY_MASTER("handle_inherit", 2); if(sp[-1].type != T_PROGRAM) { my_yyerror("Couldn't find file to inherit %s",s->str); pop_stack(); return; } if(name) { free_string(s); s=name; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  do_inherit(sp-1, flags, s);
d2c6081996-11-07Fredrik Hübinette (Hubbe)  free_string(s);
5267b71995-08-09Fredrik Hübinette (Hubbe)  pop_stack(); } /* * Return the index of the identifier found, otherwise -1. */
06983f1996-09-22Fredrik Hübinette (Hubbe) int isidentifier(struct pike_string *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) { INT32 e;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  for(e=new_program->num_identifier_references-1;e>=0;e--)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(new_program->identifier_references[e].id_flags & ID_HIDDEN) continue;
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(ID_FROM_INT(new_program, e)->name == s)
5267b71995-08-09Fredrik Hübinette (Hubbe)  return e; } return -1; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /* argument must be a shared string */
d4828c1997-07-17Fredrik Hübinette (Hubbe) int low_define_variable(struct pike_string *name, struct pike_string *type, INT32 flags, INT32 offset, INT32 run_time_type) { int n;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
d4828c1997-07-17Fredrik Hübinette (Hubbe)  struct identifier dummy; struct reference ref;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(new_program->flags & (PROGRAM_FIXED | PROGRAM_OPTIMIZED)) fatal("Attempting to add variable to fixed program\n");
22edc21998-01-29Fredrik Hübinette (Hubbe)  if(compiler_pass==2)
05bfe21998-07-20Henrik Grubbström (Grubba)  fatal("Internal error: Not allowed to add more identifiers during second compiler pass.\n" "Added identifier: \"%s\"\n", name->str);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif
d4828c1997-07-17Fredrik Hübinette (Hubbe)  copy_shared_string(dummy.name, name); copy_shared_string(dummy.type, type);
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  dummy.identifier_flags = 0;
d4828c1997-07-17Fredrik Hübinette (Hubbe)  dummy.run_time_type=run_time_type;
f016d11999-09-15Fredrik Hübinette (Hubbe)  dummy.func.offset=offset - new_program->inherits[0].storage_offset;
be478c1997-08-30Henrik Grubbström (Grubba) #ifdef PROFILING
6189631998-11-12Fredrik Hübinette (Hubbe)  dummy.self_time=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  dummy.num_calls=0;
a2a8801998-03-18Per Hedbor  dummy.total_time=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif
be478c1997-08-30Henrik Grubbström (Grubba) 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  ref.id_flags=flags;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  ref.identifier_offset=new_program->num_identifiers;
d4828c1997-07-17Fredrik Hübinette (Hubbe)  ref.inherit_offset=0;
05590d1998-04-23Fredrik Hübinette (Hubbe)  add_to_variable_index(ref.identifier_offset);
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_identifiers(dummy);
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  n=new_program->num_identifier_references; add_to_identifier_references(ref);
05590d1998-04-23Fredrik Hübinette (Hubbe) 
d4828c1997-07-17Fredrik Hübinette (Hubbe)  return n; } int map_variable(char *name, char *type, INT32 flags, INT32 offset, INT32 run_time_type) { int ret; struct pike_string *n,*t;
a786431999-11-18Martin Stjernholm  #ifdef PROGRAM_BUILD_DEBUG fprintf (stderr, "%.*sdefining variable (pass=%d): %s %s\n", compilation_depth, " ", compiler_pass, type, name); #endif
d4828c1997-07-17Fredrik Hübinette (Hubbe)  n=make_shared_string(name); t=parse_type(type); ret=low_define_variable(n,t,flags,offset,run_time_type); free_string(n); free_string(t); return ret; }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* argument must be a shared string */
06983f1996-09-22Fredrik Hübinette (Hubbe) int define_variable(struct pike_string *name, struct pike_string *type,
5267b71995-08-09Fredrik Hübinette (Hubbe)  INT32 flags) {
61e9a01998-01-25Fredrik Hübinette (Hubbe)  int n, run_time_type;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(name!=debug_findstring(name)) fatal("define_variable on nonshared string.\n"); #endif
a786431999-11-18Martin Stjernholm #ifdef PROGRAM_BUILD_DEBUG { struct pike_string *d = describe_type (type); fprintf (stderr, "%.*sdefining variable (pass=%d): %s ", compilation_depth, " ", compiler_pass, d->str); free_string (d); push_string (name); print_svalue (stderr, --sp); putc ('\n', stderr); } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(type == void_type_string) yyerror("Variables can't be of type void");
27ae842000-02-07Per Hedbor 
5267b71995-08-09Fredrik Hübinette (Hubbe)  n = isidentifier(name);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(new_program->flags & PROGRAM_PASS_1_DONE) { if(n==-1) yyerror("Pass2: Variable disappeared!");
a786431999-11-18Martin Stjernholm  else { struct identifier *id; id=ID_FROM_INT(new_program,n); free_string(id->type); copy_shared_string(id->type, type);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return n;
a786431999-11-18Martin Stjernholm  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(new_program->flags & (PROGRAM_FIXED | PROGRAM_OPTIMIZED)) fatal("Attempting to add variable to fixed program\n"); #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(n != -1) {
1994251999-09-06Fredrik Hübinette (Hubbe)  /* not inherited */
27ae842000-02-07Per Hedbor  if(new_program->identifier_references[n].inherit_offset == 0)
1994251999-09-06Fredrik Hübinette (Hubbe)  {
e774391999-12-31Henrik Grubbström (Grubba)  if (!((IDENTIFIERP(n)->id_flags | flags) & ID_EXTERN)) { my_yyerror("Identifier '%s' defined twice.",name->str); return n; } if (flags & ID_EXTERN) { /* FIXME: Check type */ return n; }
1994251999-09-06Fredrik Hübinette (Hubbe)  }
e774391999-12-31Henrik Grubbström (Grubba)  if (!(IDENTIFIERP(n)->id_flags & ID_EXTERN)) { if (IDENTIFIERP(n)->id_flags & ID_NOMASK) my_yyerror("Illegal to redefine 'nomask/final' " "variable/functions \"%s\"", name->str);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
e774391999-12-31Henrik Grubbström (Grubba)  if(!(IDENTIFIERP(n)->id_flags & ID_INLINE) || compiler_pass!=1)
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  {
9eaa6e2000-02-12Fredrik Hübinette (Hubbe)  if(!match_types(ID_FROM_INT(new_program, n)->type, type)) my_yyerror("Illegal to redefine inherited variable " "with different type.");
8aae6d1999-08-19Fredrik Hübinette (Hubbe) 
e774391999-12-31Henrik Grubbström (Grubba)  if(!IDENTIFIER_IS_VARIABLE(ID_FROM_INT(new_program, n)-> identifier_flags)) { my_yyerror("Illegal to redefine inherited variable " "with different type."); } IDENTIFIERP(n)->id_flags = flags & ~ID_EXTERN; return n; }
61e9a01998-01-25Fredrik Hübinette (Hubbe)  } }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  run_time_type=compile_type_to_runtime_type(type);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  switch(run_time_type) {
2ba9191999-10-23Fredrik Hübinette (Hubbe) #ifdef AUTO_BIGNUM
0957531999-10-25Fredrik Hübinette (Hubbe) #if 0
659ccc1999-10-25Fredrik Hübinette (Hubbe)  case T_OBJECT: /* This is to allow room for integers in variables declared as * 'object', however, this could be changed in the future to only * make room for integers if the variable was declared as * 'object(Gmp.mpz)' /Hubbe */
0957531999-10-25Fredrik Hübinette (Hubbe) #endif
2ba9191999-10-23Fredrik Hübinette (Hubbe)  case T_INT: #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case T_FUNCTION: case T_PROGRAM: run_time_type = T_MIXED;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  n=low_define_variable(name,type,flags,
1994981998-04-07Fredrik Hübinette (Hubbe)  low_add_storage(sizeof_variable(run_time_type),
90e9781999-01-31Fredrik Hübinette (Hubbe)  alignof_variable(run_time_type),0),
61e9a01998-01-25Fredrik Hübinette (Hubbe)  run_time_type);
27ae842000-02-07Per Hedbor 
5267b71995-08-09Fredrik Hübinette (Hubbe)  return n; }
5740881998-01-01Fredrik Hübinette (Hubbe) int simple_add_variable(char *name, char *type, INT32 flags) { INT32 ret; struct pike_string *name_s, *type_s; name_s=make_shared_string(name); type_s=parse_type(type);
27ae842000-02-07Per Hedbor 
5740881998-01-01Fredrik Hübinette (Hubbe)  ret=define_variable(name_s, type_s, flags); free_string(name_s); free_string(type_s); return ret; }
d2c6081996-11-07Fredrik Hübinette (Hubbe) int add_constant(struct pike_string *name, struct svalue *c, INT32 flags) { int n;
2d12341997-03-10Fredrik Hübinette (Hubbe)  struct identifier dummy; struct reference ref;
d2c6081996-11-07Fredrik Hübinette (Hubbe) 
a786431999-11-18Martin Stjernholm #ifdef PROGRAM_BUILD_DEBUG { if (c) { struct pike_string *t = get_type_of_svalue (c); struct pike_string *d = describe_type (t); fprintf (stderr, "%.*sdefining constant (pass=%d): %s ", compilation_depth, " ", compiler_pass, d->str); free_string (t); free_string (d); } else fprintf (stderr, "%.*sdeclaring constant (pass=%d): ", compilation_depth, " ", compiler_pass); push_string (name); print_svalue (stderr, --sp); putc ('\n', stderr); } #endif
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(name!=debug_findstring(name))
e43ca21996-11-15Fredrik Hübinette (Hubbe)  fatal("define_constant on nonshared string.\n");
d2c6081996-11-07Fredrik Hübinette (Hubbe) #endif n = isidentifier(name);
a566ca1999-12-14Fredrik Hübinette (Hubbe)  /* * FIXME: * No constants should be allowed to contain * any fake objects. (Fake objects can be * detected thus: fake_ob->next == fake_ob * * I would prefer to find a way to detect * this without recursing through arrays, * mapping etc. etc. * * /Hubbe */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(new_program->flags & PROGRAM_PASS_1_DONE) { if(n==-1) { yyerror("Pass2: Constant disappeared!"); }else{ struct identifier *id; id=ID_FROM_INT(new_program,n); if(id->func.offset>=0) { struct pike_string *s;
454d541999-09-18Fredrik Hübinette (Hubbe)  struct svalue *c=&PROG_FROM_INT(new_program,n)-> constants[id->func.offset].sval;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  s=get_type_of_svalue(c); free_string(id->type); id->type=s; }
a786431999-11-18Martin Stjernholm  else { #ifdef PIKE_DEBUG if (!c) fatal("Can't declare constant during second compiler pass\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif
a786431999-11-18Martin Stjernholm  free_string(id->type); id->type = get_type_of_svalue(c); id->run_time_type = c->type; id->func.offset = store_constant(c, 0, 0); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return n; } }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(new_program->flags & (PROGRAM_FIXED | PROGRAM_OPTIMIZED)) fatal("Attempting to add constant to fixed program\n");
22edc21998-01-29Fredrik Hübinette (Hubbe)  if(compiler_pass==2) fatal("Internal error: Not allowed to add more identifiers during second compiler pass.\n");
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif
2d12341997-03-10Fredrik Hübinette (Hubbe)  copy_shared_string(dummy.name, name);
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  dummy.identifier_flags = IDENTIFIER_CONSTANT;
a786431999-11-18Martin Stjernholm  if (c) { dummy.type = get_type_of_svalue(c); dummy.run_time_type=c->type; dummy.func.offset=store_constant(c, 0, 0); } else { reference_shared_string(mixed_type_string); dummy.type = mixed_type_string; dummy.run_time_type=T_MIXED; dummy.func.offset=-1; }
2d12341997-03-10Fredrik Hübinette (Hubbe) 
7fda7a1997-09-08Fredrik Hübinette (Hubbe)  ref.id_flags=flags;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  ref.identifier_offset=new_program->num_identifiers;
2d12341997-03-10Fredrik Hübinette (Hubbe)  ref.inherit_offset=0;
a2a8801998-03-18Per Hedbor #ifdef PROFILING
6189631998-11-12Fredrik Hübinette (Hubbe)  dummy.self_time=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  dummy.num_calls=0;
a2a8801998-03-18Per Hedbor  dummy.total_time=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif add_to_identifiers(dummy);
2d12341997-03-10Fredrik Hübinette (Hubbe) 
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(n != -1) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(IDENTIFIERP(n)->id_flags & ID_NOMASK)
d2c6081996-11-07Fredrik Hübinette (Hubbe)  my_yyerror("Illegal to redefine 'nomask' identifier \"%s\"", name->str);
1994251999-09-06Fredrik Hübinette (Hubbe)  /* not inherited */
27ae842000-02-07Per Hedbor  if(new_program->identifier_references[n].inherit_offset == 0)
1994251999-09-06Fredrik Hübinette (Hubbe)  {
d2c6081996-11-07Fredrik Hübinette (Hubbe)  my_yyerror("Identifier '%s' defined twice.",name->str);
1994251999-09-06Fredrik Hübinette (Hubbe)  return n; }
d2c6081996-11-07Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(!(IDENTIFIERP(n)->id_flags & ID_INLINE)) { /* override */ new_program->identifier_references[n]=ref; return n; }
d2c6081996-11-07Fredrik Hübinette (Hubbe)  }
61e9a01998-01-25Fredrik Hübinette (Hubbe)  n=new_program->num_identifier_references; add_to_identifier_references(ref);
d2c6081996-11-07Fredrik Hübinette (Hubbe)  return n; }
27ae842000-02-07Per Hedbor int simple_add_constant(char *name,
0683be1997-01-26Fredrik Hübinette (Hubbe)  struct svalue *c, INT32 flags) { INT32 ret; struct pike_string *id; id=make_shared_string(name); ret=add_constant(id, c, flags); free_string(id); return ret; }
e43ca21996-11-15Fredrik Hübinette (Hubbe) int add_integer_constant(char *name, INT32 i, INT32 flags) { struct svalue tmp; tmp.u.integer=i; tmp.type=T_INT; tmp.subtype=NUMBER_NUMBER;
0683be1997-01-26Fredrik Hübinette (Hubbe)  return simple_add_constant(name, &tmp, flags);
e43ca21996-11-15Fredrik Hübinette (Hubbe) }
45ee5d1999-02-10Fredrik Hübinette (Hubbe) int quick_add_integer_constant(char *name, int name_length, INT32 i, INT32 flags) { struct svalue tmp; struct pike_string *id; INT32 ret; tmp.u.integer=i; tmp.type=T_INT; tmp.subtype=NUMBER_NUMBER; id=make_shared_binary_string(name,name_length); ret=add_constant(id, &tmp, flags); free_string(id); return ret; }
0683be1997-01-26Fredrik Hübinette (Hubbe) int add_float_constant(char *name, double f, INT32 flags) { struct svalue tmp; tmp.type=T_FLOAT; tmp.u.float_number=f; tmp.subtype=0; return simple_add_constant(name, &tmp, flags); } int add_string_constant(char *name, char *str, INT32 flags) { INT32 ret; struct svalue tmp; tmp.type=T_STRING; tmp.subtype=0; tmp.u.string=make_shared_string(str); ret=simple_add_constant(name, &tmp, flags); free_svalue(&tmp); return ret; }
e43ca21996-11-15Fredrik Hübinette (Hubbe) 
5c0a101997-02-06Fredrik Hübinette (Hubbe) int add_program_constant(char *name, struct program *p, INT32 flags) { INT32 ret; struct svalue tmp; tmp.type=T_PROGRAM; tmp.subtype=0; tmp.u.program=p; ret=simple_add_constant(name, &tmp, flags); return ret; }
f0c3d31998-04-05Fredrik Hübinette (Hubbe) int add_object_constant(char *name, struct object *o, INT32 flags) { INT32 ret; struct svalue tmp; tmp.type=T_OBJECT; tmp.subtype=0; tmp.u.object=o; ret=simple_add_constant(name, &tmp, flags); return ret; }
c152401997-02-10Fredrik Hübinette (Hubbe) int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 flags) { struct svalue s; struct pike_string *n; INT32 ret; s.type=T_FUNCTION; s.subtype=FUNCTION_BUILTIN; s.u.efun=make_callable(cfun, name, type, flags, 0, 0); ret=simple_add_constant(name, &s, 0); free_svalue(&s); return ret; }
45ee5d1999-02-10Fredrik Hübinette (Hubbe) int debug_end_class(char *name, int namelen, INT32 flags)
5c0a101997-02-06Fredrik Hübinette (Hubbe) { INT32 ret; struct svalue tmp;
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  struct pike_string *id;
5c0a101997-02-06Fredrik Hübinette (Hubbe)  tmp.type=T_PROGRAM; tmp.subtype=0; tmp.u.program=end_program();
f839fa1997-02-28Fredrik Hübinette (Hubbe)  if(!tmp.u.program) fatal("Failed to initialize class '%s'\n",name);
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  id=make_shared_binary_string(name,namelen); ret=add_constant(id, &tmp, flags); free_string(id);
5c0a101997-02-06Fredrik Hübinette (Hubbe)  free_svalue(&tmp); return ret; }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * define a new function * if func isn't given, it is supposed to be a prototype. */
06983f1996-09-22Fredrik Hübinette (Hubbe) INT32 define_function(struct pike_string *name, struct pike_string *type,
5267b71995-08-09Fredrik Hübinette (Hubbe)  INT16 flags, INT8 function_flags, union idptr *func) { struct identifier *funp,fun; struct reference ref;
51059b1999-12-26Henrik Grubbström (Grubba)  struct svalue *lfun_type;
5267b71995-08-09Fredrik Hübinette (Hubbe)  INT32 i;
a786431999-11-18Martin Stjernholm #ifdef PROGRAM_BUILD_DEBUG { struct pike_string *d = describe_type (type); fprintf (stderr, "%.*sdefining function (pass=%d): %s ", compilation_depth, " ", compiler_pass, d->str); free_string (d); push_string (name); print_svalue (stderr, --sp); putc ('\n', stderr); } #endif
a2a8801998-03-18Per Hedbor #ifdef PROFILING
6189631998-11-12Fredrik Hübinette (Hubbe)  fun.self_time=0;
a2a8801998-03-18Per Hedbor  fun.num_calls=0; fun.total_time=0; #endif
51059b1999-12-26Henrik Grubbström (Grubba)  /* If this is an lfun, match against the predefined type. */ if ((lfun_type = low_mapping_string_lookup(lfun_types, name))) { #ifdef PIKE_DEBUG if (lfun_type->type != T_TYPE) { fatal("Bad entry in lfun_types for key \"%s\"\n", name->str); } #endif /* PIKE_DEBUG */ if (!pike_types_le(type, lfun_type->u.string)) { if (!match_types(type, lfun_type->u.string)) { yytype_error("Function type mismatch", lfun_type->u.string, type, 0); } else if (lex.pragmas & ID_STRICT_TYPES) { yytype_error("Function type mismatch", lfun_type->u.string, type, YYTE_IS_WARNING); } } }
7c429f2000-04-06Fredrik Hübinette (Hubbe)  if(function_flags & IDENTIFIER_C_FUNCTION) new_program->flags |= PROGRAM_HAS_C_METHODS;
5267b71995-08-09Fredrik Hübinette (Hubbe)  i=isidentifier(name); if(i >= 0) { /* already defined */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  funp=ID_FROM_INT(new_program, i); ref=new_program->identifier_references[i];
5267b71995-08-09Fredrik Hübinette (Hubbe) 
2acdd31995-10-29Fredrik Hübinette (Hubbe)  if(ref.inherit_offset == 0) /* not inherited */
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
51059b1999-12-26Henrik Grubbström (Grubba) 
1994251999-09-06Fredrik Hübinette (Hubbe)  if( !( IDENTIFIER_IS_FUNCTION(funp->identifier_flags) && ( (!func || func->offset == -1) || (funp->func.offset == -1))))
2acdd31995-10-29Fredrik Hübinette (Hubbe)  {
1994251999-09-06Fredrik Hübinette (Hubbe)  my_yyerror("Identifier '%s' defined twice.",name->str);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  return i; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* match types against earlier prototype or vice versa */
0d202a1995-10-20Fredrik Hübinette (Hubbe)  if(!match_types(type, funp->type))
5267b71995-08-09Fredrik Hübinette (Hubbe)  { my_yyerror("Prototype doesn't match for function %s.",name->str); } }
ae95031999-04-07Fredrik Hübinette (Hubbe)  /* We modify the old definition if it is in this program */
12bdcd1999-04-08Fredrik Hübinette (Hubbe) 
ae95031999-04-07Fredrik Hübinette (Hubbe)  if(ref.inherit_offset==0)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
ae95031999-04-07Fredrik Hübinette (Hubbe)  if(func) funp->func = *func; else funp->func.offset = -1;
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  funp->identifier_flags=function_flags;
a786431999-11-18Martin Stjernholm  free_string(funp->type); copy_shared_string(funp->type, type);
ae95031999-04-07Fredrik Hübinette (Hubbe)  }else{
1994251999-09-06Fredrik Hübinette (Hubbe) 
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  if((ref.id_flags & ID_NOMASK) #if 0 && !(funp->func.offset == -1) #endif ) { my_yyerror("Illegal to redefine 'nomask' function %s.",name->str); }
27ae842000-02-07Per Hedbor 
8aae6d1999-08-19Fredrik Hübinette (Hubbe) 
12bdcd1999-04-08Fredrik Hübinette (Hubbe)  if(ref.id_flags & ID_INLINE) {
ae95031999-04-07Fredrik Hübinette (Hubbe)  goto make_a_new_def;
12bdcd1999-04-08Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  /* Otherwise we make a new definition */ copy_shared_string(fun.name, name); copy_shared_string(fun.type, type);
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  fun.run_time_type=T_FUNCTION;
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  fun.identifier_flags=function_flags; if(function_flags & IDENTIFIER_C_FUNCTION) new_program->flags |= PROGRAM_HAS_C_METHODS;
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  if(func) fun.func = *func; else fun.func.offset = -1;
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  ref.identifier_offset=new_program->num_identifiers; add_to_identifiers(fun);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
27ae842000-02-07Per Hedbor 
ae95031999-04-07Fredrik Hübinette (Hubbe)  ref.inherit_offset = 0; ref.id_flags = flags;
8b81572000-01-15Fredrik Hübinette (Hubbe) #if 0
ae95031999-04-07Fredrik Hübinette (Hubbe)  new_program->identifier_references[i]=ref;
8b81572000-01-15Fredrik Hübinette (Hubbe) #else { int z; /* This loop could possibly be optimized by looping over * each inherit and looking up 'name' in each inherit * and then see if should be overwritten * /Hubbe */ for(z=0;z<new_program->num_identifier_references;z++) { /* Do zapp hidden identifiers */ if(new_program->identifier_references[z].id_flags & ID_HIDDEN) continue; /* Do not zapp inline ('local') identifiers */ if(new_program->identifier_references[z].inherit_offset && (new_program->identifier_references[z].id_flags & ID_INLINE)) continue; /* Do not zapp functions with the wrong name... */ if(ID_FROM_INT(new_program, z)->name != name) continue; new_program->identifier_references[z]=ref; } #ifdef PIKE_DEBUG if(MEMCMP(new_program->identifier_references+i, &ref,sizeof(ref))) fatal("New function overloading algorithm failed!\n"); #endif } #endif
ae95031999-04-07Fredrik Hübinette (Hubbe)  return i;
61e9a01998-01-25Fredrik Hübinette (Hubbe)  }
ae95031999-04-07Fredrik Hübinette (Hubbe) make_a_new_def:
5267b71995-08-09Fredrik Hübinette (Hubbe) 
12bdcd1999-04-08Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
22edc21998-01-29Fredrik Hübinette (Hubbe)  if(compiler_pass==2) fatal("Internal error: Not allowed to add more identifiers during second compiler pass.\n"); #endif
61e9a01998-01-25Fredrik Hübinette (Hubbe)  /* define a new function */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  copy_shared_string(fun.name, name); copy_shared_string(fun.type, type);
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  fun.identifier_flags=function_flags; fun.run_time_type=T_FUNCTION;
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  if(func) fun.func = *func; else fun.func.offset = -1;
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  i=new_program->num_identifiers;
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  add_to_identifiers(fun);
27ae842000-02-07Per Hedbor 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  ref.id_flags = flags; ref.identifier_offset = i; ref.inherit_offset = 0;
ae95031999-04-07Fredrik Hübinette (Hubbe) 
61e9a01998-01-25Fredrik Hübinette (Hubbe)  i=new_program->num_identifier_references; add_to_identifier_references(ref);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  return i; }
c0e4461998-06-23Fredrik Hübinette (Hubbe) int really_low_find_shared_string_identifier(struct pike_string *name, struct program *prog,
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  int flags)
c0e4461998-06-23Fredrik Hübinette (Hubbe) { struct reference *funp; struct identifier *fun; int i,t;
66b6741999-03-15Fredrik Hübinette (Hubbe) 
aed42d1999-12-29Martin Stjernholm #if 0
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  CDFPRINTF((stderr,"th(%ld) Trying to find %s flags=%d\n", (long)th_self(),name->str, flags));
aed42d1999-12-29Martin Stjernholm #endif
66b6741999-03-15Fredrik Hübinette (Hubbe) 
5dbbf81999-07-01Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (!prog) { fatal("really_low_find_shared_string_identifier(\"%s\", NULL, %d)\n"
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  "prog is NULL!\n", name->str, flags);
5dbbf81999-07-01Henrik Grubbström (Grubba)  } #endif /* PIKE_DEBUG */
c0e4461998-06-23Fredrik Hübinette (Hubbe)  for(i=0;i<(int)prog->num_identifier_references;i++) { funp = prog->identifier_references + i; if(funp->id_flags & ID_HIDDEN) continue;
66b6741999-03-15Fredrik Hübinette (Hubbe)  if(funp->id_flags & ID_STATIC)
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  if(!(flags & SEE_STATIC))
c0e4461998-06-23Fredrik Hübinette (Hubbe)  continue; fun = ID_FROM_PTR(prog, funp); /* if(fun->func.offset == -1) continue; * Prototype */ if(!is_same_string(fun->name,name)) continue; if(funp->id_flags & ID_INHERITED) { if(funp->id_flags & ID_PRIVATE) continue; for(t=0; t>=0 && t<(int)prog->num_identifier_references; t++) { struct reference *funpb; struct identifier *funb;
27ae842000-02-07Per Hedbor 
c0e4461998-06-23Fredrik Hübinette (Hubbe)  if(t==i) continue; funpb=prog->identifier_references+t;
66b6741999-03-15Fredrik Hübinette (Hubbe)  if(funpb->id_flags & ID_HIDDEN) continue;
8aae6d1999-08-19Fredrik Hübinette (Hubbe)  if(funpb->id_flags & ID_STATIC) if(!(flags & SEE_STATIC)) continue;
c0e4461998-06-23Fredrik Hübinette (Hubbe)  if((funpb->id_flags & ID_INHERITED) && t<i) continue; funb=ID_FROM_PTR(prog,funpb); /* if(funb->func.offset == -1) continue; * prototype */ if(fun->name==funb->name) t=-10; } if(t < 0) continue; } return i; } return -1; }
abac4e2000-02-16Henrik Grubbström (Grubba) int low_find_lfun(struct program *p, int lfun) {
e851712000-02-16Henrik Grubbström (Grubba)  struct pike_string *lfun_name = findstring(lfun_names[lfun]);
abac4e2000-02-16Henrik Grubbström (Grubba)  unsigned int flags = 0;
87d5c52000-02-16Henrik Grubbström (Grubba)  if (!lfun_name) return -1;
abac4e2000-02-16Henrik Grubbström (Grubba)  if ((1 <= lfun) && (lfun < 3)) { /* create() and destroy() are used even if they are static. */ flags = SEE_STATIC; } return really_low_find_shared_string_identifier(lfun_name, dmalloc_touch(struct program *, p), flags); }
5267b71995-08-09Fredrik Hübinette (Hubbe) /* * lookup the number of a function in a program given the name in * a shared_string */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) int low_find_shared_string_identifier(struct pike_string *name, struct program *prog)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int max,min,tst; struct identifier *fun;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(prog->flags & PROGRAM_FIXED)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  unsigned short *funindex = prog->identifier_index;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!funindex) fatal("No funindex in fixed program\n"); #endif
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  max = prog->num_identifier_index;
5267b71995-08-09Fredrik Hübinette (Hubbe)  min = 0; while(max != min) { tst=(max + min) >> 1; fun = ID_FROM_INT(prog, funindex[tst]); if(is_same_string(fun->name,name)) return funindex[tst]; if(my_order_strcmp(fun->name, name) > 0) max=tst; else min=tst+1; } }else{
c0e4461998-06-23Fredrik Hübinette (Hubbe)  return really_low_find_shared_string_identifier(name,prog,0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } return -1; } #ifdef FIND_FUNCTION_HASHSIZE #if FIND_FUNCTION_HASHSIZE == 0 #undef FIND_FUNCTION_HASHSIZE #endif #endif #ifdef FIND_FUNCTION_HASHSIZE struct ff_hash {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *name;
5267b71995-08-09Fredrik Hübinette (Hubbe)  int id; int fun; }; static struct ff_hash cache[FIND_FUNCTION_HASHSIZE]; #endif
06983f1996-09-22Fredrik Hübinette (Hubbe) int find_shared_string_identifier(struct pike_string *name,
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct program *prog) {
c55b911999-03-07Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG if (!prog) { fatal("find_shared_string_identifier(): No program!\n" "Identifier: %s%s%s\n", name?"\"":"", name?name->str:"NULL", name?"\"":""); } #endif /* PIKE_DEBUG */
5267b71995-08-09Fredrik Hübinette (Hubbe) #ifdef FIND_FUNCTION_HASHSIZE
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(prog -> flags & PROGRAM_FIXED)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { unsigned int hashval; hashval=my_hash_string(name); hashval+=prog->id;
f90e541995-08-17Fredrik Hübinette (Hubbe)  hashval^=(unsigned long)prog;
5267b71995-08-09Fredrik Hübinette (Hubbe)  hashval-=name->str[0]; hashval%=FIND_FUNCTION_HASHSIZE; if(is_same_string(cache[hashval].name,name) && cache[hashval].id==prog->id) return cache[hashval].fun; if(cache[hashval].name) free_string(cache[hashval].name); copy_shared_string(cache[hashval].name,name); cache[hashval].id=prog->id; return cache[hashval].fun=low_find_shared_string_identifier(name,prog); } #endif /* FIND_FUNCTION_HASHSIZE */ return low_find_shared_string_identifier(name,prog); } int find_identifier(char *name,struct program *prog) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *n;
0b9d1c1998-05-15Henrik Grubbström (Grubba)  if(!prog) { if (strlen(name) < 1024) { error("Lookup of identifier %s in destructed object.\n", name); } else { error("Lookup of long identifier in destructed object.\n"); } }
5267b71995-08-09Fredrik Hübinette (Hubbe)  n=findstring(name); if(!n) return -1; return find_shared_string_identifier(n,prog); }
06983f1996-09-22Fredrik Hübinette (Hubbe) int store_prog_string(struct pike_string *str)
5267b71995-08-09Fredrik Hübinette (Hubbe) { unsigned int i;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  for (i=0;i<new_program->num_strings;i++) if (new_program->strings[i] == str)
5267b71995-08-09Fredrik Hübinette (Hubbe)  return i; reference_shared_string(str);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_strings(str);
5267b71995-08-09Fredrik Hübinette (Hubbe)  return i; }
454d541999-09-18Fredrik Hübinette (Hubbe) int store_constant(struct svalue *foo, int equal, struct pike_string *constant_name)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
454d541999-09-18Fredrik Hübinette (Hubbe)  struct program_constant tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  unsigned int e;
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  JMP_BUF tmp2;
27ae842000-02-07Per Hedbor 
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  if(SETJMP(tmp2))
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  {
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  ONERROR tmp; struct svalue zero; SET_ONERROR(tmp,exit_on_error,"Error in store_constant in compiler!"); assign_svalue_no_free(sp++, & throw_value); APPLY_MASTER("handle_error", 1); pop_stack(); UNSET_ONERROR(tmp);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  yyerror("Couldn't store constant.");
454d541999-09-18Fredrik Hübinette (Hubbe) 
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  zero.type = T_INT; zero.subtype = NUMBER_NUMBER; zero.u.integer=0;
6bee1c1999-12-14Fredrik Hübinette (Hubbe)  UNSETJMP(tmp2);
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  return store_constant(&zero, equal, constant_name); }else{ for(e=0;e<new_program->num_constants;e++) { struct program_constant *c= new_program->constants+e; if((equal ? is_equal(& c->sval,foo) : is_eq(& c->sval,foo)) && c->name == constant_name) { UNSETJMP(tmp2); return e; } } assign_svalue_no_free(&tmp.sval,foo); if((tmp.name=constant_name)) add_ref(constant_name);
27ae842000-02-07Per Hedbor 
5d3fd91999-12-14Fredrik Hübinette (Hubbe)  add_to_constants(tmp); UNSETJMP(tmp2); return e; }
5267b71995-08-09Fredrik Hübinette (Hubbe) } /*
a36d821998-05-25Henrik Grubbström (Grubba)  * program examination functions available from Pike. */ struct array *program_indices(struct program *p) { int e; int n = 0; struct array *res; for (e = p->num_identifier_references; e--; ) { struct identifier *id; if (p->identifier_references[e].id_flags & ID_HIDDEN) { continue; } id = ID_FROM_INT(p, e); if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) { ref_push_string(ID_FROM_INT(p, e)->name); n++; } } f_aggregate(n); res = sp[-1].u.array; add_ref(res); pop_stack(); return(res); } struct array *program_values(struct program *p) { int e; int n = 0; struct array *res; for(e = p->num_identifier_references; e--; ) { struct identifier *id; if (p->identifier_references[e].id_flags & ID_HIDDEN) { continue; } id = ID_FROM_INT(p, e); if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) { struct program *p2 = PROG_FROM_INT(p, e);
454d541999-09-18Fredrik Hübinette (Hubbe)  push_svalue( & p2->constants[id->func.offset].sval);
a36d821998-05-25Henrik Grubbström (Grubba)  n++; } } f_aggregate(n); res = sp[-1].u.array; add_ref(res); pop_stack(); return(res); }
e435831998-05-25Henrik Grubbström (Grubba) void program_index_no_free(struct svalue *to, struct program *p, struct svalue *ind) { int e; struct pike_string *s; if (ind->type != T_STRING) { error("Can't index a program with a %s (expected string)\n", get_name_of_type(ind->type)); } s = ind->u.string;
1994251999-09-06Fredrik Hübinette (Hubbe)  e=find_shared_string_identifier(s, p); if(e!=-1) { struct identifier *id; id=ID_FROM_INT(p, e);
e435831998-05-25Henrik Grubbström (Grubba)  if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) { struct program *p2 = PROG_FROM_INT(p, e);
454d541999-09-18Fredrik Hübinette (Hubbe)  assign_svalue_no_free(to, ( & p2->constants[id->func.offset].sval));
e435831998-05-25Henrik Grubbström (Grubba)  return; } else { if (s->len < 1024) {
60fbcb1999-05-01Henrik Grubbström (Grubba)  error("Index \"%s\" is not constant.\n", s->str);
e435831998-05-25Henrik Grubbström (Grubba)  } else {
60fbcb1999-05-01Henrik Grubbström (Grubba)  error("Index is not constant.\n");
e435831998-05-25Henrik Grubbström (Grubba)  } } }
1994251999-09-06Fredrik Hübinette (Hubbe)  #if 1 to->type=T_INT; to->subtype=NUMBER_UNDEFINED; to->u.integer=0; #else
e435831998-05-25Henrik Grubbström (Grubba)  if (s->len < 1024) {
60fbcb1999-05-01Henrik Grubbström (Grubba)  error("No such index \"%s\".\n", s->str);
e435831998-05-25Henrik Grubbström (Grubba)  } else {
60fbcb1999-05-01Henrik Grubbström (Grubba)  error("No such index.\n");
e435831998-05-25Henrik Grubbström (Grubba)  }
1994251999-09-06Fredrik Hübinette (Hubbe) #endif
e435831998-05-25Henrik Grubbström (Grubba) }
a36d821998-05-25Henrik Grubbström (Grubba) /*
5267b71995-08-09Fredrik Hübinette (Hubbe)  * Line number support routines, now also tells what file we are in */
1016021999-10-28Fredrik Hübinette (Hubbe) 
58ef5e1999-10-19Fredrik Hübinette (Hubbe) int get_small_number(char **q)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
bd2eee2000-03-28Fredrik Hübinette (Hubbe)  /* This is a workaround for buggy cc & Tru64 */
5267b71995-08-09Fredrik Hübinette (Hubbe)  int ret;
bd2eee2000-03-28Fredrik Hübinette (Hubbe)  ret=*(signed char *)*q; (*q)++; switch(ret)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { case -127: ret=EXTRACT_WORD((unsigned char*)*q); *q+=2; return ret; case -128: ret=EXTRACT_INT((unsigned char*)*q); *q+=4; return ret; default: return ret; } } void start_line_numbering(void) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(last_file)
ea32c11998-04-13Henrik Grubbström (Grubba)  { free_string(last_file); last_file=0; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  last_pc=last_line=0; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) static void insert_small_number(INT32 a)
5267b71995-08-09Fredrik Hübinette (Hubbe) { if(a>-127 && a<127) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_linenumbers(a);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else if(a>=-32768 && a<32768){
aeeef31998-01-16Fredrik Hübinette (Hubbe)  add_to_linenumbers(-127);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  ins_short(a, add_to_linenumbers);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_linenumbers(-128); ins_int(a, add_to_linenumbers);
27ae842000-02-07Per Hedbor  }
5267b71995-08-09Fredrik Hübinette (Hubbe) }
06983f1996-09-22Fredrik Hübinette (Hubbe) void store_linenumber(INT32 current_line, struct pike_string *current_file)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
1016021999-10-28Fredrik Hübinette (Hubbe) /* if(!store_linenumbers) fatal("Fnord.\n"); */ #ifdef PIKE_DEBUG if(d_flag) { INT32 line=0, off=0; char *file=0; char *cnt=new_program->linenumbers; while(cnt < new_program->linenumbers + new_program->num_linenumbers) { if(*cnt == 127) { file=cnt+1; cnt=file+strlen(file)+1; } off+=get_small_number(&cnt); line+=get_small_number(&cnt); }
27ae842000-02-07Per Hedbor 
1016021999-10-28Fredrik Hübinette (Hubbe)  if(last_line != line || last_pc != off || (last_file && file && strcmp(last_file->str, file))) { fatal("Line numbering out of whack\n" " (line: %d ?= %d)!\n" " ( pc: %d ?= %d)!\n" " (file: %s ?= %s)!\n", last_line, line, last_pc, off, last_file?last_file->str:"N/A", file?file:"N/A"); } } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(last_line!=current_line || last_file != current_file) { if(last_file != current_file) { char *tmp; if(last_file) free_string(last_file);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  add_to_linenumbers(127); for(tmp=current_file->str; *tmp; tmp++) add_to_linenumbers(*tmp); add_to_linenumbers(0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  copy_shared_string(last_file, current_file); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  insert_small_number(PC-last_pc); insert_small_number(current_line-last_line);
5267b71995-08-09Fredrik Hübinette (Hubbe)  last_line=current_line; last_pc=PC; } } /* * return the file in which we were executing. * pc should be the program counter, prog the current * program, and line will be initialized to the line * in that file. */ char *get_line(unsigned char *pc,struct program *prog,INT32 *linep) {
9e52381998-03-01Fredrik Hübinette (Hubbe)  static char *file, *cnt; static INT32 off,line,pid; INT32 offset;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5683de1995-11-06Fredrik Hübinette (Hubbe)  if (prog == 0) return "Unkown program";
5267b71995-08-09Fredrik Hübinette (Hubbe)  offset = pc - prog->program;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(prog == new_program)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { linep[0]=0; return "Optimizer"; }
45f9931998-04-28Fredrik Hübinette (Hubbe) #if 0
9e52381998-03-01Fredrik Hübinette (Hubbe)  if(prog->id != pid || offset < off)
45f9931998-04-28Fredrik Hübinette (Hubbe) #endif
9e52381998-03-01Fredrik Hübinette (Hubbe)  { cnt=prog->linenumbers; off=line=0; file="Line not found"; pid=prog->id; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if (offset > (INT32)prog->num_program || offset<0) return file;
5267b71995-08-09Fredrik Hübinette (Hubbe)  while(cnt < prog->linenumbers + prog->num_linenumbers) {
f0c3d31998-04-05Fredrik Hübinette (Hubbe)  int oline;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(*cnt == 127) { file=cnt+1; cnt=file+strlen(file)+1; } off+=get_small_number(&cnt);
f0c3d31998-04-05Fredrik Hübinette (Hubbe)  oline=line;
5267b71995-08-09Fredrik Hübinette (Hubbe)  line+=get_small_number(&cnt);
f0c3d31998-04-05Fredrik Hübinette (Hubbe)  if(off > offset) { linep[0]=oline; return file; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  } linep[0]=line; return file; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void my_yyerror(char *fmt,...) ATTRIBUTE((format(printf,1,2)))
5267b71995-08-09Fredrik Hübinette (Hubbe) { va_list args;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  char buf[8192];
52cf141998-05-15Henrik Grubbström (Grubba) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  va_start(args,fmt);
52cf141998-05-15Henrik Grubbström (Grubba)  #ifdef HAVE_VSNPRINTF vsnprintf(buf, 8190, fmt, args); #else /* !HAVE_VSNPRINTF */ VSPRINTF(buf, fmt, args); #endif /* HAVE_VSNPRINTF */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
197d171996-05-16Fredrik Hübinette (Hubbe)  if((long)strlen(buf) >= (long)sizeof(buf))
8780ce1998-04-19Per Hedbor  fatal("Buffer overflow in my_yyerror.\n");
5267b71995-08-09Fredrik Hübinette (Hubbe)  yyerror(buf); va_end(args); }
d555692000-03-10Fredrik Hübinette (Hubbe) struct program *compile(struct pike_string *prog, struct object *handler)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
0f19431999-11-29Fredrik Hübinette (Hubbe)  ONERROR tmp;
0ee27b1998-04-14Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct program *p;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  struct lex save_lex; int save_depth=compilation_depth;
e0837a1999-07-01Fredrik Hübinette (Hubbe)  int saved_threads_disabled;
10e16f1999-11-04Henrik Grubbström (Grubba)  struct object *saved_handler = error_handler;
05590d1998-04-23Fredrik Hübinette (Hubbe)  dynamic_buffer used_modules_save = used_modules; INT32 num_used_modules_save = num_used_modules;
acbf0a1999-02-20Henrik Grubbström (Grubba)  extern void yyparse(void);
de27f01999-12-28Martin Stjernholm  struct mapping *resolve_cache_save = resolve_cache; resolve_cache = 0;
0ee27b1998-04-14Fredrik Hübinette (Hubbe) 
e0837a1999-07-01Fredrik Hübinette (Hubbe)  CDFPRINTF((stderr, "th(%ld) compile() starting compilation_depth=%d\n", (long)th_self(),compilation_depth));
10e16f1999-11-04Henrik Grubbström (Grubba)  error_handler = handler;
d555692000-03-10Fredrik Hübinette (Hubbe)  if(error_handler) { /* FIXME: support '#Pike 0.6' here */ apply(error_handler,"get_default_module",0); if(IS_ZERO(sp-1)) { pop_stack(); ref_push_mapping(get_builtin_constants()); } }else{ ref_push_mapping(get_builtin_constants()); }
10e16f1999-11-04Henrik Grubbström (Grubba) 
e0837a1999-07-01Fredrik Hübinette (Hubbe)  low_init_threads_disable(); saved_threads_disabled = threads_disabled;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
0f19431999-11-29Fredrik Hübinette (Hubbe)  SET_ONERROR(tmp, fatal_on_error,"Compiler exited with longjump!\n");
0ee27b1998-04-14Fredrik Hübinette (Hubbe) #endif
624d091996-02-24Fredrik Hübinette (Hubbe) 
05590d1998-04-23Fredrik Hübinette (Hubbe)  num_used_modules=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  save_lex=lex;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
acbf0a1999-02-20Henrik Grubbström (Grubba)  lex.end = prog->str + (prog->len << prog->size_shift); switch(prog->size_shift) { case 0: lex.current_lexer = yylex0; break; case 1: lex.current_lexer = yylex1; break; case 2: lex.current_lexer = yylex2; break; default: fatal("Program has bad shift %d!\n", prog->size_shift); break; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  lex.current_line=1; lex.current_file=make_shared_string("-");
ad9ef11999-12-13Henrik Grubbström (Grubba)  if (runtime_options & RUNTIME_STRICT_TYPES) {
fdb0121999-12-05Henrik Grubbström (Grubba)  lex.pragmas = ID_STRICT_TYPES; } else { lex.pragmas = 0; }
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
993ba72000-02-15Fredrik Hübinette (Hubbe)  low_start_new_program(0,0,0,0);
4d7b181999-12-07Fredrik Hübinette (Hubbe)  initialize_buf(&used_modules);
d555692000-03-10Fredrik Hübinette (Hubbe)  use_module(sp-1);
4d7b181999-12-07Fredrik Hübinette (Hubbe) 
bcd5741999-03-17Fredrik Hübinette (Hubbe)  if(lex.current_file)
8975b81999-10-18Fredrik Hübinette (Hubbe)  { store_linenumber(lex.current_line, lex.current_file); debug_malloc_name(new_program, lex.current_file->str, lex.current_line); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  compilation_depth=0;
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
45f9931998-04-28Fredrik Hübinette (Hubbe) /* start_line_numbering(); */
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  compiler_pass=1; lex.pos=prog->str;
0ee27b1998-04-14Fredrik Hübinette (Hubbe) 
f06a821999-07-02Henrik Grubbström (Grubba)  CDFPRINTF((stderr, "compile(): First pass\n"));
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  yyparse(); /* Parse da program */
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  p=end_first_pass(0);
aed42d1999-12-29Martin Stjernholm 
76fb831999-07-01Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
aed42d1999-12-29Martin Stjernholm  if (compilation_depth != -1) { fprintf(stderr, "compile(): compilation_depth is %d at end of pass 1.\n", compilation_depth); }
76fb831999-07-01Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
aed42d1999-12-29Martin Stjernholm  if(p) {
993ba72000-02-15Fredrik Hübinette (Hubbe)  low_start_new_program(p,0,0,0);
61e9a01998-01-25Fredrik Hübinette (Hubbe)  free_program(p); p=0;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  compiler_pass=2; lex.pos=prog->str;
f06a821999-07-02Henrik Grubbström (Grubba) 
d555692000-03-10Fredrik Hübinette (Hubbe)  use_module(sp-1);
4d7b181999-12-07Fredrik Hübinette (Hubbe) 
f06a821999-07-02Henrik Grubbström (Grubba)  CDFPRINTF((stderr, "compile(): Second pass\n"));
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  yyparse(); /* Parse da program again */ p=end_program();
aed42d1999-12-29Martin Stjernholm  #ifdef PIKE_DEBUG if (compilation_depth != -1) { fprintf(stderr, "compile(): compilation_depth is %d at end of pass 2.\n", compilation_depth); } #endif /* PIKE_DEBUG */
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
e0837a1999-07-01Fredrik Hübinette (Hubbe)  if (threads_disabled != saved_threads_disabled) {
4751d41998-04-14Henrik Grubbström (Grubba)  fatal("compile(): threads_disabled:%d saved_threads_disabled:%d\n", threads_disabled, saved_threads_disabled); }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #endif /* PIKE_DEBUG */
e0837a1999-07-01Fredrik Hübinette (Hubbe) /* threads_disabled = saved_threads_disabled + 1; /Hubbe: UGGA! */
b6f8c31999-07-01Henrik Grubbström (Grubba)  CDFPRINTF((stderr,
e0837a1999-07-01Fredrik Hübinette (Hubbe)  "th(%ld) compile() Leave: threads_disabled:%d, compilation_depth:%d\n", (long)th_self(),threads_disabled, compilation_depth));
a91ca01998-07-10Henrik Grubbström (Grubba)  exit_threads_disable(NULL);
ea32c11998-04-13Henrik Grubbström (Grubba) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  free_string(lex.current_file); lex=save_lex;
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
4d7b181999-12-07Fredrik Hübinette (Hubbe) /* unuse_modules(1); */
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(num_used_modules) fatal("Failed to pop modules properly.\n"); #endif toss_buffer(&used_modules);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  compilation_depth=save_depth;
05590d1998-04-23Fredrik Hübinette (Hubbe)  used_modules = used_modules_save; num_used_modules = num_used_modules_save ;
10e16f1999-11-04Henrik Grubbström (Grubba)  error_handler = saved_handler;
aed42d1999-12-29Martin Stjernholm #ifdef PIKE_DEBUG if (resolve_cache) fatal("resolve_cache not freed at end of compilation.\n"); #endif
de27f01999-12-28Martin Stjernholm  resolve_cache = resolve_cache_save;
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
0f19431999-11-29Fredrik Hübinette (Hubbe)  UNSET_ONERROR(tmp);
0ee27b1998-04-14Fredrik Hübinette (Hubbe) #endif
d555692000-03-10Fredrik Hübinette (Hubbe)  pop_stack(); /* pop the 'default' module */
0ee27b1998-04-14Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!p) error("Compilation failed.\n"); return p; }
0542ef1999-11-17Fredrik Hübinette (Hubbe) int pike_add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
e964ae1998-04-08Fredrik Hübinette (Hubbe)  int ret;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *name_tmp,*type_tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  union idptr tmp;
27ae842000-02-07Per Hedbor 
5267b71995-08-09Fredrik Hübinette (Hubbe)  name_tmp=make_shared_string(name); type_tmp=parse_type(type); if(cfun) { tmp.c_fun=cfun;
e964ae1998-04-08Fredrik Hübinette (Hubbe)  ret=define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION, &tmp);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
e964ae1998-04-08Fredrik Hübinette (Hubbe)  ret=define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION, 0);
5267b71995-08-09Fredrik Hübinette (Hubbe)  } free_string(name_tmp); free_string(type_tmp);
e964ae1998-04-08Fredrik Hübinette (Hubbe)  return ret;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
45ee5d1999-02-10Fredrik Hübinette (Hubbe) int quick_add_function(char *name, int name_length, void (*cfun)(INT32), char *type, int type_length, INT16 flags, int opt_flags) { int ret; struct pike_string *name_tmp,*type_tmp; union idptr tmp;
8aae6d1999-08-19Fredrik Hübinette (Hubbe) /* fprintf(stderr,"ADD_FUNC: %s\n",name); */
45ee5d1999-02-10Fredrik Hübinette (Hubbe)  name_tmp=make_shared_binary_string(name,name_length); type_tmp=make_shared_binary_string(type,type_length); if(cfun) { tmp.c_fun=cfun; ret=define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION, &tmp); }else{ ret=define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION, 0); } free_string(name_tmp); free_string(type_tmp); return ret; }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
be478c1997-08-30Henrik Grubbström (Grubba) void check_all_programs(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { struct program *p; for(p=first_program;p;p=p->next)
624d091996-02-24Fredrik Hübinette (Hubbe)  check_program(p);
5d0e211997-04-10Fredrik Hübinette (Hubbe)  #ifdef FIND_FUNCTION_HASHSIZE { unsigned long e; for(e=0;e<FIND_FUNCTION_HASHSIZE;e++) { if(cache[e].name) { check_string(cache[e].name); if(cache[e].id<0 || cache[e].id > current_program_id)
1f64351997-04-14Fredrik Hübinette (Hubbe)  fatal("Error in find_function_cache[%ld].id\n",(long)e);
5d0e211997-04-10Fredrik Hübinette (Hubbe) 
d2a0841997-04-10Fredrik Hübinette (Hubbe)  if(cache[e].fun < -1 || cache[e].fun > 65536)
1f64351997-04-14Fredrik Hübinette (Hubbe)  fatal("Error in find_function_cache[%ld].fun\n",(long)e);
5d0e211997-04-10Fredrik Hübinette (Hubbe)  } } } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) } #endif
90e9781999-01-31Fredrik Hübinette (Hubbe) #undef THIS
60d9872000-03-23Fredrik Hübinette (Hubbe) #define THIS ((struct pike_trampoline *)(CURRENT_STORAGE))
4218011999-01-31Fredrik Hübinette (Hubbe) struct program *pike_trampoline_program=0; static void apply_trampoline(INT32 args) { error("Internal error: Trampoline magic failed!\n"); }
90e9781999-01-31Fredrik Hübinette (Hubbe) static void init_trampoline(struct object *o) { THIS->frame=0; } static void exit_trampoline(struct object *o) { if(THIS->frame) { free_pike_frame(THIS->frame); THIS->frame=0; } } static void gc_check_frame(struct pike_frame *f) { if(!f) return; if(!debug_gc_check(f,T_UNKNOWN,f) && f->malloced_locals) { if(f->current_object) gc_check(f->current_object); if(f->context.prog) gc_check(f->context.prog); if(f->context.parent) gc_check(f->context.parent); gc_check_svalues(f->locals,f->num_locals); if(f->scope) gc_check_frame(f->scope); } } static void gc_check_trampoline(struct object *o) { gc_check_frame(THIS->frame); } static void gc_mark_frame(struct pike_frame *f) { if(!f) return; if(gc_mark(f)) { if(f->current_object) gc_mark_object_as_referenced(f->current_object); if(f->context.prog) gc_mark_program_as_referenced(f->context.prog); if(f->context.parent) gc_mark_object_as_referenced(f->context.parent); if(f->malloced_locals)gc_mark_svalues(f->locals,f->num_locals); if(f->scope) gc_mark_frame(f->scope); } } static void gc_mark_trampoline(struct object *o) { gc_mark_frame(THIS->frame); }
4218011999-01-31Fredrik Hübinette (Hubbe) void init_program(void) {
51059b1999-12-26Henrik Grubbström (Grubba)  int i; struct svalue key; struct svalue val;
9e26861999-12-31Martin Stjernholm  MAKE_CONSTANT_SHARED_STRING(this_program_string,"this_program");
51059b1999-12-26Henrik Grubbström (Grubba)  lfun_types = allocate_mapping(NUM_LFUNS); key.type = T_STRING; val.type = T_TYPE; for (i=0; i < NUM_LFUNS; i++) { key.u.string = make_shared_string(lfun_names[i]); val.u.string = make_pike_type(raw_lfun_types[i]); mapping_insert(lfun_types, &key, &val); free_string(val.u.string); free_string(key.u.string); }
4218011999-01-31Fredrik Hübinette (Hubbe)  start_new_program();
90e9781999-01-31Fredrik Hübinette (Hubbe)  ADD_STORAGE(struct pike_trampoline);
4218011999-01-31Fredrik Hübinette (Hubbe)  add_function("`()",apply_trampoline,"function(mixed...:mixed)",0);
90e9781999-01-31Fredrik Hübinette (Hubbe)  set_init_callback(init_trampoline); set_exit_callback(exit_trampoline); set_gc_check_callback(gc_check_trampoline); set_gc_mark_callback(gc_mark_trampoline);
4218011999-01-31Fredrik Hübinette (Hubbe)  pike_trampoline_program=end_program(); }
be478c1997-08-30Henrik Grubbström (Grubba) void cleanup_program(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int e;
51059b1999-12-26Henrik Grubbström (Grubba) 
9e26861999-12-31Martin Stjernholm  free_string(this_program_string);
51059b1999-12-26Henrik Grubbström (Grubba)  free_mapping(lfun_types);
61e9a01998-01-25Fredrik Hübinette (Hubbe) #ifdef FIND_FUNCTION_HASHSIZE
5267b71995-08-09Fredrik Hübinette (Hubbe)  for(e=0;e<FIND_FUNCTION_HASHSIZE;e++) { if(cache[e].name) { free_string(cache[e].name); cache[e].name=0; } } #endif
ae95031999-04-07Fredrik Hübinette (Hubbe)  #ifdef DO_PIKE_CLEANUP
05590d1998-04-23Fredrik Hübinette (Hubbe)  if(resolve_cache) {
aed42d1999-12-29Martin Stjernholm  free_mapping(dmalloc_touch (struct mapping *, resolve_cache));
05590d1998-04-23Fredrik Hübinette (Hubbe)  resolve_cache=0; }
4218011999-01-31Fredrik Hübinette (Hubbe)  if(pike_trampoline_program) { free_program(pike_trampoline_program); pike_trampoline_program=0; }
ae95031999-04-07Fredrik Hübinette (Hubbe) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) }
624d091996-02-24Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #ifdef GC2
c94c371996-03-28Fredrik Hübinette (Hubbe) void gc_mark_program_as_referenced(struct program *p)
624d091996-02-24Fredrik Hübinette (Hubbe) {
c94c371996-03-28Fredrik Hübinette (Hubbe)  if(gc_mark(p))
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  { int e;
454d541999-09-18Fredrik Hübinette (Hubbe)  for(e=0;e<p->num_constants;e++) gc_mark_svalues(& p->constants[e].sval, 1);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  for(e=0;e<p->num_inherits;e++) { if(p->inherits[e].parent) gc_mark_object_as_referenced(p->inherits[e].parent);
6be8a81998-10-22Fredrik Hübinette (Hubbe)  if(e && p->inherits[e].prog)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  gc_mark_program_as_referenced(p->inherits[e].prog); }
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
624d091996-02-24Fredrik Hübinette (Hubbe) }
be478c1997-08-30Henrik Grubbström (Grubba) void gc_check_all_programs(void)
624d091996-02-24Fredrik Hübinette (Hubbe) {
c94c371996-03-28Fredrik Hübinette (Hubbe)  struct program *p;
c254851999-10-24Henrik Grubbström (Grubba)  for(p=first_program;p;p=p->next)
9367351997-01-27Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  int e;
aa73fc1999-10-21Fredrik Hübinette (Hubbe) 
c254851999-10-24Henrik Grubbström (Grubba)  debug_malloc_touch(p);
aa73fc1999-10-21Fredrik Hübinette (Hubbe) 
fc046a1999-10-22Henrik Grubbström (Grubba)  for(e=0;e<p->num_constants;e++) {
454d541999-09-18Fredrik Hübinette (Hubbe)  debug_gc_check_svalues(& p->constants[e].sval, 1, T_PROGRAM, p);
fc046a1999-10-22Henrik Grubbström (Grubba)  }
9367351997-01-27Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  for(e=0;e<p->num_inherits;e++) { if(p->inherits[e].parent) {
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
0b69441998-01-19Fredrik Hübinette (Hubbe)  if(debug_gc_check(p->inherits[e].parent,T_PROGRAM,p)==-2)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  fprintf(stderr,"(program at 0x%lx -> inherit[%d].parent)\n", (long)p, e); #else
0b69441998-01-19Fredrik Hübinette (Hubbe)  debug_gc_check(p->inherits[e].parent, T_PROGRAM, p);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif } if(d_flag && p->inherits[e].name)
0b69441998-01-19Fredrik Hübinette (Hubbe)  debug_gc_check(p->inherits[e].name, T_PROGRAM, p);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
6be8a81998-10-22Fredrik Hübinette (Hubbe)  if(e && p->inherits[e].prog)
0b69441998-01-19Fredrik Hübinette (Hubbe)  debug_gc_check(p->inherits[e].prog, T_PROGRAM, p);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
9367351997-01-27Fredrik Hübinette (Hubbe)  if(d_flag) { int e; for(e=0;e<(int)p->num_strings;e++)
0b69441998-01-19Fredrik Hübinette (Hubbe)  debug_gc_check(p->strings[e], T_PROGRAM, p);
9367351997-01-27Fredrik Hübinette (Hubbe)  for(e=0;e<(int)p->num_identifiers;e++) {
0b69441998-01-19Fredrik Hübinette (Hubbe)  debug_gc_check(p->identifiers[e].name, T_PROGRAM, p); debug_gc_check(p->identifiers[e].type, T_PROGRAM, p);
9367351997-01-27Fredrik Hübinette (Hubbe)  } }
0b69441998-01-19Fredrik Hübinette (Hubbe) #endif
9367351997-01-27Fredrik Hübinette (Hubbe)  }
c94c371996-03-28Fredrik Hübinette (Hubbe) }
be478c1997-08-30Henrik Grubbström (Grubba) void gc_mark_all_programs(void)
c94c371996-03-28Fredrik Hübinette (Hubbe) { struct program *p; for(p=first_program;p;p=p->next) if(gc_is_referenced(p)) gc_mark_program_as_referenced(p); }
be478c1997-08-30Henrik Grubbström (Grubba) void gc_free_all_unreferenced_programs(void)
c94c371996-03-28Fredrik Hübinette (Hubbe) { struct program *p,*next;
624d091996-02-24Fredrik Hübinette (Hubbe)  for(p=first_program;p;p=next) {
c94c371996-03-28Fredrik Hübinette (Hubbe)  if(gc_do_free(p))
624d091996-02-24Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  int e;
8c83371998-04-16Fredrik Hübinette (Hubbe)  add_ref(p);
454d541999-09-18Fredrik Hübinette (Hubbe)  for(e=0;e<p->num_constants;e++) free_svalue(& p->constants[e].sval);
3d83892000-02-22Fredrik Hübinette (Hubbe)  p->num_constants=0; /* evil */
454d541999-09-18Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  for(e=0;e<p->num_inherits;e++) { if(p->inherits[e].parent) { free_object(p->inherits[e].parent); p->inherits[e].parent=0; } }
3d83892000-02-22Fredrik Hübinette (Hubbe)  /* FIXME: Is there anything else that needs to be freed here? */
69ee4b2000-04-06Fredrik Hübinette (Hubbe)  SET_NEXT_AND_FREE(p, free_program);
624d091996-02-24Fredrik Hübinette (Hubbe)  }else{ next=p->next; } } }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #endif /* GC2 */
c3c7031996-12-04Fredrik Hübinette (Hubbe)  void count_memory_in_programs(INT32 *num_, INT32 *size_) { INT32 size=0, num=0; struct program *p; for(p=first_program;p;p=p->next) { num++; size+=p->total_size; } *num_=num; *size_=size; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
4218011999-01-31Fredrik Hübinette (Hubbe) void push_compiler_frame(int lexical_scope)
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) { struct compiler_frame *f; f=ALLOC_STRUCT(compiler_frame);
4218011999-01-31Fredrik Hübinette (Hubbe)  f->lexical_scope=lexical_scope;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  f->current_type=0; f->current_return_type=0; f->current_number_of_locals=0; f->max_number_of_locals=0; f->previous=compiler_frame; compiler_frame=f; } void pop_local_variables(int level)
329cc01997-02-17Fredrik Hübinette (Hubbe) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  while(compiler_frame->current_number_of_locals > level) { int e; e=--(compiler_frame->current_number_of_locals); free_string(compiler_frame->variable[e].name); free_string(compiler_frame->variable[e].type);
a566ca1999-12-14Fredrik Hübinette (Hubbe)  if(compiler_frame->variable[e].def) free_node(compiler_frame->variable[e].def);
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  }
329cc01997-02-17Fredrik Hübinette (Hubbe) }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  void pop_compiler_frame(void)
329cc01997-02-17Fredrik Hübinette (Hubbe) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  struct compiler_frame *f; int e; f=compiler_frame;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(!f) fatal("Popping out of compiler frames\n"); #endif
329cc01997-02-17Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  pop_local_variables(0); if(f->current_type) free_string(f->current_type);
27ae842000-02-07Per Hedbor 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(f->current_return_type) free_string(f->current_return_type); compiler_frame=f->previous;
424d9c1999-05-02Fredrik Hübinette (Hubbe)  dmfree((char *)f);
329cc01997-02-17Fredrik Hübinette (Hubbe) }
cff0d71997-03-23Fredrik Hübinette (Hubbe)  #define GET_STORAGE_CACHE_SIZE 1024 static struct get_storage_cache { INT32 oid, pid, offset; } get_storage_cache[GET_STORAGE_CACHE_SIZE];
6bc9281998-04-10Fredrik Hübinette (Hubbe) int low_get_storage(struct program *o, struct program *p)
cff0d71997-03-23Fredrik Hübinette (Hubbe) { INT32 oid,pid, offset; unsigned INT32 hval;
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if(!o) return 0; oid=o->id;
cff0d71997-03-23Fredrik Hübinette (Hubbe)  pid=p->id;
535d171997-09-11Fredrik Hübinette (Hubbe)  hval=oid*9248339 + pid;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  hval%=GET_STORAGE_CACHE_SIZE;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
535d171997-09-11Fredrik Hübinette (Hubbe)  if(hval>GET_STORAGE_CACHE_SIZE) fatal("hval>GET_STORAGE_CACHE_SIZE"); #endif
cff0d71997-03-23Fredrik Hübinette (Hubbe)  if(get_storage_cache[hval].oid == oid && get_storage_cache[hval].pid == pid) { offset=get_storage_cache[hval].offset; }else{ INT32 e; offset=-1;
6bc9281998-04-10Fredrik Hübinette (Hubbe)  for(e=0;e<o->num_inherits;e++)
cff0d71997-03-23Fredrik Hübinette (Hubbe)  {
6bc9281998-04-10Fredrik Hübinette (Hubbe)  if(o->inherits[e].prog==p)
cff0d71997-03-23Fredrik Hübinette (Hubbe)  {
6bc9281998-04-10Fredrik Hübinette (Hubbe)  offset=o->inherits[e].storage_offset;
cff0d71997-03-23Fredrik Hübinette (Hubbe)  break; } } get_storage_cache[hval].oid=oid; get_storage_cache[hval].pid=pid; get_storage_cache[hval].offset=offset; }
6bc9281998-04-10Fredrik Hübinette (Hubbe)  return offset; } char *get_storage(struct object *o, struct program *p) {
b8896b2000-02-10Fredrik Hübinette (Hubbe)  int offset; #ifdef _REENTRANT #ifndef __NT__ if(d_flag) if(!mt_trylock(& interpreter_lock)) fatal("get_storage running unlocked!\n"); #endif #endif offset= low_get_storage(o->prog, p);
cff0d71997-03-23Fredrik Hübinette (Hubbe)  if(offset == -1) return 0; return o->storage + offset; }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  struct program *low_program_from_function(struct program *p, INT32 i) { struct svalue *f; struct identifier *id=ID_FROM_INT(p, i); if(!IDENTIFIER_IS_CONSTANT(id->identifier_flags)) return 0; if(id->func.offset==-1) return 0;
454d541999-09-18Fredrik Hübinette (Hubbe)  f=& PROG_FROM_INT(p,i)->constants[id->func.offset].sval;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(f->type!=T_PROGRAM) return 0; return f->u.program; } struct program *program_from_function(struct svalue *f) { struct identifier *id; if(f->type != T_FUNCTION) return 0; if(f->subtype == FUNCTION_BUILTIN) return 0; if(!f->u.object->prog) return 0; return low_program_from_function(f->u.object->prog, f->subtype); } struct program *program_from_svalue(struct svalue *s) { switch(s->type) {
bcf9461998-01-27Fredrik Hübinette (Hubbe)  case T_OBJECT: {
aceb8c1999-11-22Henrik Grubbström (Grubba)  struct program *p = s->u.object->prog; int call_fun; if (!p) return 0;
fdb0121999-12-05Henrik Grubbström (Grubba)  if ((call_fun = FIND_LFUN(p, LFUN_CALL)) >= 0) { /* Get the program from the return type. */ struct identifier *id = ID_FROM_INT(p, call_fun); /* FIXME: do it. */ /* fprintf(stderr, "Object type has `()().\n"); */ return 0;
aceb8c1999-11-22Henrik Grubbström (Grubba)  }
bcf9461998-01-27Fredrik Hübinette (Hubbe)  push_svalue(s); f_object_program(1); p=program_from_svalue(sp-1); pop_stack(); return p; /* We trust that there is a reference somewhere... */ }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case T_FUNCTION: return program_from_function(s); case T_PROGRAM: return s->u.program; default: return 0; } } #define FIND_CHILD_HASHSIZE 5003 struct find_child_cache_s { INT32 pid,cid,id; }; static struct find_child_cache_s find_child_cache[FIND_CHILD_HASHSIZE]; int find_child(struct program *parent, struct program *child) {
939b181998-07-17Fredrik Hübinette (Hubbe)  unsigned INT32 h=(parent->id * 9248339 + child->id); h= h % FIND_CHILD_HASHSIZE;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
939b181998-07-17Fredrik Hübinette (Hubbe)  if(h>=FIND_CHILD_HASHSIZE) fatal("find_child failed to hash within boundaries.\n");
27ae842000-02-07Per Hedbor #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(find_child_cache[h].pid == parent->id && find_child_cache[h].cid == child->id) { return find_child_cache[h].id; }else{ INT32 i; for(i=0;i<parent->num_identifier_references;i++) { if(low_program_from_function(parent, i)==child) { find_child_cache[h].pid=parent->id; find_child_cache[h].cid=child->id; find_child_cache[h].id=i; return i; } } } return -1; } void yywarning(char *fmt, ...) ATTRIBUTE((format(printf,1,2))) { char buf[4711]; va_list args;
e120eb2000-01-14Henrik Grubbström (Grubba)  /* If we have parse errors we might get erroneous warnings, * so don't print them. * This has the additional benefit of making it easier to * visually locate the actual error message. */ if (num_parse_error) return;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  va_start(args,fmt); VSPRINTF(buf, fmt, args); va_end(args); if(strlen(buf)>sizeof(buf)) fatal("Buffer overfloat in yywarning!\n");
10e16f1999-11-04Henrik Grubbström (Grubba)  if ((error_handler && error_handler->prog) || get_master()) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  ref_push_string(lex.current_file); push_int(lex.current_line); push_text(buf);
10e16f1999-11-04Henrik Grubbström (Grubba)  if (error_handler && error_handler->prog) { safe_apply(error_handler, "compile_warning", 3); } else { SAFE_APPLY_MASTER("compile_warning",3); }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  pop_stack(); } }
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  /* returns 1 if a implements b */ static int low_implements(struct program *a, struct program *b) {
c781ab1999-12-13Henrik Grubbström (Grubba)  int e;
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  struct pike_string *s=findstring("__INIT"); for(e=0;e<b->num_identifier_references;e++) {
8170e51999-12-14Henrik Grubbström (Grubba)  struct identifier *bid;
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  int i;
8170e51999-12-14Henrik Grubbström (Grubba)  if (b->identifier_references[e].id_flags & (ID_STATIC|ID_HIDDEN)) continue; /* Skip static & hidden */ bid = ID_FROM_INT(b,e);
c781ab1999-12-13Henrik Grubbström (Grubba)  if(s == bid->name) continue; /* Skip __INIT */ i = find_shared_string_identifier(bid->name,a);
8170e51999-12-14Henrik Grubbström (Grubba)  if (i == -1) {
21b2c91999-12-17Fredrik Hübinette (Hubbe)  if (b->identifier_references[e].id_flags & (ID_OPTIONAL)) continue; /* It's ok... */
8170e51999-12-14Henrik Grubbström (Grubba) #if 0 fprintf(stderr, "Missing identifier \"%s\"\n", bid->name->str); #endif /* 0 */ return 0; }
c781ab1999-12-13Henrik Grubbström (Grubba) 
8170e51999-12-14Henrik Grubbström (Grubba)  if(!match_types(ID_FROM_INT(a,i)->type, bid->type)) { #if 0 fprintf(stderr, "Identifier \"%s\" is incompatible.\n", bid->name->str); #endif /* 0 */
c781ab1999-12-13Henrik Grubbström (Grubba)  return 0;
8170e51999-12-14Henrik Grubbström (Grubba)  }
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  }
c781ab1999-12-13Henrik Grubbström (Grubba)  return 1;
0ee27b1998-04-14Fredrik Hübinette (Hubbe) } #define IMPLEMENTS_CACHE_SIZE 4711 struct implements_cache_s { INT32 aid, bid, ret; }; static struct implements_cache_s implements_cache[IMPLEMENTS_CACHE_SIZE]; /* returns 1 if a implements b, but faster */ int implements(struct program *a, struct program *b) { unsigned long hval; if(!a || !b) return -1; if(a==b) return 1;
636e471998-04-15Fredrik Hübinette (Hubbe) 
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  hval = a->id*9248339 + b->id; hval %= IMPLEMENTS_CACHE_SIZE;
71f3a21998-11-22Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
939b181998-07-17Fredrik Hübinette (Hubbe)  if(hval >= IMPLEMENTS_CACHE_SIZE) fatal("Implements_cache failed!\n"); #endif
0ee27b1998-04-14Fredrik Hübinette (Hubbe)  if(implements_cache[hval].aid==a->id && implements_cache[hval].bid==b->id) { return implements_cache[hval].ret; } /* Do it the tedious way */ implements_cache[hval].aid=a->id; implements_cache[hval].bid=b->id;
636e471998-04-15Fredrik Hübinette (Hubbe)  implements_cache[hval].ret=low_implements(a,b); return implements_cache[hval].ret;
0ee27b1998-04-14Fredrik Hübinette (Hubbe) }
05590d1998-04-23Fredrik Hübinette (Hubbe) 
e774391999-12-31Henrik Grubbström (Grubba) /* Returns 1 if a is compatible with b */ static int low_is_compatible(struct program *a, struct program *b) { int e; struct pike_string *s=findstring("__INIT"); /* Optimize the loop somewhat */ if (a->num_identifier_references < b->num_identifier_references) { struct program *tmp = a; a = b; b = tmp; } for(e=0;e<b->num_identifier_references;e++) { struct identifier *bid; int i; if (b->identifier_references[e].id_flags & (ID_STATIC|ID_HIDDEN)) continue; /* Skip static & hidden */ /* FIXME: What if they aren't static & hidden in a? */ bid = ID_FROM_INT(b,e); if(s == bid->name) continue; /* Skip __INIT */ i = find_shared_string_identifier(bid->name,a); if (i == -1) { continue; /* It's ok... */ } if(!match_types(ID_FROM_INT(a,i)->type, bid->type)) { #if 0 fprintf(stderr, "Identifier \"%s\" is incompatible.\n", bid->name->str); #endif /* 0 */ return 0; } } return 1; } static struct implements_cache_s is_compatible_cache[IMPLEMENTS_CACHE_SIZE]; /* Returns 1 if a is compatible with b * ie it's possible to write a hypothetical c that implements both. */
c4d4401999-12-31Henrik Grubbström (Grubba) int is_compatible(struct program *a, struct program *b)
e774391999-12-31Henrik Grubbström (Grubba) { unsigned long hval; unsigned long rhval; int aid, bid; if(!a || !b) return -1; if(a==b) return 1; /* Order the id's so we don't need double entries in the cache. */ aid = a->id; bid = b->id; if (aid > bid) { int tmp = aid; aid = bid; bid = tmp; } hval = aid*9248339 + bid; hval %= IMPLEMENTS_CACHE_SIZE; #ifdef PIKE_DEBUG if(hval >= IMPLEMENTS_CACHE_SIZE) fatal("Implements_cache failed!\n"); #endif if(is_compatible_cache[hval].aid==aid && is_compatible_cache[hval].bid==bid) { return is_compatible_cache[hval].ret; } if(implements_cache[hval].aid==aid && implements_cache[hval].bid==bid && implements_cache[hval].ret) { /* a implements b */ return 1; } rhval = bid*9248339 + aid; rhval %= IMPLEMENTS_CACHE_SIZE; #ifdef PIKE_DEBUG if(rhval >= IMPLEMENTS_CACHE_SIZE) fatal("Implements_cache failed!\n"); #endif if(implements_cache[rhval].aid==bid && implements_cache[rhval].bid==aid && implements_cache[rhval].ret) { /* b implements a */ return 1; } /* Do it the tedious way */ is_compatible_cache[hval].aid=aid; is_compatible_cache[hval].bid=bid; is_compatible_cache[hval].ret=low_is_compatible(a,b); return is_compatible_cache[hval].ret; }
05590d1998-04-23Fredrik Hübinette (Hubbe) 
20ea771999-12-15Fredrik Hübinette (Hubbe) /* returns 1 if a implements b */
03318e2000-03-16Fredrik Hübinette (Hubbe) int yyexplain_not_implements(struct program *a, struct program *b, int flags)
20ea771999-12-15Fredrik Hübinette (Hubbe) { int e; struct pike_string *s=findstring("__INIT"); for(e=0;e<b->num_identifier_references;e++) { struct identifier *bid; int i; if (b->identifier_references[e].id_flags & (ID_STATIC|ID_HIDDEN)) continue; /* Skip static & hidden */ bid = ID_FROM_INT(b,e); if(s == bid->name) continue; /* Skip __INIT */ i = find_shared_string_identifier(bid->name,a); if (i == -1) {
21b2c91999-12-17Fredrik Hübinette (Hubbe)  if (b->identifier_references[e].id_flags & (ID_OPTIONAL)) continue; /* It's ok... */
03318e2000-03-16Fredrik Hübinette (Hubbe)  if(flags & YYTE_IS_WARNING) yywarning("Missing identifier \"%s\".", bid->name->str); else my_yyerror("Missing identifier \"%s\".", bid->name->str);
20ea771999-12-15Fredrik Hübinette (Hubbe)  return 0; } if(!match_types(ID_FROM_INT(a,i)->type, bid->type)) { struct pike_string *s1,*s2; my_yyerror("Type of identifier dentifier \"%s\" does not match.", bid->name->str); s1=describe_type(ID_FROM_INT(a,i)->type); s2=describe_type(bid->type);
03318e2000-03-16Fredrik Hübinette (Hubbe)  if(flags & YYTE_IS_WARNING) { yywarning("Expected: %s",s1->str); yywarning("Got : %s",s2->str); }else{ my_yyerror("Expected: %s",s1->str); my_yyerror("Got : %s",s2->str); }
20ea771999-12-15Fredrik Hübinette (Hubbe)  free_string(s1); free_string(s2); return 0; } } return 1; }