1 // Copyright 2014 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.
11 const _SIGPROF
= 0 // dummy value for badsignal
13 type callbacks
struct {
15 ctxt
[cb_max
]*wincallbackcontext
19 func (c
*wincallbackcontext
) isCleanstack() bool {
23 func (c
*wincallbackcontext
) setCleanstack(cleanstack
bool) {
24 c
.cleanstack
= cleanstack
29 cbctxts
**wincallbackcontext
= &cbs
.ctxt
[0] // to simplify access to cbs.ctxt in sys_windows_*.s
31 callbackasm
byte // type isn't really byte, it's code in runtime
34 // callbackasmAddr returns address of runtime.callbackasm
35 // function adjusted by i.
36 // runtime.callbackasm is just a series of CALL instructions
37 // (each is 5 bytes long), and we want callback to arrive at
38 // correspondent call instruction instead of start of
39 // runtime.callbackasm.
40 func callbackasmAddr(i
int) uintptr {
41 return uintptr(add(unsafe
.Pointer(&callbackasm
), uintptr(i
*5)))
44 func compileCallback(fn eface
, cleanstack
bool) (code
uintptr) {
45 if fn
._type
== nil ||
(fn
._type
.kind
&kindMask
) != kindFunc
{
46 panic("compilecallback: not a function")
48 ft
:= (*functype
)(unsafe
.Pointer(fn
._type
))
50 panic("compilecallback: function must have one output parameter")
52 uintptrSize
:= unsafe
.Sizeof(uintptr(0))
53 if t
:= (**_type
)(unsafe
.Pointer(&ft
.out
[0])); (*t
).size
!= uintptrSize
{
54 panic("compilecallback: output parameter size is wrong")
58 for _
, t
:= range (*[1024](*_type
))(unsafe
.Pointer(&ft
.in
[0]))[:len(ft
.in
)] {
59 if (*t
).size
> uintptrSize
{
60 panic("compilecallback: input parameter size is wrong")
62 argsize
+= uintptrSize
67 defer unlock(&cbs
.lock
)
70 for i
:= 0; i
< n
; i
++ {
71 if cbs
.ctxt
[i
].gobody
== fn
.data
&& cbs
.ctxt
[i
].isCleanstack() == cleanstack
{
72 return callbackasmAddr(i
)
76 gothrow("too many callback functions")
79 c
:= new(wincallbackcontext
)
82 c
.setCleanstack(cleanstack
)
83 if cleanstack
&& argsize
!= 0 {
84 c
.restorestack
= argsize
91 return callbackasmAddr(n
)
94 func getLoadLibrary() uintptr
97 func syscall_loadlibrary(filename
*uint16) (handle
, err
uintptr) {
99 c
.fn
= getLoadLibrary()
101 c
.args
= uintptr(unsafe
.Pointer(&filename
))
102 cgocall_errno(unsafe
.Pointer(funcPC(asmstdcall
)), unsafe
.Pointer(&c
))
110 func getGetProcAddress() uintptr
113 func syscall_getprocaddress(handle
uintptr, procname
*byte) (outhandle
, err
uintptr) {
115 c
.fn
= getGetProcAddress()
117 c
.args
= uintptr(unsafe
.Pointer(&handle
))
118 cgocall_errno(unsafe
.Pointer(funcPC(asmstdcall
)), unsafe
.Pointer(&c
))
127 func syscall_Syscall(fn
, nargs
, a1
, a2
, a3
uintptr) (r1
, r2
, err
uintptr) {
131 c
.args
= uintptr(unsafe
.Pointer(&a1
))
132 cgocall_errno(unsafe
.Pointer(funcPC(asmstdcall
)), unsafe
.Pointer(&c
))
133 return c
.r1
, c
.r2
, c
.err
137 func syscall_Syscall6(fn
, nargs
, a1
, a2
, a3
, a4
, a5
, a6
uintptr) (r1
, r2
, err
uintptr) {
141 c
.args
= uintptr(unsafe
.Pointer(&a1
))
142 cgocall_errno(unsafe
.Pointer(funcPC(asmstdcall
)), unsafe
.Pointer(&c
))
143 return c
.r1
, c
.r2
, c
.err
147 func syscall_Syscall9(fn
, nargs
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
uintptr) (r1
, r2
, err
uintptr) {
151 c
.args
= uintptr(unsafe
.Pointer(&a1
))
152 cgocall_errno(unsafe
.Pointer(funcPC(asmstdcall
)), unsafe
.Pointer(&c
))
153 return c
.r1
, c
.r2
, c
.err
157 func syscall_Syscall12(fn
, nargs
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
, a10
, a11
, a12
uintptr) (r1
, r2
, err
uintptr) {
161 c
.args
= uintptr(unsafe
.Pointer(&a1
))
162 cgocall_errno(unsafe
.Pointer(funcPC(asmstdcall
)), unsafe
.Pointer(&c
))
163 return c
.r1
, c
.r2
, c
.err
167 func syscall_Syscall15(fn
, nargs
, a1
, a2
, a3
, a4
, a5
, a6
, a7
, a8
, a9
, a10
, a11
, a12
, a13
, a14
, a15
uintptr) (r1
, r2
, err
uintptr) {
171 c
.args
= uintptr(unsafe
.Pointer(&a1
))
172 cgocall_errno(unsafe
.Pointer(funcPC(asmstdcall
)), unsafe
.Pointer(&c
))
173 return c
.r1
, c
.r2
, c
.err