-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathpython_object.go
147 lines (119 loc) Β· 2.82 KB
/
python_object.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package main
/*
#include "starlark.h"
extern PyObject *StarlarkError;
extern PyObject *SyntaxError;
extern PyObject *EvalError;
extern PyObject *ResolveError;
*/
import "C"
import (
"fmt"
"runtime/cgo"
"sync"
"unsafe"
"go.starlark.net/resolve"
"go.starlark.net/starlark"
)
type StarlarkState struct {
Globals starlark.StringDict
Mutex sync.RWMutex
Print *C.PyObject
threadState *C.PyThreadState
}
//export ConfigureStarlark
func ConfigureStarlark(allowSet C.int, allowGlobalReassign C.int, allowRecursion C.int) {
// Ignore input values other than 0 or 1 and leave current value in place
switch allowSet {
case 0:
resolve.AllowSet = false
case 1:
resolve.AllowSet = true
}
switch allowGlobalReassign {
case 0:
resolve.AllowGlobalReassign = false
case 1:
resolve.AllowGlobalReassign = true
}
switch allowRecursion {
case 0:
resolve.AllowRecursion = false
case 1:
resolve.AllowRecursion = true
}
}
func rlockSelf(self *C.Starlark) *StarlarkState {
state := cgo.Handle(self.handle).Value().(*StarlarkState)
state.Mutex.RLock()
return state
}
func lockSelf(self *C.Starlark) *StarlarkState {
state := cgo.Handle(self.handle).Value().(*StarlarkState)
state.Mutex.Lock()
return state
}
func (state *StarlarkState) DetachGIL() {
state.threadState = C.PyEval_SaveThread()
}
func (state *StarlarkState) ReattachGIL() {
if state.threadState == nil {
return
}
C.PyEval_RestoreThread(state.threadState)
state.threadState = nil
}
//export Starlark_new
func Starlark_new(pytype *C.PyTypeObject, args *C.PyObject, kwargs *C.PyObject) *C.Starlark {
self := C.starlarkAlloc(pytype)
if self == nil {
return nil
}
state := &StarlarkState{
Globals: starlark.StringDict{},
Mutex: sync.RWMutex{},
Print: nil,
threadState: nil,
}
self.handle = C.uintptr_t(cgo.NewHandle(state))
return self
}
//export Starlark_init
func Starlark_init(self *C.Starlark, args *C.PyObject, kwargs *C.PyObject) C.int {
var globals *C.PyObject = nil
var print *C.PyObject = nil
if C.parseInitArgs(args, kwargs, &globals, &print) == 0 {
return -1
}
if print != nil {
if Starlark_set_print(self, print, nil) != 0 {
return -1
}
}
if globals != nil {
if C.PyMapping_Check(globals) != 1 {
errmsg := C.CString(fmt.Sprintf("Can't initialize globals from %s", C.GoString(globals.ob_type.tp_name)))
defer C.free(unsafe.Pointer(errmsg))
C.PyErr_SetString(C.PyExc_TypeError, errmsg)
return -1
}
retval := Starlark_set_globals(self, args, globals)
if retval == nil {
return -1
}
}
return 0
}
//export Starlark_dealloc
func Starlark_dealloc(self *C.Starlark) {
handle := cgo.Handle(self.handle)
state := handle.Value().(*StarlarkState)
handle.Delete()
state.Mutex.Lock()
defer state.Mutex.Unlock()
if state.Print != nil {
C.Py_DecRef(state.Print)
}
C.starlarkFree(self)
}
func main() {}