Merge branch 'master' into v2.1
[luajit-2.0.git] / src / lj_load.c
blob24b660a8b152cf2443e62cf81d90a78290972f57
1 /*
2 ** Load and dump code.
3 ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice in luajit.h
4 */
6 #include <errno.h>
7 #include <stdio.h>
9 #define lj_load_c
10 #define LUA_CORE
12 #include "lua.h"
13 #include "lauxlib.h"
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"
26 /* -- Load Lua source code and bytecode ----------------------------------- */
28 static TValue *cpparser(lua_State *L, lua_CFunction dummy, void *ud)
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) {
38 int xmode = 1;
39 const char *mode = ls->mode;
40 char c;
41 while ((c = *mode++)) {
42 if (c == (bc ? 'b' : 't')) xmode = 0;
43 if (c == (LJ_FR2 ? 'W' : 'X')) ls->fr2 = !LJ_FR2;
45 if (xmode) {
46 setstrV(L, L->top++, lj_err_str(L, LJ_ERR_XMODE));
47 lj_err_throw(L, LUA_ERRSYNTAX);
50 pt = bc ? lj_bcread(ls) : lj_parse(ls);
51 if (ls->fr2 == LJ_FR2) {
52 fn = lj_func_newL_empty(L, pt, tabref(L->env));
53 /* Don't combine above/below into one statement. */
54 setfuncV(L, L->top++, fn);
55 } else {
56 /* Non-native generation returns a dumpable, but non-runnable prototype. */
57 setprotoV(L, L->top++, pt);
59 return NULL;
62 LUA_API int lua_loadx(lua_State *L, lua_Reader reader, void *data,
63 const char *chunkname, const char *mode)
65 LexState ls;
66 int status;
67 ls.rfunc = reader;
68 ls.rdata = data;
69 ls.chunkarg = chunkname ? chunkname : "?";
70 ls.mode = mode;
71 lj_buf_init(L, &ls.sb);
72 status = lj_vm_cpcall(L, NULL, &ls, cpparser);
73 lj_lex_cleanup(L, &ls);
74 lj_gc_check(L);
75 return status;
78 LUA_API int lua_load(lua_State *L, lua_Reader reader, void *data,
79 const char *chunkname)
81 return lua_loadx(L, reader, data, chunkname, NULL);
84 typedef struct FileReaderCtx {
85 FILE *fp;
86 char buf[LUAL_BUFFERSIZE];
87 } FileReaderCtx;
89 static const char *reader_file(lua_State *L, void *ud, size_t *size)
91 FileReaderCtx *ctx = (FileReaderCtx *)ud;
92 UNUSED(L);
93 if (feof(ctx->fp)) return NULL;
94 *size = fread(ctx->buf, 1, sizeof(ctx->buf), ctx->fp);
95 return *size > 0 ? ctx->buf : NULL;
98 LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename,
99 const char *mode)
101 FileReaderCtx ctx;
102 int status;
103 const char *chunkname;
104 int err = 0;
105 if (filename) {
106 chunkname = lua_pushfstring(L, "@%s", filename);
107 ctx.fp = fopen(filename, "rb");
108 if (ctx.fp == NULL) {
109 L->top--;
110 lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno));
111 return LUA_ERRFILE;
113 } else {
114 ctx.fp = stdin;
115 chunkname = "=stdin";
117 status = lua_loadx(L, reader_file, &ctx, chunkname, mode);
118 if (ferror(ctx.fp)) err = errno;
119 if (filename) {
120 fclose(ctx.fp);
121 L->top--;
122 copyTV(L, L->top-1, L->top);
124 if (err) {
125 const char *fname = filename ? filename : "stdin";
126 L->top--;
127 lua_pushfstring(L, "cannot read %s: %s", fname, strerror(err));
128 return LUA_ERRFILE;
130 return status;
133 LUALIB_API int luaL_loadfile(lua_State *L, const char *filename)
135 return luaL_loadfilex(L, filename, NULL);
138 typedef struct StringReaderCtx {
139 const char *str;
140 size_t size;
141 } StringReaderCtx;
143 static const char *reader_string(lua_State *L, void *ud, size_t *size)
145 StringReaderCtx *ctx = (StringReaderCtx *)ud;
146 UNUSED(L);
147 if (ctx->size == 0) return NULL;
148 *size = ctx->size;
149 ctx->size = 0;
150 return ctx->str;
153 LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buf, size_t size,
154 const char *name, const char *mode)
156 StringReaderCtx ctx;
157 ctx.str = buf;
158 ctx.size = size;
159 return lua_loadx(L, reader_string, &ctx, name, mode);
162 LUALIB_API int luaL_loadbuffer(lua_State *L, const char *buf, size_t size,
163 const char *name)
165 return luaL_loadbufferx(L, buf, size, name, NULL);
168 LUALIB_API int luaL_loadstring(lua_State *L, const char *s)
170 return luaL_loadbuffer(L, s, strlen(s), s);
173 /* -- Dump bytecode ------------------------------------------------------- */
175 LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data)
177 cTValue *o = L->top-1;
178 uint32_t flags = LJ_FR2*BCDUMP_F_FR2; /* Default mode for legacy C API. */
179 lj_checkapi(L->top > L->base, "top slot empty");
180 if (tvisfunc(o) && isluafunc(funcV(o)))
181 return lj_bcwrite(L, funcproto(funcV(o)), writer, data, flags);
182 else
183 return 1;