summaryrefslogtreecommitdiff
path: root/Lib/octave
diff options
context:
space:
mode:
authorKarl Wette <karl.wette@gmail.com>2012-05-14 09:23:45 +0000
committerKarl Wette <karl.wette@gmail.com>2012-05-14 09:23:45 +0000
commitbf0fe8346254d8bb0d0135d943965903b74ee968 (patch)
treeba7a6d81a0d7c3ce152666870be064a4ab7ad39b /Lib/octave
parenta0dbe43c73a0fae5a7c0b1189bd901c29f21468a (diff)
downloadswig-bf0fe8346254d8bb0d0135d943965903b74ee968.tar.gz
New functions for handling Octave global variables
- Creates a copy of the variable to be assigned to the symbol table, so it can be safely deallocated on exit git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@13086 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Diffstat (limited to 'Lib/octave')
-rw-r--r--Lib/octave/octrun.swg37
1 files changed, 28 insertions, 9 deletions
diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg
index 99e022e89..a9ee5380f 100644
--- a/Lib/octave/octrun.swg
+++ b/Lib/octave/octrun.swg
@@ -1304,8 +1304,34 @@ void SWIG_Octave_SetConstant(octave_swig_type *module_ns, const std::string &nam
module_ns->assign(name, ov);
}
+SWIGRUNTIMEINLINE octave_value SWIG_Octave_GetGlobalValue(std::string name) {
+ return get_global_value(name, true);
+}
+
+SWIGRUNTIME void SWIG_Octave_SetGlobalValue(std::string name, const octave_value& value) {
+ // It is critical that a newly-allocated octave_value is passed to set_global_value(),
+ // since it and the Octave symbol table take references to the values assigned to it.
+ // If we were to pass a reference to 'value' to set_global_value(), then the Octave
+ // symbol table would hold a reference to a variable owned by the SWIG .oct module.
+ // Both will think that they own the reference (since the .oct module is dynamically
+ // loaded, it appears to have its own C++ runtime), and so they will both try to
+ // de-allocate the octave_value on exit, resulting in a double-free or seg-fault.
+ // This is prevented by giving Octave its own heap-allocated copy of 'value'.
+ octave_value *pov = new octave_value(value);
+ set_global_value(name, *pov);
+}
+
+SWIGRUNTIME void SWIG_Octave_LinkGlobalValue(std::string name) {
+#if OCTAVE_API_VERSION_NUMBER < 37
+ link_to_global_variable(curr_sym_tab->lookup(name, true));
+#else
+ symbol_table::varref(name);
+ symbol_table::mark_global(name);
+#endif
+}
+
SWIGRUNTIME swig_module_info *SWIG_Octave_GetModule(void *clientdata) {
- octave_value ov = get_global_value("__SWIG_MODULE__" SWIG_TYPE_TABLE_NAME SWIG_RUNTIME_VERSION, true);
+ octave_value ov = SWIG_Octave_GetGlobalValue("__SWIG_MODULE__" SWIG_TYPE_TABLE_NAME SWIG_RUNTIME_VERSION);
if (!ov.is_defined() ||
ov.type_id() != octave_swig_packed::static_type_id())
return 0;
@@ -1318,12 +1344,5 @@ SWIGRUNTIME swig_module_info *SWIG_Octave_GetModule(void *clientdata) {
SWIGRUNTIME void SWIG_Octave_SetModule(void *clientdata, swig_module_info *pointer) {
octave_value ov = new octave_swig_packed(0, &pointer, sizeof(swig_module_info *));
- const char *module_var = "__SWIG_MODULE__" SWIG_TYPE_TABLE_NAME SWIG_RUNTIME_VERSION;
-#if OCTAVE_API_VERSION_NUMBER<37
- link_to_global_variable(curr_sym_tab->lookup(module_var, true));
-#else
- symbol_table::varref(module_var);
- symbol_table::mark_global(module_var);
-#endif
- set_global_value(module_var, ov);
+ SWIG_Octave_SetGlobalValue("__SWIG_MODULE__" SWIG_TYPE_TABLE_NAME SWIG_RUNTIME_VERSION, ov);
}