[lua] Run destructors of local C++ objects on SWIG_fail
Arrange that destructors of local C++ objects in the wrapper function get run on SWIG_fail (which calls lua_error() which calls longjmp()). We achieve this by putting almost everything in the function in its own block, and end that right before lua_error() at which point those destructors will get called.
This commit is contained in:
parent
3dd7e93c77
commit
9ab9c71623
4 changed files with 58 additions and 4 deletions
|
|
@ -22,6 +22,13 @@
|
|||
}
|
||||
$1 = NULL;
|
||||
}
|
||||
%typemap(out) Foo trigger_internal_swig_exception
|
||||
{
|
||||
SWIG_exception(SWIG_RuntimeError, "Let's see how the bindings manage this exception!");
|
||||
#ifdef SWIG_fail
|
||||
SWIG_fail;
|
||||
#endif
|
||||
}
|
||||
|
||||
%inline %{
|
||||
#include <string>
|
||||
|
|
@ -47,4 +54,9 @@
|
|||
return (message == "null") ? NULL : foo;
|
||||
}
|
||||
|
||||
static Foo trigger_internal_swig_exception(const std::string& message)
|
||||
{
|
||||
return Foo();
|
||||
}
|
||||
|
||||
%}
|
||||
|
|
|
|||
29
Examples/test-suite/lua/exception_memory_leak_runme.lua
Normal file
29
Examples/test-suite/lua/exception_memory_leak_runme.lua
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
require("import") -- the import fn
|
||||
import("exception_memory_leak") -- import code
|
||||
eml=exception_memory_leak --alias
|
||||
|
||||
-- catch "undefined" global variables
|
||||
local env = _ENV -- Lua 5.2
|
||||
if not env then env = getfenv () end -- Lua 5.1
|
||||
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
|
||||
|
||||
a = eml.Foo()
|
||||
assert(eml.Foo_get_count() == 1)
|
||||
b = eml.Foo()
|
||||
assert(eml.Foo_get_count() == 2)
|
||||
|
||||
-- Normal behaviour
|
||||
eml.trigger_internal_swig_exception("no problem", a)
|
||||
assert(eml.Foo_get_count() == 2)
|
||||
assert(eml.Foo_get_freearg_count() == 1)
|
||||
|
||||
-- SWIG exception triggered and handled (return new object case)
|
||||
ok,ex=pcall(eml.trigger_internal_swig_exception, "null", b)
|
||||
assert(ok==false)
|
||||
assert(eml.Foo_get_count() == 2)
|
||||
assert(eml.Foo_get_freearg_count() == 2)
|
||||
|
||||
-- SWIG exception triggered and handled (return by value case).
|
||||
ok,ex=pcall(eml.trigger_internal_swig_exception, "null")
|
||||
assert(ok==false)
|
||||
assert(eml.Foo_get_count() == 2)
|
||||
Loading…
Add table
Add a link
Reference in a new issue