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