[PHP] Fix cleanup code handling issues
Fix to call cleanup code in exception situations and not to invoke the freearg typemap twice in certain situations. Fixes https://sourceforge.net/p/swig/bugs/1211/
This commit is contained in:
parent
dffa74bbe5
commit
1707d6b89b
9 changed files with 54 additions and 16 deletions
|
|
@ -234,6 +234,7 @@ CPP_TEST_CASES += \
|
|||
evil_diamond_ns \
|
||||
evil_diamond_prop \
|
||||
exception_classname \
|
||||
exception_memory_leak \
|
||||
exception_order \
|
||||
extend \
|
||||
extend_constructor_destructor \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%module r_memory_leak
|
||||
%module exception_memory_leak
|
||||
|
||||
%include <std_string.i>
|
||||
|
||||
|
|
@ -8,33 +8,38 @@
|
|||
}
|
||||
%typemap(freearg) Foo* foo
|
||||
{
|
||||
printf(" \" Object deleted\"\n");
|
||||
Foo::inc_freearg_count();
|
||||
delete $1;
|
||||
}
|
||||
%typemap(out) Foo* verify_no_memory_leak
|
||||
{
|
||||
if ($1 == NULL)
|
||||
SWIG_exception_fail(SWIG_RuntimeError, "Let's see how the bindings manage this exception!");
|
||||
$1 = NULL;
|
||||
}
|
||||
%typemap(scoerceout) Foo*
|
||||
%{ if (!is.null($result) && !is.logical($result)) {$result <- new("$R_class", ref=$result) ;}; %}
|
||||
|
||||
%inline %{
|
||||
#include <string>
|
||||
|
||||
class Foo {
|
||||
static unsigned count;
|
||||
static unsigned freearg_count;
|
||||
public:
|
||||
Foo() { ++count; }
|
||||
~Foo() { --count; }
|
||||
static unsigned get_count() { return count; }
|
||||
static unsigned get_freearg_count() { return freearg_count; }
|
||||
#ifndef SWIG
|
||||
static void inc_freearg_count() { ++freearg_count; }
|
||||
#endif
|
||||
};
|
||||
|
||||
unsigned Foo::count = 0;
|
||||
unsigned Foo::freearg_count = 0;
|
||||
|
||||
static Foo* trigger_internal_swig_exception(const std::string& message, Foo* foo)
|
||||
{
|
||||
return (message == "null") ? NULL : foo;
|
||||
};
|
||||
}
|
||||
|
||||
%}
|
||||
23
Examples/test-suite/php/exception_memory_leak_runme.php
Normal file
23
Examples/test-suite/php/exception_memory_leak_runme.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
require "tests.php";
|
||||
|
||||
check::functions(array('trigger_internal_swig_exception'));
|
||||
check::classes(array('Foo', 'exception_memory_leak'));
|
||||
// No new vars
|
||||
check::globals(array());
|
||||
|
||||
$a = new Foo();
|
||||
check::equal(Foo::get_count(), 1, "Should have 1 Foo objects");
|
||||
$b = new Foo();
|
||||
check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
|
||||
|
||||
// Normal behaviour
|
||||
trigger_internal_swig_exception("no problem", $a);
|
||||
check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
|
||||
check::equal(Foo::get_freearg_count(), 1, "freearg should have been used once");
|
||||
|
||||
// SWIG exception triggered and handled.
|
||||
trigger_internal_swig_exception("null", $b);
|
||||
check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
|
||||
check::equal(Foo::get_freearg_count(), 2, "freearg should have been used twice");
|
||||
|
|
@ -18,7 +18,6 @@ C_TEST_CASES += \
|
|||
|
||||
CPP_TEST_CASES += \
|
||||
r_double_delete \
|
||||
r_memory_leak \
|
||||
r_overload_array \
|
||||
r_sexp \
|
||||
r_overload_comma \
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
clargs <- commandArgs(trailing=TRUE)
|
||||
source(file.path(clargs[1], "unittest.R"))
|
||||
|
||||
dyn.load(paste("r_memory_leak", .Platform$dynlib.ext, sep=""))
|
||||
source("r_memory_leak.R")
|
||||
dyn.load(paste("exception_memory_leak", .Platform$dynlib.ext, sep=""))
|
||||
source("exception_memory_leak.R")
|
||||
cacheMetaData(1)
|
||||
|
||||
a <- Foo();
|
||||
|
|
@ -13,6 +13,7 @@ unittest(Foo_get_count(), 2);
|
|||
# Normal behaviour
|
||||
invisible(trigger_internal_swig_exception("no problem", a));
|
||||
unittest(Foo_get_count(), 2);
|
||||
unittest(Foo_get_freearg_count(), 1);
|
||||
# SWIG exception introduced
|
||||
result <- tryCatch({
|
||||
trigger_internal_swig_exception("null", b);
|
||||
|
|
@ -24,3 +25,4 @@ result <- tryCatch({
|
|||
unittest(1,1);
|
||||
})
|
||||
unittest(Foo_get_count(), 2);
|
||||
unittest(Foo_get_freearg_count(), 2);
|
||||
Loading…
Add table
Add a link
Reference in a new issue