libgo, compiler: Upgrade libgo to Go 1.4, except for runtime.
[official-gcc.git] / libgo / go / runtime / syscall_windows.go
blobefbcab510dad875dc2ee8decd33b96304a5ff43f
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.
5 package runtime
7 import (
8 "unsafe"
11 type callbacks struct {
12 lock mutex
13 ctxt [cb_max]*wincallbackcontext
14 n int
17 func (c *wincallbackcontext) isCleanstack() bool {
18 return c.cleanstack
21 func (c *wincallbackcontext) setCleanstack(cleanstack bool) {
22 c.cleanstack = cleanstack
25 var (
26 cbs callbacks
27 cbctxts **wincallbackcontext = &cbs.ctxt[0] // to simplify access to cbs.ctxt in sys_windows_*.s
29 callbackasm byte // type isn't really byte, it's code in runtime
32 // callbackasmAddr returns address of runtime.callbackasm
33 // function adjusted by i.
34 // runtime.callbackasm is just a series of CALL instructions
35 // (each is 5 bytes long), and we want callback to arrive at
36 // correspondent call instruction instead of start of
37 // runtime.callbackasm.
38 func callbackasmAddr(i int) uintptr {
39 return uintptr(add(unsafe.Pointer(&callbackasm), uintptr(i*5)))
42 func compileCallback(fn eface, cleanstack bool) (code uintptr) {
43 if fn._type == nil || (fn._type.kind&kindMask) != kindFunc {
44 panic("compilecallback: not a function")
46 ft := (*functype)(unsafe.Pointer(fn._type))
47 if len(ft.out) != 1 {
48 panic("compilecallback: function must have one output parameter")
50 uintptrSize := unsafe.Sizeof(uintptr(0))
51 if t := (**_type)(unsafe.Pointer(&ft.out[0])); (*t).size != uintptrSize {
52 panic("compilecallback: output parameter size is wrong")
54 argsize := uintptr(0)
55 for _, t := range (*[1024](*_type))(unsafe.Pointer(&ft.in[0]))[:len(ft.in)] {
56 if (*t).size > uintptrSize {
57 panic("compilecallback: input parameter size is wrong")
59 argsize += uintptrSize
62 lock(&cbs.lock)
63 defer unlock(&cbs.lock)
65 n := cbs.n
66 for i := 0; i < n; i++ {
67 if cbs.ctxt[i].gobody == fn.data && cbs.ctxt[i].isCleanstack() == cleanstack {
68 return callbackasmAddr(i)
71 if n >= cb_max {
72 gothrow("too many callback functions")
75 c := new(wincallbackcontext)
76 c.gobody = fn.data
77 c.argsize = argsize
78 c.setCleanstack(cleanstack)
79 if cleanstack && argsize != 0 {
80 c.restorestack = argsize
81 } else {
82 c.restorestack = 0
84 cbs.ctxt[n] = c
85 cbs.n++
87 return callbackasmAddr(n)
90 func getLoadLibrary() uintptr
92 //go:nosplit
93 func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
94 var c libcall
95 c.fn = getLoadLibrary()
96 c.n = 1
97 c.args = uintptr(unsafe.Pointer(&filename))
98 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
99 handle = c.r1
100 if handle == 0 {
101 err = c.err
103 return
106 func getGetProcAddress() uintptr
108 //go:nosplit
109 func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
110 var c libcall
111 c.fn = getGetProcAddress()
112 c.n = 2
113 c.args = uintptr(unsafe.Pointer(&handle))
114 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
115 outhandle = c.r1
116 if outhandle == 0 {
117 err = c.err
119 return
122 //go:nosplit
123 func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
124 var c libcall
125 c.fn = fn
126 c.n = nargs
127 c.args = uintptr(unsafe.Pointer(&a1))
128 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
129 return c.r1, c.r2, c.err
132 //go:nosplit
133 func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
134 var c libcall
135 c.fn = fn
136 c.n = nargs
137 c.args = uintptr(unsafe.Pointer(&a1))
138 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
139 return c.r1, c.r2, c.err
142 //go:nosplit
143 func syscall_Syscall9(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
144 var c libcall
145 c.fn = fn
146 c.n = nargs
147 c.args = uintptr(unsafe.Pointer(&a1))
148 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
149 return c.r1, c.r2, c.err
152 //go:nosplit
153 func syscall_Syscall12(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2, err uintptr) {
154 var c libcall
155 c.fn = fn
156 c.n = nargs
157 c.args = uintptr(unsafe.Pointer(&a1))
158 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
159 return c.r1, c.r2, c.err
162 //go:nosplit
163 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) {
164 var c libcall
165 c.fn = fn
166 c.n = nargs
167 c.args = uintptr(unsafe.Pointer(&a1))
168 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
169 return c.r1, c.r2, c.err