summaryrefslogtreecommitdiff
path: root/Lib/go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2015-02-04 16:08:44 -0800
committerIan Lance Taylor <iant@golang.org>2015-02-04 16:08:44 -0800
commit2562c1eb41214a57c86edb21e00de7066e1b2781 (patch)
tree4cdeb4cac7b3d0a99b8967b671d091d5f1ce23d4 /Lib/go
parent2752d78ce6ca81fbd17bc0f51ace56327af1a054 (diff)
downloadswig-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.i37
-rw-r--r--Lib/go/go.swg46
-rw-r--r--Lib/go/goruntime.swg75
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);
+}
+%}