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. \*/
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) RCSID("$Id: program.c,v 1.28 1997/03/17 03:04:43 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"
8aeeb21996-11-19Fredrik Hübinette (Hubbe)  #include <errno.h>
5267b71995-08-09Fredrik Hübinette (Hubbe) #include <fcntl.h>
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 FILE_STATE #define PROGRAM_STATE #define STRUCT #include "compilation.h" #undef STRUCT #define DECLARE #include "compilation.h" #undef DECLARE #undef FILE_STATE #undef PROGRAM_STATE
5267b71995-08-09Fredrik Hübinette (Hubbe) 
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", "`()",
5580691996-06-21Fredrik Hübinette (Hubbe) };
5267b71995-08-09Fredrik Hübinette (Hubbe) struct program *first_program = 0; struct program fake_program; static int current_program_id=0; static INT32 last_line = 0; static INT32 last_pc = 0;
06983f1996-09-22Fredrik Hübinette (Hubbe) static struct pike_string *last_file = 0;
5267b71995-08-09Fredrik Hübinette (Hubbe) dynamic_buffer inherit_names;
591c0c1997-01-19Fredrik Hübinette (Hubbe) dynamic_buffer used_modules;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5f8eb71997-02-18Fredrik Hübinette (Hubbe) void free_all_local_names(void);
591c0c1997-01-19Fredrik Hübinette (Hubbe) void use_module(struct svalue *s)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
5c0a101997-02-06Fredrik Hübinette (Hubbe)  if( (1<<s->type) & (BIT_MAPPING | BIT_OBJECT)) { assign_svalue_no_free((struct svalue *) low_make_buf_space(sizeof(struct svalue), &used_modules), s); }else{ yyerror("Module is neither mapping nor object"); }
591c0c1997-01-19Fredrik Hübinette (Hubbe) }
b8cda21997-01-21Fredrik Hübinette (Hubbe) static int low_find_shared_string_identifier(struct pike_string *name, struct program *prog);
591c0c1997-01-19Fredrik Hübinette (Hubbe) int find_module_identifier(struct pike_string *ident) { JMP_BUF tmp;
5c0a101997-02-06Fredrik Hübinette (Hubbe) 
591c0c1997-01-19Fredrik Hübinette (Hubbe)  if(SETJMP(tmp)) { 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{ struct svalue *modules=(struct svalue *)used_modules.s.str;
0683be1997-01-26Fredrik Hübinette (Hubbe)  int e=used_modules.s.len / sizeof(struct svalue);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  while(--e>=0) { push_svalue(modules+e); push_string(ident);
0683be1997-01-26Fredrik Hübinette (Hubbe)  ident->refs++;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  f_index(2);
5c0a101997-02-06Fredrik Hübinette (Hubbe)  if(!IS_UNDEFINED(sp-1))
591c0c1997-01-19Fredrik Hübinette (Hubbe)  {
5c0a101997-02-06Fredrik Hübinette (Hubbe) /* fprintf(stderr,"MOD: %s, %d %d\n",ident->str, current_line, sp[-1].type); */
591c0c1997-01-19Fredrik Hübinette (Hubbe)  UNSETJMP(tmp); return 1; }
5c0a101997-02-06Fredrik Hübinette (Hubbe)  pop_stack();
591c0c1997-01-19Fredrik Hübinette (Hubbe)  } } UNSETJMP(tmp);
b8cda21997-01-21Fredrik Hübinette (Hubbe)  { struct program_state *p; for(p=previous_program_state;p;p=p->previous) { INT32 i; if(previous_file_state && previous_file_state->previous_program_state==p->previous) break; i=low_find_shared_string_identifier(ident, &p->fake_program); if(i!=-1) { struct identifier *id; id=ID_FROM_INT(&p->fake_program, i); if(IDENTIFIER_IS_CONSTANT(id->flags)) { push_svalue(PROG_FROM_INT(&p->fake_program, i)->constants+ id->func.offset); return 1; }else{ yyerror("Identifier is not a constant"); return 0; } } } } return 0; } /* This should be optimized */ struct program *id_to_program(INT32 id) { struct program *p; if(id) for(p=first_program;p;p=p->next) if(id==p->id) return p;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  return 0; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  #define SETUP(X,Y,TYPE,AREA) \ fake_program.X=(TYPE *)areas[AREA].s.str; \ fake_program.Y=areas[AREA].s.len/sizeof(TYPE) /* * This routine sets up the struct fake_program to work almost like a * normal program, but all pointers points to the program we are currently * compiling */ void setup_fake_program() { fake_program.refs=0xffffff; SETUP(program, program_size, unsigned char, A_PROGRAM);
06983f1996-09-22Fredrik Hübinette (Hubbe)  SETUP(strings, num_strings, struct pike_string *, A_STRINGS);
5267b71995-08-09Fredrik Hübinette (Hubbe)  SETUP(inherits, num_inherits, struct inherit, A_INHERITS); SETUP(identifiers, num_identifiers, struct identifier, A_IDENTIFIERS); SETUP(identifier_references, num_identifier_references, struct reference, A_IDENTIFIER_REFERENCES); SETUP(constants, num_constants, struct svalue, A_CONSTANTS); SETUP(linenumbers, num_linenumbers, char, A_LINENUMBERS); fake_program.inherits[0].prog=&fake_program; fake_program.next=0; fake_program.prev=0; /* fake_program.lfuns=0; fake_prog.num_lfuns=0; */ fake_object.prog=&fake_program; } /* Here starts routines which are used to build new programs */ /* * Start building a new program */ void start_new_program() { int e;
5c8e891995-10-29Fredrik Hübinette (Hubbe) 
07513e1996-10-04Fredrik Hübinette (Hubbe)  threads_disabled++;
b8cda21997-01-21Fredrik Hübinette (Hubbe)  if(local_variables) setup_fake_program();
5c8e891995-10-29Fredrik Hübinette (Hubbe) #define PROGRAM_STATE #define PUSH #include "compilation.h" #undef PUSH #undef PROGRAM_STATE
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b8cda21997-01-21Fredrik Hübinette (Hubbe)  if(previous_program_state->fake_program.num_inherits) previous_program_state->fake_program.inherits[0].prog= &previous_program_state->fake_program;
36feac1997-03-06Fredrik Hübinette (Hubbe)  init_type_stack();
e43ca21996-11-15Fredrik Hübinette (Hubbe)  for(e=0; e<NUM_AREAS; e++) low_reinit_buf(areas + e); low_reinit_buf(& inherit_names);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  low_reinit_buf(& used_modules);
5267b71995-08-09Fredrik Hübinette (Hubbe)  fake_program.id = ++current_program_id;
0683be1997-01-26Fredrik Hübinette (Hubbe)  { struct inherit inherit; struct pike_string *name; inherit.prog=&fake_program; inherit.inherit_level=0; inherit.identifier_level=0; inherit.storage_offset=0; add_to_mem_block(A_INHERITS,(char *)&inherit,sizeof inherit); name=make_shared_string("this"); low_my_binary_strcat((char *)&name,sizeof(name), &inherit_names); } { struct svalue tmp; tmp.type=T_MAPPING;
94a2971997-03-01Henrik Grubbström (Grubba) #ifdef __CHECKER__ tmp.subtype=0; #endif /* __CHECKER__ */
0683be1997-01-26Fredrik Hübinette (Hubbe)  tmp.u.mapping=get_builtin_constants(); use_module(& tmp); }
2acdd31995-10-29Fredrik Hübinette (Hubbe) 
0683be1997-01-26Fredrik Hübinette (Hubbe)  num_parse_error=0;
8cc7a61995-10-30Fredrik Hübinette (Hubbe)  local_variables=ALLOC_STRUCT(locals);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  local_variables->next=0; local_variables->current_number_of_locals=0;
8cc7a61995-10-30Fredrik Hübinette (Hubbe)  local_variables->max_number_of_locals=0;
2acdd31995-10-29Fredrik Hübinette (Hubbe)  local_variables->current_type=0; local_variables->current_return_type=0;
5267b71995-08-09Fredrik Hübinette (Hubbe) } static void low_free_program(struct program *p) {
5c8e891995-10-29Fredrik Hübinette (Hubbe)  unsigned INT16 e;
5267b71995-08-09Fredrik Hübinette (Hubbe)  for(e=0; e<p->num_strings; e++) free_string(p->strings[e]); for(e=0; e<p->num_identifiers; e++) { free_string(p->identifiers[e].name); free_string(p->identifiers[e].type); } for(e=0; e<p->num_constants; e++) free_svalue(p->constants+e); for(e=1; e<p->num_inherits; e++) free_program(p->inherits[e].prog); } void really_free_program(struct program *p) { low_free_program(p); if(p->prev) p->prev->next=p->next; else first_program=p->next; if(p->next) p->next->prev=p->prev; free((char *)p);
624d091996-02-24Fredrik Hübinette (Hubbe)  GC_FREE();
5267b71995-08-09Fredrik Hübinette (Hubbe) }
2acdd31995-10-29Fredrik Hübinette (Hubbe) #ifdef DEBUG 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++) { fprintf(stderr,"%3d:",e); for(d=0;d<p->inherits[e].inherit_level;d++) fprintf(stderr," "); fprintf(stderr,"%s\n",p->inherits[e].prog->name->str); } */ fprintf(stderr,"All identifiers:\n"); 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," "); fprintf(stderr,"%s;\n",ID_FROM_INT(p,e)->name->str); } fprintf(stderr,"All sorted identifiers:\n"); for(q=0;q<(int)p->num_identifier_indexes;q++) { 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," "); fprintf(stderr,"%s;\n", ID_FROM_INT(p,e)->name->str); } } #endif
591c0c1997-01-19Fredrik Hübinette (Hubbe) static void toss_compilation_resources()
5267b71995-08-09Fredrik Hübinette (Hubbe) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string **names;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  struct svalue *modules;
5267b71995-08-09Fredrik Hübinette (Hubbe)  int e;
591c0c1997-01-19Fredrik Hübinette (Hubbe)  for (e=0; e<NUM_AREAS; e++) toss_buffer(areas+e);
5267b71995-08-09Fredrik Hübinette (Hubbe) 
06983f1996-09-22Fredrik Hübinette (Hubbe)  names=(struct pike_string **)inherit_names.s.str; e=inherit_names.s.len / sizeof(struct pike_string *);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  while(--e>=0) if(names[e]) free_string(names[e]);
5267b71995-08-09Fredrik Hübinette (Hubbe)  toss_buffer(& inherit_names);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  modules=(struct svalue *)used_modules.s.str;
0683be1997-01-26Fredrik Hübinette (Hubbe)  e=used_modules.s.len / sizeof(struct svalue);
591c0c1997-01-19Fredrik Hübinette (Hubbe)  while(--e>=0) free_svalue(modules+e); toss_buffer(& used_modules); /* Clean up */ while(local_variables) { struct locals *l; for(e=0;e<local_variables->current_number_of_locals;e++) { free_string(local_variables->variable[e].name); free_string(local_variables->variable[e].type); } if(local_variables->current_type) free_string(local_variables->current_type); if(local_variables->current_return_type) free_string(local_variables->current_return_type); l=local_variables->next; free((char *)local_variables); local_variables=l; } if(last_file) { free_string(last_file); last_file=0; } } /* * Something went wrong. * toss resources of program we were building */ void toss_current_program() { setup_fake_program(); low_free_program(&fake_program); toss_compilation_resources();
5267b71995-08-09Fredrik Hübinette (Hubbe) }
0d202a1995-10-20Fredrik Hübinette (Hubbe) #ifdef DEBUG
624d091996-02-24Fredrik Hübinette (Hubbe) void check_program(struct program *p)
0d202a1995-10-20Fredrik Hübinette (Hubbe) { INT32 size,e; unsigned INT32 checksum; 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"); size=MY_ALIGN(sizeof(struct program)); size+=MY_ALIGN(p->num_linenumbers); size+=MY_ALIGN(p->program_size); size+=MY_ALIGN(p->num_constants * sizeof(struct svalue));
06983f1996-09-22Fredrik Hübinette (Hubbe)  size+=MY_ALIGN(p->num_strings * sizeof(struct pike_string *));
0d202a1995-10-20Fredrik Hübinette (Hubbe)  size+=MY_ALIGN(p->num_identifiers * sizeof(struct identifier)); size+=MY_ALIGN(p->num_identifier_references * sizeof(struct reference)); size+=MY_ALIGN(p->num_inherits * sizeof(struct inherit)); size+=MY_ALIGN(p->num_identifier_indexes * sizeof(INT16));
a60e661995-11-15Fredrik Hübinette (Hubbe)  if(size > (INT32)p->total_size)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  fatal("Program size is in error.\n");
5267b71995-08-09Fredrik Hübinette (Hubbe) 
0d202a1995-10-20Fredrik Hübinette (Hubbe)  size-=MY_ALIGN(p->num_identifier_indexes * sizeof(INT16)); size+=MY_ALIGN(p->num_identifier_references * sizeof(INT16));
a60e661995-11-15Fredrik Hübinette (Hubbe)  if(size < (INT32)p->total_size)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  fatal("Program size is in error.\n"); #define CHECKRANGE(X,Y) if((char *)(p->X) < (char *)p || (char *)(p->X)> ((char *)p)+size) fatal("Program->%s is wrong.\n",Y) CHECKRANGE(program,"program"); CHECKRANGE(strings,"strings"); CHECKRANGE(inherits,"inherits"); CHECKRANGE(identifier_references,"identifier_references"); CHECKRANGE(identifiers,"identifier"); CHECKRANGE(identifier_index,"identifier_index"); CHECKRANGE(constants,"constants"); CHECKRANGE(linenumbers,"linenumbers"); checksum=hashmem(p->program, p->program_size, p->program_size) + hashmem((unsigned char*)p->linenumbers,p->num_linenumbers,p->num_linenumbers); if(!checksum) checksum=1; if(!p->checksum) { p->checksum=checksum; }else{ if(p->checksum != checksum) fatal("Someone changed a program!!!\n"); }
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=0;e<(int)p->num_constants;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  { check_svalue(p->constants + e); }
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=0;e<(int)p->num_strings;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  check_string(p->strings[e]);
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=0;e<(int)p->num_identifiers;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  { check_string(p->identifiers[e].name); check_string(p->identifiers[e].type);
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(p->identifiers[e].flags & ~15)
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); }
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=0;e<(int)p->num_identifier_references;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  { if(p->identifier_references[e].inherit_offset > p->num_inherits) fatal("Inherit offset is wrong!\n"); if(p->identifier_references[e].identifier_offset > p->inherits[p->identifier_references[e].inherit_offset].prog->num_identifiers) fatal("Identifier offset is wrong!\n"); }
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=0;e<(int)p->num_identifier_indexes;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); }
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=0;e<(int)p->num_inherits;e++)
0d202a1995-10-20Fredrik Hübinette (Hubbe)  { if(p->inherits[e].storage_offset < 0) fatal("Inherit->storage_offset is wrong.\n"); } } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe)  /* internal function to make the index-table */ static int funcmp(const void *a,const void *b) { return my_order_strcmp(ID_FROM_INT(&fake_program, *(unsigned short *)a)->name, ID_FROM_INT(&fake_program, *(unsigned short *)b)->name); } /* * Finish this program, returning the newly built program */ #define INS_BLOCK(PTR,PTRS,TYPE,AREA) \
f90e541995-08-17Fredrik Hübinette (Hubbe) prog->PTR=(TYPE *)p; \
5267b71995-08-09Fredrik Hübinette (Hubbe) if((prog->PTRS = areas[AREA].s.len/sizeof(TYPE))) \ { \ MEMCPY(p,areas[AREA].s.str, areas[AREA].s.len); \
f90e541995-08-17Fredrik Hübinette (Hubbe)  p+=MY_ALIGN(areas[AREA].s.len); \
5267b71995-08-09Fredrik Hübinette (Hubbe) } struct program *end_program() {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string **names;
5267b71995-08-09Fredrik Hübinette (Hubbe)  int size, i,e,t; char *p; struct program *prog; /* * Define the __INIT function, but only if there was any code * to initialize. */ if (init_node) { union idptr tmp;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *s;
329cc01997-02-17Fredrik Hübinette (Hubbe)  push_locals();
5267b71995-08-09Fredrik Hübinette (Hubbe)  s=make_shared_string("__INIT");
329cc01997-02-17Fredrik Hübinette (Hubbe)  dooptcode(s, mknode(F_ARG_LIST, init_node,mknode(F_RETURN,mkintnode(0),0)), function_type_string, 0); pop_locals();
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_string(s);
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  init_node=0;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
36feac1997-03-06Fredrik Hübinette (Hubbe)  exit_type_stack();
5267b71995-08-09Fredrik Hübinette (Hubbe)  if (num_parse_error > 0) { toss_current_program(); prog=0; }else{ setup_fake_program();
f90e541995-08-17Fredrik Hübinette (Hubbe)  size = MY_ALIGN(sizeof (struct program)); for (i=0; i<NUM_AREAS; i++) size += MY_ALIGN(areas[i].s.len); size+=MY_ALIGN(fake_program.num_identifier_references * sizeof(unsigned short));
5267b71995-08-09Fredrik Hübinette (Hubbe)  p = (char *)xalloc(size); prog = (struct program *)p; *prog = fake_program; prog->total_size = size; prog->refs = 1;
f90e541995-08-17Fredrik Hübinette (Hubbe)  p += MY_ALIGN(sizeof (struct program));
5267b71995-08-09Fredrik Hübinette (Hubbe)  INS_BLOCK(program,program_size,unsigned char,A_PROGRAM); INS_BLOCK(linenumbers,num_linenumbers,char,A_LINENUMBERS); INS_BLOCK(identifiers,num_identifiers,struct identifier,A_IDENTIFIERS); INS_BLOCK(identifier_references,num_identifier_references,struct reference,A_IDENTIFIER_REFERENCES);
06983f1996-09-22Fredrik Hübinette (Hubbe)  INS_BLOCK(strings,num_strings,struct pike_string *,A_STRINGS);
5267b71995-08-09Fredrik Hübinette (Hubbe)  INS_BLOCK(inherits,num_inherits,struct inherit,A_INHERITS); INS_BLOCK(constants,num_constants,struct svalue,A_CONSTANTS); /* Ok, sort for binsearch */ prog->identifier_index=(unsigned short *)p;
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=i=0;i<(int)prog->num_identifier_references;i++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { struct reference *funp; struct identifier *fun; funp=prog->identifier_references+i; if(funp->flags & (ID_HIDDEN|ID_STATIC)) continue; if(funp->flags & ID_INHERITED) { if(funp->flags & ID_PRIVATE) continue; fun=ID_FROM_PTR(prog, funp); if(fun->func.offset == -1) continue; /* prototype */ /* check for multiple definitions */
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(t=0;t>=0 && t<(int)prog->num_identifier_references;t++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { struct reference *funpb; struct identifier *funb; if(t==i) continue; funpb=prog->identifier_references+t; if(funpb->flags & (ID_HIDDEN|ID_STATIC)) continue; if((funpb->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; } prog->identifier_index[e]=i; e++; } prog->num_identifier_indexes=e; fsort((void *)prog->identifier_index, e,sizeof(unsigned short),(fsortfun)funcmp);
f90e541995-08-17Fredrik Hübinette (Hubbe)  p+=MY_ALIGN(prog->num_identifier_indexes*sizeof(unsigned short));
5267b71995-08-09Fredrik Hübinette (Hubbe) 
591c0c1997-01-19Fredrik Hübinette (Hubbe)  toss_compilation_resources();
5267b71995-08-09Fredrik Hübinette (Hubbe)  prog->inherits[0].prog=prog; prog->prev=0; if(prog->next=first_program) first_program->prev=prog; first_program=prog;
0d202a1995-10-20Fredrik Hübinette (Hubbe) 
5580691996-06-21Fredrik Hübinette (Hubbe)  for(i=0;i<NUM_LFUNS;i++) prog->lfuns[i]=find_identifier(lfun_names[i],prog);
0d202a1995-10-20Fredrik Hübinette (Hubbe) #ifdef 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) 
06983f1996-09-22Fredrik Hübinette (Hubbe)  GC_ALLOC();
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
5c8e891995-10-29Fredrik Hübinette (Hubbe) #define PROGRAM_STATE #define POP #include "compilation.h" #undef POP #undef PROGRAM_STATE
b8cda21997-01-21Fredrik Hübinette (Hubbe)  if(fake_program.num_inherits) fake_program.inherits[0].prog=&fake_program;
07513e1996-10-04Fredrik Hübinette (Hubbe)  threads_disabled--;
a8ef6e1996-12-03Fredrik Hübinette (Hubbe)  free_all_nodes();
5267b71995-08-09Fredrik Hübinette (Hubbe)  return prog; } /* * Allocate needed for this program in the object structure. * An offset to the data is returned. */ SIZE_T add_storage(SIZE_T size) { SIZE_T offset; offset=fake_program.storage_needed;
f90e541995-08-17Fredrik Hübinette (Hubbe)  size=MY_ALIGN(size);
5267b71995-08-09Fredrik Hübinette (Hubbe)  fake_program.storage_needed += size; return offset; } /* * 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) { fake_program.init=init; } /* * 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) { fake_program.exit=exit; }
06983f1996-09-22Fredrik Hübinette (Hubbe) int low_reference_inherited_identifier(int e,struct pike_string *name)
5267b71995-08-09Fredrik Hübinette (Hubbe) { struct reference funp; struct program *p; int i,d; p=fake_program.inherits[e].prog; i=find_shared_string_identifier(name,p); if(i==-1) return i; if(p->identifier_references[i].flags & ID_HIDDEN) return -1; if(ID_FROM_INT(p,i)->func.offset == -1) /* prototype */ return -1; funp=p->identifier_references[i];
0d202a1995-10-20Fredrik Hübinette (Hubbe)  funp.inherit_offset+=e;
5267b71995-08-09Fredrik Hübinette (Hubbe)  funp.flags|=ID_HIDDEN;
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(d=0;d<(int)fake_program.num_identifier_references;d++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { struct reference *fp; fp=fake_program.identifier_references+d; if(!MEMCMP((char *)fp,(char *)&funp,sizeof funp)) return d; } add_to_mem_block(A_IDENTIFIER_REFERENCES,(char *)&funp,sizeof funp); return fake_program.num_identifier_references; }
06983f1996-09-22Fredrik Hübinette (Hubbe) int reference_inherited_identifier(struct pike_string *super_name, struct pike_string *function_name)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string **names;
5267b71995-08-09Fredrik Hübinette (Hubbe)  int e,i; #ifdef DEBUG if(function_name!=debug_findstring(function_name)) fatal("reference_inherited_function on nonshared string.\n"); #endif
06983f1996-09-22Fredrik Hübinette (Hubbe)  names=(struct pike_string **)inherit_names.s.str;
5267b71995-08-09Fredrik Hübinette (Hubbe)  setup_fake_program(); for(e=fake_program.num_inherits-1;e>0;e--) { if(fake_program.inherits[e].inherit_level!=1) continue; if(!names[e]) continue; if(super_name) { int l; l=names[e]->len; if(l<super_name->len) continue; if(strncmp(super_name->str, names[e]->str+l-super_name->len, super_name->len)) continue; } i=low_reference_inherited_identifier(e,function_name); if(i==-1) continue; return i; } return -1; }
06983f1996-09-22Fredrik Hübinette (Hubbe) void rename_last_inherit(struct pike_string *n)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string **names;
5267b71995-08-09Fredrik Hübinette (Hubbe)  int e;
06983f1996-09-22Fredrik Hübinette (Hubbe)  names=(struct pike_string **)inherit_names.s.str; e=inherit_names.s.len / sizeof(struct pike_string *);
5267b71995-08-09Fredrik Hübinette (Hubbe)  free_string(names[e-1]); copy_shared_string(names[e-1],n); } /* * make this program inherit another program */
06983f1996-09-22Fredrik Hübinette (Hubbe) void do_inherit(struct program *p,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)  setup_fake_program(); inherit_offset = fake_program.num_inherits; storage_offset=fake_program.storage_needed; add_storage(p->storage_needed);
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]; inherit.prog->refs++; inherit.identifier_level += fake_program.num_identifier_references; inherit.storage_offset += storage_offset; inherit.inherit_level ++; add_to_mem_block(A_INHERITS,(char *)&inherit,sizeof inherit);
d2c6081996-11-07Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  low_my_binary_strcat((char *)&name,sizeof(name),&inherit_names);
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(name) { reference_shared_string(name); name=0; }
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; if (fun.flags & ID_NOMASK) { int n; n = isidentifier(name); if (n != -1 && ID_FROM_INT(&fake_program,n)->func.offset != -1) my_yyerror("Illegal to redefine 'nomask' function/variable \"%s\"",name->str); }
5580691996-06-21Fredrik Hübinette (Hubbe)  if(fun.flags & ID_PRIVATE) fun.flags|=ID_HIDDEN;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if (fun.flags & ID_PUBLIC) fun.flags |= flags & ~ID_PRIVATE; else fun.flags |= flags; fun.flags |= ID_INHERITED; add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&fun, sizeof fun); } /* Ska det h{r vara s} h{r? */ s=findstring("__INIT"); if(s) { if(-1 != find_shared_string_identifier(s,p)) { e=reference_inherited_identifier(0, s); init_node=mknode(F_ARG_LIST, init_node, mkcastnode(void_type_string, mkapplynode(mkidentifiernode(e),0))); } } }
06983f1996-09-22Fredrik 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); reference_shared_string(current_file); push_string(current_file); 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; } do_inherit(sp[-1].u.program, 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; setup_fake_program();
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(e=0;e<(int)fake_program.num_identifier_references;e++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { if(fake_program.identifier_references[e].flags & ID_HIDDEN) continue; if(ID_FROM_INT(& fake_program, e)->name == s) return e; } return -1; } /* 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) { int n; #ifdef DEBUG if(name!=debug_findstring(name)) fatal("define_variable on nonshared string.\n"); #endif if(type == void_type_string) yyerror("Variables can't be of type void"); setup_fake_program(); n = isidentifier(name); if(n != -1) { setup_fake_program(); if (IDENTIFIERP(n)->flags & ID_NOMASK) my_yyerror("Illegal to redefine 'nomask' variable/functions \"%s\"", name->str); if(PROG_FROM_INT(& fake_program, n) == &fake_program)
27bd811996-10-09Fredrik Hübinette (Hubbe)  my_yyerror("Variable '%s' defined twice.",name->str);
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(ID_FROM_INT(& fake_program, n)->type != type)
27bd811996-10-09Fredrik Hübinette (Hubbe)  my_yyerror("Illegal to redefine inherited variable with different type.");
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(ID_FROM_INT(& fake_program, n)->flags != flags)
27bd811996-10-09Fredrik Hübinette (Hubbe)  my_yyerror("Illegal to redefine inherited variable with different type.");
5267b71995-08-09Fredrik Hübinette (Hubbe)  } else { struct identifier dummy; struct reference ref; copy_shared_string(dummy.name, name); copy_shared_string(dummy.type, type); dummy.flags = 0; dummy.run_time_type=compile_type_to_runtime_type(type); if(dummy.run_time_type == T_FUNCTION) dummy.run_time_type = T_MIXED; dummy.func.offset=add_storage(dummy.run_time_type == T_MIXED ? sizeof(struct svalue) : sizeof(union anything)); ref.flags=flags; ref.identifier_offset=areas[A_IDENTIFIERS].s.len / sizeof dummy; ref.inherit_offset=0; add_to_mem_block(A_IDENTIFIERS, (char *)&dummy, sizeof dummy); fake_program.num_identifiers ++; n=areas[A_IDENTIFIER_REFERENCES].s.len / sizeof ref; add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&ref, sizeof ref); fake_program.num_identifier_references ++; } return n; }
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)  #ifdef DEBUG 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 setup_fake_program(); n = isidentifier(name);
2d12341997-03-10Fredrik Hübinette (Hubbe)  copy_shared_string(dummy.name, name); dummy.type = get_type_of_svalue(c); dummy.flags = IDENTIFIER_CONSTANT; dummy.run_time_type=c->type; dummy.func.offset=store_constant(c, 0); ref.flags=flags; ref.identifier_offset=fake_program.num_identifiers; ref.inherit_offset=0; add_to_mem_block(A_IDENTIFIERS, (char *)&dummy, sizeof dummy); fake_program.num_identifiers ++;
d2c6081996-11-07Fredrik Hübinette (Hubbe)  if(n != -1) { if (IDENTIFIERP(n)->flags & ID_NOMASK) my_yyerror("Illegal to redefine 'nomask' identifier \"%s\"", name->str); if(PROG_FROM_INT(& fake_program, n) == &fake_program) my_yyerror("Identifier '%s' defined twice.",name->str);
2d12341997-03-10Fredrik Hübinette (Hubbe)  fake_program.identifier_references[n]=ref; } else {
d2c6081996-11-07Fredrik Hübinette (Hubbe)  n=areas[A_IDENTIFIER_REFERENCES].s.len / sizeof ref; add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&ref, sizeof ref); fake_program.num_identifier_references ++; } return n; }
0683be1997-01-26Fredrik Hübinette (Hubbe) int simple_add_constant(char *name, 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) }
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; }
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; }
5c0a101997-02-06Fredrik Hübinette (Hubbe) int end_class(char *name, INT32 flags) { INT32 ret; struct svalue tmp; 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);
5c0a101997-02-06Fredrik Hübinette (Hubbe)  ret=simple_add_constant(name, &tmp, flags); 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; INT32 i; i=isidentifier(name); setup_fake_program(); if(i >= 0) { /* already defined */ funp=ID_FROM_INT(&fake_program, i); ref=fake_program.identifier_references[i];
2acdd31995-10-29Fredrik Hübinette (Hubbe)  if(ref.inherit_offset == 0) /* not inherited */
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
2acdd31995-10-29Fredrik Hübinette (Hubbe)  if(!(!func || func->offset == -1) && !(funp->func.offset == -1)) { my_yyerror("Redeclaration of function %s.",name->str); 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); } } /* it's just another prototype, don't define anything */ if(!func || func->offset == -1) return i; if((ref.flags & ID_NOMASK) && !(funp->func.offset == -1)) { my_yyerror("Illegal to redefine 'nomask' function %s.",name->str); } /* We modify the old definition if it is in this program */ if(ref.inherit_offset==0) { if(func) funp->func = *func; else funp->func.offset = -1; funp->flags=function_flags; }else{ /* Otherwise we make a new definition */ copy_shared_string(fun.name, name); copy_shared_string(fun.type, type); fun.run_time_type=T_FUNCTION; fun.flags=function_flags; if(func) fun.func = *func; else fun.func.offset = -1; ref.identifier_offset=fake_program.num_identifiers; add_to_mem_block(A_IDENTIFIERS, (char *)&fun, sizeof(fun)); } ref.inherit_offset = 0; ref.flags = flags; fake_program.identifier_references[i]=ref; }else{ /* define it */ copy_shared_string(fun.name, name); copy_shared_string(fun.type, type); fun.flags=function_flags; fun.run_time_type=T_FUNCTION; if(func) fun.func = *func; else fun.func.offset = -1; i=fake_program.num_identifiers; add_to_mem_block(A_IDENTIFIERS, (char *)&fun, sizeof(fun)); ref.flags = flags; ref.identifier_offset = i; ref.inherit_offset = 0; i=fake_program.num_identifier_references; add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&ref, sizeof ref); } return i; } /* * lookup the number of a function in a program given the name in * a shared_string */
06983f1996-09-22Fredrik Hübinette (Hubbe) static int low_find_shared_string_identifier(struct pike_string *name,
5267b71995-08-09Fredrik Hübinette (Hubbe)  struct program *prog) { int max,min,tst; struct reference *funp; struct identifier *fun; unsigned short *funindex; funindex = prog->identifier_index; if(funindex) { max = prog->num_identifier_indexes; 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{ int i,t;
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(i=0;i<(int)prog->num_identifier_references;i++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { funp = prog->identifier_references + i; if(funp->flags & ID_HIDDEN) continue; fun = ID_FROM_PTR(prog, funp); if(fun->func.offset == -1) continue; /* Prototype */ if(!is_same_string(fun->name,name)) continue; if(funp->flags & ID_INHERITED) { if(funp->flags & ID_PRIVATE) continue;
5c8e891995-10-29Fredrik Hübinette (Hubbe)  for(t=0; t>=0 && t<(int)prog->num_identifier_references; t++)
5267b71995-08-09Fredrik Hübinette (Hubbe)  { if(t == i) continue; if(is_same_string(fun->name, ID_FROM_INT(prog, i)->name)) t=-10; } if(t < 0) continue; } return i; } } 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) { #ifdef FIND_FUNCTION_HASHSIZE if(prog!=&fake_program) { 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;
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!prog)
24697f1997-03-12Henrik Grubbström (Grubba)  error("Lookup of identifier %s in destructed object.\n", name);
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;
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string **p;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
06983f1996-09-22Fredrik Hübinette (Hubbe)  p = (struct pike_string **)areas[A_STRINGS].s.str;
5267b71995-08-09Fredrik Hübinette (Hubbe)  for (i=0;i<areas[A_STRINGS].s.len / sizeof str;i++) if (p[i] == str) return i; reference_shared_string(str); add_to_mem_block(A_STRINGS, (char *)&str, sizeof str); return i; }
5683de1995-11-06Fredrik Hübinette (Hubbe) int store_constant(struct svalue *foo, int equal)
5267b71995-08-09Fredrik Hübinette (Hubbe) { struct svalue *s,tmp; unsigned int e; s=(struct svalue *)areas[A_CONSTANTS].s.str;
5683de1995-11-06Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe)  for(e=0;e<areas[A_CONSTANTS].s.len / sizeof(struct svalue);e++)
5683de1995-11-06Fredrik Hübinette (Hubbe)  if(equal ? is_equal(s+e,foo) : is_eq(s+e,foo))
5267b71995-08-09Fredrik Hübinette (Hubbe)  return e; assign_svalue_no_free(&tmp,foo); add_to_mem_block(A_CONSTANTS,(char *)&tmp,sizeof(struct svalue)); return e; } /* * Line number support routines, now also tells what file we are in */ static int get_small_number(char **q) { int ret; switch(ret=(*(signed char **)q)++[0]) { 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) { if(last_file) { free_string(last_file); last_file=0; } last_pc=last_line=0; } static void insert_small_number(int a,int area) { if(a>-127 && a<127) { ins_byte(a,area); }else if(a>=-32768 && a<32768){ ins_signed_byte(-127,area); ins_short(a,area); }else{ ins_signed_byte(-128,area);
d72a871996-04-13Fredrik Hübinette (Hubbe)  ins_int(a,area);
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) { if(last_line!=current_line || last_file != current_file) { if(last_file != current_file) { char *tmp; if(last_file) free_string(last_file); ins_byte(127,A_LINENUMBERS); for(tmp=current_file->str; *tmp; tmp++) ins_byte(*tmp,A_LINENUMBERS); ins_byte(0,A_LINENUMBERS); copy_shared_string(last_file, current_file); } insert_small_number(PC-last_pc,A_LINENUMBERS); insert_small_number(current_line-last_line,A_LINENUMBERS); 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) { char *file; INT32 off,line,offset; char *cnt;
5683de1995-11-06Fredrik Hübinette (Hubbe)  if (prog == 0) return "Unkown program";
5267b71995-08-09Fredrik Hübinette (Hubbe)  offset = pc - prog->program; if(prog == & fake_program) { linep[0]=0; return "Optimizer"; } #ifdef DEBUG if (offset > (INT32)prog->program_size || offset<0)
6283791995-09-01Fredrik Hübinette (Hubbe)  fatal("Illegal offset %ld in program.\n", (long)offset);
5267b71995-08-09Fredrik Hübinette (Hubbe) #endif cnt=prog->linenumbers; off=line=0; file="Line not found"; while(cnt < prog->linenumbers + prog->num_linenumbers) { if(*cnt == 127) { file=cnt+1; cnt=file+strlen(file)+1; } off+=get_small_number(&cnt); if(off > offset) break; line+=get_small_number(&cnt); } linep[0]=line; return file; } void my_yyerror(char *fmt,...) { va_list args; char buf[1000]; va_start(args,fmt); VSPRINTF(buf,fmt,args);
197d171996-05-16Fredrik Hübinette (Hubbe)  if((long)strlen(buf) >= (long)sizeof(buf))
5267b71995-08-09Fredrik Hübinette (Hubbe)  fatal("Buffer overflow in my_yyerror."); yyerror(buf); va_end(args); } /*
06983f1996-09-22Fredrik Hübinette (Hubbe)  * Compile an PIKE file. Input is supposed to be initalized already.
5267b71995-08-09Fredrik Hübinette (Hubbe)  */ void compile() { int yyparse(); start_line_numbering(); num_parse_error = 0; init_node=0; yyparse(); /* Parse da program */ free_all_local_names(); }
06983f1996-09-22Fredrik Hübinette (Hubbe) struct program *compile_file(struct pike_string *file_name)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int fd; struct program *p;
624d091996-02-24Fredrik Hübinette (Hubbe) 
cf39c21996-11-18Fredrik Hübinette (Hubbe)  while(1) { fd=open(file_name->str,O_RDONLY); if(fd >= 0) break; if(errno != EINTR)
d72bae1997-01-31Fredrik Hübinette (Hubbe)  { #ifdef HAVE_STRERROR error("Couldn't open file '%s'. (%s)\n",file_name->str,strerror(errno)); #else error("Couldn't open file '%s'. (ERRNO=%d)\n",file_name->str,errno); #endif }
cf39c21996-11-18Fredrik Hübinette (Hubbe)  }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
5c8e891995-10-29Fredrik Hübinette (Hubbe) #define FILE_STATE #define PUSH #include "compilation.h" #undef PUSH
5267b71995-08-09Fredrik Hübinette (Hubbe)  start_new_file(fd,file_name);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  start_new_program();
5267b71995-08-09Fredrik Hübinette (Hubbe)  compile(); p=end_program();
2acdd31995-10-29Fredrik Hübinette (Hubbe)  end_new_file();
5c8e891995-10-29Fredrik Hübinette (Hubbe)  #define POP #include "compilation.h" #undef POP #undef FILE_STATE
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!p) error("Failed to compile %s.\n",file_name->str); return p; }
06983f1996-09-22Fredrik Hübinette (Hubbe) struct program *compile_string(struct pike_string *prog, struct pike_string *name)
5267b71995-08-09Fredrik Hübinette (Hubbe) { struct program *p;
5c8e891995-10-29Fredrik Hübinette (Hubbe)  #define FILE_STATE #define PUSH #include "compilation.h" #undef PUSH
5267b71995-08-09Fredrik Hübinette (Hubbe)  start_new_string(prog->str,prog->len,name);
2acdd31995-10-29Fredrik Hübinette (Hubbe)  start_new_program();
5267b71995-08-09Fredrik Hübinette (Hubbe)  compile(); p=end_program();
2acdd31995-10-29Fredrik Hübinette (Hubbe)  end_new_file();
5c8e891995-10-29Fredrik Hübinette (Hubbe)  #define POP #include "compilation.h" #undef POP #undef FILE_STATE
5267b71995-08-09Fredrik Hübinette (Hubbe)  if(!p) error("Compilation failed.\n"); return p; } void add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags) {
06983f1996-09-22Fredrik Hübinette (Hubbe)  struct pike_string *name_tmp,*type_tmp;
5267b71995-08-09Fredrik Hübinette (Hubbe)  union idptr tmp; name_tmp=make_shared_string(name); type_tmp=parse_type(type); if(cfun) { tmp.c_fun=cfun; define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION, &tmp); }else{ define_function(name_tmp, type_tmp, flags, IDENTIFIER_C_FUNCTION, 0); } free_string(name_tmp); free_string(type_tmp); } #ifdef DEBUG
624d091996-02-24Fredrik Hübinette (Hubbe) void check_all_programs()
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);
5267b71995-08-09Fredrik Hübinette (Hubbe) } #endif void cleanup_program() { #ifdef FIND_FUNCTION_HASHSIZE int e; for(e=0;e<FIND_FUNCTION_HASHSIZE;e++) { if(cache[e].name) { free_string(cache[e].name); cache[e].name=0; } } #endif }
624d091996-02-24Fredrik 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)) gc_mark_svalues(p->constants, p->num_constants);
624d091996-02-24Fredrik Hübinette (Hubbe) } void gc_check_all_programs() {
c94c371996-03-28Fredrik Hübinette (Hubbe)  struct program *p; for(p=first_program;p;p=p->next)
9367351997-01-27Fredrik Hübinette (Hubbe)  {
c94c371996-03-28Fredrik Hübinette (Hubbe)  gc_check_svalues(p->constants, p->num_constants);
9367351997-01-27Fredrik Hübinette (Hubbe)  if(d_flag) { int e; for(e=0;e<(int)p->num_strings;e++) gc_check(p->strings[e]); for(e=0;e<(int)p->num_identifiers;e++) { gc_check(p->identifiers[e].name); gc_check(p->identifiers[e].type); } } }
c94c371996-03-28Fredrik Hübinette (Hubbe) } void gc_mark_all_programs() { struct program *p; for(p=first_program;p;p=p->next) if(gc_is_referenced(p)) gc_mark_program_as_referenced(p); } void gc_free_all_unreferenced_programs() { 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)  { p->refs++;
c94c371996-03-28Fredrik Hübinette (Hubbe)  free_svalues(p->constants, p->num_constants, -1);
624d091996-02-24Fredrik Hübinette (Hubbe)  next=p->next; free_program(p); }else{ next=p->next; } } } #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; }
329cc01997-02-17Fredrik Hübinette (Hubbe) void push_locals() { struct locals *l; l=ALLOC_STRUCT(locals); l->current_type=0; l->current_return_type=0; l->next=local_variables; l->current_number_of_locals=0; l->max_number_of_locals=0; local_variables=l; } void pop_locals() { struct locals *l; free_all_local_names(); l=local_variables->next; if(local_variables->current_type) free_string(local_variables->current_type); if(local_variables->current_return_type) free_string(local_variables->current_return_type); free((char *)local_variables); local_variables=l; /* insert check if ( local->next == parent locals ) here */ }