作者:reuse
项目:lu
// Peval evaluates a piece of lua code. no panic when error occur.
func (l *Lua) Peval(code string, envs ...interface{}) (returns []interface{}, err error) {
defer C.lua_settop(l.State, 0)
C.push_errfunc(l.State)
curTop := C.lua_gettop(l.State)
// parse
cCode := C.CString(code)
defer C.free(unsafe.Pointer(cCode))
if ret := C.luaL_loadstring(l.State, cCode); ret != 0 { // load error
return nil, fmt.Errorf("LOAD ERROR: %s", C.GoString(C.lua_tolstring(l.State, -1, nil)))
}
// env
if len(envs) > 0 {
if len(envs)%2 != 0 {
return nil, fmt.Errorf("number of arguments not match")
}
C.lua_createtable(l.State, 0, 0)
for i := 0; i < len(envs); i += 2 {
name, ok := envs[i].(string)
if !ok {
return nil, fmt.Errorf("name must be string, not %v", envs[i])
}
C.lua_pushstring(l.State, cstr(name))
err := l.pushGoValue(envs[i+1], name)
if err != nil {
return nil, err
}
C.lua_rawset(l.State, -3)
}
// set env
C.set_eval_env(l.State)
}
// call
l.err = nil
if ret := C.lua_pcall(l.State, 0, C.LUA_MULTRET, -2); ret != 0 {
// error occured
return nil, fmt.Errorf("CALL ERROR: %s", C.GoString(C.lua_tolstring(l.State, -1, nil)))
} else if l.err != nil { // error raise by invokeGoFunc
return nil, l.err
} else {
// return values
nReturn := C.lua_gettop(l.State) - curTop
returns = make([]interface{}, int(nReturn))
for i := C.int(0); i < nReturn; i++ {
value, err := l.toGoValue(-1-i, interfaceType)
if err != nil {
return nil, err
}
if value != nil {
returns[int(nReturn-1-i)] = value.Interface()
} else {
returns[int(nReturn-1-i)] = nil
}
}
}
return
}
作者:vro
项目:lu
func Tostring(s *State, index int) string {
var l C.size_t
cs := C.lua_tolstring((*C.lua_State)(s),
C.int(index), &l)
// Remake this into a string!
return C.GoStringN(cs, C.int(l))
}
作者:rdlaitil
项目:lea
// Converts the Lua value at the given valid index to a Go
// string. The Lua value must be a string or a number; otherwise,
// the function returns an empty string. If the value is a number, then
// Tostring also changes the actual value in the stack to a string. (This
// change confuses Next when Tostring is applied to keys during a table
// traversal). The string always has a zero ('\0') after its last
// character (as in C), but can contain other zeros in its body.
func (this *State) Tostring(index int) string {
str := C.lua_tolstring(this.luastate, C.int(index), nil)
if str == nil {
return ""
}
return C.GoString(str)
}
作者:hxyx
项目:goinf
func (state State) getStructField(structPtr reflect.Value, lkey C.int) (ret int, err error) {
L := state.L
vm := state.VM
structValue := structPtr.Elem()
t := structValue.Type()
info := vm.findStruct(t)
if info == nil {
return -1, fmt.Errorf("can not index a solid struct")
}
ltype := int(C.lua_type(L, lkey))
if ltype != C.LUA_TSTRING {
return -1, fmt.Errorf("field key of struct must be a string")
}
//
//key := stringFromLua(L, lkey)
//fld, ok := info.fields[key]
//
// <hack> using string pstr cache
pstr := C.lua_tolstring(L, lkey, nil)
// </hack>
fld, ok := info.cache[pstr]
if !ok {
key := stringFromLua(L, lkey)
return -1, fmt.Errorf("not such field `%v'", key)
}
value := getStructFieldValue(structValue, fld)
state.goToLuaValue(value)
return 1, nil
}
作者:ngocthanhi
项目:sk
// Initializes the Lua context and compiles the source code.
func (e *ExecutionEngine) init() error {
if e.state != nil {
return nil
}
// Initialize the state and open the libraries.
e.state = C.luaL_newstate()
if e.state == nil {
return errors.New("Unable to initialize Lua context.")
}
C.luaL_openlibs(e.state)
// Generate the header file.
err := e.generateHeader()
if err != nil {
e.Destroy()
return err
}
// Compile the script.
e.fullSource = fmt.Sprintf("%v\n%v", e.header, e.source)
source := C.CString(e.fullSource)
defer C.free(unsafe.Pointer(source))
ret := C.luaL_loadstring(e.state, source)
if ret != 0 {
defer e.Destroy()
errstring := C.GoString(C.lua_tolstring(e.state, -1, nil))
return fmt.Errorf("skyd.ExecutionEngine: Syntax Error: %v", errstring)
}
// Run script once to initialize.
ret = C.lua_pcall(e.state, 0, 0, 0)
if ret != 0 {
defer e.Destroy()
errstring := C.GoString(C.lua_tolstring(e.state, -1, nil))
return fmt.Errorf("skyd.ExecutionEngine: Init Error: %v", errstring)
}
// Setup cursor.
err = e.initCursor()
if err != nil {
e.Destroy()
return err
}
return nil
}
作者:hxyx
项目:goinf
func (sinfo *structInfo) makeFieldsIndexCache(vm *VM) {
L := vm.globalL
sinfo.cache = make(map[*C.char]*structField, len(sinfo.fields))
sinfo.lref = make(map[string]int, len(sinfo.fields))
for key, field := range sinfo.fields {
pushStringToLua(L, key)
pstr := C.lua_tolstring(L, -1, nil)
sinfo.cache[pstr] = field
sinfo.lref[key] = int(C.luaL_ref(L, C.LUA_REGISTRYINDEX))
}
}
作者:reuse
项目:lg
func (self *Lua) RunString(code string) {
defer func() {
if r := recover(); r != nil {
if self.PrintTraceback { //NOCOVER
print("============ start lua traceback ============\n")
self.RunString(`print(debug.traceback())`)
print("============ end lua traceback ==============\n")
}
panic(r)
}
}()
cCode := cstr(code)
C.setup_message_handler(self.State)
if ret := C.luaL_loadstring(self.State, cCode); ret != C.int(0) {
self.Panic("%s", C.GoString(C.lua_tolstring(self.State, -1, nil)))
}
ret := C.lua_pcallk(self.State, 0, 0, C.lua_gettop(self.State)-C.int(1), 0, nil)
if ret != C.int(0) {
self.Panic("%s", C.GoString(C.lua_tolstring(self.State, -1, nil)))
}
C.lua_settop(self.State, 0)
}
作者:hxyx
项目:goinf
func packLuaString(out io.Writer, state State, object int) (n int, err error) {
var cslen C.size_t
cs := C.lua_tolstring(state.L, C.int(object), &cslen)
// <HACK> pretend a []byte slice to avoid intermediate buffer
slhead := reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(cs)),
Len: int(cslen), Cap: int(cslen),
}
pslice := (*[]byte)(unsafe.Pointer(&slhead))
// </HACK>
return P.PackRaw(out, *pslice)
}
作者:ngocthanhi
项目:sk
// Executes an aggregation over the iterator.
func (e *ExecutionEngine) Aggregate() (interface{}, error) {
functionName := C.CString("sky_aggregate")
defer C.free(unsafe.Pointer(functionName))
C.lua_getfield(e.state, -10002, functionName)
C.lua_pushlightuserdata(e.state, unsafe.Pointer(e.cursor))
rc := C.lua_pcall(e.state, 1, 1, 0)
if rc != 0 {
luaErrString := C.GoString(C.lua_tolstring(e.state, -1, nil))
fmt.Println(e.FullAnnotatedSource())
return nil, fmt.Errorf("skyd.ExecutionEngine: Unable to aggregate: %s", luaErrString)
}
return e.decodeResult()
}
作者:hxyx
项目:goinf
func luaUnpackFromString(state State) int {
// arg 1 is func udata itself
var cslen C.size_t
cs := C.lua_tolstring(state.L, C.int(2), &cslen)
// <HACK> pretend a []byte slice to avoid intermediate buffer
slhead := reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(cs)),
Len: int(cslen), Cap: int(cslen),
}
pslice := (*[]byte)(unsafe.Pointer(&slhead))
// </HACK>
reader := bytes.NewReader(*pslice)
return UnpackToLua(reader, state)
}
作者:reuse
项目:lu
// Pcall calls a lua function. no panic
func (l *Lua) Pcall(fullname string, args ...interface{}) (returns []interface{}, err error) {
C.push_errfunc(l.State)
curTop := C.lua_gettop(l.State)
// get function
path := strings.Split(fullname, ".")
for i, name := range path {
if i == 0 {
C.lua_getfield(l.State, C.LUA_GLOBALSINDEX, cstr(name))
} else {
if C.lua_type(l.State, -1) != C.LUA_TTABLE {
return nil, fmt.Errorf("%s is not a function", fullname)
}
C.lua_pushstring(l.State, cstr(name))
C.lua_gettable(l.State, -2)
C.lua_remove(l.State, -2) // remove table
}
}
if C.lua_type(l.State, -1) != C.LUA_TFUNCTION {
return nil, fmt.Errorf("%s is not a function", fullname)
}
// args
for _, arg := range args {
l.pushGoValue(arg, "")
}
// call
l.err = nil
if ret := C.lua_pcall(l.State, C.int(len(args)), C.LUA_MULTRET, C.int(-(len(args))-2)); ret != 0 {
// error occured
return nil, fmt.Errorf("CALL ERROR: %s", C.GoString(C.lua_tolstring(l.State, -1, nil)))
} else if l.err != nil { // error raise by invokeGoFunc
return nil, l.err
} else {
// return values
nReturn := C.lua_gettop(l.State) - curTop
returns = make([]interface{}, int(nReturn))
for i := C.int(0); i < nReturn; i++ {
value, err := l.toGoValue(-1-i, interfaceType)
if err != nil {
return nil, err
}
returns[int(nReturn-1-i)] = value.Interface()
}
}
return
}
作者:ngocthanhi
项目:sk
// Decodes the result from a function into a Go object.
func (e *ExecutionEngine) decodeResult() (interface{}, error) {
// Encode Lua object into msgpack.
rc := C.mp_pack(e.state)
if rc != 1 {
return nil, errors.New("skyd.ExecutionEngine: Unable to msgpack decode Lua result")
}
sz := C.size_t(0)
ptr := C.lua_tolstring(e.state, -1, (*C.size_t)(&sz))
str := C.GoStringN(ptr, (C.int)(sz))
C.lua_settop(e.state, -(1)-1) // lua_pop()
// Decode msgpack into a Go object.
var ret interface{}
decoder := msgpack.NewDecoder(bytes.NewBufferString(str), nil)
err := decoder.Decode(&ret)
if err != nil {
return nil, err
}
return ret, nil
}
作者:ngocthanhi
项目:sk
// Executes an merge over the iterator.
func (e *ExecutionEngine) Merge(results interface{}, data interface{}) (interface{}, error) {
functionName := C.CString("sky_merge")
defer C.free(unsafe.Pointer(functionName))
C.lua_getfield(e.state, -10002, functionName)
err := e.encodeArgument(results)
if err != nil {
return results, err
}
err = e.encodeArgument(data)
if err != nil {
return results, err
}
rc := C.lua_pcall(e.state, 2, 1, 0)
if rc != 0 {
luaErrString := C.GoString(C.lua_tolstring(e.state, -1, nil))
fmt.Println(e.FullAnnotatedSource())
return results, fmt.Errorf("skyd.ExecutionEngine: Unable to merge: %s", luaErrString)
}
return e.decodeResult()
}
作者:ngocthanhi
项目:sk
// Initializes the cursor used by the script.
func (e *ExecutionEngine) initCursor() error {
// Create the cursor.
minPropertyId, maxPropertyId := e.propertyFile.NextIdentifiers()
e.cursor = C.sky_cursor_new((C.int32_t)(minPropertyId), (C.int32_t)(maxPropertyId))
e.cursor.context = unsafe.Pointer(e)
C.executionEngine_setNextObjectFunc(unsafe.Pointer(e.cursor))
// Initialize the cursor from within Lua.
functionName := C.CString("sky_init_cursor")
defer C.free(unsafe.Pointer(functionName))
C.lua_getfield(e.state, -10002, functionName)
C.lua_pushlightuserdata(e.state, unsafe.Pointer(e.cursor))
//fmt.Printf("%s\n\n", e.FullAnnotatedSource())
rc := C.lua_pcall(e.state, 1, 0, 0)
if rc != 0 {
luaErrString := C.GoString(C.lua_tolstring(e.state, -1, nil))
return fmt.Errorf("Unable to init cursor: %s", luaErrString)
}
return nil
}
作者:reuse
项目:lg
func (self *Lua) CallFunction(name string, args ...interface{}) {
defer func() {
if r := recover(); r != nil {
if self.PrintTraceback { //NOCOVER
print("============ start lua traceback ============\n")
self.RunString(`print(debug.traceback())`)
print("============ end lua traceback ==============\n")
}
panic(r)
}
}()
cName := cstr(name)
C.setup_message_handler(self.State)
C.lua_getglobal(self.State, cName)
for _, arg := range args {
self.PushGoValue(reflect.ValueOf(arg))
}
ret := C.lua_pcallk(self.State, C.int(len(args)), 0, C.lua_gettop(self.State)-C.int(len(args)+2), 0, nil)
if ret != C.int(0) {
self.Panic("%s", C.GoString(C.lua_tolstring(self.State, -1, nil)))
}
}
作者:1lan
项目:golu
//export golua_interface_newindex_callback
func golua_interface_newindex_callback(Li interface{}, iid uint, field_name_cstr *C.char) int {
L := Li.(*State)
iface := L.registry[iid]
ifacevalue := reflect.ValueOf(iface).Elem()
field_name := C.GoString(field_name_cstr)
fval := ifacevalue.FieldByName(field_name)
if fval.Kind() == reflect.Ptr {
fval = fval.Elem()
}
luatype := LuaValType(C.lua_type(L.s, 3))
switch fval.Kind() {
case reflect.Bool:
if luatype == LUA_TBOOLEAN {
fval.SetBool(int(C.lua_toboolean(L.s, 3)) != 0)
return 1
} else {
L.PushString("Wrong assignment to field " + field_name)
return -1
}
case reflect.Int:
fallthrough
case reflect.Int8:
fallthrough
case reflect.Int16:
fallthrough
case reflect.Int32:
fallthrough
case reflect.Int64:
if luatype == LUA_TNUMBER {
fval.SetInt(int64(C.lua_tointeger(L.s, 3)))
return 1
} else {
L.PushString("Wrong assignment to field " + field_name)
return -1
}
case reflect.Uint:
fallthrough
case reflect.Uint8:
fallthrough
case reflect.Uint16:
fallthrough
case reflect.Uint32:
fallthrough
case reflect.Uint64:
if luatype == LUA_TNUMBER {
fval.SetUint(uint64(C.lua_tointeger(L.s, 3)))
return 1
} else {
L.PushString("Wrong assignment to field " + field_name)
return -1
}
case reflect.String:
if luatype == LUA_TSTRING {
fval.SetString(C.GoString(C.lua_tolstring(L.s, 3, nil)))
return 1
} else {
L.PushString("Wrong assignment to field " + field_name)
return -1
}
case reflect.Float32:
fallthrough
case reflect.Float64:
if luatype == LUA_TNUMBER {
fval.SetFloat(float64(C.lua_tonumber(L.s, 3)))
return 1
} else {
L.PushString("Wrong assignment to field " + field_name)
return -1
}
}
L.PushString("Unsupported type of field " + field_name + ": " + fval.Type().String())
return -1
}
作者:matthewtid
项目:golu
func (L *State) ToString(index int) string {
var size C.size_t
//C.GoString(C.lua_tolstring(L.s, C.int(index), &size));
return C.GoString(C.lua_tolstring(L.s, C.int(index), &size))
}
作者:aarzill
项目:golu
func (L *State) ToBytes(index int) []byte {
var size C.size_t
b := C.lua_tolstring(L.s, C.int(index), &size)
return C.GoBytes(unsafe.Pointer(b), C.int(size))
}
作者:gooop
项目:glu
func (L *State) getString(i int) (ret string) {
return C.GoString(C.lua_tolstring(L.s, C.int(i+1), nil))
}
作者:reuse
项目:lg
func (lua *Lua) toGoValue(i C.int, paramType reflect.Type) (ret reflect.Value) {
luaType := C.lua_type(lua.State, i)
paramKind := paramType.Kind()
switch paramKind {
case reflect.Bool:
if luaType != C.LUA_TBOOLEAN {
lua.Panic("not a boolean")
}
ret = reflect.ValueOf(C.lua_toboolean(lua.State, i) == C.int(1))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if luaType != C.LUA_TNUMBER {
lua.Panic("not an integer")
}
ret = reflect.New(paramType).Elem()
ret.SetInt(int64(C.lua_tointegerx(lua.State, i, nil)))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
if luaType != C.LUA_TNUMBER {
lua.Panic("not an unsigned")
}
ret = reflect.New(paramType).Elem()
ret.SetUint(uint64(C.lua_tointegerx(lua.State, i, nil)))
case reflect.Float32, reflect.Float64:
if luaType != C.LUA_TNUMBER {
lua.Panic("not a float")
}
ret = reflect.New(paramType).Elem()
ret.SetFloat(float64(C.lua_tonumberx(lua.State, i, nil)))
case reflect.Interface:
switch luaType {
case C.LUA_TNUMBER:
ret = reflect.New(floatType).Elem()
ret.SetFloat(float64(C.lua_tonumberx(lua.State, i, nil)))
case C.LUA_TSTRING:
ret = reflect.New(stringType).Elem()
ret.SetString(C.GoString(C.lua_tolstring(lua.State, i, nil)))
case C.LUA_TLIGHTUSERDATA:
ret = reflect.ValueOf(C.lua_topointer(lua.State, i))
case C.LUA_TBOOLEAN:
ret = reflect.New(boolType).Elem()
ret.SetBool(C.lua_toboolean(lua.State, i) == C.int(1))
//TODO nil
//TODO table
default:
lua.Panic("wrong interface argument: %v", paramKind)
}
case reflect.String:
if luaType != C.LUA_TSTRING {
lua.Panic("not a string")
}
ret = reflect.New(paramType).Elem()
ret.SetString(C.GoString(C.lua_tolstring(lua.State, i, nil)))
case reflect.Slice:
switch luaType {
case C.LUA_TSTRING:
ret = reflect.New(paramType).Elem()
cstr := C.lua_tolstring(lua.State, i, nil)
ret.SetBytes(C.GoBytes(unsafe.Pointer(cstr), C.int(C.strlen(cstr))))
case C.LUA_TTABLE:
ret = reflect.MakeSlice(paramType, 0, 0)
C.lua_pushnil(lua.State)
elemType := paramType.Elem()
for C.lua_next(lua.State, i) != 0 {
ret = reflect.Append(ret, lua.toGoValue(-1, elemType))
C.lua_settop(lua.State, -2)
}
default:
lua.Panic("wrong slice argument")
}
case reflect.Ptr:
if luaType != C.LUA_TLIGHTUSERDATA {
lua.Panic("not a pointer")
}
pointer := C.lua_topointer(lua.State, i)
ret = reflect.NewAt(paramType, unsafe.Pointer(&pointer)).Elem()
case reflect.Map:
if luaType != C.LUA_TTABLE {
lua.Panic("not a map")
}
ret = reflect.MakeMap(paramType)
C.lua_pushnil(lua.State)
keyType := paramType.Key()
elemType := paramType.Elem()
for C.lua_next(lua.State, i) != 0 {
ret.SetMapIndex(
lua.toGoValue(-2, keyType),
lua.toGoValue(-1, elemType))
C.lua_settop(lua.State, -2)
}
case reflect.UnsafePointer:
ret = reflect.ValueOf(C.lua_topointer(lua.State, i))
//TODO complex64/128
//TODO array
//TODO chan
//TODO func
//TODO struct
default:
lua.Panic("unknown argument type %v", paramType)
}
return
}