github.com/aergoio/aergo@v1.3.1/cmd/aergoluac/util/luac_util.go (about) 1 package util 2 3 /* 4 #cgo CFLAGS: -I${SRCDIR}/../../../libtool/include/luajit-2.1 5 #cgo LDFLAGS: ${SRCDIR}/../../../libtool/lib/libluajit-5.1.a -lm 6 7 #include <stdlib.h> 8 #include <lualib.h> 9 #include "compile.h" 10 */ 11 import "C" 12 import ( 13 "bufio" 14 "bytes" 15 "encoding/binary" 16 "errors" 17 "fmt" 18 "github.com/aergoio/aergo/cmd/aergoluac/encoding" 19 "io/ioutil" 20 "os" 21 "runtime" 22 "unsafe" 23 ) 24 25 func NewLState() *C.lua_State { 26 L := C.luac_vm_newstate() 27 if L == nil { 28 runtime.GC() 29 L = C.luac_vm_newstate() 30 } 31 return L 32 } 33 34 func CloseLState(L *C.lua_State) { 35 if L != nil { 36 C.luac_vm_close(L) 37 } 38 } 39 40 func Compile(L *C.lua_State, code string) ([]byte, error) { 41 cstr := C.CString(code) 42 defer C.free(unsafe.Pointer(cstr)) 43 if errMsg := C.vm_loadstring(L, cstr); errMsg != nil { 44 return nil, errors.New(C.GoString(errMsg)) 45 } 46 if errMsg := C.vm_stringdump(L); errMsg != nil { 47 return nil, errors.New(C.GoString(errMsg)) 48 } 49 return dumpToBytes(L), nil 50 } 51 52 func CompileFromFile(srcFileName, outFileName, abiFileName string) error { 53 cSrcFileName := C.CString(srcFileName) 54 cOutFileName := C.CString(outFileName) 55 cAbiFileName := C.CString(abiFileName) 56 L := C.luac_vm_newstate() 57 defer C.free(unsafe.Pointer(cSrcFileName)) 58 defer C.free(unsafe.Pointer(cOutFileName)) 59 defer C.free(unsafe.Pointer(cAbiFileName)) 60 defer C.luac_vm_close(L) 61 62 if errMsg := C.vm_compile(L, cSrcFileName, cOutFileName, cAbiFileName); errMsg != nil { 63 return errors.New(C.GoString(errMsg)) 64 } 65 return nil 66 } 67 68 func DumpFromFile(srcFileName string) error { 69 cSrcFileName := C.CString(srcFileName) 70 L := C.luac_vm_newstate() 71 defer C.free(unsafe.Pointer(cSrcFileName)) 72 defer C.luac_vm_close(L) 73 74 if errMsg := C.vm_loadfile(L, cSrcFileName); errMsg != nil { 75 return errors.New(C.GoString(errMsg)) 76 } 77 if errMsg := C.vm_stringdump(L); errMsg != nil { 78 return errors.New(C.GoString(errMsg)) 79 } 80 81 fmt.Println(encoding.EncodeCode(dumpToBytes(L))) 82 return nil 83 } 84 85 func DumpFromStdin() error { 86 fi, err := os.Stdin.Stat() 87 if err != nil { 88 return err 89 } 90 var buf []byte 91 if (fi.Mode() & os.ModeCharDevice) == 0 { 92 buf, err = ioutil.ReadAll(os.Stdin) 93 if err != nil { 94 return err 95 } 96 } else { 97 var bBuf bytes.Buffer 98 scanner := bufio.NewScanner(os.Stdin) 99 for scanner.Scan() { 100 bBuf.WriteString(scanner.Text() + "\n") 101 } 102 if err = scanner.Err(); err != nil { 103 return err 104 } 105 buf = bBuf.Bytes() 106 } 107 srcCode := C.CString(string(buf)) 108 L := C.luac_vm_newstate() 109 defer C.free(unsafe.Pointer(srcCode)) 110 defer C.luac_vm_close(L) 111 112 if errMsg := C.vm_loadstring(L, srcCode); errMsg != nil { 113 return errors.New(C.GoString(errMsg)) 114 } 115 if errMsg := C.vm_stringdump(L); errMsg != nil { 116 return errors.New(C.GoString(errMsg)) 117 } 118 fmt.Println(encoding.EncodeCode(dumpToBytes(L))) 119 return nil 120 } 121 122 func dumpToBytes(L *C.lua_State) []byte { 123 var s *C.char 124 var l C.size_t 125 b := make([]byte, 4) 126 s = C.lua_tolstring(L, -2, &l) 127 binary.LittleEndian.PutUint32(b, uint32(l)) 128 b = append(b, C.GoBytes(unsafe.Pointer(s), C.int(l))...) 129 s = C.lua_tolstring(L, -1, &l) 130 b = append(b, C.GoBytes(unsafe.Pointer(s), C.int(l))...) 131 return b 132 }