swig -go: don't use crosscall2 for panicking

Instead rely only on documented and exported interfaces.
This commit is contained in:
Ian Lance Taylor 2021-09-15 17:56:01 -07:00
commit 6ca5d5d722
2 changed files with 32 additions and 52 deletions

View file

@ -88,52 +88,7 @@ typedef struct { void* array; intgo len; intgo cap; } _goslice_;
%}
#ifndef SWIGGO_GCCGO
/* Boilerplate for C/C++ code when using 6g/8g. This code is compiled
with gcc. */
%insert(runtime) %{
#define swiggo_size_assert_eq(x, y, name) typedef char name[(x-y)*(x-y)*-2+1];
#define swiggo_size_assert(t, n) swiggo_size_assert_eq(sizeof(t), n, swiggo_sizeof_##t##_is_not_##n)
swiggo_size_assert(char, 1)
swiggo_size_assert(short, 2)
swiggo_size_assert(int, 4)
typedef long long swiggo_long_long;
swiggo_size_assert(swiggo_long_long, 8)
swiggo_size_assert(float, 4)
swiggo_size_assert(double, 8)
#ifdef __cplusplus
extern "C" {
#endif
extern void crosscall2(void (*fn)(void *, int), void *, int);
extern char* _cgo_topofstack(void) __attribute__ ((weak));
extern void _cgo_allocate(void *, int);
extern void _cgo_panic(void *, int);
#ifdef __cplusplus
}
#endif
static char *_swig_topofstack() {
if (_cgo_topofstack) {
return _cgo_topofstack();
} else {
return 0;
}
}
static void _swig_gopanic(const char *p) {
struct {
const char *p;
} SWIGSTRUCTPACKED a;
a.p = p;
crosscall2(_cgo_panic, &a, (int) sizeof a);
}
%}
#else
#ifdef SWIGGO_GCCGO
/* Boilerplate for C/C++ code when using gccgo. */
%insert(runtime) %{
@ -154,12 +109,6 @@ extern void _cgo_panic(const char *);
#endif
%insert(runtime) %{
#define SWIG_contract_assert(expr, msg) \
if (!(expr)) { _swig_gopanic(msg); } else
%}
#ifndef SWIGGO_GCCGO
%go_import("unsafe", _ "runtime/cgo")

View file

@ -637,6 +637,37 @@ private:
Printv(f_cgo_comment, "import \"C\"\n", NULL);
Printv(f_cgo_comment, "\n", NULL);
bool need_panic = false;
if (Strstr(f_c_runtime, "SWIG_contract_assert(") != 0 || Strstr(f_c_wrappers, "SWIG_contract_assert(") != 0) {
Printv(f_c_begin, "\n#define SWIG_contract_assert(expr, msg) if (!(expr)) { _swig_gopanic(msg); } else\n\n", NULL);
need_panic = true;
}
if (!gccgo_flag && (need_panic || Strstr(f_c_runtime, "_swig_gopanic") != 0 || Strstr(f_c_wrappers, "_swig_gopanic") != 0)) {
Printv(f_go_header, "//export cgo_panic_", unique_id, "\n", NULL);
Printv(f_go_header, "func cgo_panic_", unique_id, "(p *byte) {\n", NULL);
Printv(f_go_header, "\ts := (*[1024]byte)(unsafe.Pointer(p))[:]\n", NULL);
Printv(f_go_header, "\tvar i int\n", NULL);
Printv(f_go_header, "\tvar b byte\n", NULL);
Printv(f_go_header, "\tfor i, b = range s {\n", NULL);
Printv(f_go_header, "\t\tif b == 0 {\n", NULL);
Printv(f_go_header, "\t\t\ti--\n", NULL);
Printv(f_go_header, "\t\t\tbreak\n", NULL);
Printv(f_go_header, "\t\t}\n", NULL);
Printv(f_go_header, "\t}\n", NULL);
Printv(f_go_header, "\tpanic(string(s[:i+1]))\n", NULL);
Printv(f_go_header, "}\n\n", NULL);
Printv(f_c_begin, "\nextern\n", NULL);
Printv(f_c_begin, "#ifdef __cplusplus\n", NULL);
Printv(f_c_begin, " \"C\"\n", NULL);
Printv(f_c_begin, "#endif\n", NULL);
Printv(f_c_begin, " void cgo_panic_", unique_id, "(const char*);\n", NULL);
Printv(f_c_begin, "static void _swig_gopanic(const char *p) {\n", NULL);
Printv(f_c_begin, " cgo_panic_", unique_id, "(p);\n", NULL);
Printv(f_c_begin, "}\n\n", NULL);
}
Dump(f_c_runtime, f_c_begin);
Dump(f_c_wrappers, f_c_begin);
Dump(f_c_init, f_c_begin);