1998-01-13
1998-01-13 23:01:47 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>
-
b1f4eb39528f16bb6a6f876e2458255e588283a1
(1342 lines)
(+766/-576)
[
Show
| Annotate
]
Branch: 7.9
Compiler update to use two pass
Rev: src/acconfig.h:1.14
Rev: src/builtin_functions.c:1.59
Rev: src/builtin_functions.h:1.5
Rev: src/compilation.h:1.4
Rev: src/configure.in:1.149
Rev: src/cpp.c:1.3
Rev: src/docode.c:1.24
Rev: src/docode.h:1.4
Rev: src/gc.c:1.24
Rev: src/interpret.c:1.57
Rev: src/interpret.h:1.16
Rev: src/language.yacc:1.51
Rev: src/las.c:1.40
Rev: src/las.h:1.9
Rev: src/lex.c:1.37
Rev: src/lex.h:1.7
Rev: src/main.c:1.32
Rev: src/modules/Image/blit.c:1.26
Rev: src/modules/Image/colortable.c:1.33
Rev: src/modules/Image/dct.c:1.11
Rev: src/modules/Image/image.c:1.73
Rev: src/modules/Image/matrix.c:1.13
Rev: src/modules/Image/operator.c:1.11
Rev: src/modules/Image/pattern.c:1.11
Rev: src/modules/Image/pnm.c:1.9
Rev: src/modules/Image/polyfill.c:1.18
Rev: src/modules/Image/togif.c:1.29
Rev: src/modules/Image/x.c:1.17
Rev: src/modules/Pipe/pipe.c:1.15
Rev: src/modules/Regexp/glue.c:1.9
Rev: src/modules/_Crypto/cbc.c:1.10
Rev: src/modules/_Crypto/crypto.c:1.24
Rev: src/modules/_Crypto/des.c:1.11
Rev: src/modules/_Crypto/pipe.c:1.11
Rev: src/modules/_Crypto/sha.c:1.9
Rev: src/modules/files/socktest.pike:1.6
Rev: src/modules/system/system.c:1.37
Rev: src/object.c:1.31
Rev: src/object.h:1.13
Rev: src/opcodes.c:1.10
Rev: src/operators.c:1.22
Rev: src/peep.c:1.16
Rev: src/peep.in:1.9
Rev: src/pike_types.c:1.27
Rev: src/pike_types.h:1.6
Rev: src/program.c:1.48
Rev: src/program.h:1.24
Rev: src/program_areas.h:1.2
Rev: src/stralloc.c:1.21
Rev: src/stralloc.h:1.10
Rev: src/svalue.c:1.18
Rev: src/testsuite.in:1.64
Rev: src/threads.c:1.51
Rev: src/threads.h:1.26
4:
||| See the files COPYING and DISCLAIMER for more information.
\*/
#include "global.h"
- RCSID("$Id: program.c,v 1.47 1998/01/02 01:05:51 hubbe Exp $");
+ RCSID("$Id: program.c,v 1.48 1998/01/13 22:56:49 hubbe Exp $");
#include "program.h"
#include "object.h"
#include "dynamic_buffer.h"
28:
#include <errno.h>
#include <fcntl.h>
+
+ #undef ATTRIBUTE
+ #define ATTRIBUTE(X)
+
+
/*
* Define the size of the cache that is used for method lookup.
*/
#define FIND_FUNCTION_HASHSIZE 4711
- #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
+
-
+
char *lfun_names[] = {
"__INIT",
"create",
91:
};
struct program *first_program = 0;
+ static int current_program_id=0;
- struct program fake_program;
+ struct program *new_program=0;
+ struct program *malloc_size_program=0;
- static int current_program_id=0;
+ int compiler_pass;
+ int compilation_depth;
+ struct compiler_frame *compiler_frame=0;
static INT32 last_line = 0;
static INT32 last_pc = 0;
static struct pike_string *last_file = 0;
- dynamic_buffer inherit_names;
+
dynamic_buffer used_modules;
- void free_all_local_names(void);
+ /* So what if we don't have templates? / Hubbe */
-
+ #ifdef DEBUG
+ #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) \
+ void PIKE_CONCAT(add_to_,NAME) (TYPE ARG) { \
+ CHECK_FOO(NUMTYPE,TYPE,NAME); \
+ if(malloc_size_program->PIKE_CONCAT(num_,NAME) == new_program->PIKE_CONCAT(num_,NAME)) { \
+ void *tmp; \
+ malloc_size_program->PIKE_CONCAT(num_,NAME) *= 2; \
+ malloc_size_program->PIKE_CONCAT(num_,NAME)++; \
+ tmp=realloc((char *)new_program->NAME, \
+ sizeof(TYPE) * \
+ malloc_size_program->PIKE_CONCAT(num_,NAME)); \
+ if(!tmp) fatal("Out of memory.\n"); \
+ new_program->NAME=tmp; \
+ } \
+ new_program->NAME[new_program->PIKE_CONCAT(num_,NAME)++]=(ARG); \
+ }
+
+ #include "program_areas.h"
+
+ 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));
+ }
+
void use_module(struct svalue *s)
{
if( (1<<s->type) & (BIT_MAPPING | BIT_OBJECT))
116:
}
- static int low_find_shared_string_identifier(struct pike_string *name,
+
+ int low_find_shared_string_identifier(struct pike_string *name,
struct program *prog);
- int find_module_identifier(struct pike_string *ident)
+
+
+ struct node_s *find_module_identifier(struct pike_string *ident)
{
JMP_BUF tmp;
-
+ node *ret;
- #ifdef DEBUG
- if(recoveries && sp-evaluator_stack < recoveries->sp)
- fatal("Stack error in compiation (underflow)\n");
- #endif
-
+
if(SETJMP(tmp))
{
ONERROR tmp;
152:
{
/* fprintf(stderr,"MOD: %s, %d %d\n",ident->str, current_line, sp[-1].type); */
UNSETJMP(tmp);
- return 1;
+ ret=mksvaluenode(sp-1);
+ pop_stack();
+ return ret;
}
pop_stack();
}
160:
UNSETJMP(tmp);
{
- struct program_state *p;
- for(p=previous_program_state;p;p=p->previous)
+ struct program_state *p=previous_program_state;
+ int n;
+ for(n=0;n<compilation_depth;n++,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);
+ int i=low_find_shared_string_identifier(ident, p->new_program);
if(i!=-1)
{
struct identifier *id;
- id=ID_FROM_INT(&p->fake_program, i);
+ id=ID_FROM_INT(p->new_program, i);
if(IDENTIFIER_IS_CONSTANT(id->identifier_flags))
{
- push_svalue(PROG_FROM_INT(&p->fake_program, i)->constants+
+ ret=mksvaluenode(PROG_FROM_INT(p->new_program, i)->constants+
id->func.offset);
- return 1;
+ return ret;
}else{
- yyerror("Identifier is not a constant");
- return 0;
+ return mkexternalnode(n, i, id);
}
}
}
}
-
+
return 0;
}
- /* This should be optimized */
+ 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];
+
struct program *id_to_program(INT32 id)
{
struct program *p;
-
+ INT32 h;
+ if(!id) return 0;
+ h=id & (ID_TO_PROGRAM_CACHE_SIZE-1);
+
+ if((p=id_to_program_cache[h]))
+ if(p->id==id) return p;
+
if(id)
-
+ {
for(p=first_program;p;p=p->next)
-
+ {
if(id==p->id)
-
+ {
+ if(id_to_program_cache[h])
+ free_program(id_to_program_cache[h]);
+
+ id_to_program_cache[h]=p;
+ p->refs++;
return p;
-
+ }
+ }
+ }
return 0;
}
- #define SETUP(X,Y,TYPE,AREA) \
- fake_program.X=(TYPE *)areas[AREA].s.str; \
- fake_program.Y=areas[AREA].s.len/sizeof(TYPE)
+ /* Here starts routines which are used to build new programs */
- /*
- * 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
+ /* 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)
*/
- void setup_fake_program(void)
+ void optimize_program(struct program *p)
{
- fake_program.refs=0xffffff;
- SETUP(program, program_size, unsigned char, A_PROGRAM);
- SETUP(strings, num_strings, struct pike_string *, A_STRINGS);
- 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);
+ SIZE_T size=0;
+ char *data;
- fake_program.inherits[0].prog=&fake_program;
- fake_program.next=0;
- fake_program.prev=0;
- fake_program.flags=0;
- /*
- fake_program.lfuns=0;
- fake_prog.num_lfuns=0;
- */
- #ifdef PROFILING
- fake_program.num_clones = 0;
- #endif /* PROFILING */
- fake_object.prog=&fake_program;
+ /* Already done (shouldn't happen, but who knows?) */
+ if(p->flags & PROGRAM_OPTIMIZED) return;
+
+ #define FOO(NUMTYPE,TYPE,NAME) \
+ size+=MY_ALIGN(p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]));
+ #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) \
+ MEMCPY(data+size,p->NAME,p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0])); \
+ free((char *)p->NAME); \
+ p->NAME=(TYPE *)(data+size); \
+ size+=MY_ALIGN(p->PIKE_CONCAT(num_,NAME)*sizeof(p->NAME[0]));
+ #include "program_areas.h"
+
+ p->total_size=size + sizeof(struct program);
+
+ p->flags |= PROGRAM_OPTIMIZED;
}
- /* Here starts routines which are used to build new programs */
+ /* internal function to make the index-table */
+ static int funcmp(const void *a,const void *b)
+ {
+ 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;
+ #ifdef DEBUG
+ 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 */
+
+ /* check for multiple definitions */
+ for(t=i+1;t>=0 && t<(int)new_program->num_identifier_references;t++)
+ {
+ struct reference *funpb;
+ struct identifier *funb;
+
+ 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,
+ sizeof(unsigned short),(fsortfun)funcmp);
+
+
+ for(i=0;i<NUM_LFUNS;i++)
+ new_program->lfuns[i]=find_identifier(lfun_names[i],new_program);
+
+ new_program->flags |= PROGRAM_FIXED;
+ }
+
/*
* Start building a new program
*/
- void start_new_program(void)
+ void low_start_new_program(struct program *p,
+ struct pike_string *name,
+ int flags)
{
int e;
threads_disabled++;
- if(local_variables)
- setup_fake_program();
- #define PROGRAM_STATE
+ compilation_depth++;
+
+ if(!p)
+ {
+ p=ALLOC_STRUCT(program);
+ MEMSET(p, 0, sizeof(struct program));
+
+ p->refs=1;
+ p->id=++current_program_id;
+
+ if((p->next=first_program)) first_program->prev=p;
+ first_program=p;
+ }else{
+ p->refs++;
+ }
+
+ if(name)
+ {
+ struct svalue s;
+ s.type=T_PROGRAM;
+ s.u.program=p;
+ add_constant(name, &s, flags);
+ }
+
#define PUSH
#include "compilation.h"
- #undef PUSH
- #undef PROGRAM_STATE
+
- if(previous_program_state->fake_program.num_inherits)
- previous_program_state->fake_program.inherits[0].prog=
- &previous_program_state->fake_program;
-
+
init_type_stack();
- for(e=0; e<NUM_AREAS; e++) low_reinit_buf(areas + e);
- low_reinit_buf(& inherit_names);
+
low_reinit_buf(& used_modules);
- fake_program.id = ++current_program_id;
+
-
+ if(p && (p->flags & PROGRAM_FINISHED))
{
- 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);
+ yyerror("Pass2: Program already done");
+ p=0;
}
-
+ malloc_size_program = ALLOC_STRUCT(program);
+ new_program=p;
-
+ 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"
+ }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;
+ i.name=0;
+ add_to_inherits(i);
+ }
+
+ {
struct svalue tmp;
tmp.type=T_MAPPING;
#ifdef __CHECKER__
287:
use_module(& tmp);
}
+ init_node=0;
num_parse_error=0;
- local_variables=ALLOC_STRUCT(locals);
- local_variables->next=0;
- local_variables->current_number_of_locals=0;
- local_variables->max_number_of_locals=0;
- local_variables->current_type=0;
- local_variables->current_return_type=0;
+
+ push_compiler_frame();
}
- static void low_free_program(struct program *p)
+ void start_new_program(void)
{
-
+ low_start_new_program(0,0,0);
+ }
+
+
+ void really_free_program(struct program *p)
+ {
unsigned INT16 e;
-
+
+ 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;
+
for(e=0; e<p->num_strings; e++)
free_string(p->strings[e]);
312:
free_svalue(p->constants+e);
for(e=1; e<p->num_inherits; e++)
+ {
free_program(p->inherits[e].prog);
-
+ if(p->inherits[e].parent)
+ free_object(p->inherits[e].parent);
}
- void really_free_program(struct program *p)
- {
- low_free_program(p);
-
+
if(p->prev)
p->prev->next=p->next;
else
327:
if(p->next)
p->next->prev=p->prev;
+ if(p->flags & PROGRAM_OPTIMIZED)
+ {
+ if(p->program)
+ free(p->program);
+ #define FOO(NUMTYPE,TYPE,NAME) p->NAME=0;
+ #include "program_areas.h"
+ }else{
+ #define FOO(NUMTYPE,TYPE,NAME) \
+ if(p->NAME) { free((char *)p->NAME); p->NAME=0; }
+ #include "program_areas.h"
+ }
+
free((char *)p);
GC_FREE();
}
#ifdef DEBUG
-
+
void dump_program_desc(struct program *p)
{
int e,d,q;
349: Inside #if defined(DEBUG)
}
*/
- fprintf(stderr,"All identifiers: (this=%08x)\n",(unsigned int)p);
+ 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," (%08x) %s;\t",
- (unsigned int)INHERIT_FROM_INT(p,e)->prog,
- ID_FROM_INT(p,e)->name->str);
- if(p->identifier_references[e].id_flags&ID_HIDDEN)
- fprintf(stderr," (hidden)");
- if(p->identifier_references[e].id_flags&ID_INHERITED)
- fprintf(stderr," (inherited)");
- fprintf(stderr,"\n");
+ 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++)
+ for(q=0;q<(int)p->num_identifier_index;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," (%08x) %s;\t",
- (unsigned int)INHERIT_FROM_INT(p,e)->prog,
- ID_FROM_INT(p,e)->name->str);
- if(p->identifier_references[e].id_flags & ID_HIDDEN)
- fprintf(stderr," (hidden)");
- if(p->identifier_references[e].id_flags&ID_INHERITED)
- fprintf(stderr," (inherited)");
- fprintf(stderr,"\n");
+ fprintf(stderr,"%s;\n", ID_FROM_INT(p,e)->name->str);
}
}
#endif
static void toss_compilation_resources(void)
{
- struct pike_string **names;
- struct svalue *modules;
- int e;
+ free_program(new_program);
+ new_program=0;
- for (e=0; e<NUM_AREAS; e++) toss_buffer(areas+e);
-
- names=(struct pike_string **)inherit_names.s.str;
- e=inherit_names.s.len / sizeof(struct pike_string *);
- while(--e>=0) if(names[e]) free_string(names[e]);
- toss_buffer(& inherit_names);
-
- modules=(struct svalue *)used_modules.s.str;
- e=used_modules.s.len / sizeof(struct svalue);
- while(--e>=0) free_svalue(modules+e);
- toss_buffer(& used_modules);
-
- /* Clean up */
- while(local_variables)
+ if(malloc_size_program)
{
- 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);
+ free((char *)malloc_size_program);
+ malloc_size_program=0;
}
- if(local_variables->current_type)
- free_string(local_variables->current_type);
+ while(compiler_frame)
+ pop_compiler_frame();
- 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(void)
+
{
- setup_fake_program();
- low_free_program(&fake_program);
- toss_compilation_resources();
+ struct svalue *modules=(struct svalue *)used_modules.s.str;
+ INT32 e;
+
+ for(e=0;e<(long)(used_modules.s.len / sizeof(struct svalue));e++)
+ free_svalue(modules+e);
+
+ toss_buffer(&used_modules);
}
-
+ }
+
#ifdef DEBUG
void check_program(struct program *p)
{
465: Inside #if defined(DEBUG)
if(p->storage_needed < 0)
fatal("Program->storage_needed < 0.\n");
+ if(p->num_identifier_index > p->num_identifier_references)
+ fatal("Too many identifier index entries in program!\n");
+
+ #if 0
size=MY_ALIGN(sizeof(struct program));
size+=MY_ALIGN(p->num_linenumbers);
size+=MY_ALIGN(p->program_size);
485: Inside #if defined(DEBUG)
if(size < (INT32)p->total_size)
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)
- #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");
509:
if(p->checksum != checksum)
fatal("Someone changed a program!!!\n");
}
+ #endif
for(e=0;e<(int)p->num_constants;e++)
- {
+
check_svalue(p->constants + e);
- }
+
for(e=0;e<(int)p->num_strings;e++)
check_string(p->strings[e]);
540:
fatal("Identifier offset is wrong!\n");
}
-
- for(e=0;e<(int)p->num_identifier_indexes;e++)
+ for(e=0;e<(int)p->num_identifier_index;e++)
{
if(p->identifier_index[e] > p->num_identifier_references)
fatal("Program->identifier_indexes[%ld] is wrong\n",(long)e);
549:
for(e=0;e<(int)p->num_inherits;e++)
{
- struct program *tmp_prog=p->inherits[e].prog;
- INT32 d;
-
+
if(p->inherits[e].storage_offset < 0)
fatal("Inherit->storage_offset is wrong.\n");
-
- for(d=0;d<(int)tmp_prog->num_identifiers;d++)
- {
- struct identifier *id=tmp_prog->identifiers+d;
-
- if(IDENTIFIER_IS_VARIABLE(id->identifier_flags))
- {
- INT32 offset,size,e2;
- offset=p->inherits[e].storage_offset + id->func.offset;
- size=id->run_time_type == T_MIXED ? sizeof(struct svalue) : sizeof(union anything);
-
- if(offset < 0 || offset+size > p->storage_needed)
- fatal("Variable located outside allocated space.\n");
-
-
- for(e2=0;e2<(int)p->num_inherits;e2++)
- {
- struct program *tmp_prog2=p->inherits[e2].prog;
- INT32 d2;
-
- for(d2=0;d2<(int)tmp_prog2->num_identifiers;d2++)
- {
- struct identifier *id2=tmp_prog2->identifiers+d2;
-
- if(e==e2 && d==d2) continue;
-
- if(IDENTIFIER_IS_VARIABLE(id2->identifier_flags))
- {
- INT32 offset2,size2;
-
- offset2=p->inherits[e2].storage_offset + id2->func.offset;
- size2=id2->run_time_type == T_MIXED ? sizeof(struct svalue) : sizeof(union anything);
- if( (offset > offset2) ?
- (offset2+size2 > offset) :
- (offset+size > offset2))
- {
- fatal("Variable %s (%ld+%ld) and %s (%ld+%ld) overlap.\n",
- id->name->str, (long)offset, (long)size,
- id2->name->str, (long)offset2, (long)size2);
+
}
}
- }
- }
- }
- }
- }
- }
+
#endif
- /* internal function to make the index-table */
- static int funcmp(const void *a,const void *b)
+ struct program *end_first_pass(int finish)
{
- 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) \
- prog->PTR=(TYPE *)p; \
- if((prog->PTRS = areas[AREA].s.len/sizeof(TYPE))) \
- { \
- MEMCPY(p,areas[AREA].s.str, areas[AREA].s.len); \
- p+=MY_ALIGN(areas[AREA].s.len); \
- }
-
- struct program *end_program(void)
- {
- struct pike_string **names;
- 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)
+ if(init_node)
{
union idptr tmp;
struct pike_string *s;
- push_locals();
+
s=make_shared_string("__INIT");
dooptcode(s,
mknode(F_ARG_LIST,
init_node,mknode(F_RETURN,mkintnode(0),0)),
function_type_string,
0);
- pop_locals();
+
free_string(s);
init_node=0;
}
-
+ pop_compiler_frame(); /* Pop __INIT local variables */
+
exit_type_stack();
- if (num_parse_error > 0)
+ if(num_parse_error > 0)
{
- toss_current_program();
+
prog=0;
}else{
- setup_fake_program();
- 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));
+ prog=new_program;
+ prog->refs++;
- p = (char *)xalloc(size);
- prog = (struct program *)p;
- *prog = fake_program;
- prog->total_size = size;
- prog->refs = 1;
- prog->flags=0;
- p += MY_ALIGN(sizeof (struct program));
-
- 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);
- INS_BLOCK(strings,num_strings,struct pike_string *,A_STRINGS);
- INS_BLOCK(inherits,num_inherits,struct inherit,A_INHERITS);
- INS_BLOCK(constants,num_constants,struct svalue,A_CONSTANTS);
-
- #ifdef PROFILING
- /* There is probably a better place for this, but... */
- for (i=0; i < prog->num_identifiers; i++) {
- prog->identifiers[i].num_calls = 0;
- }
- #endif /* PROFILING */
-
- /* Ok, sort for binsearch */
- prog->identifier_index=(unsigned short *)p;
- for(e=i=0;i<(int)prog->num_identifier_references;i++)
- {
- struct reference *funp;
- struct identifier *fun;
- funp=prog->identifier_references+i;
- if(funp->id_flags & (ID_HIDDEN|ID_STATIC)) continue;
-
- if(funp->id_flags & ID_INHERITED)
- {
- fun=ID_FROM_PTR(prog, funp);
- /* if(fun->func.offset == -1) continue; prototype */
-
- /* check for multiple definitions */
- for(t=i+1;t>=0 && t<(int)prog->num_identifier_references;t++)
- {
- struct reference *funpb;
- struct identifier *funb;
-
- funpb=prog->identifier_references+t;
- if(funpb->id_flags & (ID_HIDDEN|ID_STATIC)) 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);
-
- p+=MY_ALIGN(prog->num_identifier_indexes*sizeof(unsigned short));
-
- toss_compilation_resources();
-
- prog->inherits[0].prog=prog;
- prog->prev=0;
- if((prog->next=first_program))
- first_program->prev=prog;
- first_program=prog;
-
- for(i=0;i<NUM_LFUNS;i++)
- prog->lfuns[i]=find_identifier(lfun_names[i],prog);
-
+
#ifdef DEBUG
check_program(prog);
if(l_flag)
dump_program_desc(prog);
#endif
-
+ new_program->flags |= PROGRAM_PASS_1_DONE;
+
+ if(finish)
+ {
+ fixate_program();
+ optimize_program(new_program);
+ new_program->flags |= PROGRAM_FINISHED;
+ }
+
GC_ALLOC();
}
-
+ toss_compilation_resources();
- #define PROGRAM_STATE
+
#define POP
#include "compilation.h"
- #undef POP
- #undef PROGRAM_STATE
- if(fake_program.num_inherits)
- fake_program.inherits[0].prog=&fake_program;
+
+ compilation_depth--;
threads_disabled--;
free_all_nodes();
return prog;
}
/*
-
+ * Finish this program, returning the newly built program
+ */
+ struct program *end_program(void)
+ {
+ return end_first_pass(1);
+ }
+
+
+ /*
* 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;
+ offset=new_program->storage_needed;
size=MY_ALIGN(size);
- fake_program.storage_needed += size;
+ new_program->storage_needed += size;
return offset;
}
773:
*/
void set_init_callback(void (*init)(struct object *))
{
- fake_program.init=init;
+ new_program->init=init;
}
/*
782:
*/
void set_exit_callback(void (*exit)(struct object *))
{
- fake_program.exit=exit;
+ new_program->exit=exit;
}
/*
791:
*/
void set_gc_mark_callback(void (*m)(struct object *))
{
- fake_program.gc_marked=m;
+ new_program->gc_marked=m;
}
-
- int low_reference_inherited_identifier(int e,struct pike_string *name)
+ int low_reference_inherited_identifier(int e,
+ struct pike_string *name)
{
struct reference funp;
struct program *p;
int i,d;
- p=fake_program.inherits[e].prog;
+ p=new_program->inherits[e].prog;
i=find_shared_string_identifier(name,p);
if(i==-1) return i;
if(p->identifier_references[i].id_flags & ID_HIDDEN)
return -1;
- if(ID_FROM_INT(p,i)->func.offset == -1) /* prototype */
- return -1;
-
+
funp=p->identifier_references[i];
funp.inherit_offset+=e;
funp.id_flags|=ID_HIDDEN;
- for(d=0;d<(int)fake_program.num_identifier_references;d++)
+ for(d=0;d<(int)new_program->num_identifier_references;d++)
{
struct reference *fp;
- fp=fake_program.identifier_references+d;
+ fp=new_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;
+ add_to_identifier_references(funp);
+ return new_program->num_identifier_references -1;
}
-
-
+
int reference_inherited_identifier(struct pike_string *super_name,
struct pike_string *function_name)
{
- struct pike_string **names;
+
int e,i;
#ifdef DEBUG
840:
fatal("reference_inherited_function on nonshared string.\n");
#endif
- names=(struct pike_string **)inherit_names.s.str;
- setup_fake_program();
-
- for(e=fake_program.num_inherits-1;e>0;e--)
+ for(e=new_program->num_inherits-1;e>0;e--)
{
- if(fake_program.inherits[e].inherit_level!=1) continue;
- if(!names[e]) continue;
+ if(new_program->inherits[e].inherit_level!=1) continue;
+ if(!new_program->inherits[e].name) 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))
+ if(super_name != new_program->inherits[e].name)
continue;
- }
+
i=low_reference_inherited_identifier(e,function_name);
if(i==-1) continue;
868:
void rename_last_inherit(struct pike_string *n)
{
- struct pike_string **names;
- int e;
- names=(struct pike_string **)inherit_names.s.str;
- e=inherit_names.s.len / sizeof(struct pike_string *);
- free_string(names[e-1]);
- copy_shared_string(names[e-1],n);
+ 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);
}
/*
* make this program inherit another program
*/
- void do_inherit(struct program *p,INT32 flags, struct pike_string *name)
+ void do_inherit(struct svalue *prog,
+ INT32 flags,
+ struct pike_string *name)
{
int e, inherit_offset, storage_offset;
struct inherit inherit;
struct pike_string *s;
- setup_fake_program();
+ struct program *p=program_from_svalue(prog);
- inherit_offset = fake_program.num_inherits;
+
- storage_offset=fake_program.storage_needed;
+ if(!p)
+ {
+ yyerror("Illegal program pointer.");
+ return;
+ }
+
+ inherit_offset = new_program->num_inherits;
+
+ storage_offset=new_program->storage_needed;
add_storage(p->storage_needed);
for(e=0; e<(int)p->num_inherits; e++)
{
inherit=p->inherits[e];
inherit.prog->refs++;
- inherit.identifier_level += fake_program.num_identifier_references;
+ inherit.identifier_level += new_program->num_identifier_references;
inherit.storage_offset += storage_offset;
inherit.inherit_level ++;
- add_to_mem_block(A_INHERITS,(char *)&inherit,sizeof inherit);
+ if(!e)
+ {
+ if(prog->type == T_FUNCTION)
+ {
+ inherit.parent=prog->u.object;
+ inherit.parent_identifier=prog->subtype;
+ }
+ }
+ if(inherit.parent) inherit.parent->refs++;
- low_my_binary_strcat((char *)&name,sizeof(name),&inherit_names);
+
if(name)
{
-
+ if(e==0)
+ {
+ inherit.name=name;
reference_shared_string(name);
- name=0;
+
}
-
+ 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;
+ }
+ add_to_inherits(inherit);
+ }
for (e=0; e < (int)p->num_identifier_references; e++)
{
923:
{
int n;
n = isidentifier(name);
- if (n != -1 && ID_FROM_INT(&fake_program,n)->func.offset != -1)
+ if (n != -1 && ID_FROM_INT(new_program,n)->func.offset != -1)
my_yyerror("Illegal to redefine 'nomask' function/variable \"%s\"",name->str);
}
935:
fun.id_flags |= flags;
fun.id_flags |= ID_INHERITED;
- add_to_mem_block(A_IDENTIFIER_REFERENCES, (char *)&fun, sizeof fun);
+ add_to_identifier_references(fun);
}
/* Ska det h{r vara s} h{r? */
953:
}
}
- void simple_do_inherit(struct pike_string *s, INT32 flags,struct pike_string *name)
+ void simple_do_inherit(struct pike_string *s,
+ INT32 flags,
+ struct pike_string *name)
{
reference_shared_string(s);
push_string(s);
- reference_shared_string(current_file);
- push_string(current_file);
+ ref_push_string(lex.current_file);
SAFE_APPLY_MASTER("handle_inherit", 2);
if(sp[-1].type != T_PROGRAM)
973:
free_string(s);
s=name;
}
- do_inherit(sp[-1].u.program, flags, s);
+ do_inherit(sp-1, flags, s);
free_string(s);
pop_stack();
}
984:
int isidentifier(struct pike_string *s)
{
INT32 e;
- setup_fake_program();
- for(e=(int)fake_program.num_identifier_references-1;e>=0;e--)
+ for(e=new_program->num_identifier_references-1;e>=0;e--)
{
- if(fake_program.identifier_references[e].id_flags & ID_HIDDEN) continue;
+ if(new_program->identifier_references[e].id_flags & ID_HIDDEN) continue;
- if(ID_FROM_INT(& fake_program, e)->name == s)
+ if(ID_FROM_INT(new_program, e)->name == s)
return e;
}
return -1;
}
-
+ /* argument must be a shared string */
int low_define_variable(struct pike_string *name,
struct pike_string *type,
INT32 flags,
1002:
INT32 run_time_type)
{
int n;
+
struct identifier dummy;
struct reference ref;
-
+ #ifdef DEBUG
+ if(new_program->flags & (PROGRAM_FIXED | PROGRAM_OPTIMIZED))
+ fatal("Attempting to add variable to fixed program\n");
+ #endif
+
copy_shared_string(dummy.name, name);
copy_shared_string(dummy.type, type);
dummy.identifier_flags = 0;
dummy.run_time_type=run_time_type;
dummy.func.offset=offset;
-
+
#ifdef PROFILING
- dummy.num_calls = 0;
- #endif /* PROFILING */
+ dummy.num_calls=0;
+ #endif
ref.id_flags=flags;
- ref.identifier_offset=areas[A_IDENTIFIERS].s.len / sizeof dummy;
+ ref.identifier_offset=new_program->num_identifiers;
ref.inherit_offset=0;
- add_to_mem_block(A_IDENTIFIERS, (char *)&dummy, sizeof dummy);
- fake_program.num_identifiers ++;
+ add_to_identifiers(dummy);
- 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 ++;
+ n=new_program->num_identifier_references;
+ add_to_identifier_references(ref);
return n;
}
-
+
int map_variable(char *name,
char *type,
INT32 flags,
1061:
if(type == void_type_string)
yyerror("Variables can't be of type void");
- setup_fake_program();
+
n = isidentifier(name);
-
+ if(new_program->flags & PROGRAM_PASS_1_DONE)
+ {
+ if(n==-1)
+ yyerror("Pass2: Variable disappeared!");
+ else
+ return n;
+ }
+
+ #ifdef DEBUG
+ if(new_program->flags & (PROGRAM_FIXED | PROGRAM_OPTIMIZED))
+ fatal("Attempting to add variable to fixed program\n");
+ #endif
+
if(n != -1)
{
- setup_fake_program();
+
if (IDENTIFIERP(n)->id_flags & ID_NOMASK)
my_yyerror("Illegal to redefine 'nomask' variable/functions \"%s\"", name->str);
- if(PROG_FROM_INT(& fake_program, n) == &fake_program)
+ if(PROG_FROM_INT(new_program, n) == new_program)
my_yyerror("Variable '%s' defined twice.",name->str);
- if(ID_FROM_INT(& fake_program, n)->type != type)
+ if(ID_FROM_INT(new_program, n)->type != type)
my_yyerror("Illegal to redefine inherited variable with different type.");
- if(ID_FROM_INT(& fake_program, n)->identifier_flags != flags)
+ if(ID_FROM_INT(new_program, n)->identifier_flags != flags)
my_yyerror("Illegal to redefine inherited variable with different type.");
} else {
int run_time_type=compile_type_to_runtime_type(type);
- if(run_time_type == T_FUNCTION) run_time_type = T_MIXED;
+
- n=low_define_variable(name, type, flags,
+ switch(run_time_type)
+ {
+ case T_FUNCTION:
+ case T_PROGRAM:
+ run_time_type = T_MIXED;
+ }
+
+ n=low_define_variable(name,type,flags,
add_storage(run_time_type == T_MIXED ?
sizeof(struct svalue) :
sizeof(union anything)),
run_time_type);
-
+
+
}
return n;
1109:
return ret;
}
-
+ /* FIXME: add_constant with c==0 means declaration */
int add_constant(struct pike_string *name,
struct svalue *c,
INT32 flags)
1123:
fatal("define_constant on nonshared string.\n");
#endif
- setup_fake_program();
+
n = isidentifier(name);
-
+
+ if(new_program->flags & PROGRAM_PASS_1_DONE)
+ {
+ if(n==-1)
+ {
+ yyerror("Pass2: Constant disappeared!");
+ }else{
+ #if 1
+ struct identifier *id;
+ id=ID_FROM_INT(new_program,n);
+ if(id->func.offset>=0)
+ {
+ struct pike_string *s;
+ struct svalue *c=PROG_FROM_INT(new_program,n)->constants+
+ id->func.offset;
+ s=get_type_of_svalue(c);
+ free_string(id->type);
+ id->type=s;
+ }
+ #endif
+ return n;
+ }
+ }
+
+ #ifdef DEBUG
+ if(new_program->flags & (PROGRAM_FIXED | PROGRAM_OPTIMIZED))
+ fatal("Attempting to add constant to fixed program\n");
+ #endif
+
copy_shared_string(dummy.name, name);
dummy.type = get_type_of_svalue(c);
1134:
dummy.func.offset=store_constant(c, 0);
- #ifdef PROFILING
- /* Not strictly necessary, but... */
- dummy.num_calls = 0;
- #endif /* PROFILING */
-
+
ref.id_flags=flags;
- ref.identifier_offset=fake_program.num_identifiers;
+ ref.identifier_offset=new_program->num_identifiers;
ref.inherit_offset=0;
- add_to_mem_block(A_IDENTIFIERS, (char *)&dummy, sizeof dummy);
- fake_program.num_identifiers ++;
+ #ifdef PROFILEING
+ dummy.num_calls=0;
+ #endif
-
+ add_to_identifiers(dummy);
+
if(n != -1)
{
- if (IDENTIFIERP(n)->id_flags & ID_NOMASK)
+ if(IDENTIFIERP(n)->id_flags & ID_NOMASK)
my_yyerror("Illegal to redefine 'nomask' identifier \"%s\"", name->str);
- if(PROG_FROM_INT(& fake_program, n) == &fake_program)
+ if(PROG_FROM_INT(new_program, n) == new_program)
my_yyerror("Identifier '%s' defined twice.",name->str);
- fake_program.identifier_references[n]=ref;
+ new_program->identifier_references[n]=ref;
} else {
- 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 ++;
+ n=new_program->num_identifier_references;
+ add_to_identifier_references(ref);
}
return n;
1270:
i=isidentifier(name);
- setup_fake_program();
+
if(i >= 0)
{
/* already defined */
- funp=ID_FROM_INT(&fake_program, i);
- ref=fake_program.identifier_references[i];
+ funp=ID_FROM_INT(new_program, i);
+ ref=new_program->identifier_references[i];
if(ref.inherit_offset == 0) /* not inherited */
{
1294:
}
}
- /* it's just another prototype, don't define anything */
- if(!func || func->offset == -1) return i;
-
- if((ref.id_flags & ID_NOMASK) &&
- !(funp->func.offset == -1))
+ if((ref.id_flags & ID_NOMASK) && !(funp->func.offset == -1))
{
my_yyerror("Illegal to redefine 'nomask' function %s.",name->str);
}
1326:
else
fun.func.offset = -1;
- #ifdef PROFILING
- fun.num_calls = 0;
- #endif /* PROFILING */
-
- ref.identifier_offset=fake_program.num_identifiers;
- add_to_mem_block(A_IDENTIFIERS, (char *)&fun, sizeof(fun));
+ ref.identifier_offset=new_program->num_identifiers;
+ add_to_identifiers(fun);
}
ref.inherit_offset = 0;
ref.id_flags = flags;
- fake_program.identifier_references[i]=ref;
+ new_program->identifier_references[i]=ref;
}else{
/* define it */
1352:
else
fun.func.offset = -1;
- i=fake_program.num_identifiers;
- add_to_mem_block(A_IDENTIFIERS, (char *)&fun, sizeof(fun));
+ i=new_program->num_identifiers;
+ #ifdef PROFILING
+ fun.num_calls = 0;
+ #endif /* PROFILING */
-
+ add_to_identifiers(fun);
+
ref.id_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);
-
+ i=new_program->num_identifier_references;
+ add_to_identifier_references(ref);
}
return i;
}
1371:
* lookup the number of a function in a program given the name in
* a shared_string
*/
- static int low_find_shared_string_identifier(struct pike_string *name,
+ int low_find_shared_string_identifier(struct pike_string *name,
struct program *prog)
{
int max,min,tst;
struct reference *funp;
struct identifier *fun;
- unsigned short *funindex;
+
- funindex = prog->identifier_index;
- if(funindex)
+ if(prog->flags & PROGRAM_FIXED)
{
- max = prog->num_identifier_indexes;
+ unsigned short *funindex = prog->identifier_index;
+
+ #ifdef DEBUG
+ if(!funindex)
+ fatal("No funindex in fixed program\n");
+ #endif
+
+ max = prog->num_identifier_index;
min = 0;
while(max != min)
{
1401:
funp = prog->identifier_references + i;
if(funp->id_flags & ID_HIDDEN) continue;
fun = ID_FROM_PTR(prog, funp);
- if(fun->func.offset == -1) continue; /* Prototype */
+ /* if(fun->func.offset == -1) continue; * Prototype */
if(!is_same_string(fun->name,name)) continue;
if(funp->id_flags & ID_INHERITED)
{
1448:
struct program *prog)
{
#ifdef FIND_FUNCTION_HASHSIZE
- if(prog!=&fake_program)
+ if(prog -> flags & PROGRAM_FIXED)
{
unsigned int hashval;
hashval=my_hash_string(name);
1483:
int store_prog_string(struct pike_string *str)
{
unsigned int i;
- struct pike_string **p;
+
- p = (struct pike_string **)areas[A_STRINGS].s.str;
-
- for (i=0;i<areas[A_STRINGS].s.len / sizeof str;i++)
- if (p[i] == str)
+ for (i=0;i<new_program->num_strings;i++)
+ if (new_program->strings[i] == str)
return i;
reference_shared_string(str);
- add_to_mem_block(A_STRINGS, (char *)&str, sizeof str);
+ add_to_strings(str);
return i;
}
int store_constant(struct svalue *foo, int equal)
{
- struct svalue *s,tmp;
+ struct svalue tmp;
unsigned int e;
- s=(struct svalue *)areas[A_CONSTANTS].s.str;
+
- for(e=0;e<areas[A_CONSTANTS].s.len / sizeof(struct svalue);e++)
- if(equal ? is_equal(s+e,foo) : is_eq(s+e,foo))
+ for(e=0;e<new_program->num_constants;e++)
+ {
+ struct svalue *s=new_program->constants + e;
+ if(equal ? is_equal(s,foo) : is_eq(s,foo))
return e;
-
+ }
assign_svalue_no_free(&tmp,foo);
- add_to_mem_block(A_CONSTANTS,(char *)&tmp,sizeof(struct svalue));
+ add_to_constants(tmp);
return e;
}
1536:
void start_line_numbering(void)
{
- if(last_file) { free_string(last_file); last_file=0; }
+ if(last_file)
+ {
+ free_string(last_file);
+ last_file=0;
+ }
last_pc=last_line=0;
}
- static void insert_small_number(int a,int area)
+ static void insert_small_number(INT32 a)
{
if(a>-127 && a<127)
{
- ins_byte(a,area);
+ add_to_linenumbers(a);
}else if(a>=-32768 && a<32768){
- ins_signed_byte(-127,area);
- ins_short(a,area);
+ add_to_linenumbers(a);
+ ins_short(a, add_to_linenumbers);
}else{
- ins_signed_byte(-128,area);
- ins_int(a,area);
+ add_to_linenumbers(-128);
+ ins_int(a, add_to_linenumbers);
}
}
1562:
{
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);
+ add_to_linenumbers(127);
+ for(tmp=current_file->str; *tmp; tmp++)
+ add_to_linenumbers(*tmp);
+ add_to_linenumbers(0);
copy_shared_string(last_file, current_file);
}
- insert_small_number(PC-last_pc,A_LINENUMBERS);
- insert_small_number(current_line-last_line,A_LINENUMBERS);
+ insert_small_number(PC-last_pc);
+ insert_small_number(current_line-last_line);
last_line=current_line;
last_pc=PC;
}
1589:
if (prog == 0) return "Unkown program";
offset = pc - prog->program;
- if(prog == & fake_program)
+ if(prog == new_program)
{
linep[0]=0;
return "Optimizer";
}
- #ifdef DEBUG
- if (offset > (INT32)prog->program_size || offset<0)
- fatal("Illegal offset %ld in program.\n", (long)offset);
- #endif
-
+
cnt=prog->linenumbers;
off=line=0;
file="Line not found";
-
+ if (offset > (INT32)prog->num_program || offset<0)
+ return file;
+
while(cnt < prog->linenumbers + prog->num_linenumbers)
{
if(*cnt == 127)
1618:
return file;
}
- void my_yyerror(char *fmt,...)
+ void my_yyerror(char *fmt,...) ATTRIBUTE((format(printf,1,2)))
{
va_list args;
- char buf[1000];
+ char buf[8192];
va_start(args,fmt);
VSPRINTF(buf,fmt,args);
1632:
va_end(args);
}
- /*
- * Compile an PIKE file. Input is supposed to be initalized already.
- */
- void compile(void)
+ struct program *compile(struct pike_string *prog)
{
- int yyparse(void);
+ struct program *p;
+ struct lex save_lex;
+ int save_depth=compilation_depth;
+ void yyparse(void);
- start_line_numbering();
+ save_lex=lex;
- num_parse_error = 0;
- init_node=0;
+ lex.end=prog->str+prog->len;
+ lex.current_line=1;
+ lex.current_file=make_shared_string("-");
+ lex.pragmas=0;
- yyparse(); /* Parse da program */
- #ifdef DEBUG
- if(recoveries && sp-evaluator_stack < recoveries->sp)
- fatal("Stack error in compilation (underflow after yyparse)\n");
- #endif
- free_all_local_names();
- }
+ start_new_program();
+ compilation_depth=0;
- struct program *compile_file(struct pike_string *file_name)
- {
- int fd;
- struct program *p;
+ start_line_numbering();
- while(1)
- {
- fd=open(file_name->str,O_RDONLY);
- if(fd >= 0) break;
- if(errno != EINTR)
- {
- #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
- }
- }
+ compiler_pass=1;
+ lex.pos=prog->str;
+ yyparse(); /* Parse da program */
- #define FILE_STATE
- #define PUSH
- #include "compilation.h"
- #undef PUSH
+ p=end_first_pass(0);
- start_new_file(fd,file_name);
- start_new_program();
- compile();
+ if(p && !num_parse_error)
+ {
+ low_start_new_program(p,0,0);
+ compiler_pass=2;
+ lex.pos=prog->str;
+ yyparse(); /* Parse da program again */
p=end_program();
- end_new_file();
-
- #define POP
- #include "compilation.h"
- #undef POP
- #undef FILE_STATE
-
- if(!p) error("Failed to compile %s.\n",file_name->str);
- return p;
+
}
- struct program *compile_string(struct pike_string *prog,
- struct pike_string *name)
- {
- struct program *p;
+
- #define FILE_STATE
- #define PUSH
- #include "compilation.h"
- #undef PUSH
+ free_string(lex.current_file);
+ lex=save_lex;
- start_new_string(prog->str,prog->len,name);
- start_new_program();
- compile();
- p=end_program();
- end_new_file();
+ compilation_depth=save_depth;
- #define POP
- #include "compilation.h"
- #undef POP
- #undef FILE_STATE
-
+
if(!p) error("Compilation failed.\n");
return p;
}
1786:
#endif
}
+ #ifdef GC2
+
void gc_mark_program_as_referenced(struct program *p)
{
if(gc_mark(p))
-
+ {
+ int e;
gc_mark_svalues(p->constants, p->num_constants);
-
+
+ for(e=0;e<p->num_inherits;e++)
+ {
+ if(p->inherits[e].parent)
+ gc_mark_object_as_referenced(p->inherits[e].parent);
+
+ if(e)
+ gc_mark_program_as_referenced(p->inherits[e].prog);
}
-
+ }
+ }
+
void gc_check_all_programs(void)
{
struct program *p;
for(p=first_program;p;p=p->next)
{
- debug_gc_check_svalues(p->constants, p->num_constants, T_PROGRAM, p);
+ int e;
+ gc_check_svalues(p->constants, p->num_constants);
-
+ for(e=0;e<p->num_inherits;e++)
+ {
+ if(p->inherits[e].parent)
+ {
#ifdef DEBUG
-
+ if(gc_check(p->inherits[e].parent)==-2)
+ fprintf(stderr,"(program at 0x%lx -> inherit[%d].parent)\n",
+ (long)p,
+ e);
+ #else
+ gc_check(p->inherits[e].parent);
+ #endif
+ }
+
+ if(d_flag && p->inherits[e].name)
+ gc_check(p->inherits[e].name);
+
+ if(e)
+ gc_check(p->inherits[e].prog);
+ }
+
if(d_flag)
{
int e;
1812: Inside #if defined(DEBUG)
gc_check(p->identifiers[e].type);
}
}
- #endif
+
}
}
1832:
{
if(gc_do_free(p))
{
+ int e;
p->refs++;
free_svalues(p->constants, p->num_constants, -1);
-
+ for(e=0;e<p->num_inherits;e++)
+ {
+ if(p->inherits[e].parent)
+ {
+ free_object(p->inherits[e].parent);
+ p->inherits[e].parent=0;
+ }
+ }
next=p->next;
free_program(p);
}else{
1842:
}
}
+ #endif /* GC2 */
-
+
void count_memory_in_programs(INT32 *num_, INT32 *size_)
{
INT32 size=0, num=0;
1855:
*num_=num;
*size_=size;
}
- void push_locals(void)
+
+ void push_compiler_frame(void)
{
- 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;
+ struct compiler_frame *f;
+ f=ALLOC_STRUCT(compiler_frame);
+ 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_locals(void)
+ void pop_local_variables(int level)
{
- 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);
+ 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);
+ }
+ }
- local_variables=l;
- /* insert check if ( local->next == parent locals ) here */
+
+ void pop_compiler_frame(void)
+ {
+ struct compiler_frame *f;
+ int e;
+ f=compiler_frame;
+ #ifdef DEBUG
+ if(!f)
+ fatal("Popping out of compiler frames\n");
+ #endif
+
+ pop_local_variables(0);
+ if(f->current_type)
+ free_string(f->current_type);
+
+ if(f->current_return_type)
+ free_string(f->current_return_type);
+
+ compiler_frame=f->previous;
+ free((char *)f);
}
1897:
oid=o->prog->id;
pid=p->id;
hval=oid*9248339 + pid;
- hval %= GET_STORAGE_CACHE_SIZE;
+ hval%=GET_STORAGE_CACHE_SIZE;
#ifdef DEBUG
if(hval>GET_STORAGE_CACHE_SIZE)
fatal("hval>GET_STORAGE_CACHE_SIZE");
1926:
if(offset == -1) return 0;
return o->storage + offset;
}
+
+ 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;
+ f=PROG_FROM_INT(p,i)->constants + id->func.offset;
+ 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)
+ {
+ 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)
+ {
+ INT32 h=(parent->id * 9248339 + child->id) % FIND_CHILD_HASHSIZE;
+ 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;
+ va_start(args,fmt);
+ VSPRINTF(buf, fmt, args);
+ va_end(args);
+
+ if(strlen(buf)>sizeof(buf))
+ fatal("Buffer overfloat in yywarning!\n");
+
+ if(get_master())
+ {
+ ref_push_string(lex.current_file);
+ push_int(lex.current_line);
+ push_text(buf);
+ SAFE_APPLY_MASTER("compile_warning",3);
+ pop_stack();
+ }
+ }