|
|
|
|
|
|
|
#include "global.h" |
#include "program.h" |
#include "object.h" |
#include "dynamic_buffer.h" |
#include "pike_types.h" |
#include "stralloc.h" |
#include "las.h" |
#include "lex.h" |
#include "pike_macros.h" |
#include "fsort.h" |
#include "pike_error.h" |
#include "docode.h" |
#include "interpret.h" |
#include "hashtable.h" |
#include "main.h" |
#include "pike_memory.h" |
#include "gc.h" |
#include "threads.h" |
#include "constants.h" |
#include "operators.h" |
#include "builtin_functions.h" |
#include "stuff.h" |
#include "mapping.h" |
#include "cyclic.h" |
#include "pike_security.h" |
#include "pike_types.h" |
#include "opcodes.h" |
#include "version.h" |
#include "block_alloc.h" |
#include "pikecode.h" |
#include "pike_compiler.h" |
#include "module_support.h" |
|
#include <errno.h> |
#include <fcntl.h> |
|
#define sp Pike_sp |
|
#undef ATTRIBUTE |
#define ATTRIBUTE(X) |
|
static void low_enter_compiler(struct object *ce, int inherit); |
static void exit_program_struct(struct program *); |
static size_t add_xstorage(size_t size, |
size_t alignment, |
ptrdiff_t modulo_orig); |
|
#undef EXIT_BLOCK |
#define EXIT_BLOCK(P) exit_program_struct( (P) ) |
|
#undef COUNT_OTHER |
#define COUNT_OTHER() do{ \ |
struct program *p; \ |
for(p=first_program;p;p=p->next) \ |
{ \ |
size+=p->total_size - sizeof (struct program); \ |
} \ |
}while(0) |
|
BLOCK_ALLOC_FILL_PAGES(program, 4) |
|
|
|
|
|
#ifdef COMPILER_DEBUG |
#define CDFPRINTF(X) fprintf X |
#else /* !COMPILER_DEBUG */ |
#define CDFPRINTF(X) |
#endif /* COMPILER_DEBUG */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define FIND_FUNCTION_HASHSIZE 15013 |
|
|
#define FIND_FUNCTION_HASH_TRESHOLD 9 |
|
|
#define DECLARE |
#include "compilation.h" |
|
struct pike_string *this_program_string; |
static struct pike_string *this_string, *this_function_string; |
static struct pike_string *UNDEFINED_string; |
|
|
struct pike_string *parser_system_string; |
struct pike_string *type_check_system_string; |
|
const char *const lfun_names[] = { |
"__INIT", |
"create", |
"destroy", |
"`+", |
"`-", |
"`&", |
"`|", |
"`^", |
"`<<", |
"`>>", |
"`*", |
"`/", |
"`%", |
"`~", |
"`==", |
"`<", |
"`>", |
"__hash", |
"cast", |
"`!", |
"`[]", |
"`[]=", |
"`->", |
"`->=", |
"_sizeof", |
"_indices", |
"_values", |
"`()", |
"``+", |
"``-", |
"``&", |
"``|", |
"``^", |
"``<<", |
"``>>", |
"``*", |
"``/", |
"``%", |
"`+=", |
"_is_type", |
"_sprintf", |
"_equal", |
"_m_delete", |
"_get_iterator", |
"`[..]", |
|
"_search", |
}; |
|
struct pike_string *lfun_strings[NELEM(lfun_names)]; |
|
static struct mapping *lfun_ids; |
|
|
static struct mapping *lfun_types; |
|
static const char *const raw_lfun_types[] = { |
tFuncV(tNone,tVoid,tVoid), |
tFuncV(tNone,tZero,tVoid), |
tFuncV(tOr(tVoid,tInt),tVoid,tVoid), |
tFuncV(tZero,tZero,tMix), |
tFunc(tOr(tVoid,tZero),tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tZero,tVoid,tMix), |
tFuncV(tZero,tVoid,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tNone,tVoid,tMix), |
tFuncV(tMix,tVoid,tInt), |
tFuncV(tMix,tVoid,tInt), |
tFuncV(tMix,tVoid,tInt), |
tFuncV(tNone,tVoid,tInt), |
tFuncV(tString,tVoid,tMix), |
tFuncV(tNone,tVoid,tInt), |
tFuncV(tZero,tVoid,tMix), |
tFuncV(tZero tSetvar(0,tZero),tVoid,tVar(0)), |
tFuncV(tStr,tVoid,tMix), |
tFuncV(tStr tSetvar(0,tZero),tVoid,tVar(0)), |
tFuncV(tNone,tVoid,tInt), |
tFuncV(tNone,tVoid,tArray), |
tFuncV(tNone,tVoid,tArray), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tZero,tZero,tMix), |
tFuncV(tZero,tVoid,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tZero,tVoid,tMix), |
tFuncV(tZero,tVoid,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tNone,tZero,tMix), |
tFuncV(tZero,tZero,tMix), |
tFuncV(tStr,tVoid,tInt), |
tFuncV(tInt tOr(tMap(tStr,tInt),tVoid),tVoid,tStr), |
tFuncV(tMix,tVoid,tInt), |
tFuncV(tZero,tVoid,tMix), |
tFuncV(tNone,tVoid,tObj), |
tFuncV(tZero tRangeBound tZero tRangeBound, tVoid, tMix), |
|
tFuncV(tZero tOr(tZero, tVoid), tVoid, tMix), |
}; |
|
|
static struct pike_type *lfun_getter_type_string = NULL; |
static struct pike_type *lfun_setter_type_string = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct program *first_program = 0; |
static int current_program_id = PROG_DYNAMIC_ID_START; |
|
struct program *null_program=0; |
|
struct program *compilation_program = 0; |
struct program *compilation_env_program = 0; |
struct object *compilation_environment = NULL; |
|
struct program *gc_internal_program = 0; |
static struct program *gc_mark_program_pos = 0; |
|
static struct mapping *resolve_cache=0; |
|
#ifdef PIKE_DEBUG |
#define CHECK_FILE_ENTRY(PROG, POS, LEN, SHIFT) \ |
do { \ |
if (SHIFT < 0 || SHIFT > 2 || \ |
POS + (LEN << SHIFT) > PROG->linenumbers + PROG->num_linenumbers) \ |
Pike_fatal ("Invalid file entry in linenumber info.\n"); \ |
} while (0) |
#else |
#define CHECK_FILE_ENTRY(PROG, POS, LEN, SHIFT) do {} while (0) |
#endif |
|
int get_small_number(char **q); |
|
PMOD_EXPORT void do_free_program (struct program *p) |
{ |
if (p) |
free_program(p); |
} |
|
|
|
#ifdef PIKE_DEBUG |
#define CHECK_FOO(NUMTYPE,TYPE,NAME) \ |
if(Pike_compiler->malloc_size_program-> PIKE_CONCAT(num_,NAME) < \ |
Pike_compiler->new_program-> PIKE_CONCAT(num_,NAME)) \ |
Pike_fatal("Pike_compiler->new_program->num_" #NAME " is out of order\n");\ |
if(Pike_compiler->new_program->flags & PROGRAM_OPTIMIZED) \ |
Pike_fatal("Tried to reallocate fixed program.\n") |
|
#else |
#define CHECK_FOO(NUMTYPE,TYPE,NAME) |
#endif |
|
#ifndef RELOCATE_program |
#define RELOCATE_program(ORIG, NEW) |
#endif /* !RELOCATE_program */ |
#define RELOCATE_linenumbers(ORIG,NEW) |
#define RELOCATE_identifier_index(ORIG,NEW) |
#define RELOCATE_variable_index(ORIG,NEW) |
#define RELOCATE_identifier_references(ORIG,NEW) |
#define RELOCATE_strings(ORIG,NEW) |
#define RELOCATE_inherits(ORIG,NEW) |
#define RELOCATE_identifiers(ORIG,NEW) |
#define RELOCATE_constants(ORIG,NEW) |
#define RELOCATE_relocations(ORIG,NEW) |
|
#if SIZEOF_LONG_LONG == 8 |
|
#define MAXVARS(NUMTYPE) \ |
(NUMTYPE)(sizeof(NUMTYPE)==1?254: \ |
(sizeof(NUMTYPE)==2?65534: \ |
(sizeof(NUMTYPE)==4?4294967294U:18446744073709551614ULL))) |
#else |
#define MAXVARS(NUMTYPE) \ |
(NUMTYPE)(sizeof(NUMTYPE)==1?254: (sizeof(NUMTYPE)==2?65534:4294967294U)) |
#endif |
|
#ifdef PIKE_USE_MACHINE_CODE |
|
* many OSes require us to use mmap to allocate memory for our |
* machine code. |
*/ |
#define BAR(NUMTYPE,TYPE,ARGTYPE,NAME) \ |
void PIKE_CONCAT(low_add_to_,NAME) (struct program_state *state, \ |
TYPE ARG) { \ |
NUMTYPE m = state->malloc_size_program->PIKE_CONCAT(num_,NAME); \ |
CHECK_FOO(NUMTYPE,TYPE,NAME); \ |
if(m == state->new_program->PIKE_CONCAT(num_,NAME)) { \ |
TYPE *tmp; \ |
if(m==MAXVARS(NUMTYPE)) { \ |
yyerror("Too many " #NAME "."); \ |
return; \ |
} \ |
m = MINIMUM(m*2+1,MAXVARS(NUMTYPE)); \ |
tmp = mexec_realloc((void *)state->new_program->NAME, \ |
sizeof(TYPE) * m); \ |
if(!tmp) Pike_fatal("Out of memory.\n"); \ |
PIKE_CONCAT(RELOCATE_,NAME)(state->new_program, tmp); \ |
state->malloc_size_program->PIKE_CONCAT(num_,NAME)=m; \ |
state->new_program->NAME=tmp; \ |
} \ |
state->new_program-> \ |
NAME[state->new_program->PIKE_CONCAT(num_,NAME)++]=(ARG); \ |
} \ |
void PIKE_CONCAT(add_to_,NAME) (ARGTYPE ARG) { \ |
PIKE_CONCAT(low_add_to_,NAME) ( Pike_compiler, ARG ); \ |
} |
#endif /* PIKE_USE_MACHINE_CODE */ |
|
|
|
#define FOO(NUMTYPE,TYPE,ARGTYPE,NAME) \ |
void PIKE_CONCAT(low_add_to_,NAME) (struct program_state *state, \ |
TYPE ARG) { \ |
NUMTYPE m = state->malloc_size_program->PIKE_CONCAT(num_,NAME); \ |
CHECK_FOO(NUMTYPE,TYPE,NAME); \ |
if(m == state->new_program->PIKE_CONCAT(num_,NAME)) { \ |
TYPE *tmp; \ |
if(m==MAXVARS(NUMTYPE)) { \ |
yyerror("Too many " #NAME "."); \ |
return; \ |
} \ |
m = MINIMUM(m*2+1,MAXVARS(NUMTYPE)); \ |
tmp = realloc((void *)state->new_program->NAME, \ |
sizeof(TYPE) * m); \ |
if(!tmp) Pike_fatal("Out of memory.\n"); \ |
PIKE_CONCAT(RELOCATE_,NAME)(state->new_program, tmp); \ |
state->malloc_size_program->PIKE_CONCAT(num_,NAME)=m; \ |
state->new_program->NAME=tmp; \ |
} \ |
state->new_program-> \ |
NAME[state->new_program->PIKE_CONCAT(num_,NAME)++]=(ARG); \ |
} \ |
void PIKE_CONCAT(add_to_,NAME) (ARGTYPE ARG) { \ |
PIKE_CONCAT(low_add_to_,NAME) ( Pike_compiler, ARG ); \ |
} |
|
|
|
#define PASS1ONLY(NUMTYPE,TYPE,ARGTYPE,NAME) \ |
void PIKE_CONCAT(low_add_to_,NAME) (struct program_state *state, \ |
TYPE ARG) { \ |
NUMTYPE m = state->malloc_size_program->PIKE_CONCAT(num_,NAME); \ |
CHECK_FOO(NUMTYPE,TYPE,NAME); \ |
DO_IF_DEBUG(if (state->compiler_pass != 1) { \ |
Pike_fatal("Adding " TOSTR(NAME) " in pass %d.\n", \ |
state->compiler_pass); \ |
}); \ |
if(m == state->new_program->PIKE_CONCAT(num_,NAME)) { \ |
TYPE *tmp; \ |
if(m==MAXVARS(NUMTYPE)) { \ |
yyerror("Too many " #NAME "."); \ |
return; \ |
} \ |
m = MINIMUM(m*2+1,MAXVARS(NUMTYPE)); \ |
tmp = realloc((void *)state->new_program->NAME, \ |
sizeof(TYPE) * m); \ |
if(!tmp) Pike_fatal("Out of memory.\n"); \ |
PIKE_CONCAT(RELOCATE_,NAME)(state->new_program, tmp); \ |
state->malloc_size_program->PIKE_CONCAT(num_,NAME)=m; \ |
state->new_program->NAME=tmp; \ |
} \ |
state->new_program-> \ |
NAME[state->new_program->PIKE_CONCAT(num_,NAME)++]=(ARG); \ |
} \ |
void PIKE_CONCAT(add_to_,NAME) (ARGTYPE ARG) { \ |
PIKE_CONCAT(low_add_to_,NAME) ( Pike_compiler, ARG ); \ |
} |
|
|
#include "program_areas.h" |
|
|
#define add_to_program(ARG) do { \ |
debug_malloc_touch(Pike_compiler->new_program->program); \ |
add_to_program(ARG); \ |
} while(0) |
|
void ins_int(INT32 i, void (*func)(char tmp)) |
{ |
int e; |
unsigned char *p = (unsigned char *)&i; |
for(e=0;e<(long)sizeof(i);e++) { |
func(p[e]); |
} |
} |
|
void ins_short(int i, void (*func)(char tmp)) |
{ |
int e; |
unsigned char *p = (unsigned char *)&i; |
for(e=0;e<(long)sizeof(i);e++) { |
func(p[e]); |
} |
} |
|
#if 0 |
|
* before checking for duplicates in add_constant. */ |
static void debug_add_to_identifiers (struct identifier id) |
{ |
if (d_flag) { |
int i; |
for (i = 0; i < Pike_compiler->new_program->num_identifiers; i++) |
if (Pike_compiler->new_program->identifiers[i].name == id.name) { |
dump_program_tables (Pike_compiler->new_program, 0); |
Pike_fatal ("Adding identifier twice, old at %s:%d #%d.\n", |
Pike_compiler->new_program->identifiers[i].filename? |
Pike_compiler->new_program->identifiers[i].filename:"-", |
Pike_compiler->new_program->identifiers[i].linenumber, |
i); |
} |
} |
add_to_identifiers (id); |
} |
#else |
#define debug_add_to_identifiers(ARG) add_to_identifiers(ARG) |
#endif |
|
void add_relocated_int_to_program(INT32 i) |
{ |
add_to_relocations(Pike_compiler->new_program->num_program); |
ins_int(i, (void (*)(char))add_to_program); |
} |
|
void use_module(struct svalue *s) |
{ |
struct compilation *c = THIS_COMPILATION; |
if( (1<<s->type) & (BIT_MAPPING | BIT_OBJECT | BIT_PROGRAM)) |
{ |
c->num_used_modules++; |
Pike_compiler->num_used_modules++; |
assign_svalue_no_free((struct svalue *) |
low_make_buf_space(sizeof(struct svalue), |
&c->used_modules), s); |
if(Pike_compiler->module_index_cache) |
{ |
free_mapping(Pike_compiler->module_index_cache); |
Pike_compiler->module_index_cache=0; |
} |
}else{ |
yyerror("Module is neither mapping nor object"); |
} |
} |
|
void unuse_modules(INT32 howmany) |
{ |
struct compilation *c = THIS_COMPILATION; |
if(!howmany) return; |
#ifdef PIKE_DEBUG |
if(howmany *sizeof(struct svalue) > c->used_modules.s.len) |
Pike_fatal("Unusing too many modules.\n"); |
#endif |
c->num_used_modules -= howmany; |
Pike_compiler->num_used_modules-=howmany; |
low_make_buf_space(-sizeof(struct svalue)*howmany, &c->used_modules); |
free_svalues((struct svalue *)low_make_buf_space(0, &c->used_modules), |
howmany, |
BIT_MAPPING | BIT_OBJECT | BIT_PROGRAM); |
if(Pike_compiler->module_index_cache) |
{ |
free_mapping(Pike_compiler->module_index_cache); |
Pike_compiler->module_index_cache=0; |
} |
} |
|
int low_find_shared_string_identifier(struct pike_string *name, |
struct program *prog); |
|
|
|
static struct node_s *index_modules(struct pike_string *ident, |
struct mapping **module_index_cache, |
int num_used_modules, |
struct svalue *modules) |
{ |
if(*module_index_cache) |
{ |
struct svalue *tmp=low_mapping_string_lookup(*module_index_cache,ident); |
if(tmp) |
{ |
if(!(SAFE_IS_ZERO(tmp) && tmp->subtype==1)) |
return mksvaluenode(tmp); |
return 0; |
} |
} |
|
|
|
{ |
JMP_BUF tmp; |
|
if(SETJMP(tmp)) |
handle_compile_exception ("Couldn't index a module with %S.", ident); |
else { |
int e = num_used_modules; |
struct svalue *m = modules - num_used_modules; |
|
while(--e>=0) |
{ |
push_svalue(m+e); |
ref_push_string(ident); |
f_index(2); |
|
if(!IS_UNDEFINED(Pike_sp-1)) |
{ |
struct node_s *ret; |
UNSETJMP(tmp); |
|
if (Pike_compiler->compiler_pass == 2 && |
((Pike_sp[-1].type == T_OBJECT && |
Pike_sp[-1].u.object == placeholder_object) || |
(Pike_sp[-1].type == T_PROGRAM && |
Pike_sp[-1].u.program == placeholder_program))) { |
my_yyerror("Got placeholder %s (resolver problem) " |
"when indexing a module with %S.", |
get_name_of_type (Pike_sp[-1].type), ident); |
ret = 0; |
} |
else { |
if(!*module_index_cache) |
*module_index_cache = allocate_mapping(10); |
mapping_string_insert(*module_index_cache, ident, Pike_sp-1); |
ret = mksvaluenode(Pike_sp-1); |
} |
pop_stack(); |
return ret; |
} |
pop_stack(); |
} |
} |
UNSETJMP(tmp); |
} |
|
|
|
return 0; |
} |
|
struct node_s *resolve_identifier(struct pike_string *ident); |
|
struct node_s *find_module_identifier(struct pike_string *ident, |
int see_inherit) |
{ |
struct compilation *c = THIS_COMPILATION; |
struct node_s *ret; |
|
struct svalue *modules=(struct svalue *) |
(c->used_modules.s.str + c->used_modules.s.len); |
|
{ |
struct program_state *p=Pike_compiler; |
int n; |
for(n=0;n<=c->compilation_depth;n++,p=p->previous) |
{ |
int i; |
if(see_inherit) |
{ |
i=really_low_find_shared_string_identifier(ident, |
p->new_program, |
SEE_STATIC|SEE_PRIVATE); |
if(i!=-1) |
{ |
if ((p->flags & COMPILATION_FORCE_RESOLVE) && |
(p->compiler_pass == 2) && |
((p->num_inherits + 1) < p->new_program->num_inherits) && |
(PTR_FROM_INT(p->new_program, i)->inherit_offset > |
p->num_inherits)) { |
|
|
|
continue; |
} |
return p == Pike_compiler ? |
mkidentifiernode(i) : |
mkexternalnode(p->new_program, i); |
} |
} |
|
if((ret=index_modules(ident, |
&p->module_index_cache, |
p->num_used_modules, |
modules))) return ret; |
modules-=p->num_used_modules; |
#ifdef PIKE_DEBUG |
if( ((char *)modules ) < c->used_modules.s.str) |
Pike_fatal("Modules out of whack!\n"); |
#endif |
} |
} |
|
return resolve_identifier(ident); |
} |
|
|
|
|
|
|
struct node_s *resolve_identifier(struct pike_string *ident) |
{ |
struct compilation *c = THIS_COMPILATION; |
node *ret = NULL; |
|
|
if (ident == UNDEFINED_string) { |
struct svalue s; |
s.type = T_INT; |
s.subtype = NUMBER_UNDEFINED; |
s.u.integer = 0; |
return mkconstantsvaluenode(&s); |
} |
|
if(resolve_cache) |
{ |
struct svalue *tmp=low_mapping_string_lookup(resolve_cache,ident); |
if(tmp) |
{ |
if(!IS_UNDEFINED (tmp)) |
return mkconstantsvaluenode(tmp); |
|
return 0; |
} |
} |
|
CHECK_COMPILER(); |
|
ref_push_string(ident); |
ref_push_string(c->lex.current_file); |
if (c->handler) { |
ref_push_object(c->handler); |
} else { |
push_int(0); |
} |
if (!safe_apply_current2(PC_RESOLV_FUN_NUM, 3, NULL)) |
handle_compile_exception ("Error resolving %S.", ident); |
|
if (Pike_compiler->compiler_pass == 2 && |
((Pike_sp[-1].type == T_OBJECT && |
Pike_sp[-1].u.object == placeholder_object) || |
(Pike_sp[-1].type == T_PROGRAM && |
Pike_sp[-1].u.program == placeholder_program))) { |
my_yyerror("Got placeholder %s (resolver problem) " |
"when resolving %S.", |
get_name_of_type (Pike_sp[-1].type), ident->str); |
} else { |
if(!resolve_cache) |
resolve_cache=dmalloc_touch(struct mapping *, allocate_mapping(10)); |
mapping_string_insert(resolve_cache,ident,Pike_sp-1); |
|
if(!IS_UNDEFINED (Pike_sp-1)) |
{ |
ret=mkconstantsvaluenode(Pike_sp-1); |
} |
} |
pop_stack(); |
|
return ret; |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct node_s *program_magic_identifier (struct program_state *state, |
int state_depth, int inherit_num, |
struct pike_string *ident, |
int colon_colon_ref) |
{ |
#if 0 |
fprintf (stderr, "magic_identifier (state, %d, %d, %s, %d)\n", |
state_depth, inherit_num, ident->str, colon_colon_ref); |
#endif |
|
if (!inherit_num && TEST_COMPAT(7,6)) { |
|
inherit_num = -1; |
} |
|