[Go] Remove all calls to _swig_goallocate in the Go runtime, except

for the one from _swig_makegostring.  _swig_goallocate can not work
with the future Go 1.5 release.  When using Go 1.5 attempts to call
_swig_goallocate will fail at link time.
This commit is contained in:
Ian Lance Taylor 2015-02-04 16:08:44 -08:00
commit 2562c1eb41
4 changed files with 146 additions and 17 deletions

View file

@ -8,16 +8,41 @@
typedef struct SWIGCDATA {
char *data;
intgo len;
intgo cap;
} SWIGCDATA;
%}
%typemap(gotype) SWIGCDATA %{ []byte %}
%typemap(gotype) SWIGCDATA "[]byte"
%typemap(imtype) SWIGCDATA "uint64"
%typemap(out) SWIGCDATA %{
$result.data = (char*)_swig_goallocate($1.len);
memcpy($result.data, $1.data, $1.len);
$result.len = (intgo)$1.len;
$result.cap = $result.len;
struct swigcdata { intgo size; void* data; } *swig_out;
swig_out = (struct swigcdata*)malloc(sizeof(*swig_out));
if (swig_out) {
swig_out->size = $1.len;
swig_out->data = malloc(swig_out->size);
if (swig_out->data) {
memcpy(swig_out->data, $1.data, swig_out->size);
}
}
$result = (unsigned long long)swig_out;
%}
%typemap(goout) SWIGCDATA %{
{
type swigcdata struct { size int; data uintptr }
p := (*swigcdata)(unsafe.Pointer(uintptr($1)))
if p == nil || p.data == 0 {
$result = nil
} else {
b := make([]byte, p.size)
a := (*[0x7fffffff]byte)(unsafe.Pointer(p.data))[:p.size]
copy(b, a)
Swig_free(p.data)
Swig_free(uintptr(unsafe.Pointer(p)))
$result = b
}
}
%}
/* -----------------------------------------------------------------------------

View file

@ -141,7 +141,7 @@
double
%{ $result = ($1_ltype)$input; %}
%typemap(directorout) const bool &,
%typemap(directorout,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) const bool &,
const char &,
const signed char &,
const unsigned char &,
@ -156,8 +156,8 @@
const float &,
const double &
%{
$result = ($1_ltype)_swig_goallocate(sizeof($*1_ltype));
*$result = *($1_ltype)&$input;
$result = new $*1_ltype($input);
swig_acquire_pointer(&swig_mem, $result);
%}
/* The size_t type. */
@ -185,10 +185,10 @@
%typemap(directorout) size_t
%{ $result = ($1_ltype)$input; %}
%typemap(directorout) const size_t &
%typemap(directorout,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) const size_t &
%{
$result = ($1_ltype)_swig_goallocate(sizeof($*1_ltype));
*$result = *($1_ltype)$input;
$result = new $*1_ltype($input);
swig_acquire_pointer(&swig_mem, $result);
%}
/* Member pointers. */
@ -201,8 +201,34 @@
%typemap(out) SWIGTYPE (CLASS::*)
%{
$result = _swig_goallocate(sizeof($1_ltype));
*($&1_ltype)$result = $1;
struct swig_out_type { intgo size; void* val; } *swig_out;
swig_out = (struct swig_out_type*)malloc(sizeof(*swig_out));
if (swig_out) {
swig_out->size = sizeof($1_ltype);
swig_out->val = malloc(swig_out->size);
if (swig_out->val) {
*($&1_ltype)(swig_out->val) = $1;
}
}
$result = swig_out;
%}
%typemap(goout) SWIGTYPE (CLASS::*)
%{
{
type swig_out_type struct { size int; val uintptr }
p := (*swig_out_type)(unsafe.Pointer($1))
if p == nil || p.val == 0 {
$result = nil
} else {
m := make([]byte, p.size)
a := (*[1024]byte)(unsafe.Pointer(p.val))[:p.size]
copy(m, a)
Swig_free(p.val)
Swig_free(uintptr(unsafe.Pointer(p)))
$result = &m[0]
}
}
%}
%typemap(directorin) SWIGTYPE (CLASS::*)
@ -210,8 +236,8 @@
%typemap(directorout) SWIGTYPE (CLASS::*)
%{
$result = _swig_goallocate(sizeof($1_ltype));
*($&1_ltype)$result = $input;
$result = new $1_ltype($input);
swig_acquire_pointer(&swig_mem, $result);
%}
/* Pointers. */

View file

@ -4,6 +4,12 @@
* Go runtime code for the various generated files.
* ------------------------------------------------------------ */
%inline %{
static void Swig_free(void* p) {
free(p);
}
%}
%insert(runtime) %{
#include <stddef.h>
#include <stdio.h>
@ -242,3 +248,72 @@ var Swig_escape_val interface{}
type _swig_fnptr *byte
type _swig_memberptr *byte
%}
/* Handle memory management for directors. */
%insert(director) %{
#include <map>
namespace {
struct GCItem {
virtual ~GCItem() {}
};
struct GCItem_var {
GCItem_var(GCItem *item = 0) : _item(item) {
}
GCItem_var& operator=(GCItem *item) {
GCItem *tmp = _item;
_item = item;
delete tmp;
return *this;
}
~GCItem_var() {
delete _item;
}
GCItem* operator->() {
return _item;
}
private:
GCItem *_item;
};
template <typename Type>
struct GCItem_T : GCItem {
GCItem_T(Type *ptr) : _ptr(ptr) {
}
virtual ~GCItem_T() {
delete _ptr;
}
private:
Type *_ptr;
};
}
class Swig_memory {
public:
template <typename Type>
void swig_acquire_pointer(Type* vptr) {
if (vptr) {
swig_owner[vptr] = new GCItem_T<Type>(vptr);
}
}
private:
typedef std::map<void *, GCItem_var> swig_ownership_map;
swig_ownership_map swig_owner;
};
template <typename Type>
static void swig_acquire_pointer(Swig_memory** pmem, Type* ptr) {
if (!pmem) {
*pmem = new Swig_memory;
}
(*pmem)->swig_acquire_pointer(ptr);
}
%}

View file

@ -534,6 +534,7 @@ private:
Printf(f_c_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module);
Printf(f_c_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module);
Printf(f_c_directors_h, "class Swig_memory;\n\n");
Printf(f_c_directors, "\n// C++ director class methods.\n");
String *filename = Swig_file_filename(c_filename_h);
@ -3076,7 +3077,7 @@ private:
p = nextParm(p);
}
Printv(f_c_directors, "),\n", NULL);
Printv(f_c_directors, " go_val(swig_p)\n", NULL);
Printv(f_c_directors, " go_val(swig_p), swig_mem(0)\n", NULL);
Printv(f_c_directors, "{ }\n\n", NULL);
if (Getattr(n, "sym:overloaded") && !Getattr(n, "sym:nextSibling")) {
@ -3201,6 +3202,7 @@ private:
} else {
Printv(f_c_directors, " ", wname, "(go_val);\n", NULL);
}
Printv(f_c_directors, " delete swig_mem;\n", NULL);
}
Printv(f_c_directors, "}\n\n", NULL);
@ -4266,6 +4268,7 @@ private:
Printv(f_c_directors_h, " private:\n", NULL);
Printv(f_c_directors_h, " void *go_val;\n", NULL);
Printv(f_c_directors_h, " Swig_memory *swig_mem;\n", NULL);
Printv(f_c_directors_h, "};\n\n", NULL);
class_name = NULL;