github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/runtime/callback_windows.c (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "runtime.h" 6 #include "type.h" 7 #include "typekind.h" 8 #include "defs_GOOS_GOARCH.h" 9 #include "os_GOOS.h" 10 #include "zasm_GOOS_GOARCH.h" 11 12 typedef struct Callbacks Callbacks; 13 struct Callbacks { 14 Lock; 15 WinCallbackContext* ctxt[cb_max]; 16 int32 n; 17 }; 18 19 static Callbacks cbs; 20 21 WinCallbackContext** runtime·cbctxts; // to simplify access to cbs.ctxt in sys_windows_*.s 22 23 // Call back from windows dll into go. 24 byte * 25 runtime·compilecallback(Eface fn, bool cleanstack) 26 { 27 FuncType *ft; 28 Type *t; 29 int32 argsize, i, n; 30 WinCallbackContext *c; 31 32 if(fn.type == nil || fn.type->kind != KindFunc) 33 runtime·panicstring("compilecallback: not a function"); 34 ft = (FuncType*)fn.type; 35 if(ft->out.len != 1) 36 runtime·panicstring("compilecallback: function must have one output parameter"); 37 if(((Type**)ft->out.array)[0]->size != sizeof(uintptr)) 38 runtime·panicstring("compilecallback: output parameter size is wrong"); 39 argsize = 0; 40 for(i=0; i<ft->in.len; i++) { 41 t = ((Type**)ft->in.array)[i]; 42 if(t->size > sizeof(uintptr)) 43 runtime·panicstring("compilecallback: input parameter size is wrong"); 44 argsize += sizeof(uintptr); 45 } 46 47 runtime·lock(&cbs); 48 if(runtime·cbctxts == nil) 49 runtime·cbctxts = &(cbs.ctxt[0]); 50 n = cbs.n; 51 for(i=0; i<n; i++) { 52 if(cbs.ctxt[i]->gobody == fn.data) { 53 runtime·unlock(&cbs); 54 // runtime·callbackasm is just a series of CALL instructions 55 // (each is 5 bytes long), and we want callback to arrive at 56 // correspondent call instruction instead of start of 57 // runtime·callbackasm. 58 return (byte*)runtime·callbackasm + i * 5; 59 } 60 } 61 if(n >= cb_max) 62 runtime·throw("too many callback functions"); 63 c = runtime·mal(sizeof *c); 64 c->gobody = fn.data; 65 c->argsize = argsize; 66 if(cleanstack && argsize!=0) 67 c->restorestack = argsize; 68 else 69 c->restorestack = 0; 70 cbs.ctxt[n] = c; 71 cbs.n++; 72 runtime·unlock(&cbs); 73 74 // as before 75 return (byte*)runtime·callbackasm + n * 5; 76 }