Mercurial
comparison third_party/luajit/src/lj_load.c @ 186:8cf4ec5e2191 hg-web
Fixed merge conflict.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 23 Jan 2026 22:38:59 -0800 |
| parents | 94705b5986b3 |
| children |
comparison
equal
deleted
inserted
replaced
| 176:fed99fc04e12 | 186:8cf4ec5e2191 |
|---|---|
| 1 /* | |
| 2 ** Load and dump code. | |
| 3 ** Copyright (C) 2005-2023 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 setstrV(L, L->top++, lj_err_str(L, LJ_ERR_XMODE)); | |
| 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 { | |
| 67 return lua_loadx(L, reader, data, chunkname, NULL); | |
| 68 } | |
| 69 | |
| 70 typedef struct FileReaderCtx { | |
| 71 FILE *fp; | |
| 72 char buf[LUAL_BUFFERSIZE]; | |
| 73 } FileReaderCtx; | |
| 74 | |
| 75 static const char *reader_file(lua_State *L, void *ud, size_t *size) | |
| 76 { | |
| 77 FileReaderCtx *ctx = (FileReaderCtx *)ud; | |
| 78 UNUSED(L); | |
| 79 if (feof(ctx->fp)) return NULL; | |
| 80 *size = fread(ctx->buf, 1, sizeof(ctx->buf), ctx->fp); | |
| 81 return *size > 0 ? ctx->buf : NULL; | |
| 82 } | |
| 83 | |
| 84 LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename, | |
| 85 const char *mode) | |
| 86 { | |
| 87 FileReaderCtx ctx; | |
| 88 int status; | |
| 89 const char *chunkname; | |
| 90 if (filename) { | |
| 91 ctx.fp = fopen(filename, "rb"); | |
| 92 if (ctx.fp == NULL) { | |
| 93 lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno)); | |
| 94 return LUA_ERRFILE; | |
| 95 } | |
| 96 chunkname = lua_pushfstring(L, "@%s", filename); | |
| 97 } else { | |
| 98 ctx.fp = stdin; | |
| 99 chunkname = "=stdin"; | |
| 100 } | |
| 101 status = lua_loadx(L, reader_file, &ctx, chunkname, mode); | |
| 102 if (ferror(ctx.fp)) { | |
| 103 L->top -= filename ? 2 : 1; | |
| 104 lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(errno)); | |
| 105 if (filename) | |
| 106 fclose(ctx.fp); | |
| 107 return LUA_ERRFILE; | |
| 108 } | |
| 109 if (filename) { | |
| 110 L->top--; | |
| 111 copyTV(L, L->top-1, L->top); | |
| 112 fclose(ctx.fp); | |
| 113 } | |
| 114 return status; | |
| 115 } | |
| 116 | |
| 117 LUALIB_API int luaL_loadfile(lua_State *L, const char *filename) | |
| 118 { | |
| 119 return luaL_loadfilex(L, filename, NULL); | |
| 120 } | |
| 121 | |
| 122 typedef struct StringReaderCtx { | |
| 123 const char *str; | |
| 124 size_t size; | |
| 125 } StringReaderCtx; | |
| 126 | |
| 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 | |
| 137 LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buf, size_t size, | |
| 138 const char *name, const char *mode) | |
| 139 { | |
| 140 StringReaderCtx ctx; | |
| 141 ctx.str = buf; | |
| 142 ctx.size = size; | |
| 143 return lua_loadx(L, reader_string, &ctx, name, mode); | |
| 144 } | |
| 145 | |
| 146 LUALIB_API int luaL_loadbuffer(lua_State *L, const char *buf, size_t size, | |
| 147 const char *name) | |
| 148 { | |
| 149 return luaL_loadbufferx(L, buf, size, name, NULL); | |
| 150 } | |
| 151 | |
| 152 LUALIB_API int luaL_loadstring(lua_State *L, const char *s) | |
| 153 { | |
| 154 return luaL_loadbuffer(L, s, strlen(s), s); | |
| 155 } | |
| 156 | |
| 157 /* -- Dump bytecode ------------------------------------------------------- */ | |
| 158 | |
| 159 LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data) | |
| 160 { | |
| 161 cTValue *o = L->top-1; | |
| 162 lj_checkapi(L->top > L->base, "top slot empty"); | |
| 163 if (tvisfunc(o) && isluafunc(funcV(o))) | |
| 164 return lj_bcwrite(L, funcproto(funcV(o)), writer, data, 0); | |
| 165 else | |
| 166 return 1; | |
| 167 } | |
| 168 |