diff options
author | Ian Lance Taylor <iant@golang.org> | 2015-02-04 16:08:44 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2015-02-04 16:08:44 -0800 |
commit | 2562c1eb41214a57c86edb21e00de7066e1b2781 (patch) | |
tree | 4cdeb4cac7b3d0a99b8967b671d091d5f1ce23d4 /Lib/go | |
parent | 2752d78ce6ca81fbd17bc0f51ace56327af1a054 (diff) | |
download | swig-2562c1eb41214a57c86edb21e00de7066e1b2781.tar.gz |
[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.
Diffstat (limited to 'Lib/go')
-rw-r--r-- | Lib/go/cdata.i | 37 | ||||
-rw-r--r-- | Lib/go/go.swg | 46 | ||||
-rw-r--r-- | Lib/go/goruntime.swg | 75 |
3 files changed, 142 insertions, 16 deletions
diff --git a/Lib/go/cdata.i b/Lib/go/cdata.i index 9e6dc2161..cd7b253b9 100644 --- a/Lib/go/cdata.i +++ b/Lib/go/cdata.i @@ -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 + } + } %} /* ----------------------------------------------------------------------------- diff --git a/Lib/go/go.swg b/Lib/go/go.swg index e0ad5d147..2342be046 100644 --- a/Lib/go/go.swg +++ b/Lib/go/go.swg @@ -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. */ diff --git a/Lib/go/goruntime.swg b/Lib/go/goruntime.swg index ef64186b7..19ccf5ae9 100644 --- a/Lib/go/goruntime.swg +++ b/Lib/go/goruntime.swg @@ -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); +} +%} |