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.673 2008/04/20 13:00:42 grubba Exp $
+ || $Id: program.c,v 1.674 2008/04/24 16:03:54 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:3048: 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"
+ "%*sString table:\n"
+ "%*s ####: Value\n",
+ indent, "", indent, "");
+ for (d = 0; d < p->num_strings; d++) {
+ fprintf(stderr, "%*s %4d: [%p]\"%s\"(%d characters)\n",
+ indent, "", (int)d, p->strings[d], p->strings[d]->str, p->strings[d]->len);
+ }
+
+ 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]);
}
}
pike.git/src/program.c:7253:
{
struct pike_string *ident;
struct pike_string *filename;
struct object *handler = NULL;
get_all_args("resolv", args, "%W%W.%O",
&ident, &filename, &handler);
if(get_master())
{
- struct compilation *c = THIS_COMPILATION;
+
DECLARE_CYCLIC();
if(BEGIN_CYCLIC(ident, filename))
{
my_yyerror("Recursive module dependency in %S.", ident);
}else{
SET_CYCLIC_RET(1);
APPLY_MASTER("resolv", args);
}
END_CYCLIC();
} else {
pop_n_elems(args);
push_undefined();
}
}
-
+ /*! @decl object get_compilation_handler(int major, int minor)
+ *!
+ *! Get compatibility handler for Pike @[major].@[minor].
+ *!
+ *! @note
+ *! This function is typically called by
+ *! @[PikeCompiler()->get_compilation_handler()].
+ */
+ static void f_compilation_env_get_compilation_handler(INT32 args)
+ {
+ if(get_master())
+ {
+ APPLY_MASTER("get_compilation_handler", args);
+ } else {
+ pop_n_elems(args);
+ push_undefined();
+ }
+ }
+
+ /*! @decl mapping(string:mixed)|object get_default_module()
+ *!
+ *! Get the default module for the current compatibility level
+ *! (ie typically the value returned by @[predef::all_constants()]).
+ *!
+ *! The default implementation calls the corresponding function
+ *! in the master object.
+ *!
+ *! @returns
+ *! @mixed
+ *! @type mapping(string:mixed)|object
+ *! Constant table to use.
+ *!
+ *! @type int(0..0)
+ *! Use the builtin constant table.
+ *! @endmixed
+ *!
+ *! @note
+ *! This function is typically called by
+ *! @[Pike_compiler()->get_default_module()].
+ */
+ static void f_compilation_env_get_default_module(INT32 args)
+ {
+ if(get_master())
+ {
+ APPLY_MASTER("get_default_module", args);
+ } else {
+ pop_n_elems(args);
+ push_undefined();
+ }
+ }
+
/*! @class PikeCompiler
*!
*! The Pike compiler.
*!
*! An object of this class compiles a single string
*! of Pike code.
*/
static void free_compilation(struct compilation *c)
{
pike.git/src/program.c:7711:
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;
+ add_ref(c->default_module.u.mapping = get_builtin_constants());
+ c->default_module.type = T_MAPPING;
+ c->major = -1;
+ c->minor = -1;
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;
}
}
pike.git/src/program.c:7797:
ref_push_string(message);
apply_low(handler, fun, 3);
stack_pop_n_elems_keep_top(args);
}
/*! @decl void create(string|void source, @
*! CompilationHandler|void handler, @
*! int|void major, int|void minor,@
*! program|void target, object|void placeholder)
*!
- *! Create a Pike compiler object for a source string.
+ *! Create a PikeCompiler object for a source string.
*!
*! This function takes a piece of Pike code as a string and
*! initializes a compiler object accordingly.
*!
*! The optional argument @[handler] is used to specify an alternative
*! error handler. If it is not specified the current master object
*! at compile time will be used.
*!
*! The optional arguments @[major] and @[minor] are used to tell the
*! compiler to attempt to be compatible with Pike @[major].@[minor].
pike.git/src/program.c:7871:
if (c->p) free_program(c->p);
c->p = NULL;
if (c->prog) free_string(c->prog);
if ((c->prog=aprog)) add_ref(aprog);
if (c->handler) free_object(c->handler);
if ((c->handler=ahandler)) add_ref(ahandler);
- c->major=amajor;
- c->minor=aminor;
-
+
if (c->target) free_program(c->target);
if ((c->target=atarget)) add_ref(atarget);
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))
- {
+ push_int(amajor?amajor:-1);
+ push_int(aminor?aminor:-1);
+ apply_current(PC_CHANGE_COMPILER_COMPATIBILITY_FUN_NUM, 2);
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--;
+
STACK_LEVEL_DONE(args);
pop_n_elems(args);
push_int(0);
}
/*! @decl program compile()
*!
*! Compile the current source into a program.
*!
*! This function compiles the current Pike source code
pike.git/src/program.c:8049:
if (((handler = c->handler) && handler->prog &&
((fun = find_identifier("resolv", handler->prog)) != -1)) ||
((handler = c->compat_handler) && handler->prog &&
((fun = find_identifier("resolv", handler->prog)) != -1))) {
apply_low(handler, fun, args);
} else {
apply_external(1, CE_RESOLV_FUN_NUM, args);
}
}
+ /*! @decl object get_compilation_handler(int major, int minor)
+ *!
+ *! Get compatibility handler for Pike @[major].@[minor].
+ *!
+ *! @note
+ *! This function is called by @[change_compiler_compatibility()].
+ */
+ static void f_compilation_get_compilation_handler(INT32 args)
+ {
+ struct compilation *c = THIS_COMPILATION;
+ struct object *handler;
+ int fun = -1;
+
+ if (((handler = c->handler) && handler->prog &&
+ ((fun = find_identifier("get_compilation_handler", handler->prog)) != -1)) ||
+ ((handler = c->compat_handler) && handler->prog &&
+ ((fun = find_identifier("get_compilation_handler", handler->prog)) != -1))) {
+ apply_low(handler, fun, args);
+ } else {
+ apply_external(1, CE_GET_COMPILATION_HANDLER_FUN_NUM, args);
+ }
+ }
+
+ /*! @decl mapping(string:mixed)|object get_default_module()
+ *!
+ *! Get the default module for the current compatibility level
+ *! (ie typically the value returned by @[predef::all_constants()]).
+ *!
+ *! The default implementation calls the corresponding function
+ *! in the current handler, the current compatibility handler
+ *! or in the parent @[CompilationEnvironment] in that order.
+ *!
+ *! @returns
+ *! @mixed
+ *! @type mapping(string:mixed)|object
+ *! Constant table to use.
+ *!
+ *! @type int(0..0)
+ *! Use the builtin constant table.
+ *! @endmixed
+ *!
+ *! @note
+ *! This function is called by @[change_compiler_compatibility()].
+ */
+ static void f_compilation_get_default_module(INT32 args)
+ {
+ struct compilation *c = THIS_COMPILATION;
+ struct object *handler;
+ int fun = -1;
+
+ if (((handler = c->handler) && handler->prog &&
+ ((fun = find_identifier("get_default_module", handler->prog)) != -1)) ||
+ ((handler = c->compat_handler) && handler->prog &&
+ ((fun = find_identifier("get_default_module", handler->prog)) != -1))) {
+ apply_low(handler, fun, args);
+ } else {
+ apply_external(1, CE_GET_DEFAULT_MODULE_FUN_NUM, args);
+ }
+ }
+
+ /*! @decl void change_compiler_compatibility(int major, int minor)
+ *!
+ *! Change compiler to attempt to be compatible with Pike @[major].@[minor].
+ */
+ static void f_compilation_change_compiler_compatibility(INT32 args)
+ {
+ struct compilation *c = THIS_COMPILATION;
+ int major = -1;
+ int minor = -1;
+
+ STACK_LEVEL_START(args);
+
+ get_all_args("change_compiler_compatibility", args, "%d%d",
+ &major, &minor);
+
+ if ((major == -1) && (minor == -1)) {
+ major = PIKE_MAJOR_VERSION;
+ minor = PIKE_MINOR_VERSION;
+ }
+
+ if ((major == Pike_compiler->compat_major) &&
+ (minor == Pike_compiler->compat_minor)) {
+ /* Optimization: Already at this compat level. */
+ pop_n_elems(args);
+ push_int(0);
+ return;
+ }
+
+ Pike_compiler->compat_major=major;
+ Pike_compiler->compat_minor=minor;
+
+ /* Optimization: The up to date compiler shouldn't need a compat handler. */
+ if((major != PIKE_MAJOR_VERSION) || (minor != PIKE_MINOR_VERSION))
+ {
+ apply_current(PC_GET_COMPILATION_HANDLER_FUN_NUM, args);
+
+ 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");
+ }
+ if (c->compat_handler == Pike_sp[-1].u.object) {
+ /* Still at the same compat level. */
+ pop_stack();
+ push_int(0);
+ return;
+ } else {
+ if(c->compat_handler) free_object(c->compat_handler);
+ c->compat_handler = Pike_sp[-1].u.object;
+ dmalloc_touch_svalue(Pike_sp-1);
+ Pike_sp--;
+ }
+ } else {
+ pop_stack();
+ if(c->compat_handler) {
+ free_object(c->compat_handler);
+ c->compat_handler = NULL;
+ } else {
+ /* No change in compat handler. */
+ push_int(0);
+ return;
+ }
+ }
+ } else {
+ pop_n_elems(args);
+ if (c->compat_handler) {
+ free_object(c->compat_handler);
+ c->compat_handler = NULL;
+ } else {
+ /* No change in compat handler. */
+ push_int(0);
+ return;
+ }
+ }
+
+ STACK_LEVEL_CHECK(0);
+
+ Pike_fp->args = 0; /* Clean up the stack frame. */
+
+ apply_current(PC_GET_DEFAULT_MODULE_FUN_NUM, 0);
+
+ if(Pike_sp[-1].type == T_INT)
+ {
+ pop_stack();
+ ref_push_mapping(get_builtin_constants());
+ }
+
+ STACK_LEVEL_CHECK(1);
+
+ assign_svalue(&c->default_module, Pike_sp-1);
+
+ /* Replace the implicit import of all_constants() with
+ * the new value.
+ */
+ if(Pike_compiler->num_used_modules)
+ {
+ free_svalue( (struct svalue *)used_modules.s.str );
+ ((struct svalue *)used_modules.s.str)[0]=sp[-1];
+ sp--;
+ dmalloc_touch_svalue(sp);
+ if(Pike_compiler->module_index_cache)
+ {
+ free_mapping(Pike_compiler->module_index_cache);
+ Pike_compiler->module_index_cache=0;
+ }
+ }else{
+ use_module(sp-1);
+ pop_stack();
+ }
+
+ STACK_LEVEL_DONE(0);
+ push_int(0);
+ }
+
+ static void f_compilation__sprintf(INT32 args)
+ {
+ struct compilation *c = THIS_COMPILATION;
+ struct string_builder buf;
+ init_string_builder_alloc(&buf, 50, 0);
+ string_builder_strcat(&buf, "PikeCompiler(");
+ if (c->prog) {
+ string_builder_strcat(&buf, "\"\", ");
+ } else {
+ string_builder_strcat(&buf, "UNDEFINED, ");
+ }
+ if (c->handler) {
+ ref_push_object(c->handler);
+ string_builder_sprintf(&buf, "%O, ", Pike_sp-1);
+ pop_stack();
+ } else {
+ string_builder_strcat(&buf, "UNDEFINED, ");
+ }
+ string_builder_sprintf(&buf, "%d, %d, %s, %s)",
+ c->major, c->minor,
+ c->target?"target":"UNDEFINED",
+ c->placeholder?"placeholder":"UNDEFINED");
+ pop_n_elems(args);
+ push_string(finish_string_builder(&buf));
+ }
+
/* Fake being called via PikeCompiler()->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.
*/
pike.git/src/program.c:8154:
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
*/
/*! @endclass
*/
pike.git/src/program.c:8280:
ADD_FUNCTION("compile", f_compilation_compile,
tFunc(tNone, tPrg(tObj)), 0);
ADD_FUNCTION("resolv", f_compilation_resolv,
tFunc(tStr tStr tObj, tMix), 0);
ADD_FUNCTION("create", f_compilation_create,
tFunc(tOr(tStr, tVoid) tOr(tObj, tVoid)
tOr(tInt, tVoid) tOr(tInt, tVoid)
- tOr(tPrg(tObj), tVoid) tOr(tObj, tVoid), tVoid), 0);
+ tOr(tPrg(tObj), tVoid) tOr(tObj, tVoid), tVoid),
+ ID_STATIC);
-
+ ADD_FUNCTION("get_compilation_handler",
+ f_compilation_get_compilation_handler,
+ tFunc(tInt tInt, tObj), 0);
+
+ ADD_FUNCTION("get_default_module", f_compilation_get_default_module,
+ tFunc(tNone, tOr(tMap(tStr, tMix), tObj)), 0);
+
+ ADD_FUNCTION("change_compiler_compatibility",
+ f_compilation_change_compiler_compatibility,
+ tFunc(tInt tInt, tVoid), 0);
+
+ ADD_FUNCTION("_sprintf", f_compilation__sprintf,
+ tFunc(tInt tOr(tMap(tStr, tMix), tVoid), tStr), ID_STATIC);
+
start_new_program();
ADD_STORAGE(struct program_state);
Pike_compiler->new_program->event_handler = program_state_event_handler;
Pike_compiler->new_program->flags |=
PROGRAM_NEEDS_PARENT|PROGRAM_USES_PARENT|PROGRAM_HAS_C_METHODS;
/* Alias for report above. */
low_define_alias(NULL, NULL, 0, 1, PC_REPORT_FUN_NUM);
pike.git/src/program.c:8323:
* Remove the one we added above, so that we don't get it double.
*/
p2->xstorage = 0;
end_class("PikeCompiler", 0);
/* end_class()/end_program() has zapped the inherit once again,
* so we need to repair the frame pointer.
*/
Pike_fp->context = compilation_program->inherits;
+ ADD_FUNCTION("get_compilation_handler",
+ f_compilation_env_get_compilation_handler,
+ tFunc(tInt tInt, tObj), 0);
+
+ ADD_FUNCTION("get_default_module",
+ f_compilation_env_get_default_module,
+ tFunc(tNone, tOr(tMap(tStr, tMix), tObj)), 0);
+
{
struct pike_string *type_name;
struct svalue type_value;
/* enum SeverityLevel { NOTICE, WARNING, ERROR, FATAL } */
type_value.type = PIKE_T_TYPE;
type_value.subtype = 0;
type_value.u.type = CONSTTYPE(tName("SeverityLevel", tInt03));
simple_add_constant("SeverityLevel", &type_value, 0);
free_svalue(&type_value);
pike.git/src/program.c:9752:
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 (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(c->compat_handler)
- {
- 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");
- }
- c->compat_handler = dmalloc_touch(struct object *, Pike_sp[-1].u.object);
- dmalloc_touch_svalue(Pike_sp-1);
- Pike_sp--;
- } else {
+ safe_apply_current2(PC_CHANGE_COMPILER_COMPATIBILITY_FUN_NUM, 2,
+ "change_compiler_compatibility");
pop_stack();
}
- 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());
- }
-
- STACK_LEVEL_CHECK(1);
-
- if(Pike_compiler->num_used_modules)
- {
- free_svalue( (struct svalue *)used_modules.s.str );
- ((struct svalue *)used_modules.s.str)[0]=sp[-1];
- sp--;
- dmalloc_touch_svalue(sp);
- if(Pike_compiler->module_index_cache)
- {
- free_mapping(Pike_compiler->module_index_cache);
- Pike_compiler->module_index_cache=0;
- }
- }else{
- use_module(sp-1);
- pop_stack();
- }
-
- Pike_compiler->compat_major=major;
- Pike_compiler->compat_minor=minor;
-
- STACK_LEVEL_DONE(0);
- }
-
+
#ifdef PIKE_USE_MACHINE_CODE
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
void make_program_executable(struct program *p)
{
if (!p->num_program) return;
if ((p->event_handler == compat_event_handler) &&