From 1eea3e41039daaf58b6fffcfeccee645ad0d4b3e Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Sat, 13 Oct 2007 21:32:51 +0000 Subject: [PATCH] Fix module messup when calling into Python. [SVN r39988] --- src/engine/compile.c | 45 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/engine/compile.c b/src/engine/compile.c index 411f972f5..cd5a91941 100644 --- a/src/engine/compile.c +++ b/src/engine/compile.c @@ -896,6 +896,15 @@ call_python_function(RULE* r, FRAME* frame) return result; } + +module_t* python_module() +{ + static module_t* python = 0; + if ( !python ) + python = bindmodule("__python__"); + return python; +} + #endif /* @@ -937,7 +946,41 @@ evaluate_rule( #ifdef HAVE_PYTHON if (rule->python_function) { - return call_python_function(rule, frame); + /* The below messing with modules is due to the + way modules are implemented in jam. + Suppose we're in module M1 now. The global + variable map actually holds 'M1' variables, + and M1->variables hold global variables. + + If we call Python right away, and then Python + call back Jam, and jam does: + + module M1 { } + + then jam will try to swap current global + variables with M1->variables. The result will + be that global variables map will hold + global variables, and any variables settings + we do will go to global module, not M1. + + By restoring basic state, where global + variable map hold global variable, we make + sure any fugure 'module M1' will work OK. */ + + LIST *result; + module_t *m = python_module(); + + frame->module = m; + + exit_module( prev_module ); + enter_module( m ); + + result = call_python_function(rule, frame); + + exit_module( m ); + enter_module ( prev_module ); + + return result; } #endif