github.com/aergoio/aergo@v1.3.1/cmd/aergoluac/util/compile.c (about) 1 2 #include <stdlib.h> 3 #include <string.h> 4 #include <lualib.h> 5 #include <lauxlib.h> 6 #include <luajit.h> 7 #include "state_module.h" 8 #include "_cgo_export.h" 9 10 lua_State *luac_vm_newstate() 11 { 12 lua_State *L = luaL_newstate(); 13 if (L == NULL) { 14 return NULL; 15 } 16 luaL_openlibs(L); 17 luac_open_state(L); 18 return L; 19 } 20 21 void luac_vm_close(lua_State *L) 22 { 23 if (L != NULL) 24 lua_close(L); 25 } 26 27 static int kpt_lua_Writer(struct lua_State *L, const void *p, size_t sz, void *u) 28 { 29 return (fwrite(p, sz, 1, (FILE *)u) != 1) && (sz != 0); 30 } 31 32 #define GEN_ABI() \ 33 do { \ 34 if (lua_pcall(L, 0, 0, 0) != 0) { \ 35 return lua_tostring(L, -1); \ 36 } \ 37 lua_getfield(L, LUA_GLOBALSINDEX, "abi"); \ 38 lua_getfield(L, -1, "autoload"); \ 39 if (lua_pcall(L, 0, 0, 0) != 0) { \ 40 return lua_tostring(L, -1); \ 41 } \ 42 lua_getfield(L, -1, "generate"); \ 43 if (lua_pcall(L, 0, 1, 0) != 0) { \ 44 return lua_tostring(L, -1); \ 45 } \ 46 if (!lua_isstring(L, -1)) { \ 47 return "empty ABI string"; \ 48 } \ 49 } while(0) 50 51 const char *vm_compile(lua_State *L, const char *code, const char *byte, const char *abi) 52 { 53 FILE *f = NULL; 54 55 if (luaL_loadfile(L, code) != 0) { 56 return lua_tostring(L, -1); 57 } 58 f = fopen(byte, "wb"); 59 if (f == NULL) { 60 return "cannot open a bytecode file"; 61 } 62 if (lua_dump(L, kpt_lua_Writer, f) != 0) { 63 fclose(f); 64 return lua_tostring(L, -1); 65 } 66 fclose(f); 67 68 if (abi != NULL && strlen(abi) > 0) { 69 f = fopen(abi, "wb"); 70 if (f == NULL) { 71 return "cannot open a abi file"; 72 } 73 GEN_ABI(); 74 fwrite((char *)lua_tostring(L, -1), 1, lua_strlen(L, -1), f); 75 fclose(f); 76 } 77 78 return NULL; 79 } 80 81 static int writer_buf(lua_State *L, const void *p, size_t size, void *b) 82 { 83 luaL_addlstring((luaL_Buffer *)b, (const char *)p, size); 84 return 0; 85 } 86 87 const char *vm_loadfile(lua_State *L, const char *code) 88 { 89 if (luaL_loadfile(L, code) != 0) { 90 return lua_tostring(L, -1); 91 } 92 return NULL; 93 } 94 95 const char *vm_loadstring(lua_State *L, const char *code) 96 { 97 if (luaL_loadstring(L, code) != 0) { 98 return lua_tostring(L, -1); 99 } 100 return NULL; 101 } 102 103 const char *vm_stringdump(lua_State *L) 104 { 105 luaL_Buffer b; 106 107 luaL_buffinit(L, &b); 108 if (lua_dump(L, writer_buf, &b) != 0) { 109 return lua_tostring(L, -1); 110 } 111 luaL_pushresult(&b); /* code dump */ 112 if (!lua_isstring(L, -1)) { 113 return "empty bytecode"; 114 } 115 lua_pushvalue(L, -2); /* code dump code */ 116 GEN_ABI(); /* code dump code abi */ 117 lua_remove(L, -2); /* code dump abi */ 118 return NULL; 119 } 120