add in_interpreter flag

This commit is contained in:
David Rose 2001-06-07 19:43:18 +00:00
parent 3ceb686cd7
commit e4622d5696
13 changed files with 134 additions and 43 deletions

View File

@ -132,6 +132,16 @@
#define PYTHON_LPATH
#defer HAVE_PYTHON $[isdir $[PYTHON_IPATH]]
// Do you want to enable the "in_interpreter" global variable? This
// will enable some callbacks, particularly the MemoryUsage object, to
// know whether they were called from Python code (or other high-level
// show code) and react accordingly, generally for debugging
// purporses. It adds a bit of runtime overhead, and isn't usually
// useful unless we're building a debug tree anyway. The default is
// to enable it only for optimize levels 1 and 2.
#defer TRACK_IN_INTERPRETER $[<= $[OPTIMIZE], 2]
// Is NSPR installed, and where? This is the Netscape Portable
// Runtime library, downloadable as part of the Mozilla package from
// mozilla.org. It provides portable threading and networking

View File

@ -31,6 +31,9 @@ $[cdefine HAVE_DINKUM]
/* Define if we have Python installed. */
$[cdefine HAVE_PYTHON]
/* Define if we have want to track callbacks from within the show code. */
$[cdefine TRACK_IN_INTERPRETER]
/* Define if we have NSPR installed. */
$[cdefine HAVE_NSPR]

View File

@ -739,9 +739,14 @@ Warning: Variable $[upcase $[tree]]_INSTALL is not set!
$[filter -D%,$[C++FLAGS]] \
$[INTERROGATE_OPTIONS] \
$[if $[INTERROGATE_PYTHON_INTERFACE],-python] \
$[if $[<= $[OPTIMIZE], 1],-spam] \
$[if $[INTERROGATE_C_INTERFACE],-c]
$[if $[INTERROGATE_C_INTERFACE],-c] \
$[if $[TRACK_IN_INTERPRETER],-track-interpreter] \
$[if $[<= $[OPTIMIZE], 1],-spam]
#defer interrogate_module_options \
$[if $[INTERROGATE_PYTHON_INTERFACE],-python] \
$[if $[INTERROGATE_C_INTERFACE],-c] \
$[if $[TRACK_IN_INTERPRETER],-track-interpreter]
// Include the global definitions for this particular build_type, if

View File

@ -494,7 +494,7 @@ lib$[TARGET]_igatemscan = $[igatemscan]
#define target $[so_dir]/$[igatemout]
#define sources $(lib$[TARGET]_igatemscan)
$[target] : $[sources] $[so_dir]/stamp
$[TAB] interrogate_module -oc $[target] -module "$[igatemod]" -library "$[igatelib]" -python $[sources]
$[TAB] interrogate_module -oc $[target] -module "$[igatemod]" -library "$[igatelib]" $[interrogate_module_options] $[sources]
#define target $[igatemout:%.cxx=$[so_dir]/%.obj]
#define source $[so_dir]/$[igatemout]

View File

@ -465,7 +465,7 @@ lib$[TARGET]_igatemscan = $[osfilename $[igatemscan]]
#define target $[so_dir]\$[igatemout]
#define sources $(lib$[TARGET]_igatemscan)
$[target] : $[sources]
$[TAB] interrogate_module -oc $[target] -module "$[igatemod]" -library "$[igatelib]" -python $[sources]
$[TAB] interrogate_module -oc $[target] -module "$[igatemod]" -library "$[igatelib]" $[interrogate_module_options] $[sources]
#define target $[igatemout:%.cxx=$[so_dir]\%.obj]
#define source $[so_dir]\$[igatemout]

View File

@ -260,7 +260,15 @@ $[TAB]@test -d $[directory] || mkdir -p $[directory]
// Now it's time to start generating the rules to make our actual
// targets.
igate : $[get_igatedb(metalib_target lib_target ss_lib_target):%=$[so_dir]/%]
// Determine which files will be generated during the interrogate
// pass, and make a special "igate" rule to generate all of them.
#define build_igate
#forscopes metalib_target lib_target ss_lib_target
#define igatemscan $[components $[get_igatedb],$[active_component_libs]]
#define igatemout $[if $[igatemscan],lib$[TARGET]_module.cxx]
#set build_igate $[build_igate] $[get_igatedb:%=$[so_dir]/%] $[igatemout:%=$[so_dir]/%]
#end metalib_target lib_target ss_lib_target
igate : $[sort $[build_igate]]
/////////////////////////////////////////////////////////////////////
@ -375,7 +383,7 @@ lib$[TARGET]_igatemscan = $[igatemscan]
#define target $[so_dir]/$[igatemout]
#define sources $(lib$[TARGET]_igatemscan)
$[target] : $[sources]
$[TAB]interrogate_module -oc $[target] -module "$[igatemod]" -library "$[igatelib]" -python $[sources]
$[TAB]interrogate_module -oc $[target] -module "$[igatemod]" -library "$[igatelib]" $[interrogate_module_options] $[sources]
#define target $[igatemout:%.cxx=$[so_dir]/%.o]
#define source $[so_dir]/$[igatemout]

View File

@ -46,6 +46,7 @@ bool watch_asserts = false;
bool true_wrapper_names = false;
bool build_c_wrappers = false;
bool build_python_wrappers = false;
bool track_interpreter = false;
bool save_unique_names = false;
bool no_database = false;
bool generate_spam = false;
@ -72,6 +73,7 @@ enum CommandOptions {
CO_true_names,
CO_c,
CO_python,
CO_track_interpreter,
CO_unique_names,
CO_nodb,
CO_longlong,
@ -94,6 +96,7 @@ static struct option long_options[] = {
{ "true-names", no_argument, NULL, CO_true_names },
{ "c", no_argument, NULL, CO_c },
{ "python", no_argument, NULL, CO_python },
{ "track-interpreter", no_argument, NULL, CO_track_interpreter },
{ "unique-names", no_argument, NULL, CO_unique_names },
{ "nodb", no_argument, NULL, CO_nodb },
{ "longlong", required_argument, NULL, CO_longlong },
@ -231,6 +234,11 @@ void show_help() {
<< " Either or both of -c and/or -python may be specified. If both are\n"
<< " omitted, the default is -c.\n\n"
<< " -track-interpreter\n"
<< " Generate code within each wrapper function to adjust the global\n"
<< " variable \"in_interpreter\" to indicated whether code is running\n"
<< " within the Panda C++ environment or within the high-level language.\n"
<< " -unique-names\n"
<< " Compile a table into the library (i.e. generate code into the -oc\n"
<< " file) that defines a lookup of each function wrapper by its unique\n"
@ -361,6 +369,10 @@ main(int argc, char *argv[]) {
build_python_wrappers = true;
break;
case CO_track_interpreter:
track_interpreter = true;
break;
case CO_unique_names:
save_unique_names = true;
break;

View File

@ -40,6 +40,7 @@ extern bool watch_asserts;
extern bool true_wrapper_names;
extern bool build_c_wrappers;
extern bool build_python_wrappers;
extern bool track_python;
extern bool save_unique_names;
extern bool no_database;
extern bool generate_spam;

View File

@ -40,6 +40,7 @@ string module_name;
string library_name;
bool build_c_wrappers = false;
bool build_python_wrappers = false;
bool track_interpreter = false;
// Short command-line options.
static const char *short_options = "";
@ -51,6 +52,7 @@ enum CommandOptions {
CO_library,
CO_c,
CO_python,
CO_track_interpreter,
};
static struct option long_options[] = {
@ -59,6 +61,7 @@ static struct option long_options[] = {
{ "library", required_argument, NULL, CO_library },
{ "c", no_argument, NULL, CO_c },
{ "python", no_argument, NULL, CO_python },
{ "track-interpreter", no_argument, NULL, CO_track_interpreter },
{ NULL }
};
@ -77,8 +80,9 @@ upcase_string(const string &str) {
int
write_python_table(ostream &out) {
out << "\n#include <dtoolbase.h>\n\n"
<< "\n#include <Python.h>\n\n";
out << "\n#include <dtoolbase.h>\n"
<< "#include <interrogate_request.h>\n\n"
<< "#include <Python.h>\n\n";
int count = 0;
@ -160,8 +164,11 @@ write_python_table(ostream &out) {
<< "extern \"C\" void init" << library_name << "();\n"
<< "#endif\n\n"
<< "void init" << library_name << "() {\n"
<< " Py_InitModule(\"" << library_name << "\", python_methods);\n"
<< "void init" << library_name << "() {\n";
if (track_interpreter) {
out << " in_interpreter = 1;\n";
}
out << " Py_InitModule(\"" << library_name << "\", python_methods);\n"
<< "}\n\n";
return count;
@ -196,6 +203,10 @@ main(int argc, char *argv[]) {
build_python_wrappers = true;
break;
case CO_track_interpreter:
track_interpreter = true;
break;
default:
exit(1);
}

View File

@ -71,7 +71,8 @@ show_type_or_expression(const string &str) {
CPPType *type = parser.parse_type(str);
if (type != NULL) {
cout << "\nType: " << *type << "\n"
<< "Defined in: " << type->_file << "\n\n";
<< "Defined in: " << type->_file << "\n"
<< "Subtype code is: " << (int)type->get_subtype() << "\n\n";
CPPStructType *stype = type->as_struct_type();
if (stype != (CPPStructType *)NULL) {

View File

@ -144,6 +144,10 @@ write_wrapper(ostream &out, const string &wrapper_name) const {
out << " if (PyArg_ParseTuple(args, \"" << format_specifiers
<< "\"" << parameter_list << ")) {\n";
if (track_interpreter) {
out << " in_interpreter = 0;\n";
}
if (_return_type->new_type_is_atomic_string()) {
// Treat strings as a special case. We don't want to format the
// return expression.
@ -153,6 +157,11 @@ write_wrapper(ostream &out, const string &wrapper_name) const {
out << " ";
type->output_instance(out, "return_value", &parser);
out << " = " << return_expr << ";\n";
if (track_interpreter) {
out << " in_interpreter = 1;\n";
}
return_expr = manage_return_value(out, 4, "return_value");
test_assert(out, 4);
pack_return_value(out, return_expr);
@ -160,6 +169,9 @@ write_wrapper(ostream &out, const string &wrapper_name) const {
} else {
string return_expr = call_function(out, 4, true, pexprs);
if (return_expr.empty()) {
if (track_interpreter) {
out << " in_interpreter = 1;\n";
}
test_assert(out, 4);
out << " return Py_BuildValue(\"\");\n";
@ -168,6 +180,9 @@ write_wrapper(ostream &out, const string &wrapper_name) const {
out << " ";
type->output_instance(out, "return_value", &parser);
out << " = " << return_expr << ";\n";
if (track_interpreter) {
out << " in_interpreter = 1;\n";
}
return_expr = manage_return_value(out, 4, "return_value");
test_assert(out, 4);

View File

@ -21,6 +21,10 @@
#include <string.h> // for strdup
#ifdef TRACK_IN_INTERPRETER
int in_interpreter = false;
#endif
void
interrogate_request_database(const char *database_filename) {
InterrogateModuleDef *def = new InterrogateModuleDef;

View File

@ -1,33 +1,35 @@
// Filename: interrogate_request.h
// Created by: drose (01Aug00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
/* Filename: interrogate_request.h
* Created by: drose (01Aug00)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* PANDA 3D SOFTWARE
* Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
*
* All use of this software is subject to the terms of the Panda 3d
* Software license. You should have received a copy of this license
* along with this source code; you will also find a current copy of
* the license at http://www.panda3d.org/license.txt .
*
* To contact the maintainers of this program write to
* panda3d@yahoogroups.com .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef INTERROGATE_REQUEST
#define INTERROGATE_REQUEST
#include <dtoolbase.h>
// The functions here are simple functions that are intended to be
// called during static init time for the various libraries that
// contain interrogate data. They provide interfaces to add the
// module's interrogate data to the main interrogate database.
// The interface is entirely C here--no C++--so that it may be called
// from C modules if required.
/*
* The functions here are simple functions that are intended to be
* called during static init time for the various libraries that
* contain interrogate data. They provide interfaces to add the
* module's interrogate data to the main interrogate database.
*
* The interface is entirely C here--no C++--so that it may be called
* from C modules if required.
*/
#ifdef __cplusplus
@ -35,15 +37,17 @@ extern "C" {
#endif
// This is the simplest interface. It just requests that the given
// database filename (*.in) be read in. This makes the interrogate
// data available, but doesn't allow matching the database information
// up with any compiled-in function wrappers or anything.
/*
* This is the simplest interface. It just requests that the given
* database filename (*.in) be read in. This makes the interrogate
* data available, but doesn't allow matching the database information
* up with any compiled-in function wrappers or anything.
*/
EXPCL_DTOOLCONFIG void interrogate_request_database(const char *database_filename);
// The more sophisticated interface uses these structures.
/* The more sophisticated interface uses these structures. */
typedef struct {
const char *name;
@ -69,11 +73,28 @@ typedef struct {
} InterrogateModuleDef;
// This requests that the given module be loaded and made available.
// This includes all of the function pointers and/or unique names that
// might be compiled in.
/*
* This requests that the given module be loaded and made available.
* This includes all of the function pointers and/or unique names that
* might be compiled in.
*/
EXPCL_DTOOLCONFIG void interrogate_request_module(InterrogateModuleDef *def);
#ifdef TRACK_IN_INTERPRETER
/*
* If we're tracking whether we're currently running in Python code
* (mainly for the purpose of debug logging from memory allocation
* callbacks), this variable will record that state. It will be set
* true whenever we return to Python code, and false whenever we are
* entering local C or C++ code. The flag will be toggled off and
* on within each generated Python wrapper function.
*
* This will mis-categorize some code that runs at static
* initialization time, but it will correctly identify the vast
* majority of code.
*/
EXPCL_DTOOLCONFIG extern int in_interpreter;
#endif // TRACK_IN_INTERPRETER
#ifdef __cplusplus
}