lj_load.c 4.4 KB

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