[Go] Add goargout typemap.
This commit is contained in:
parent
0dd7b61c57
commit
acaaa0f31f
6 changed files with 286 additions and 44 deletions
|
|
@ -5,6 +5,9 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
Version 3.0.3 (in progress)
|
Version 3.0.3 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2014-09-09: ianlancetaylor
|
||||||
|
[Go] Add goargout typemap.
|
||||||
|
|
||||||
2014-09-09: olly
|
2014-09-09: olly
|
||||||
[PHP] Fix segmentation faults with directors in PHP >= 5.4, and
|
[PHP] Fix segmentation faults with directors in PHP >= 5.4, and
|
||||||
reenable runme tests for director_basic testcase. Fix from
|
reenable runme tests for director_basic testcase. Fix from
|
||||||
|
|
|
||||||
|
|
@ -773,6 +773,27 @@ to gotype. If this is not defined no conversion is done.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>argout</td>
|
||||||
|
<td>
|
||||||
|
C/C++ code to adjust an argument value when returning from a function.
|
||||||
|
This is called after the real C/C++ function has run. This uses the
|
||||||
|
internally generated C/C++ type, based on imtype. This is only useful
|
||||||
|
for a pointer type of some sort. If this is not defined nothing will
|
||||||
|
be done.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>goargout</td>
|
||||||
|
<td>
|
||||||
|
Go code to adjust an argument value when returning from a function.
|
||||||
|
This is called after the real C/C++ function has run. The value will
|
||||||
|
be in imtype. This is only useful for a pointer type of some sort.
|
||||||
|
If this is not defined nothing will be done.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>directorin</td>
|
<td>directorin</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
||||||
|
|
@ -32,4 +32,12 @@ func main() {
|
||||||
fmt.Println("got", m, "want", want)
|
fmt.Println("got", m, "want", want)
|
||||||
panic(m)
|
panic(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a := []string{"a", "bc", "def"}
|
||||||
|
go_inout.DoubleArray(&a)
|
||||||
|
dwant := []string{"a", "bc", "def", "aa", "bcbc", "defdef"}
|
||||||
|
if !reflect.DeepEqual(a, dwant) {
|
||||||
|
fmt.Println("got", a, "want", dwant)
|
||||||
|
panic(a)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
// Test the goin and goout typemaps.
|
// Test the goin, goout, and goargout typemaps.
|
||||||
|
|
||||||
%module go_inout
|
%module go_inout
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%inline
|
%inline
|
||||||
|
|
@ -21,7 +23,7 @@ struct RetStruct {
|
||||||
|
|
||||||
// Write a typemap that calls C++ by converting in and out of JSON.
|
// Write a typemap that calls C++ by converting in and out of JSON.
|
||||||
|
|
||||||
%go_import("encoding/json")
|
%go_import("encoding/json", "bytes", "encoding/binary")
|
||||||
|
|
||||||
%insert(go_header)
|
%insert(go_header)
|
||||||
%{
|
%{
|
||||||
|
|
@ -77,3 +79,121 @@ RetStruct Same(MyStruct s)
|
||||||
}
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%inline
|
||||||
|
%{
|
||||||
|
|
||||||
|
struct MyArray {
|
||||||
|
std::vector<std::string> strings;
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint64_t getuint64(const char* s) {
|
||||||
|
uint64_t ret = 0;
|
||||||
|
for (int i = 0; i < 8; i++, s++) {
|
||||||
|
ret |= static_cast<uint64_t>(*s) << i * 8;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void putuint64(std::string *s, size_t off, uint64_t v) {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
(*s)[off + i] = (v >> (i * 8)) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%typemap(gotype) MyArray* "*[]string"
|
||||||
|
|
||||||
|
%typemap(imtype) MyArray* "*string"
|
||||||
|
|
||||||
|
// Encode the slice as a single string, with length prefixes.
|
||||||
|
%typemap(goin) MyArray*
|
||||||
|
%{
|
||||||
|
{
|
||||||
|
var buf bytes.Buffer
|
||||||
|
bin := binary.LittleEndian
|
||||||
|
var b [8]byte
|
||||||
|
bin.PutUint64(b[:], uint64(len(*$input)))
|
||||||
|
buf.Write(b[:])
|
||||||
|
for _, s := range *$input {
|
||||||
|
bin.PutUint64(b[:], uint64(len(s)))
|
||||||
|
buf.Write(b[:])
|
||||||
|
buf.WriteString(s)
|
||||||
|
}
|
||||||
|
str := buf.String()
|
||||||
|
$result = &str
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Unpack the string holding the packed slice.
|
||||||
|
%typemap(in) MyArray* (MyArray t)
|
||||||
|
%{
|
||||||
|
{
|
||||||
|
_gostring_ *s = $input;
|
||||||
|
const char *p = static_cast<const char *>(s->p);
|
||||||
|
uint64_t len = getuint64(p);
|
||||||
|
p += 8;
|
||||||
|
t.strings.resize(len);
|
||||||
|
for (uint64_t i = 0; i < len; i++) {
|
||||||
|
uint64_t slen = getuint64(p);
|
||||||
|
p += 8;
|
||||||
|
t.strings[i].assign(p, slen);
|
||||||
|
p += slen;
|
||||||
|
}
|
||||||
|
$1 = &t;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Pack the vector into a string.
|
||||||
|
%typemap(argout) MyArray*
|
||||||
|
%{
|
||||||
|
{
|
||||||
|
size_t tot = 8;
|
||||||
|
std::vector<std::string>::const_iterator p;
|
||||||
|
for (p = $1->strings.begin(); p != $1->strings.end(); ++p) {
|
||||||
|
tot += 8 + p->size();
|
||||||
|
}
|
||||||
|
std::string str;
|
||||||
|
str.resize(tot);
|
||||||
|
putuint64(&str, 0, $1->strings.size());
|
||||||
|
size_t off = 8;
|
||||||
|
for (p = $1->strings.begin(); p != $1->strings.end(); ++p) {
|
||||||
|
putuint64(&str, off, p->size());
|
||||||
|
off += 8;
|
||||||
|
str.replace(off, p->size(), *p);
|
||||||
|
off += p->size();
|
||||||
|
}
|
||||||
|
*$input = _swig_makegostring(str.data(), str.size());
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Unpack the string into a []string.
|
||||||
|
%typemap(goargout) MyArray*
|
||||||
|
%{
|
||||||
|
{
|
||||||
|
str := *$input
|
||||||
|
bin := binary.LittleEndian
|
||||||
|
size := bin.Uint64([]byte(str[:8]))
|
||||||
|
str = str[8:]
|
||||||
|
r := make([]string, size)
|
||||||
|
for i := range r {
|
||||||
|
len := bin.Uint64([]byte(str[:8]))
|
||||||
|
str = str[8:]
|
||||||
|
r[i] = str[:len]
|
||||||
|
str = str[len:]
|
||||||
|
}
|
||||||
|
*$1 = r
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%inline
|
||||||
|
%{
|
||||||
|
void DoubleArray(MyArray* v) {
|
||||||
|
size_t size = v->strings.size();
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
v->strings.push_back(v->strings[i] + v->strings[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
|
||||||
|
|
@ -225,13 +225,13 @@
|
||||||
%{ $1 = *($&1_ltype)&$input; %}
|
%{ $1 = *($&1_ltype)&$input; %}
|
||||||
|
|
||||||
%typemap(out) SWIGTYPE *
|
%typemap(out) SWIGTYPE *
|
||||||
%{ *($&1_ltype)&$result = $1; %}
|
%{ *($&1_ltype)&$result = ($1_ltype)$1; %}
|
||||||
|
|
||||||
%typemap(directorin) SWIGTYPE *
|
%typemap(directorin) SWIGTYPE *
|
||||||
%{ $input = ($1_ltype)$1; %}
|
%{ *($&1_ltype)&$input = ($1_ltype)$1; %}
|
||||||
|
|
||||||
%typemap(directorout) SWIGTYPE *
|
%typemap(directorout) SWIGTYPE *
|
||||||
%{ $result = ($1_ltype)$input; %}
|
%{ $result = *($&1_ltype)&$input; %}
|
||||||
|
|
||||||
%apply SWIGTYPE * { SWIGTYPE *const }
|
%apply SWIGTYPE * { SWIGTYPE *const }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -868,6 +868,7 @@ private:
|
||||||
Swig_typemap_attach_parms("default", parms, dummy);
|
Swig_typemap_attach_parms("default", parms, dummy);
|
||||||
Swig_typemap_attach_parms("gotype", parms, dummy);
|
Swig_typemap_attach_parms("gotype", parms, dummy);
|
||||||
Swig_typemap_attach_parms("goin", parms, dummy);
|
Swig_typemap_attach_parms("goin", parms, dummy);
|
||||||
|
Swig_typemap_attach_parms("goargout", parms, dummy);
|
||||||
Swig_typemap_attach_parms("imtype", parms, dummy);
|
Swig_typemap_attach_parms("imtype", parms, dummy);
|
||||||
int parm_count = emit_num_arguments(parms);
|
int parm_count = emit_num_arguments(parms);
|
||||||
int required_count = emit_num_required(parms);
|
int required_count = emit_num_required(parms);
|
||||||
|
|
@ -892,20 +893,25 @@ private:
|
||||||
|
|
||||||
bool needs_wrapper = (gccgo_flag || receiver || is_constructor || is_destructor || parm_count > required_count);
|
bool needs_wrapper = (gccgo_flag || receiver || is_constructor || is_destructor || parm_count > required_count);
|
||||||
|
|
||||||
|
bool has_goout = false;
|
||||||
|
if (goout) {
|
||||||
|
has_goout = true;
|
||||||
|
}
|
||||||
|
|
||||||
// See whether any of the function parameters are represented by
|
// See whether any of the function parameters are represented by
|
||||||
// interface values. When calling the C++ code, we need to convert
|
// interface values. When calling the C++ code, we need to convert
|
||||||
// back to a uintptr.
|
// back to a uintptr.
|
||||||
if (!needs_wrapper) {
|
Parm *p = parms;
|
||||||
Parm *p = parms;
|
for (int i = 0; i < parm_count; ++i) {
|
||||||
for (int i = 0; i < parm_count; ++i) {
|
p = getParm(p);
|
||||||
p = getParm(p);
|
String *ty = Getattr(p, "type");
|
||||||
String *ty = Getattr(p, "type");
|
if (Getattr(p, "tmap:goargout")) {
|
||||||
if (goTypeIsInterface(p, ty) || Getattr(p, "tmap:goin") != NULL) {
|
has_goout = true;
|
||||||
needs_wrapper = true;
|
needs_wrapper = true;
|
||||||
break;
|
} else if (goTypeIsInterface(p, ty) || Getattr(p, "tmap:goin")) {
|
||||||
}
|
needs_wrapper = true;
|
||||||
p = nextParm(p);
|
|
||||||
}
|
}
|
||||||
|
p = nextParm(p);
|
||||||
}
|
}
|
||||||
if (goTypeIsInterface(n, result) || goout != NULL) {
|
if (goTypeIsInterface(n, result) || goout != NULL) {
|
||||||
needs_wrapper = true;
|
needs_wrapper = true;
|
||||||
|
|
@ -982,7 +988,7 @@ private:
|
||||||
|
|
||||||
Printv(f_go_wrappers, "func ", NULL);
|
Printv(f_go_wrappers, "func ", NULL);
|
||||||
|
|
||||||
Parm *p = parms;
|
p = parms;
|
||||||
int pi = 0;
|
int pi = 0;
|
||||||
|
|
||||||
// Add the receiver if this is a method.
|
// Add the receiver if this is a method.
|
||||||
|
|
@ -1097,7 +1103,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gccgo_flag) {
|
if (gccgo_flag) {
|
||||||
if (goout != NULL || is_constructor) {
|
if (has_goout || is_constructor) {
|
||||||
Printv(call, "\tfunc() {\n", NULL);
|
Printv(call, "\tfunc() {\n", NULL);
|
||||||
}
|
}
|
||||||
Printv(call, "\tdefer SwigCgocallDone()\n", NULL);
|
Printv(call, "\tdefer SwigCgocallDone()\n", NULL);
|
||||||
|
|
@ -1143,6 +1149,7 @@ private:
|
||||||
if ((i == 0 && is_destructor) || ((i > 0 || !receiver || base || is_constructor) && goTypeIsInterface(p, pt))) {
|
if ((i == 0 && is_destructor) || ((i > 0 || !receiver || base || is_constructor) && goTypeIsInterface(p, pt))) {
|
||||||
Printv(call, ".Swigcptr()", NULL);
|
Printv(call, ".Swigcptr()", NULL);
|
||||||
}
|
}
|
||||||
|
Setattr(p, "emit:goinput", ln);
|
||||||
} else {
|
} else {
|
||||||
String *ivar = NewString("");
|
String *ivar = NewString("");
|
||||||
Printf(ivar, "_swig_i_%d", i);
|
Printf(ivar, "_swig_i_%d", i);
|
||||||
|
|
@ -1154,19 +1161,22 @@ private:
|
||||||
Printv(f_go_wrappers, goin, NULL);
|
Printv(f_go_wrappers, goin, NULL);
|
||||||
Delete(goin);
|
Delete(goin);
|
||||||
Printv(call, ivar, NULL);
|
Printv(call, ivar, NULL);
|
||||||
|
Setattr(p, "emit:goinput", ivar);
|
||||||
}
|
}
|
||||||
|
|
||||||
p = nextParm(p);
|
p = nextParm(p);
|
||||||
}
|
}
|
||||||
Printv(call, ")\n", NULL);
|
Printv(call, ")\n", NULL);
|
||||||
|
|
||||||
if (gccgo_flag && (goout != NULL || is_constructor)) {
|
if (gccgo_flag && (has_goout || is_constructor)) {
|
||||||
Printv(call, "\t}()\n", NULL);
|
Printv(call, "\t}()\n", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Printv(f_go_wrappers, call, NULL);
|
Printv(f_go_wrappers, call, NULL);
|
||||||
Delete(call);
|
Delete(call);
|
||||||
|
|
||||||
|
goargout(parms, parm_count);
|
||||||
|
|
||||||
if (need_return_var) {
|
if (need_return_var) {
|
||||||
if (goout == NULL) {
|
if (goout == NULL) {
|
||||||
Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
|
Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
|
||||||
|
|
@ -1676,6 +1686,32 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
* goargout()
|
||||||
|
*
|
||||||
|
* Handle Go argument output code if any. This is used for the Go
|
||||||
|
* function. This assumes that each parameter has an "emit:goinput"
|
||||||
|
* property with the name to use to refer to that parameter.
|
||||||
|
* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void goargout(ParmList *parms, int parm_count) {
|
||||||
|
Parm *p = parms;
|
||||||
|
for (int i = 0; i < parm_count; ++i) {
|
||||||
|
p = getParm(p);
|
||||||
|
String *tm = Getattr(p, "tmap:goargout");
|
||||||
|
if (!tm) {
|
||||||
|
p = nextSibling(p);
|
||||||
|
} else {
|
||||||
|
tm = Copy(tm);
|
||||||
|
Replaceall(tm, "$result", "swig_r");
|
||||||
|
Replaceall(tm, "$input", Getattr(p, "emit:goinput"));
|
||||||
|
Printv(f_go_wrappers, tm, NULL);
|
||||||
|
Delete(tm);
|
||||||
|
p = Getattr(p, "tmap:goargout:next");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
* freearg()
|
* freearg()
|
||||||
*
|
*
|
||||||
|
|
@ -3170,6 +3206,7 @@ private:
|
||||||
Swig_typemap_attach_parms("directorargout", parms, w);
|
Swig_typemap_attach_parms("directorargout", parms, w);
|
||||||
Swig_typemap_attach_parms("godirectorin", parms, w);
|
Swig_typemap_attach_parms("godirectorin", parms, w);
|
||||||
Swig_typemap_attach_parms("goin", parms, dummy);
|
Swig_typemap_attach_parms("goin", parms, dummy);
|
||||||
|
Swig_typemap_attach_parms("goargout", parms, dummy);
|
||||||
|
|
||||||
if (!is_ignored) {
|
if (!is_ignored) {
|
||||||
// We use an interface to see if this method is defined in Go.
|
// We use an interface to see if this method is defined in Go.
|
||||||
|
|
@ -3282,16 +3319,29 @@ private:
|
||||||
if (GetFlag(n, "abstract")) {
|
if (GetFlag(n, "abstract")) {
|
||||||
Printv(f_go_wrappers, "\tpanic(\"call to pure virtual method\")\n", NULL);
|
Printv(f_go_wrappers, "\tpanic(\"call to pure virtual method\")\n", NULL);
|
||||||
} else {
|
} else {
|
||||||
|
bool has_goout = false;
|
||||||
String *goout = NULL;
|
String *goout = NULL;
|
||||||
if (SwigType_type(result) != T_VOID) {
|
if (SwigType_type(result) != T_VOID) {
|
||||||
Printv(f_go_wrappers, "\tvar swig_r ", goImType(n, result), "\n", NULL);
|
Printv(f_go_wrappers, "\tvar swig_r ", goImType(n, result), "\n", NULL);
|
||||||
goout = Swig_typemap_lookup("goout", n, "swig_r", NULL);
|
goout = Swig_typemap_lookup("goout", n, "swig_r", NULL);
|
||||||
|
if (goout) {
|
||||||
|
has_goout = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = parms;
|
||||||
|
for (int i = 0; i < parm_count; ++i) {
|
||||||
|
p = getParm(p);
|
||||||
|
if (Getattr(p, "tmap:goargout")) {
|
||||||
|
has_goout = true;
|
||||||
|
}
|
||||||
|
p = nextParm(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
String *call = NewString("");
|
String *call = NewString("");
|
||||||
|
|
||||||
if (gccgo_flag) {
|
if (gccgo_flag) {
|
||||||
if (goout != NULL) {
|
if (has_goout) {
|
||||||
Printv(call, "\tfunc() {\n", NULL);
|
Printv(call, "\tfunc() {\n", NULL);
|
||||||
}
|
}
|
||||||
Printv(call, "\tdefer SwigCgocallDone()\n", NULL);
|
Printv(call, "\tdefer SwigCgocallDone()\n", NULL);
|
||||||
|
|
@ -3320,6 +3370,7 @@ private:
|
||||||
if (goTypeIsInterface(p, pt)) {
|
if (goTypeIsInterface(p, pt)) {
|
||||||
Printv(call, ".Swigcptr()", NULL);
|
Printv(call, ".Swigcptr()", NULL);
|
||||||
}
|
}
|
||||||
|
Setattr(p, "emit:goinput", ln);
|
||||||
} else {
|
} else {
|
||||||
String *ivar = NewString("");
|
String *ivar = NewString("");
|
||||||
Printf(ivar, "_swig_i_%d", i);
|
Printf(ivar, "_swig_i_%d", i);
|
||||||
|
|
@ -3331,7 +3382,7 @@ private:
|
||||||
Printv(f_go_wrappers, goin, NULL);
|
Printv(f_go_wrappers, goin, NULL);
|
||||||
Delete(goin);
|
Delete(goin);
|
||||||
Printv(call, ivar, NULL);
|
Printv(call, ivar, NULL);
|
||||||
Delete(ivar);
|
Setattr(p, "emit:goinput", ivar);
|
||||||
}
|
}
|
||||||
|
|
||||||
p = nextParm(p);
|
p = nextParm(p);
|
||||||
|
|
@ -3339,13 +3390,15 @@ private:
|
||||||
|
|
||||||
Printv(call, ")\n", NULL);
|
Printv(call, ")\n", NULL);
|
||||||
|
|
||||||
if (gccgo_flag && goout != NULL) {
|
if (gccgo_flag && has_goout) {
|
||||||
Printv(call, "\t}()\n", NULL);
|
Printv(call, "\t}()\n", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Printv(f_go_wrappers, call, NULL);
|
Printv(f_go_wrappers, call, NULL);
|
||||||
Delete(call);
|
Delete(call);
|
||||||
|
|
||||||
|
goargout(parms, parm_count);
|
||||||
|
|
||||||
if (SwigType_type(result) != T_VOID) {
|
if (SwigType_type(result) != T_VOID) {
|
||||||
if (goout == NULL) {
|
if (goout == NULL) {
|
||||||
Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
|
Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
|
||||||
|
|
@ -3526,6 +3579,7 @@ private:
|
||||||
String *goin = Getattr(p, "tmap:goin");
|
String *goin = Getattr(p, "tmap:goin");
|
||||||
if (goin == NULL) {
|
if (goin == NULL) {
|
||||||
Printv(call, ln, NULL);
|
Printv(call, ln, NULL);
|
||||||
|
Setattr(p, "emit:goinput", ln);
|
||||||
} else {
|
} else {
|
||||||
String *ivar = NewString("");
|
String *ivar = NewString("");
|
||||||
Printf(ivar, "_swig_i_%d", i);
|
Printf(ivar, "_swig_i_%d", i);
|
||||||
|
|
@ -3537,7 +3591,7 @@ private:
|
||||||
Printv(f_go_wrappers, goin, NULL);
|
Printv(f_go_wrappers, goin, NULL);
|
||||||
Delete(goin);
|
Delete(goin);
|
||||||
Printv(call, ivar, NULL);
|
Printv(call, ivar, NULL);
|
||||||
Delete(ivar);
|
Setattr(p, "emit:goinput", ivar);
|
||||||
}
|
}
|
||||||
|
|
||||||
Delete(ln);
|
Delete(ln);
|
||||||
|
|
@ -3554,6 +3608,8 @@ private:
|
||||||
Printv(f_go_wrappers, call, NULL);
|
Printv(f_go_wrappers, call, NULL);
|
||||||
Delete(call);
|
Delete(call);
|
||||||
|
|
||||||
|
goargout(parms, parm_count);
|
||||||
|
|
||||||
if (SwigType_type(result) != T_VOID) {
|
if (SwigType_type(result) != T_VOID) {
|
||||||
if (goout == NULL) {
|
if (goout == NULL) {
|
||||||
Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
|
Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
|
||||||
|
|
@ -3838,6 +3894,21 @@ private:
|
||||||
|
|
||||||
Printv(w->code, " crosscall2(", callback_wname, ", &swig_a, (int) sizeof swig_a);\n", NULL);
|
Printv(w->code, " crosscall2(", callback_wname, ", &swig_a, (int) sizeof swig_a);\n", NULL);
|
||||||
|
|
||||||
|
/* Marshal outputs */
|
||||||
|
for (p = parms; p;) {
|
||||||
|
String *tm;
|
||||||
|
if ((tm = Getattr(p, "tmap:directorargout"))) {
|
||||||
|
tm = Copy(tm);
|
||||||
|
Replaceall(tm, "$result", "jresult");
|
||||||
|
Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
|
||||||
|
Printv(w->code, tm, "\n", NIL);
|
||||||
|
Delete(tm);
|
||||||
|
p = Getattr(p, "tmap:directorargout:next");
|
||||||
|
} else {
|
||||||
|
p = nextSibling(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (SwigType_type(result) != T_VOID) {
|
if (SwigType_type(result) != T_VOID) {
|
||||||
String *result_str = NewString("c_result");
|
String *result_str = NewString("c_result");
|
||||||
String *tm = Swig_typemap_lookup("directorout", n, result_str, NULL);
|
String *tm = Swig_typemap_lookup("directorout", n, result_str, NULL);
|
||||||
|
|
@ -3886,7 +3957,7 @@ private:
|
||||||
|
|
||||||
String *pn = NewString("g");
|
String *pn = NewString("g");
|
||||||
Append(pn, Getattr(p, "lname"));
|
Append(pn, Getattr(p, "lname"));
|
||||||
Setattr(p, "emit:input", pn);
|
Setattr(p, "emit:directorinput", pn);
|
||||||
|
|
||||||
String *tm = gccgoCTypeForGoValue(n, Getattr(p, "type"), pn);
|
String *tm = gccgoCTypeForGoValue(n, Getattr(p, "type"), pn);
|
||||||
Wrapper_add_local(w, pn, tm);
|
Wrapper_add_local(w, pn, tm);
|
||||||
|
|
@ -3915,6 +3986,21 @@ private:
|
||||||
}
|
}
|
||||||
Printv(w->code, callback_wname, "(go_val", args, ");\n", NULL);
|
Printv(w->code, callback_wname, "(go_val", args, ");\n", NULL);
|
||||||
|
|
||||||
|
/* Marshal outputs */
|
||||||
|
for (p = parms; p;) {
|
||||||
|
String *tm;
|
||||||
|
if ((tm = Getattr(p, "tmap:directorargout"))) {
|
||||||
|
tm = Copy(tm);
|
||||||
|
Replaceall(tm, "$result", "jresult");
|
||||||
|
Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
|
||||||
|
Printv(w->code, tm, "\n", NIL);
|
||||||
|
Delete(tm);
|
||||||
|
p = Getattr(p, "tmap:directorargout:next");
|
||||||
|
} else {
|
||||||
|
p = nextSibling(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (SwigType_type(result) != T_VOID) {
|
if (SwigType_type(result) != T_VOID) {
|
||||||
String *result_str = NewString("c_result");
|
String *result_str = NewString("c_result");
|
||||||
String *tm = Swig_typemap_lookup("directorout", n, result_str, NULL);
|
String *tm = Swig_typemap_lookup("directorout", n, result_str, NULL);
|
||||||
|
|
@ -3933,21 +4019,6 @@ private:
|
||||||
Delete(result_str);
|
Delete(result_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Marshal outputs */
|
|
||||||
for (p = parms; p;) {
|
|
||||||
String *tm;
|
|
||||||
if ((tm = Getattr(p, "tmap:directorargout"))) {
|
|
||||||
tm = Copy(tm);
|
|
||||||
Replaceall(tm, "$result", "jresult");
|
|
||||||
Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
|
|
||||||
Printv(w->code, tm, "\n", NIL);
|
|
||||||
Delete(tm);
|
|
||||||
p = Getattr(p, "tmap:directorargout:next");
|
|
||||||
} else {
|
|
||||||
p = nextSibling(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
assert(is_pure_virtual);
|
assert(is_pure_virtual);
|
||||||
Printv(w->code, " _swig_gopanic(\"call to pure virtual function ", Getattr(parent, "sym:name"), name, "\");\n", NULL);
|
Printv(w->code, " _swig_gopanic(\"call to pure virtual function ", Getattr(parent, "sym:name"), name, "\");\n", NULL);
|
||||||
|
|
@ -4990,6 +5061,17 @@ private:
|
||||||
String *gcCTypeForGoValue(Node *n, SwigType *type, String *name) {
|
String *gcCTypeForGoValue(Node *n, SwigType *type, String *name) {
|
||||||
bool is_interface;
|
bool is_interface;
|
||||||
String *gt = goTypeWithInfo(n, type, true, &is_interface);
|
String *gt = goTypeWithInfo(n, type, true, &is_interface);
|
||||||
|
|
||||||
|
String *tail = NewString("");
|
||||||
|
SwigType *t = SwigType_typedef_resolve_all(type);
|
||||||
|
if (!SwigType_isreference(t)) {
|
||||||
|
while (Strncmp(gt, "*", 1) == 0) {
|
||||||
|
Replace(gt, "*", "", DOH_REPLACE_FIRST);
|
||||||
|
Printv(tail, "*", NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Delete(t);
|
||||||
|
|
||||||
bool is_string = Strcmp(gt, "string") == 0;
|
bool is_string = Strcmp(gt, "string") == 0;
|
||||||
bool is_slice = Strncmp(gt, "[]", 2) == 0;
|
bool is_slice = Strncmp(gt, "[]", 2) == 0;
|
||||||
bool is_function = Strcmp(gt, "_swig_fnptr") == 0;
|
bool is_function = Strcmp(gt, "_swig_fnptr") == 0;
|
||||||
|
|
@ -5017,18 +5099,21 @@ private:
|
||||||
if (is_string) {
|
if (is_string) {
|
||||||
// Note that we don't turn a reference to a string into a
|
// Note that we don't turn a reference to a string into a
|
||||||
// pointer to a string. Strings are immutable anyhow.
|
// pointer to a string. Strings are immutable anyhow.
|
||||||
ret = NewString("_gostring_ ");
|
ret = NewString("");
|
||||||
Append(ret, name);
|
Printv(ret, "_gostring_", tail, " ", name, NULL);
|
||||||
|
Delete(tail);
|
||||||
return ret;
|
return ret;
|
||||||
} else if (is_slice) {
|
} else if (is_slice) {
|
||||||
// Slices are always passed as a _goslice_, whether or not references
|
// Slices are always passed as a _goslice_, whether or not references
|
||||||
// are involved.
|
// are involved.
|
||||||
ret = NewString("_goslice_ ");
|
ret = NewString("");
|
||||||
Append(ret, name);
|
Printv(ret, "_goslice_", tail, " ", name, NULL);
|
||||||
|
Delete(tail);
|
||||||
return ret;
|
return ret;
|
||||||
} else if (is_function || is_member) {
|
} else if (is_function || is_member) {
|
||||||
ret = NewString("void *");
|
ret = NewString("");
|
||||||
Append(ret, name);
|
Printv(ret, "void*", tail, " ", name, NULL);
|
||||||
|
Delete(tail);
|
||||||
return ret;
|
return ret;
|
||||||
} else if (is_complex64) {
|
} else if (is_complex64) {
|
||||||
ret = NewString("_Complex float ");
|
ret = NewString("_Complex float ");
|
||||||
|
|
@ -5045,6 +5130,7 @@ private:
|
||||||
SwigType_add_pointer(t);
|
SwigType_add_pointer(t);
|
||||||
ret = SwigType_lstr(t, name);
|
ret = SwigType_lstr(t, name);
|
||||||
Delete(t);
|
Delete(t);
|
||||||
|
Delete(tail);
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
SwigType *t = SwigType_typedef_resolve_all(type);
|
SwigType *t = SwigType_typedef_resolve_all(type);
|
||||||
|
|
@ -5068,6 +5154,7 @@ private:
|
||||||
}
|
}
|
||||||
Delete(q);
|
Delete(q);
|
||||||
Delete(t);
|
Delete(t);
|
||||||
|
Delete(tail);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5100,14 +5187,17 @@ private:
|
||||||
} else if (is_float64) {
|
} else if (is_float64) {
|
||||||
ret = NewString("double ");
|
ret = NewString("double ");
|
||||||
} else {
|
} else {
|
||||||
|
Delete(tail);
|
||||||
return SwigType_lstr(type, name);
|
return SwigType_lstr(type, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Append(ret, tail);
|
||||||
if (SwigType_isreference(type)) {
|
if (SwigType_isreference(type)) {
|
||||||
Append(ret, "* ");
|
Append(ret, "* ");
|
||||||
}
|
}
|
||||||
Append(ret, name);
|
Append(ret, name);
|
||||||
|
Delete(tail);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue