-
Notifications
You must be signed in to change notification settings - Fork 4
/
cgluer.go
89 lines (74 loc) · 1.35 KB
/
cgluer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// +build ignore
// This file is intended to be executed by "go generate".
package main
import (
"os"
"strconv"
"text/template"
)
var fileTemplate = template.Must(template.New("").Parse(`package wren
/*
{{range .}}extern void f{{.}}(void* vm);
{{end}}
static inline void* get_f(int i) {
switch (i) {
{{range .}}case {{.}}: return f{{.}};
{{end}}default: return (void*)(0);
}
}
*/
import "C"
import (
"errors"
"sync"
"unsafe"
)
const MAX_REGISTRATIONS = {{len .}}
var (
fMap = make(map[int]func())
fMapGuard sync.Mutex
counter int
)
{{range .}}
//export f{{.}}
func f{{.}}(vm unsafe.Pointer) {
f := fMap[{{.}}]
if f == nil {
panic("function {{.}} not registered")
}
f()
}
{{end}}
func registerFunc(name string, f func()) (unsafe.Pointer, error) {
if (counter+1) >= MAX_REGISTRATIONS {
return nil, errors.New("maximum function registration reached")
}
fMapGuard.Lock()
defer fMapGuard.Unlock()
fMap[counter] = f
ptr := C.get_f(C.int(counter))
counter++
return ptr, nil
}
`))
func main() {
if len(os.Args) == 1 {
panic("no number provided")
}
n, err := strconv.Atoi(os.Args[1])
if err != nil {
panic(err)
}
f, err := os.Create("cglue.go")
if err != nil {
panic(err)
}
defer f.Close()
data := make([]int, n)
for i := 0; i < n; i++ {
data[i] = i
}
if err := fileTemplate.Execute(f, data); err != nil {
panic(err)
}
}