pike.git/src/program.c:1:
/*
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
- || $Id: program.c,v 1.659 2008/04/07 01:45:53 mbaehr Exp $
+ || $Id: program.c,v 1.660 2008/04/14 10:14:41 grubba Exp $
*/
#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"
pike.git/src/program.c:28:
#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 <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{ \
pike.git/src/program.c:1211:
/*! @endclass
*/
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 object *error_handler=0;
- struct object *compat_handler=0;
-
+
struct program *gc_internal_program = 0;
static struct program *gc_mark_program_pos = 0;
int compilation_depth=-1;
dynamic_buffer used_modules;
static struct mapping *resolve_cache=0;
#ifdef PIKE_DEBUG
#define CHECK_FILE_ENTRY(PROG, POS, LEN, SHIFT) \
do { \
pike.git/src/program.c:1609:
{
if(!IS_UNDEFINED (tmp))
return mkconstantsvaluenode(tmp);
return 0;
}
}
if(get_master())
{
+ struct compilation *c = THIS_COMPILATION;
DECLARE_CYCLIC();
node *ret=0;
- if(BEGIN_CYCLIC(ident, lex.current_file))
+ if(BEGIN_CYCLIC(ident, c->lex.current_file))
{
my_yyerror("Recursive module dependency in %S.", ident);
}else{
SET_CYCLIC_RET(1);
ref_push_string(ident);
- ref_push_string(lex.current_file);
- if (error_handler) {
- ref_push_object(error_handler);
+ ref_push_string(c->lex.current_file);
+ if (c->handler) {
+ ref_push_object(c->handler);
} else {
push_int(0);
}
- if (safe_apply_handler("resolv", error_handler, compat_handler, 3, 0)) {
+ if (safe_apply_handler("resolv", c->handler, c->compat_handler, 3, 0)) {
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 {
pike.git/src/program.c:1970: Inside #if defined(PIKE_DEBUG) and #if defined(DEBUG_MALLOC)
}
}
#endif
return get_program_line(p, line);
}
#endif
int override_identifier (struct reference *new_ref, struct pike_string *name)
{
+ struct compilation *c = THIS_COMPILATION;
int id = -1, cur_id = 0, is_used = 0;
int new_is_variable =
IDENTIFIER_IS_VARIABLE(ID_FROM_PTR(Pike_compiler->new_program,
new_ref)->identifier_flags);
/* This loop could possibly be optimized by looping over
* each inherit and looking up 'name' in each inherit
* and then see if should be overwritten
* /Hubbe
*/
-
+ CHECK_COMPILER();
+
for(;cur_id<Pike_compiler->new_program->num_identifier_references;cur_id++)
{
struct reference *ref =
Pike_compiler->new_program->identifier_references + cur_id;
struct identifier *i;
/* No need to do anything for ourselves. */
if (ref == new_ref) continue;
/* Do not zapp hidden identifiers */
pike.git/src/program.c:2033: Inside #if defined(PIKE_DEBUG)
#ifdef PIKE_DEBUG
if (!inh->inherit_level) {
Pike_fatal("Inherit without intermediate levels.\n");
}
#endif
sub_ref = PTR_FROM_INT(inh->prog, cur_id - inh->identifier_level);
/* Check if the symbol was used before it was inherited. */
- if ((lex.pragmas & ID_STRICT_TYPES) &&
+ if ((c->lex.pragmas & ID_STRICT_TYPES) &&
(sub_ref->id_flags & ID_USED)) {
struct identifier *sub_id = ID_FROM_PTR(inh->prog, sub_ref);
if (IDENTIFIER_IS_FUNCTION(sub_id->identifier_flags)) {
if ((Pike_compiler->compiler_pass == 2) &&
!pike_types_le(ID_FROM_PTR(Pike_compiler->new_program,
new_ref)->type, sub_id->type)) {
yywarning("Type mismatch when overloading function %S.", name);
yyexplain_nonmatching_types(sub_id->type,
ID_FROM_PTR(Pike_compiler->new_program,
new_ref)->type,
pike.git/src/program.c:2078:
*ref=*new_ref;
ref->id_flags |= is_used;
id = cur_id;
}
return id;
}
void fixate_program(void)
{
+ struct compilation *c = THIS_COMPILATION;
INT32 i,e,t;
struct program *p=Pike_compiler->new_program;
-
+ CHECK_COMPILER();
+
if(p->flags & PROGRAM_FIXED) return;
#ifdef PIKE_DEBUG
if(p->flags & PROGRAM_OPTIMIZED)
Pike_fatal("Cannot fixate optimized program\n");
#endif
/* Fixup the runtime type for functions.
* (T_MIXED is used as the tentative type marker in pass 1).
*/
for (i=0; i < p->num_identifiers; i++) {
pike.git/src/program.c:2154:
found_better=t;
/* FIXME: Is this stuff needed?
* It looks like it already is done by define_function().
*
* Yes -- It's needed in case of mixin.
*/
if(funa_is_prototype && (funb->func.offset != -1) &&
!(funp->id_flags & ID_INLINE))
{
- if ((lex.pragmas & ID_STRICT_TYPES) &&
+ if ((c->lex.pragmas & ID_STRICT_TYPES) &&
(funp->id_flags & ID_USED)) {
/* Verify that the types are compatible. */
if (!pike_types_le(funb->type, fun->type)) {
yywarning("Type mismatch when overloading %S.", fun->name);
yyexplain_nonmatching_types(fun->type, funb->type,
YYTE_IS_WARNING);
}
}
funp->inherit_offset = funpb->inherit_offset;
funp->identifier_offset = funpb->identifier_offset;
}
if(!funa_is_prototype && funb->func.offset == -1)
{
- if ((lex.pragmas & ID_STRICT_TYPES) &&
+ if ((c->lex.pragmas & ID_STRICT_TYPES) &&
(funpb->id_flags & ID_USED)) {
/* Verify that the types are compatible. */
if (!pike_types_le(fun->type, funb->type)) {
yywarning("Type mismatch when overloading %S.", fun->name);
yyexplain_nonmatching_types(funb->type, fun->type,
YYTE_IS_WARNING);
}
}
funpb->inherit_offset = funp->inherit_offset;
funpb->identifier_offset = funp->identifier_offset;
pike.git/src/program.c:2260:
}
}
#ifdef DEBUG_MALLOC
{
#define DBSTR(X) ((X)?(X)->str:"")
int e,v;
INT32 line;
struct pike_string *tmp;
struct memory_map *m=0;;
- if(lex.current_file &&
- lex.current_file->str &&
- lex.current_file->len &&
- !strcmp(lex.current_file->str,"-"))
+ if(c->lex.current_file &&
+ c->lex.current_file->str &&
+ c->lex.current_file->len &&
+ !strcmp(c->lex.current_file->str,"-"))
{
- m=dmalloc_alloc_mmap( DBSTR(lex.current_file), lex.current_line);
+ m=dmalloc_alloc_mmap( DBSTR(c->lex.current_file), c->lex.current_line);
}
else if( (tmp=find_program_name(Pike_compiler->new_program, &line)) )
{
m=dmalloc_alloc_mmap( tmp->str, line);
free_string(tmp);
}else{
m=dmalloc_alloc_mmap( "program id", Pike_compiler->new_program->id);
}
for(e=0;e<Pike_compiler->new_program->num_inherits;e++)
pike.git/src/program.c:2346:
/*
* Start building a new program
*/
void low_start_new_program(struct program *p,
int pass,
struct pike_string *name,
int flags,
int *idp)
{
+ struct compilation *c = THIS_COMPILATION;
int id=0;
struct svalue tmp;
-
+ CHECK_COMPILER();
+
#ifdef WITH_FACETS
if(Pike_compiler->compiler_pass == 1 && p) {
p->facet_class = 0;
p->facet_index = -1;
p->facet_group = NULL;
}
#endif
/* We don't want to change thread, but we don't want to
* wait for the other threads to complete either.
pike.git/src/program.c:2380:
{
p=low_allocate_program();
if(name)
{
tmp.u.program=p;
id=add_constant(name, &tmp, flags & ~ID_EXTERN);
#if 0
fprintf(stderr,"Compiling class %s, depth=%d\n",name->str,compilation_depth);
}else{
fprintf(stderr,"Compiling file %s, depth=%d\n",
- lex.current_file ? lex.current_file->str : "-",
+ c->lex.current_file ? c->lex.current_file->str : "-",
compilation_depth);
#endif
}
}else{
tmp.u.program=p;
add_ref(p);
if((pass == 2) && name)
{
struct identifier *i;
id=isidentifier(name);
pike.git/src/program.c:2492: Inside #if defined(PROGRAM_BUILD_DEBUG)
push_string (name);
print_svalue (stderr, --Pike_sp);
putc ('\n', stderr);
}
else
fprintf (stderr, "%.*sstarting program %d (pass=%d)\n",
compilation_depth, " ", Pike_compiler->new_program->id, Pike_compiler->compiler_pass);
#endif
if (compilation_depth >= 1) {
- if(TEST_COMPAT(7,2) || (lex.pragmas & ID_SAVE_PARENT))
+ if(TEST_COMPAT(7,2) || (c->lex.pragmas & ID_SAVE_PARENT))
{
p->flags |= PROGRAM_USES_PARENT;
- }else if (!(lex.pragmas & ID_DONT_SAVE_PARENT)) {
+ }else if (!(c->lex.pragmas & ID_DONT_SAVE_PARENT)) {
struct pike_string *tmp=findstring("__pragma_save_parent__");
if(tmp)
{
struct node_s *n=find_module_identifier(tmp, 0);
if(n)
{
int do_save_parent = !node_is_false(n); /* Default to true. */
free_node(n);
if (do_save_parent) p->flags |= PROGRAM_USES_PARENT;
}
pike.git/src/program.c:2606:
push_compiler_frame(0);
copy_pike_type(Pike_compiler->compiler_frame->current_return_type,
void_type_string);
debug_malloc_touch(Pike_compiler->fake_object);
debug_malloc_touch(Pike_compiler->fake_object->storage);
}
PMOD_EXPORT void debug_start_new_program(int line, const char *file)
{
- struct pike_string *save_file =
- dmalloc_touch(struct pike_string *, lex.current_file);
- int save_line = lex.current_line;
+ struct pike_string *save_file;
+ int save_line;
+ struct compilation *c;
-
+ CHECK_COMPILER();
+ c = THIS_COMPILATION;
+
+ save_file = dmalloc_touch(struct pike_string *, c->lex.current_file);
+ save_line = c->lex.current_line;
+
{ /* Trim off the leading path of the compilation environment. */
const char *p = DEFINETOSTR(PIKE_SRC_ROOT), *f = file;
while (*p && *p == *f) p++, f++;
while (*f == '/' || *f == '\\') f++;
- lex.current_file = make_shared_string(f);
- lex.current_line = line;
+ c->lex.current_file = make_shared_string(f);
+ c->lex.current_line = line;
}
CDFPRINTF((stderr,
"th(%ld) start_new_program(%d, %s): "
"threads_disabled:%d, compilation_depth:%d\n",
(long)th_self(), line, file, threads_disabled, compilation_depth));
low_start_new_program(0,1,0,0,0);
- store_linenumber(line,lex.current_file);
+ store_linenumber(line,c->lex.current_file);
debug_malloc_name(Pike_compiler->new_program, file, line);
- free_string(lex.current_file);
- lex.current_file = dmalloc_touch(struct pike_string *, save_file);
- lex.current_line = save_line;
+ free_string(c->lex.current_file);
+ c->lex.current_file = dmalloc_touch(struct pike_string *, save_file);
+ c->lex.current_line = save_line;
}
static void exit_program_struct(struct program *p)
{
unsigned e;
#ifdef PIKE_DEBUG
if (p->refs) {
#ifdef DEBUG_MALLOC
pike.git/src/program.c:3038: Inside #if defined(PIKE_DEBUG)
c->sval.u.ptr);
#else /* !0 */
fprintf(stderr, "%*s %4d: %-15s %"PRINTPTRDIFFT"d\n",
indent, "",
d, get_name_of_type (c->sval.type),
c->offset);
#endif /* 0 */
}
fprintf(stderr, "\n"
+ "%*sLFUN table:\n"
+ "%*s LFUN Ref# Name\n",
+ indent, "", indent, "");
+ for (d = 0; d < NUM_LFUNS; d++) {
+ if (p->lfuns[d] != -1) {
+ fprintf(stderr, "%*s %4d: %04d %s\n",
+ indent, "", d, p->lfuns[d], lfun_names[d]);
+ }
+ }
+
+ fprintf(stderr, "\n"
"%*sLinenumber table:\n",
indent, "");
{
INT32 off = 0, line = 0;
char *cnt = p->linenumbers;
while (cnt < p->linenumbers + p->num_linenumbers) {
if (*cnt == 127) {
int len, shift;
char *file;
pike.git/src/program.c:4438:
default:
resolv_class(n);
do_inherit(Pike_sp-1, flags, name);
pop_stack();
}
}
int call_handle_inherit(struct pike_string *s)
{
+ struct compilation *c = THIS_COMPILATION;
int args;
-
+ CHECK_COMPILER();
+
reference_shared_string(s);
push_string(s);
if (!TEST_COMPAT(7,6)) {
/* In Pike 7.7 and later filenames belonging to Pike are assumed
* to be encoded according to UTF-8.
*/
f_string_to_utf8(1);
}
- ref_push_string(lex.current_file);
- if (error_handler && error_handler->prog) {
- ref_push_object(error_handler);
+ ref_push_string(c->lex.current_file);
+ if (c->handler && c->handler->prog) {
+ ref_push_object(c->handler);
args = 3;
}
else args = 2;
- if (safe_apply_handler("handle_inherit", error_handler, compat_handler,
+ if (safe_apply_handler("handle_inherit", c->handler, c->compat_handler,
args, BIT_PROGRAM|BIT_FUNCTION|BIT_ZERO))
if (Pike_sp[-1].type != T_INT)
return 1;
else {
pop_stack();
my_yyerror("Couldn't find program %S", s);
}
else {
handle_compile_exception ("Error finding program");
}
pike.git/src/program.c:5307:
* define a new function
* if func isn't given, it is supposed to be a prototype.
*/
INT32 define_function(struct pike_string *name,
struct pike_type *type,
unsigned flags,
unsigned function_flags,
union idptr *func,
unsigned opt_flags)
{
+ struct compilation *c = THIS_COMPILATION;
struct identifier *funp,fun;
struct reference ref;
struct svalue *lfun_type;
int run_time_type = T_FUNCTION;
INT32 i;
INT32 getter_setter_offset = -1;
-
+ CHECK_COMPILER();
+
#ifdef PROGRAM_BUILD_DEBUG
{
struct pike_string *d = describe_type (type);
fprintf (stderr, "%.*sdefining function (pass=%d): %s ",
compilation_depth, " ", Pike_compiler->compiler_pass, d->str);
free_string (d);
push_string (name);
print_svalue (stderr, --Pike_sp);
putc ('\n', stderr);
}
pike.git/src/program.c:5344: Inside #if defined(PIKE_DEBUG)
#ifdef PIKE_DEBUG
if (lfun_type->type != T_TYPE) {
Pike_fatal("Bad entry in lfun_types for key \"%s\"\n", name->str);
}
#endif /* PIKE_DEBUG */
if (!pike_types_le(type, lfun_type->u.type)) {
if (!match_types(type, lfun_type->u.type)) {
my_yyerror("Type mismatch for callback function %S:", name);
yytype_error(NULL, lfun_type->u.type, type, 0);
Pike_fatal("Type mismatch!\n");
- } else if (lex.pragmas & ID_STRICT_TYPES) {
+ } else if (c->lex.pragmas & ID_STRICT_TYPES) {
yywarning("Type mismatch for callback function %S:", name);
yytype_error(NULL, lfun_type->u.type, type,
YYTE_IS_WARNING);
}
}
} else if (((name->len > 3) &&
(index_shared_string(name, 0) == '`') &&
(index_shared_string(name, 1) == '-') &&
(index_shared_string(name, 2) == '>')) ||
((name->len > 1) &&
pike.git/src/program.c:5389:
symbol_type = get_argument_type(type, 0);
}
if (symbol) {
/* We got a getter or a setter. */
struct reference *ref;
if (!pike_types_le(type, gs_type)) {
if (!match_types(type, gs_type)) {
my_yyerror("Type mismatch for callback function %S:", name);
yytype_error(NULL, gs_type, type, 0);
- } else if (lex.pragmas & ID_STRICT_TYPES) {
+ } else if (c->lex.pragmas & ID_STRICT_TYPES) {
yywarning("Type mismatch for callback function %S:", name);
yytype_error(NULL, gs_type, type, YYTE_IS_WARNING);
}
}
i = isidentifier(symbol);
if ((i >= 0) &&
!((ref = PTR_FROM_INT(Pike_compiler->new_program, i))->
id_flags & ID_INHERITED)) {
/* Not an inherited symbol. */
struct identifier *id = ID_FROM_INT(Pike_compiler->new_program, i);
pike.git/src/program.c:6784:
}
else {
pop_stack();
return NULL;
}
}
void handle_compile_exception (const char *yyerror_fmt, ...)
{
struct svalue thrown;
+ struct compilation *c = THIS_COMPILATION;
+
+ CHECK_COMPILER();
+
move_svalue (&thrown, &throw_value);
mark_free_svalue (&throw_value);
if (yyerror_fmt) {
va_list args;
va_start (args, yyerror_fmt);
va_yyerror (yyerror_fmt, args);
va_end (args);
}
push_svalue(&thrown);
- low_safe_apply_handler("compile_exception", error_handler, compat_handler, 1);
+ low_safe_apply_handler("compile_exception", c->handler, c->compat_handler, 1);
if (SAFE_IS_ZERO(sp-1)) {
struct pike_string *s = format_exception_for_error_msg (&thrown);
if (s) {
low_yyerror(s);
free_string (s);
}
}
pop_stack();
pike.git/src/program.c:6953:
}
}
#else
#define verify_supporters();
#endif
void init_supporter(struct Supporter *s,
supporter_callback *fun,
void *data)
{
+ CDFPRINTF((stderr, "th(%ld) init_supporter() supporter=%p data=%p.\n",
+ (long) th_self(), s, data));
verify_supporters();
#ifdef PIKE_DEBUG
s->magic = 0x500b0127;
#endif
s->previous=current_supporter;
current_supporter=s;
s->depends_on=0;
s->dependants=0;
s->next_dependant=0;
pike.git/src/program.c:6988:
if(c->depends_on)
{
#ifdef PIKE_DEBUG
struct Supporter *s;
for (s = c->depends_on->dependants; s; s = s->next_dependant)
if (s == c) Pike_fatal("Dependant already linked in.\n");
#endif
ret++;
c->next_dependant = c->depends_on->dependants;
c->depends_on->dependants=c;
+ add_ref(c->self);
+ CDFPRINTF((stderr, "th(%ld) unlink_current_supporter() supporter=%p depends on %p.\n",
+ (long) th_self(), c, c->depends_on));
}
current_supporter=c->previous;
verify_supporters();
return ret;
}
void free_supporter(struct Supporter *c)
{
verify_supporters();
if (c->depends_on) {
pike.git/src/program.c:7010:
if (*s == c) {*s = c->next_dependant; break;}
c->depends_on = 0;
}
verify_supporters();
}
int call_dependants(struct Supporter *s, int finish)
{
int ok = 1;
struct Supporter *tmp;
+ CDFPRINTF((stderr, "th(%ld) call_dependants() supporter=%p finish=%d.\n",
+ (long) th_self(), s, finish));
verify_supporters();
while((tmp=s->dependants))
{
-
+ CDFPRINTF((stderr, "th(%ld) dependant: %p (data:%p).\n",
+ (long) th_self(), tmp, tmp->data));
s->dependants=tmp->next_dependant;
#ifdef PIKE_DEBUG
tmp->next_dependant=0;
#endif
verify_supporters();
if (!tmp->fun(tmp->data, finish)) ok = 0;
verify_supporters();
-
+ free_object(tmp->self);
}
return ok;
}
int report_compiler_dependency(struct program *p)
{
int ret=0;
struct Supporter *c,*cc;
if (p == Pike_compiler->new_program) {
/* Depends on self... */
return 0;
}
-
+
+ CDFPRINTF((stderr, "th(%ld) %p depends on %p\n",
+ (long)th_self(), Pike_compiler->new_program, p));
+
verify_supporters();
if (Pike_compiler->flags & COMPILATION_FORCE_RESOLVE)
return 0;
for(cc=current_supporter;cc;cc=cc->previous)
{
if(cc->prog &&
!(cc->prog->flags & PROGRAM_PASS_1_DONE))
{
c=cc->depends_on;
if(!c) c=cc->previous;
pike.git/src/program.c:7059:
ret++; /* dependency registred */
}
}
}
}
verify_supporters();
return ret;
}
- /*! @class PikeCompiler
+ /*! @class CompilerEnviroment
*!
- *! The Pike compiler.
+ *! The compiler environment.
*/
- struct compilation
- {
- struct Supporter supporter;
- struct pike_string *prog;
- struct object *handler;
- int major, minor;
- struct program *target;
- struct object *placeholder;
-
- struct program *p;
- struct lex save_lex;
- int save_depth;
- int saved_threads_disabled;
- struct object *saved_handler;
- struct object *saved_compat_handler;
- dynamic_buffer used_modules_save;
- INT32 num_used_modules_save;
- struct mapping *resolve_cache_save;
-
- struct svalue default_module;
- };
-
+
static void free_compilation(struct compilation *c)
{
debug_malloc_touch(c);
- free_string(c->prog);
+ if (c->prog) free_string(c->prog);
if(c->handler) free_object(c->handler);
-
+ if(c->compat_handler) free_object(c->compat_handler);
if(c->target) free_program(c->target);
if(c->placeholder) free_object(c->placeholder);
-
+ if(c->lex.current_file) free_string(c->lex.current_file);
free_svalue(& c->default_module);
free_supporter(&c->supporter);
verify_supporters();
}
static void run_init(struct compilation *c)
{
debug_malloc_touch(c);
c->save_depth=compilation_depth;
compilation_depth=-1;
- c->saved_handler = error_handler;
- if((error_handler = c->handler))
- add_ref(error_handler);
+ if (c->compat_handler) free_object(c->compat_handler);
+ c->compat_handler=0;
- c->saved_compat_handler = compat_handler;
- compat_handler=0;
-
+
c->used_modules_save = used_modules;
c->num_used_modules_save = Pike_compiler->num_used_modules;
Pike_compiler->num_used_modules=0;
c->resolve_cache_save = resolve_cache;
resolve_cache = 0;
- c->save_lex=lex;
+ c->lex.current_line=1;
+ free_string(c->lex.current_file);
+ c->lex.current_file=make_shared_string("-");
- lex.current_line=1;
- lex.current_file=make_shared_string("-");
-
+
if (runtime_options & RUNTIME_STRICT_TYPES)
{
- lex.pragmas = ID_STRICT_TYPES;
+ c->lex.pragmas = ID_STRICT_TYPES;
} else {
- lex.pragmas = 0;
+ c->lex.pragmas = 0;
}
- lex.end = c->prog->str + (c->prog->len << c->prog->size_shift);
+ c->lex.end = c->prog->str + (c->prog->len << c->prog->size_shift);
switch(c->prog->size_shift)
{
- case 0: lex.current_lexer = yylex0; break;
- case 1: lex.current_lexer = yylex1; break;
- case 2: lex.current_lexer = yylex2; break;
+ case 0: c->lex.current_lexer = yylex0; break;
+ case 1: c->lex.current_lexer = yylex1; break;
+ case 2: c->lex.current_lexer = yylex2; break;
default:
Pike_fatal("Program has bad shift %d!\n", c->prog->size_shift);
break;
}
- lex.pos=c->prog->str;
+ c->lex.pos=c->prog->str;
}
static void run_init2(struct compilation *c)
{
debug_malloc_touch(c);
Pike_compiler->compiler = c;
initialize_buf(&used_modules);
use_module(& c->default_module);
pike.git/src/program.c:7184: Inside #if defined(PIKE_DEBUG)
fprintf(stderr, "compile(): compilation_depth is %d\n",
compilation_depth);
}
#endif /* PIKE_DEBUG */
compilation_depth=c->save_depth;
if (resolve_cache)
free_mapping(resolve_cache);
resolve_cache = c->resolve_cache_save;
- if (error_handler) free_object(error_handler);
- error_handler = c->saved_handler;
-
- if (compat_handler) free_object(compat_handler);
- compat_handler = c->saved_compat_handler;
-
- free_string(lex.current_file);
- lex=c->save_lex;
+
verify_supporters();
}
static void zap_placeholder(struct compilation *c)
{
/* fprintf(stderr, "Destructing placeholder.\n"); */
if (c->placeholder->storage) {
yyerror("Placeholder already has storage!");
#if 0
fprintf(stderr, "Placeholder already has storage!\n"
pike.git/src/program.c:7279: Inside #if 0
#if 0
CDFPRINTF((stderr, "th(%ld) compile(): First pass\n",
(long)th_self()));
#endif
do_yyparse(); /* Parse da program */
if (!Pike_compiler->new_program->num_linenumbers) {
/* The lexer didn't write an initial entry. */
- store_linenumber(0, lex.current_file);
+ store_linenumber(0, c->lex.current_file);
#ifdef DEBUG_MALLOC
- if(strcmp(lex.current_file->str,"-"))
- debug_malloc_name(Pike_compiler->new_program, lex.current_file->str, 0);
+ if(strcmp(c->lex.current_file->str,"-"))
+ debug_malloc_name(Pike_compiler->new_program, c->lex.current_file->str, 0);
#endif
}
CDFPRINTF((stderr, "th(%ld) %p run_pass1() done for %s\n",
- (long)th_self(), Pike_compiler->new_program, lex.current_file->str));
+ (long)th_self(), Pike_compiler->new_program,
+ c->lex.current_file->str));
ret=unlink_current_supporter(& c->supporter);
c->p=end_first_pass(0);
run_exit(c);
if(c->placeholder)
{
if(!c->p || (c->placeholder->storage))
pike.git/src/program.c:7336:
c->p=0;
run_init2(c);
CDFPRINTF((stderr,
"th(%ld) %p run_pass2() start: "
"threads_disabled:%d, compilation_depth:%d\n",
(long)th_self(), Pike_compiler->new_program,
threads_disabled, compilation_depth));
+ CDFPRINTF((stderr,
+ "th(%ld) %p:\n"
+ "%s\n"
+ "---\n"
+ "%s\n", (long)th_self(), Pike_compiler->new_program,
+ c->prog->str, c->lex.pos));
+
verify_supporters();
do_yyparse(); /* Parse da program */
CDFPRINTF((stderr, "th(%ld) %p run_pass2() done for %s\n",
- (long)th_self(), Pike_compiler->new_program, lex.current_file->str));
+ (long)th_self(), Pike_compiler->new_program,
+ c->lex.current_file->str));
verify_supporters();
c->p=end_program();
run_exit(c);
}
static void run_cleanup(struct compilation *c, int delayed)
{
pike.git/src/program.c:7451:
}
}
verify_supporters();
}
static int call_delayed_pass2(struct compilation *cc, int finish)
{
int ok = 0;
debug_malloc_touch(cc);
+ debug_malloc_touch(cc->p);
+
CDFPRINTF((stderr, "th(%ld) %p %s delayed compile.\n",
(long) th_self(), cc->p, finish ? "continuing" : "cleaning up"));
-
+ /* Reenter the delayed compilation. */
+ add_ref(cc->supporter.self);
+ low_enter_compiler(cc->supporter.self, cc->compilation_inherit);
+
if(finish && cc->p) run_pass2(cc);
run_cleanup(cc,1);
-
+ exit_compiler();
+
debug_malloc_touch(cc);
#ifdef PIKE_DEBUG
if(cc->supporter.dependants)
Pike_fatal("Que???\n");
#endif
if(cc->p) {
ok = finish;
free_program(cc->p); /* later */
}
CDFPRINTF((stderr, "th(%ld) %p delayed compile %s.\n",
(long) th_self(), cc->target, ok ? "done" : "failed"));
- free_compilation(cc);
- free(cc);
+
verify_supporters();
return ok;
}
- #define THIS_COMPILATION ((struct compilation *)(Pike_fp->current_storage))
-
+
static void compilation_event_handler(int e)
{
struct compilation *c = THIS_COMPILATION;
-
+
switch (e) {
case PROG_EVENT_INIT:
-
+ CDFPRINTF((stderr, "th(%ld) compilation: INIT(%p).\n",
+ (long) th_self(), c));
+ MEMSET(c, 0, sizeof(*c));
+ c->supporter.self = Pike_fp->current_object; /* NOTE: Not ref-counted! */
+ c->compilation_inherit =
+ Pike_fp->context - Pike_fp->current_object->prog->inherits;
c->default_module.type = T_INT;
c->default_module.subtype = NUMBER_NUMBER;
-
+ c->lex.current_line = 1;
+ c->lex.current_file = make_shared_string("-");
break;
case PROG_EVENT_EXIT:
-
+ CDFPRINTF((stderr, "th(%ld) compilation: EXIT(%p).\n",
+ (long) th_self(), c));
free_compilation(c);
break;
}
}
- /*! @decl void compile(string code)
- *!
- *! Compile a segment of Pike code.
- */
- static void f_compilation_compile(INT32 args)
- {
- pop_n_elems(args);
- push_int(0);
- }
-
+
/*! @decl void report(SeverityLevel severity, @
- *! string filename, int linenumber, @
- *! string subsystem, @
- *! string message, mixed ... extra_args)
+ *! string filename, int linenumber, @
+ *! string subsystem, @
+ *! string message, mixed ... extra_args)
*!
*! Report a diagnostic from the compiler.
*/
static void f_compilation_report(INT32 args)
{
-
+ struct compilation *c = THIS_COMPILATION;
int level;
struct pike_string *filename;
INT_TYPE linenumber;
struct pike_string *subsystem;
struct pike_string *message;
if (args > 5) {
f_sprintf(args - 4);
args = 5;
}
- get_all_args("report", args, "%d%S%i%S%S",
+ get_all_args("report", args, "%d%W%i%W%W",
&level, &filename, &linenumber, &subsystem, &message);
- fprintf(stderr, "%s:%ld: %s\n", filename->str, linenumber, message->str);
+
+ /* Ignore informational level messages */
+ if (level) {
+ if ((c->handler && c->handler->prog) ||
+ (c->compat_handler && c->compat_handler->prog) ||
+ get_master()) {
+ ref_push_string(filename);
+ push_int(linenumber);
+ ref_push_string(message);
+ if (level >= 2) {
+ low_safe_apply_handler("compile_error",
+ c->handler, c->compat_handler, 3);
+ args++;
+ } else {
+ low_safe_apply_handler("compile_warning",
+ c->handler, c->compat_handler, 3);
+ args++;
+ }
+ } else {
+ if (level >= 2) {
+ fprintf(stderr, "%s:%ld: %s\n",
+ filename->str, linenumber, message->str);
+ } else {
+ fprintf(stderr, "%s:%ld: Warning: %s\n",
+ filename->str, linenumber, message->str);
+ }
+ fflush(stderr);
+ }
+ }
pop_n_elems(args);
push_int(0);
}
-
+ /*! @decl program compile(string source, CompilationHandler|void handler, @
+ *! int|void major, int|void minor,@
+ *! program|void target, object|void placeholder)
+ *!
+ *! Compile a string to a program.
+ *!
+ *! This function takes a piece of Pike code as a string and
+ *! compiles it into a clonable program.
+ *!
+ *! The optional argument @[handler] is used to specify an alternative
+ *! error handler. If it is not specified the current master object will
+ *! be used.
+ *!
+ *! The optional arguments @[major] and @[minor] are used to tell the
+ *! compiler to attempt to be compatible with Pike @[major].@[minor].
+ *!
+ *! @note
+ *! Note that @[source] must contain the complete source for a program.
+ *! It is not possible to compile a single expression or statement.
+ *!
+ *! Also note that @[compile()] does not preprocess the program.
+ *! To preprocess the program you can use @[compile_string()] or
+ *! call the preprocessor manually by calling @[cpp()].
+ *!
+ *! @seealso
+ *! @[compile_string()], @[compile_file()], @[cpp()], @[master()],
+ *! @[CompilationHandler]
+ */
+ static void f_compilation_compile(INT32 args)
+ {
+ struct pike_string *aprog;
+ struct object *ahandler = NULL;/* error handler */
+ int amajor = -1;
+ int aminor = -1;
+ struct program *atarget = NULL;
+ struct object *aplaceholder = NULL;
+ int delay, dependants_ok = 1;
+ struct program *ret;
+ #ifdef PIKE_DEBUG
+ ONERROR tmp;
+ #endif
+ struct compilation *c = THIS_COMPILATION;
+
+ if (c->target) {
+ Pike_error("CompilationEnvironment in use.\n");
+ }
+
+ STACK_LEVEL_START(args);
+
+ get_all_args("compile", args, "%W.%O%d%d%P%O",
+ &aprog, &ahandler,
+ &amajor, &aminor,
+ &atarget, &aplaceholder);
+
+ if (args == 3) {
+ SIMPLE_BAD_ARG_ERROR("compile", 4, "int");
+ }
+
+ check_c_stack(65536);
+
+ CDFPRINTF((stderr, "th(%ld) %p compile() enter, placeholder=%p\n",
+ (long) th_self(), atarget, aplaceholder));
+
+ debug_malloc_touch(c);
+
+ verify_supporters();
+
+ if (c->p) free_program(c->p);
+ c->p = NULL;
+ if (c->prog) free_string(c->prog);
+ add_ref(c->prog=aprog);
+ if (ahandler) {
+ if (c->handler) free_object(c->handler);
+ add_ref(c->handler = ahandler);
+ }
+ c->major=amajor;
+ c->minor=aminor;
+
+ if((c->target=atarget)) add_ref(atarget);
+ else c->target = low_allocate_program();
+
+ if (c->placeholder) free_object(c->placeholder);
+ if ((c->placeholder=aplaceholder)) add_ref(aplaceholder);
+
+ if (c->handler)
+ {
+ if (safe_apply_handler ("get_default_module", c->handler, NULL,
+ 0, BIT_MAPPING|BIT_OBJECT|BIT_ZERO)) {
+ if(SAFE_IS_ZERO(Pike_sp-1))
+ {
+ pop_stack();
+ ref_push_mapping(get_builtin_constants());
+ }
+ } else {
+ ref_push_mapping(get_builtin_constants());
+ }
+ }else{
+ ref_push_mapping(get_builtin_constants());
+ }
+ free_svalue(& c->default_module);
+ c->default_module=Pike_sp[-1];
+ dmalloc_touch_svalue(Pike_sp-1);
+ Pike_sp--;
+
+ #ifdef PIKE_DEBUG
+ SET_ONERROR(tmp, fatal_on_error,"Compiler exited with longjump!\n");
+ #endif
+
+ low_init_threads_disable();
+ c->saved_threads_disabled = threads_disabled;
+
+ init_supporter(& c->supporter,
+ (supporter_callback *) call_delayed_pass2,
+ (void *)c);
+
+ delay=run_pass1(c) && c->p;
+ dependants_ok = call_dependants(& c->supporter, !!c->p );
+ #ifdef PIKE_DEBUG
+ /* FIXME */
+ UNSET_ONERROR(tmp);
+ #endif
+
+ if(delay)
+ {
+ CDFPRINTF((stderr, "th(%ld) %p compile() finish later, placeholder=%p.\n",
+ (long) th_self(), c->target, c->placeholder));
+ /* finish later */
+ add_ref(c->p);
+ verify_supporters();
+ /* We're hanging in the supporter. */
+ ret = c->p;
+ }else{
+ /* finish now */
+ if(c->p) run_pass2(c);
+ debug_malloc_touch(c);
+ run_cleanup(c,0);
+
+ ret=c->p;
+ c->p = NULL;
+
+ debug_malloc_touch(c);
+
+ if (!dependants_ok) {
+ CDFPRINTF((stderr, "th(%ld) %p compile() reporting failure "
+ "since a dependant failed.\n",
+ (long) th_self(), c->target));
+ if (ret) free_program(ret);
+ throw_error_object(low_clone(compilation_error_program), 0, 0, 0,
+ "Compilation failed.\n");
+ }
+ if(!ret) {
+ CDFPRINTF((stderr, "th(%ld) %p compile() failed.\n",
+ (long) th_self(), c->target));
+ throw_error_object(low_clone(compilation_error_program), 0, 0, 0,
+ "Compilation failed.\n");
+ }
+ debug_malloc_touch(ret);
+ #ifdef PIKE_DEBUG
+ if (a_flag > 2) {
+ dump_program_tables(ret, 0);
+ }
+ #endif /* PIKE_DEBUG */
+ verify_supporters();
+ }
+ STACK_LEVEL_DONE(args);
+ pop_n_elems(args);
+ if (ret)
+ push_program(ret);
+ else
+ push_int(0);
+ }
+
+ /* Fake being called via CompilationEnvironment()->compile()
+ *
+ * This function is used to set up the environment for
+ * compiling C efuns and modules.
+ *
+ * Note: Since this is a stack frame, it will be cleaned up
+ * automatically on error, so no need to use ONERROR().
+ *
+ * Note: Steals a reference from ce.
+ */
+ static void low_enter_compiler(struct object *ce, int inherit)
+ {
+ struct pike_frame *new_frame = alloc_pike_frame();
+ #ifdef PROFILING
+ new_frame->children_base = Pike_interpreter.accounted_time;
+ new_frame->start_time = get_cpu_time() - Pike_interpreter.unlocked_time;
+ new_frame->ident = CE_COMPILE_FUN_NUM; /* Fake call of compile(). */
+ #endif /* PROFILING */
+ new_frame->next = Pike_fp;
+ new_frame->current_object = ce;
+ /* Note: The compilation environment object hangs on this frame,
+ * so that it will be freed when the frame dies.
+ */
+ new_frame->current_program = ce->prog;
+ add_ref(new_frame->current_program);
+ new_frame->context = compilation_program->inherits + inherit;
+ new_frame->current_storage = ce->storage + new_frame->context->storage_offset;
+ #ifdef PIKE_DEBUG
+ if (new_frame->context->prog != compilation_program) {
+ Pike_fatal("Invalid inherit for compilation context (%p != %p).\n",
+ new_frame->context->prog, compilation_program);
+ }
+ #endif /* PIKE_DEBUG */
+ new_frame->fun = new_frame->context->identifier_level + CE_COMPILE_FUN_NUM;
+ new_frame->expendible = Pike_sp;
+ new_frame->locals = Pike_sp;
+ new_frame->save_sp = Pike_sp;
+ new_frame->save_mark_sp = Pike_mark_sp;
+ new_frame->mark_sp_base = Pike_mark_sp;
+ new_frame->args = 0;
+ new_frame->num_locals = 0;
+ new_frame->pc = 0;
+ new_frame->return_addr = 0;
+ new_frame->scope = 0;
+ new_frame->save_sp = Pike_sp;
+ Pike_fp = new_frame;
+ }
+
+ void enter_compiler(struct pike_string *filename, int linenumber)
+ {
+ struct object *ce = clone_object(compilation_program, 0);
+ struct compilation *c;
+
+ low_enter_compiler(ce, 0);
+
+ c = THIS_COMPILATION;
+ if (filename) {
+ free_string(c->lex.current_file);
+ copy_shared_string(c->lex.current_file, filename);
+ }
+ if (linenumber) {
+ c->lex.current_line = linenumber;
+ }
+ }
+
+ /* Reverse the effect of enter_compiler().
+ */
+ void exit_compiler(void)
+ {
+ #ifdef PIKE_DEBUG
+ if ((Pike_fp->current_program != compilation_program) ||
+ (Pike_fp->fun != 2)) {
+ Pike_fatal("exit_compiler(): Frame stack out of whack!\n");
+ }
+ #endif /* PIKE_DEBUG */
+ POP_PIKE_FRAME();
+ }
+
+ /*! @class PikeCompiler
+ *!
+ *! The Pike compiler.
+ */
+
+ /*! @decl void report(SeverityLevel severity, @
+ *! string filename, int linenumber, @
+ *! string subsystem, @
+ *! string message, mixed ... extra_args)
+ *!
+ *! Report a diagnostic from the compiler.
+ *!
+ *! The default implementation calls @[CompilerEnvironment::report()]
+ *! with the same arguments.
+ */
+
+ #define THIS_PROGRAM_STATE ((struct program_state *)(Pike_fp->current_storage))
+
+ static void program_state_event_handler(int event)
+ {
+ #if 0
+ struct program_state *c = THIS_PROGRAM_STATE;
+ switch (event) {
+ case PROG_EVENT_INIT:
+ #define INIT
+ #include "compilation.h"
+ break;
+ case PROG_EVENT_EXIT:
+ #define EXIT
+ #include "compilation.h"
+ break;
+ }
+ #endif /* 0 */
+
+ fprintf(stderr, "program_state_event_handler(%d) obj:%p prog:%p\n",
+ event, Pike_fp->current_object, Pike_fp->current_program);
+ }
+
+ /*! @endclass
+ */
+
+ /*! @endclass
+ */
+
/* Strap the compiler by creating the compilation program by hand. */
static void compile_compiler(void)
{
- struct program *p = compilation_program = low_allocate_program();
- struct reference *ref;
- struct identifier *i;
- struct inherit *inh;
- unsigned INT16 *ix;
+ struct program *p = compilation_program = low_allocate_program(), *p2;
+ struct program_constant *pc;
+ struct reference *ref, *ref2;
+ struct identifier *i, *i2;
+ struct inherit *inh, *inh2;
+ unsigned INT16 *ix, *ix2;
+ int e;
p->parent_info_storage = -1;
p->event_handler = compilation_event_handler;
p->flags |= PROGRAM_HAS_C_METHODS;
- p->inherits = inh = malloc(sizeof(struct inherit));
- p->identifier_references = ref = malloc(sizeof(struct reference) * 2);
- p->identifiers = i = malloc(sizeof(struct identifier) * 2);
- p->identifier_index = ix = malloc(sizeof(unsigned INT16) * 2);
+ p->inherits = inh = xalloc(sizeof(struct inherit));
+ p->identifier_references = ref = xalloc(sizeof(struct reference) * 3);
+ p->identifiers = i = xalloc(sizeof(struct identifier) * 3);
+ p->identifier_index = ix = xalloc(sizeof(unsigned INT16) * 3);
+ p->constants = pc = xalloc(sizeof(struct program_constant) * 1);
inh->prog = p;
inh->inherit_level = 0;
inh->identifier_level = 0;
inh->parent_identifier = -1;
inh->parent_offset = OBJECT_PARENT;
inh->identifier_ref_offset = 0;
inh->storage_offset = 0;
inh->parent = NULL;
inh->name = NULL;
p->num_inherits = 1;
/* ADD_STORAGE(struct compilation); */
p->alignment_needed = ALIGNOF(struct compilation);
p->inherits->storage_offset = 0;
p->storage_needed = sizeof(struct compilation);
- /* ADD_FUNCTION("compile", f_compilation_compile, ...); */
- i->name = make_shared_string("compile");
- i->type = make_pike_type(tFunc(tStr, tPrg(tObj)));
+ /* ADD_FUNCTION("report", f_compilation_report, ...); */
+ i->name = make_shared_string("report");
+ i->type = make_pike_type(tFuncV(tName("SeverityLevel", tInt03) tStr tIntPos
+ tStr tStr, tMix, tVoid));
i->run_time_type = T_FUNCTION;
i->identifier_flags = IDENTIFIER_C_FUNCTION;
- i->func.c_fun = f_compilation_compile;
+ i->func.c_fun = f_compilation_report;
i->opt_flags = 0;
-
+ #ifdef PROFILING
+ i->self_time = 0;
+ i->num_calls = 0;
+ i->total_time = 0;
+ #endif
i++;
*(ix++) = ref->identifier_offset = compilation_program->num_identifiers++;
p->num_identifier_index++;
ref->id_flags = 0;
ref->inherit_offset = 0;
ref++;
p->num_identifier_references++;
- /* ADD_FUNCTION("report", f_compilation_report, ...); */
- i->name = make_shared_string("report");
- i->type = make_pike_type(tFuncV(tName("SeverityLevel", tInt03) tStr tIntPos
+ p2 = low_allocate_program();
+
+ pc->sval.u.program = p2;
+ pc->sval.type = T_PROGRAM;
+ pc->sval.subtype = 0;
+ pc->offset = -1;
+ i->name = make_shared_string("PikeCompiler");
+ i->type = get_type_of_svalue(&pc->sval);
+ i->run_time_type = T_PROGRAM;
+ i->identifier_flags = IDENTIFIER_CONSTANT;
+ i->func.offset = p->num_constants++;
+ pc++;
+ i->opt_flags = 0;
+ #ifdef PROFILING
+ i->self_time = 0;
+ i->num_calls = 0;
+ i->total_time = 0;
+ #endif
+ i++;
+ *(ix++) = ref->identifier_offset = compilation_program->num_identifiers++;
+ p->num_identifier_index++;
+ ref->id_flags = 0;
+ ref->inherit_offset = 0;
+ ref++;
+ p->num_identifier_references++;
+
+ /* FIXME: Parent info. */
+ p2->event_handler = program_state_event_handler;
+ p2->flags |= PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT|PROGRAM_HAS_C_METHODS;
+ p2->parent_info_storage = 0;
+ p2->xstorage = sizeof(struct parent_info);
+
+ p2->inherits = inh2 = malloc(sizeof(struct inherit));
+ p2->identifier_references = ref2 = malloc(sizeof(struct reference) * 2);
+ p2->identifiers = i2 = malloc(sizeof(struct identifier) * 2);
+ p2->identifier_index = ix2 = malloc(sizeof(unsigned INT16) * 2);
+
+ inh2->prog = p2;
+ inh2->inherit_level = 0;
+ inh2->identifier_level = 0;
+ inh2->parent_identifier = -1;
+ inh2->parent_offset = OBJECT_PARENT;
+ inh2->identifier_ref_offset = 0;
+ inh2->storage_offset = p2->xstorage;
+ inh2->parent = NULL;
+ inh2->name = NULL;
+ p2->num_inherits = 1;
+
+ /* ADD_STORAGE(struct program_state); */
+ p2->alignment_needed = ALIGNOF(struct program_state);
+ p2->inherits->storage_offset = p2->xstorage;
+ p2->storage_needed = p2->xstorage + sizeof(struct program_state);
+
+ /* low_define_alias(NULL, NULL, 0, 1, 0); */
+ i2->name = make_shared_string("report");
+ i2->type = make_pike_type(tFuncV(tName("SeverityLevel", tInt03) tStr tIntPos
tStr tStr, tMix, tVoid));
-
+ i2->run_time_type = T_FUNCTION;
+ i2->identifier_flags = IDENTIFIER_C_FUNCTION | IDENTIFIER_ALIAS;
+ i2->func.ext_ref.depth = 1;
+ i2->func.ext_ref.id = 0;
+ i2->opt_flags = 0;
+ #ifdef PROFILING
+ i2->self_time = 0;
+ i2->num_calls = 0;
+ i2->total_time = 0;
+ #endif
+ i2++;
+ *(ix2++) = ref2->identifier_offset = p2->num_identifiers++;
+ p2->num_identifier_index++;
+ ref2->id_flags = 0;
+ ref2->inherit_offset = 0;
+ ref2++;
+ p2->num_identifier_references++;
+
+
+ p2->flags |= PROGRAM_PASS_1_DONE;
+
+ fsort_program_identifier_index(p2->identifier_index, ix2-1, p2);
+ p2->flags |= PROGRAM_FIXED;
+
+ /* Yes, it is supposed to start at 0 /Grubba */
+ for(e=0;e<NUM_LFUNS;e++) {
+ int id = p2->lfuns[e] = low_find_lfun(p2, e);
+ }
+
+ optimize_program(p2);
+ p2->flags |= PROGRAM_FINISHED;
+
+
+ /* ADD_FUNCTION("compile", f_compilation_compile, ...); */
+ i->name = make_shared_string("compile");
+ i->type = make_pike_type(tFunc(tStr, tPrg(tObj)));
i->run_time_type = T_FUNCTION;
i->identifier_flags = IDENTIFIER_C_FUNCTION;
- i->func.c_fun = f_compilation_report;
+ i->func.c_fun = f_compilation_compile;
i->opt_flags = 0;
-
+ #ifdef PROFILING
+ i->self_time = 0;
+ i->num_calls = 0;
+ i->total_time = 0;
+ #endif
i++;
*(ix++) = ref->identifier_offset = compilation_program->num_identifiers++;
p->num_identifier_index++;
ref->id_flags = 0;
ref->inherit_offset = 0;
ref++;
p->num_identifier_references++;
p->flags |= PROGRAM_PASS_1_DONE;
fsort_program_identifier_index(p->identifier_index, ix-1, p);
p->flags |= PROGRAM_FIXED;
-
+ /* Yes, it is supposed to start at 0 /Grubba */
+ for(e=0;e<NUM_LFUNS;e++) {
+ int id = p->lfuns[e] = low_find_lfun(p, e);
+ }
+
optimize_program(p);
p->flags |= PROGRAM_FINISHED;
-
+
+ add_global_program("CompilerEnvironment", p);
}
- /*! @endclass
- */
-
+
struct program *compile(struct pike_string *aprog,
struct object *ahandler,/* error handler */
int amajor, int aminor,
struct program *atarget,
struct object *aplaceholder)
{
int delay, dependants_ok = 1;
struct program *ret;
#ifdef PIKE_DEBUG
ONERROR tmp;
#endif
- struct compilation *c=ALLOC_STRUCT(compilation);
+ struct object *ce;
+ struct compilation *c;
- verify_supporters();
+ /* FIXME! */
-
+ Pike_fatal("Old C-level compile() function called!\n");
+
CDFPRINTF((stderr, "th(%ld) %p compile() enter, placeholder=%p\n",
(long) th_self(), atarget, aplaceholder));
-
+ ce = clone_object(compilation_program, 0);
+ c = (struct compilation *)ce->storage;
+
debug_malloc_touch(c);
-
+
+ verify_supporters();
+
c->p = NULL;
add_ref(c->prog=aprog);
if((c->handler=ahandler)) add_ref(ahandler);
c->major=amajor;
c->minor=aminor;
if((c->target=atarget)) add_ref(atarget);
if((c->placeholder=aplaceholder)) add_ref(aplaceholder);
c->default_module.type=T_INT;
c->default_module.subtype = NUMBER_NUMBER;
pike.git/src/program.c:7690:
return c->p; /* freed later */
}else{
/* finish now */
if(c->p) run_pass2(c);
debug_malloc_touch(c);
run_cleanup(c,0);
ret=c->p;
debug_malloc_touch(c);
- free_compilation(c);
- free(c);
+ free_object(ce);
if (!dependants_ok) {
CDFPRINTF((stderr, "th(%ld) %p compile() reporting failure "
"since a dependant failed.\n",
(long) th_self(), c->target));
if (ret) free_program(ret);
throw_error_object(low_clone(compilation_error_program), 0, 0, 0,
"Compilation failed.\n");
}
if(!ret) {
pike.git/src/program.c:7948:
void init_program(void)
{
size_t i;
struct svalue key;
struct svalue val;
struct svalue id;
init_program_blocks();
compile_compiler();
+ enter_compiler(NULL, 0);
+
MAKE_CONST_STRING(this_program_string,"this_program");
MAKE_CONST_STRING(this_string,"this");
MAKE_CONST_STRING(UNDEFINED_string,"UNDEFINED");
lfun_ids = allocate_mapping(NUM_LFUNS);
lfun_types = allocate_mapping(NUM_LFUNS);
for (i=0; i < NELEM(lfun_names); i++) {
lfun_strings[i] = make_shared_string(lfun_names[i]);
id.type = T_INT;
pike.git/src/program.c:8029:
tFunc(tInt tOr(tMapping,tVoid),tStr), 0);
placeholder_program=end_program();
placeholder_object=fast_clone_object(placeholder_program);
s.type=T_OBJECT;
s.subtype = 0;
s.u.object=placeholder_object;
low_add_constant("__placeholder_object",&s);
debug_malloc_touch(placeholder_object);
}
+
+ exit_compiler();
}
void cleanup_program(void)
{
size_t e;
free_type(lfun_setter_type_string);
free_type(lfun_getter_type_string);
free_mapping(lfun_types);
free_mapping(lfun_ids);
pike.git/src/program.c:8388:
f->current_function_number=-2; /* no function */
f->recur_label=-1;
f->is_inline=0;
f->num_args=-1;
f->opt_flags = OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND; /* FIXME: Should be 0. */
Pike_compiler->compiler_frame=f;
}
void low_pop_local_variables(int level)
{
+ struct compilation *c = THIS_COMPILATION;
while(Pike_compiler->compiler_frame->current_number_of_locals > level)
{
int e;
e=--(Pike_compiler->compiler_frame->current_number_of_locals);
if ((Pike_compiler->compiler_pass == 2) &&
!(Pike_compiler->compiler_frame->variable[e].flags &
LOCAL_VAR_IS_USED)) {
- struct pike_string *save_file = lex.current_file;
- int save_line = lex.current_line;
- lex.current_file = Pike_compiler->compiler_frame->variable[e].file;
- lex.current_line = Pike_compiler->compiler_frame->variable[e].line;
+ struct pike_string *save_file = c->lex.current_file;
+ int save_line = c->lex.current_line;
+ c->lex.current_file = Pike_compiler->compiler_frame->variable[e].file;
+ c->lex.current_line = Pike_compiler->compiler_frame->variable[e].line;
yywarning("Unused local variable %S.",
Pike_compiler->compiler_frame->variable[e].name);
- lex.current_file = save_file;
- lex.current_line = save_line;
+ c->lex.current_file = save_file;
+ c->lex.current_line = save_line;
}
free_string(Pike_compiler->compiler_frame->variable[e].name);
free_type(Pike_compiler->compiler_frame->variable[e].type);
if(Pike_compiler->compiler_frame->variable[e].def)
free_node(Pike_compiler->compiler_frame->variable[e].def);
free_string(Pike_compiler->compiler_frame->variable[e].file);
}
}
void pop_local_variables(int level)
{
#if 1
-
+ struct compilation *c = THIS_COMPILATION;
/* We need to save the variables Kuppo (but not their names) */
if(level < Pike_compiler->compiler_frame->min_number_of_locals)
{
/* FIXME: Consider using flags to indicate whether a local variable
* actually is used from a nested scope. */
for(;level<Pike_compiler->compiler_frame->min_number_of_locals;level++)
{
if ((Pike_compiler->compiler_pass == 2) &&
!(Pike_compiler->compiler_frame->variable[level].flags &
LOCAL_VAR_IS_USED)) {
- struct pike_string *save_file = lex.current_file;
- int save_line = lex.current_line;
- lex.current_file = Pike_compiler->compiler_frame->variable[level].file;
- lex.current_line = Pike_compiler->compiler_frame->variable[level].line;
+ struct pike_string *save_file = c->lex.current_file;
+ int save_line = c->lex.current_line;
+ c->lex.current_file =
+ Pike_compiler->compiler_frame->variable[level].file;
+ c->lex.current_line =
+ Pike_compiler->compiler_frame->variable[level].line;
yywarning("Unused local variable %S.",
Pike_compiler->compiler_frame->variable[level].name);
- lex.current_file = save_file;
- lex.current_line = save_line;
+ c->lex.current_file = save_file;
+ c->lex.current_line = save_line;
/* Make sure we only warn once... */
Pike_compiler->compiler_frame->variable[level].flags |=
LOCAL_VAR_IS_USED;
}
free_string(Pike_compiler->compiler_frame->variable[level].name);
copy_shared_string(Pike_compiler->compiler_frame->variable[level].name,
empty_pike_string);
/* FIXME: Do we need to keep the filenames? */
}
}
pike.git/src/program.c:8642: Inside #if 0
return i;
}
}
}
return -1;
}
#endif /* 0 */
void yywarning(char *fmt, ...)
{
+ struct compilation *c = THIS_COMPILATION;
struct string_builder s;
struct pike_string *msg;
va_list args;
-
+ CHECK_COMPILER();
+
/* If we have parse errors we might get erroneous warnings,
* so don't print them.
* This has the additional benefit of making it easier to
* visually locate the actual error message.
*/
if (Pike_compiler->num_parse_error) return;
init_string_builder(&s, 0);
va_start(args,fmt);
string_builder_vsprintf(&s, fmt, args);
va_end(args);
msg = finish_string_builder(&s);
if (master_object) {
- if (lex.current_file) {
- ref_push_string(lex.current_file);
- } else {
- push_empty_string();
- }
- push_int(lex.current_line);
+ ref_push_string(c->lex.current_file);
+ push_int(c->lex.current_line);
push_string(msg);
low_safe_apply_handler("compile_warning",
- error_handler, compat_handler, 3);
+ c->handler, c->compat_handler, 3);
pop_stack();
} else {
if (!msg->size_shift) {
fprintf(stderr, "%s:%d: Warning: %s\n",
- lex.current_file->str, lex.current_line, msg->str);
+ c->lex.current_file->str, c->lex.current_line, msg->str);
}
free_string(msg);
}
}
/* returns 1 if a implements b */
static int low_implements(struct program *a, struct program *b)
{
pike.git/src/program.c:8994:
find_external_context(&loc, depth);
if (!loc.o->prog)
Pike_error ("Cannot access storage of destructed parent object.\n");
return loc.o->storage + loc.inherit->storage_offset;
}
PMOD_EXPORT void change_compiler_compatibility(int major, int minor)
{
+ struct compilation *c = THIS_COMPILATION;
+
+ CHECK_COMPILER();
+
STACK_LEVEL_START(0);
if(major == PIKE_MAJOR_VERSION && minor == PIKE_MINOR_VERSION)
{
push_int(0); /* optimization */
} else {
if(major == Pike_compiler->compat_major &&
minor == Pike_compiler->compat_minor) {
/* Optimization -- reuse the current compat handler. */
- if (compat_handler) {
- ref_push_object(compat_handler);
+ if (c->compat_handler) {
+ ref_push_object(c->compat_handler);
} else {
push_int(0);
}
} else {
push_int(major);
push_int(minor);
SAFE_APPLY_MASTER("get_compilation_handler",2);
}
}
STACK_LEVEL_CHECK(1);
- if(compat_handler)
+ if(c->compat_handler)
{
- free_object(compat_handler);
- compat_handler = NULL;
+ free_object(c->compat_handler);
+ c->compat_handler = NULL;
}
if((Pike_sp[-1].type == T_OBJECT) && (Pike_sp[-1].u.object->prog))
{
if (Pike_sp[-1].subtype) {
/* FIXME: */
Pike_error("Subtyped compat handlers are not supported yet.\n");
}
- compat_handler = dmalloc_touch(struct object *, Pike_sp[-1].u.object);
+ c->compat_handler = dmalloc_touch(struct object *, Pike_sp[-1].u.object);
dmalloc_touch_svalue(Pike_sp-1);
Pike_sp--;
} else {
pop_stack();
}
- if (safe_apply_handler ("get_default_module", error_handler, compat_handler,
+ if (safe_apply_handler ("get_default_module",
+ c->handler, c->compat_handler,
0, BIT_MAPPING|BIT_OBJECT|BIT_ZERO)) {
if(Pike_sp[-1].type == T_INT)
{
pop_stack();
ref_push_mapping(get_builtin_constants());
}
} else {
ref_push_mapping(get_builtin_constants());
}