[Go] More fixes for Go 1.4. Ensure that values with argout or freearg

typemapes escape, and refer to them using local variables loaded at
the start of the function, in case the argout or freearg template
causes a stack copy.
This commit is contained in:
Ian Lance Taylor 2014-10-11 19:07:14 -07:00
commit 1226970b9f

View file

@ -919,6 +919,18 @@ private:
} else if (goTypeIsInterface(p, ty) || Getattr(p, "tmap:goin")) { } else if (goTypeIsInterface(p, ty) || Getattr(p, "tmap:goin")) {
needs_wrapper = true; needs_wrapper = true;
} }
// If the parameter has an argout or freearg typemap, we need to
// make sure that it escapes, in case it contains any pointers.
if (Getattr(p, "tmap:argout") || Getattr(p, "tmap:freearg")) {
if (!goTypeIsInterface(p, Getattr(p, "type"))) {
String *tm = goWrapperType(p, Getattr(p, "type"), false);
Printf(f_go_wrappers, "var %s_escape_%d %s\n", wname, i, tm);
Delete(tm);
needs_wrapper = true;
}
}
p = nextParm(p); p = nextParm(p);
} }
if (goTypeIsInterface(n, result) || goout != NULL) { if (goTypeIsInterface(n, result) || goout != NULL) {
@ -1204,6 +1216,15 @@ private:
Setattr(p, "emit:goinput", ivar); Setattr(p, "emit:goinput", ivar);
} }
// If the parameter has an argout or freearg typemap, make
// sure that it escapes.
if (Getattr(p, "tmap:argout") || Getattr(p, "tmap:freearg")) {
// No need to do anything for C++ class type.
if (!goTypeIsInterface(p, pt)) {
Printf(f_go_wrappers, "\t%s_escape_%d = %s\n", wname, i, Getattr(p, "emit:goinput"));
}
}
p = nextParm(p); p = nextParm(p);
} }
Printv(call, ")\n", NULL); Printv(call, ")\n", NULL);
@ -1342,11 +1363,19 @@ private:
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 *ln = Getattr(p, "lname"); String *ln = Getattr(p, "lname");
SwigType *pt = Getattr(p, "type"); SwigType *pt = Getattr(p, "type");
String *ct = gcCTypeForGoValue(p, pt, ln); String *ct = gcCTypeForGoValue(p, pt, ln);
Printv(f->code, "\t\t\t", ct, ";\n", NULL); Printv(f->code, "\t\t\t", ct, ";\n", NULL);
Delete(ct); Delete(ct);
String *gn = NewStringf("_swig_go_%d", i);
ct = gcCTypeForGoValue(p, pt, gn);
Setattr(p, "emit:input", gn);
Wrapper_add_local(f, gn, ct);
Delete(ct);
p = nextParm(p); p = nextParm(p);
} }
if (SwigType_type(result) != T_VOID) { if (SwigType_type(result) != T_VOID) {
@ -1367,23 +1396,28 @@ private:
Printv(f->code, "\n", NULL); Printv(f->code, "\n", NULL);
// Copy the input arguments out of the structure into the // Copy the input arguments out of the structure into the Go local
// parameter variables. // variables.
p = parms; 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 *ln = Getattr(p, "lname");
String *gn = Getattr(p, "emit:input");
Printv(f->code, "\t", gn, " = swig_a->", ln, ";\n", NULL);
p = nextParm(p);
}
// Apply the in typemaps.
p = parms;
for (int i = 0; i < parm_count; ++i) {
p = getParm(p);
String *tm = Getattr(p, "tmap:in"); String *tm = Getattr(p, "tmap:in");
if (!tm) { if (!tm) {
Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument\n", SwigType_str(Getattr(p, "type"), 0)); Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument\n", SwigType_str(Getattr(p, "type"), 0));
} else { } else {
String *ln = Getattr(p, "lname");
String *input = NewString("");
Printv(input, "swig_a->", ln, NULL);
tm = Copy(tm); tm = Copy(tm);
Replaceall(tm, "$input", input); String *gn = Getattr(p, "emit:input");
Setattr(p, "emit:input", input); Replaceall(tm, "$input", gn);
if (i < required_count) { if (i < required_count) {
Printv(f->code, "\t", tm, "\n", NULL); Printv(f->code, "\t", tm, "\n", NULL);
} else { } else {