forked from caketop/python-starlark-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
python_object.go
128 lines (103 loc) Β· 2.51 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
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
}
//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
}
//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}
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() {}