From 1dd401899fc230073295cf86db4a5d66eefdba85 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sun, 22 Feb 2015 11:09:58 -0800 Subject: [Go] Change SWIG directors to use a handle instead of a Go pointer. In future releases of Go it will not be possible to pass Go pointers into C/C++ code. The handle is automatically translated back to the Go value using a Go map. Since directors must be explicitly deleted, we can reliably use that call to remove the handle from the map. --- Lib/go/goruntime.swg | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'Lib/go') diff --git a/Lib/go/goruntime.swg b/Lib/go/goruntime.swg index 19ccf5ae9..f76da9c78 100644 --- a/Lib/go/goruntime.swg +++ b/Lib/go/goruntime.swg @@ -317,3 +317,58 @@ static void swig_acquire_pointer(Swig_memory** pmem, Type* ptr) { (*pmem)->swig_acquire_pointer(ptr); } %} + +/* For directors we need C++ to track a Go pointer. Since we can't + pass a Go pointer into C++, we use a map to track the pointers on + the Go side. */ + +%go_import("sync") + +%insert(go_header) %{ +type _ sync.Mutex +%} + +%insert(go_director) %{ + +var swigDirectorTrack struct { + sync.Mutex + m map[int]interface{} + c int +} + +func swigDirectorAdd(v interface{}) int { + swigDirectorTrack.Lock() + defer swigDirectorTrack.Unlock() + if swigDirectorTrack.m == nil { + swigDirectorTrack.m = make(map[int]interface{}) + } + swigDirectorTrack.c++ + ret := swigDirectorTrack.c + swigDirectorTrack.m[ret] = v + return ret +} + +func swigDirectorLookup(c int) interface{} { + swigDirectorTrack.Lock() + defer swigDirectorTrack.Unlock() + ret := swigDirectorTrack.m[c] + if ret == nil { + panic("C++ director pointer not found (possible use-after-free)") + } + return ret +} + +func swigDirectorDelete(c int) { + swigDirectorTrack.Lock() + defer swigDirectorTrack.Unlock() + if swigDirectorTrack.m[c] == nil { + if c > swigDirectorTrack.c { + panic("C++ director pointer invalid (possible memory corruption") + } else { + panic("C++ director pointer not found (possible use-after-free)") + } + } + delete(swigDirectorTrack.m, c) +} + +%} -- cgit v1.2.1