Fix recording of __concat metamethod.
[luajit-2.0.git] / src / lj_load.c
blob152ef6daa86de7c387b6ddc1964a7f81b9c44ea6
1 /*
2 ** Load and dump code.
3 ** Copyright (C) 2005-2023 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 if (filename) {
105 ctx.fp = fopen(filename, "rb");
106 if (ctx.fp == NULL) {
107 lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno));
108 return LUA_ERRFILE;
110 chunkname = lua_pushfstring(L, "@%s", filename);
111 } else {
112 ctx.fp = stdin;
113 chunkname = "=stdin";
115 status = lua_loadx(L, reader_file, &ctx, chunkname, mode);
116 if (ferror(ctx.fp)) {
117 L->top -= filename ? 2 : 1;
118 lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(errno));
119 if (filename)
120 fclose(ctx.fp);
121 return LUA_ERRFILE;
123 if (filename) {
124 L->top--;
125 copyTV(L, L->top-1, L->top);
126 fclose(ctx.fp);
128 return status;
131 LUALIB_API int luaL_loadfile(lua_State *L, const char *filename)
133 return luaL_loadfilex(L, filename, NULL);
136 typedef struct StringReaderCtx {
137 const char *str;
138 size_t size;
139 } StringReaderCtx;
141 static const char *reader_string(lua_State *L, void *ud, size_t *size)
143 StringReaderCtx *ctx = (StringReaderCtx *)ud;
144 UNUSED(L);
145 if (ctx->size == 0) return NULL;
146 *size = ctx->size;
147 ctx->size = 0;
148 return ctx->str;
151 LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buf, size_t size,
152 const char *name, const char *mode)
154 StringReaderCtx ctx;
155 ctx.str = buf;
156 ctx.size = size;
157 return lua_loadx(L, reader_string, &ctx, name, mode);
160 LUALIB_API int luaL_loadbuffer(lua_State *L, const char *buf, size_t size,
161 const char *name)
163 return luaL_loadbufferx(L, buf, size, name, NULL);
166 LUALIB_API int luaL_loadstring(lua_State *L, const char *s)
168 return luaL_loadbuffer(L, s, strlen(s), s);
171 /* -- Dump bytecode ------------------------------------------------------- */
173 LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data)
175 cTValue *o = L->top-1;
176 uint32_t flags = LJ_FR2*BCDUMP_F_FR2; /* Default mode for legacy C API. */
177 lj_checkapi(L->top > L->base, "top slot empty");
178 if (tvisfunc(o) && isluafunc(funcV(o)))
179 return lj_bcwrite(L, funcproto(funcV(o)), writer, data, flags);
180 else
181 return 1;