ljx

FORK: LuaJIT with native 5.2 and 5.3 support
git clone https://git.neptards.moe/neptards/ljx.git
Log | Files | Refs | README

lj_load.c (4251B)


      1 /*
      2 ** Load and dump code.
      3 ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
      4 */
      5 
      6 #include <errno.h>
      7 #include <stdio.h>
      8 
      9 #define lj_load_c
     10 #define LUA_CORE
     11 
     12 #include "lua.h"
     13 #include "lauxlib.h"
     14 
     15 #include "lj_obj.h"
     16 #include "lj_gc.h"
     17 #include "lj_err.h"
     18 #include "lj_buf.h"
     19 #include "lj_func.h"
     20 #include "lj_frame.h"
     21 #include "lj_vm.h"
     22 #include "lj_lex.h"
     23 #include "lj_bcdump.h"
     24 #include "lj_parse.h"
     25 
     26 /* -- Load Lua source code and bytecode ----------------------------------- */
     27 
     28 static TValue *cpparser(lua_State *L, lua_CFunction dummy, void *ud)
     29 {
     30   LexState *ls = (LexState *)ud;
     31   GCproto *pt;
     32   GCfunc *fn;
     33   int bc;
     34   UNUSED(dummy);
     35   cframe_errfunc(L->cframe) = -1;  /* Inherit error function. */
     36   bc = lj_lex_setup(L, ls);
     37   if (ls->mode && !strchr(ls->mode, bc ? 'b' : 't')) {
     38     lj_err_pushv(L, LJ_ERR_XMODE, bc ? "binary" : "text", ls->mode);
     39     lj_err_throw(L, LUA_ERRSYNTAX);
     40   }
     41   pt = bc ? lj_bcread(ls) : lj_parse(ls);
     42   fn = lj_func_newL_empty(L, pt, tabref(L->env));
     43   /* Don't combine above/below into one statement. */
     44   setfuncV(L, L->top++, fn);
     45   return NULL;
     46 }
     47 
     48 LUA_API int lua_loadx(lua_State *L, lua_Reader reader, void *data,
     49 		      const char *chunkname, const char *mode)
     50 {
     51   LexState ls;
     52   int status;
     53   ls.rfunc = reader;
     54   ls.rdata = data;
     55   ls.chunkarg = chunkname ? chunkname : "?";
     56   ls.mode = mode;
     57   lj_buf_init(L, &ls.sb);
     58   status = lj_vm_cpcall(L, NULL, &ls, cpparser);
     59   lj_lex_cleanup(L, &ls);
     60   lj_gc_check(L);
     61   return status;
     62 }
     63 
     64 LUA_API int lua_load(lua_State *L, lua_Reader reader, void *data,
     65 		     const char *chunkname
     66 #if LJ_ABIVER != 51
     67 		     , const char *mode
     68 #endif
     69 		     )
     70 {
     71   return lua_loadx(L, reader, data, chunkname,
     72 #if LJ_ABIVER != 51
     73                    mode
     74 #else
     75                    NULL
     76 #endif
     77       );
     78 }
     79 
     80 typedef struct FileReaderCtx {
     81   FILE *fp;
     82   char buf[LUAL_BUFFERSIZE];
     83 } FileReaderCtx;
     84 
     85 static const char *reader_file(lua_State *L, void *ud, size_t *size)
     86 {
     87   FileReaderCtx *ctx = (FileReaderCtx *)ud;
     88   UNUSED(L);
     89   if (feof(ctx->fp)) return NULL;
     90   *size = fread(ctx->buf, 1, sizeof(ctx->buf), ctx->fp);
     91   return *size > 0 ? ctx->buf : NULL;
     92 }
     93 
     94 LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename,
     95 			      const char *mode)
     96 {
     97   FileReaderCtx ctx;
     98   int status;
     99   const char *chunkname;
    100   if (filename) {
    101     ctx.fp = fopen(filename, "rb");
    102     if (ctx.fp == NULL) {
    103       lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno));
    104       return LUA_ERRFILE;
    105     }
    106     chunkname = lua_pushfstring(L, "@%s", filename);
    107   } else {
    108     ctx.fp = stdin;
    109     chunkname = "=stdin";
    110   }
    111   status = lua_loadx(L, reader_file, &ctx, chunkname, mode);
    112   if (ferror(ctx.fp)) {
    113     L->top -= filename ? 2 : 1;
    114     lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(errno));
    115     if (filename)
    116       fclose(ctx.fp);
    117     return LUA_ERRFILE;
    118   }
    119   if (filename) {
    120     L->top--;
    121     copyTV(L, L->top-1, L->top);
    122     fclose(ctx.fp);
    123   }
    124   return status;
    125 }
    126 
    127 LUALIB_API int luaL_loadfile(lua_State *L, const char *filename)
    128 {
    129   return luaL_loadfilex(L, filename, NULL);
    130 }
    131 
    132 typedef struct StringReaderCtx {
    133   const char *str;
    134   size_t size;
    135 } StringReaderCtx;
    136 
    137 static const char *reader_string(lua_State *L, void *ud, size_t *size)
    138 {
    139   StringReaderCtx *ctx = (StringReaderCtx *)ud;
    140   UNUSED(L);
    141   if (ctx->size == 0) return NULL;
    142   *size = ctx->size;
    143   ctx->size = 0;
    144   return ctx->str;
    145 }
    146 
    147 LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buf, size_t size,
    148 				const char *name, const char *mode)
    149 {
    150   StringReaderCtx ctx;
    151   ctx.str = buf;
    152   ctx.size = size;
    153   return lua_loadx(L, reader_string, &ctx, name, mode);
    154 }
    155 
    156 LUALIB_API int luaL_loadbuffer(lua_State *L, const char *buf, size_t size,
    157 			       const char *name)
    158 {
    159   return luaL_loadbufferx(L, buf, size, name, NULL);
    160 }
    161 
    162 LUALIB_API int luaL_loadstring(lua_State *L, const char *s)
    163 {
    164   return luaL_loadbuffer(L, s, strlen(s), s);
    165 }
    166 
    167 /* -- Dump bytecode ------------------------------------------------------- */
    168 
    169 LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data)
    170 {
    171   cTValue *o = L->top-1;
    172   api_check(L, L->top > L->base);
    173   if (tvisfunc(o) && isluafunc(funcV(o)))
    174     return lj_bcwrite(L, funcproto(funcV(o)), writer, data, 0);
    175   else
    176     return 1;
    177 }
    178