|
@@ -0,0 +1,168 @@
|
|
|
|
+/*
|
|
|
|
+** Load and dump code.
|
|
|
|
+** Copyright (C) 2005-2012 Mike Pall. See Copyright Notice in luajit.h
|
|
|
|
+*/
|
|
|
|
+
|
|
|
|
+#include <errno.h>
|
|
|
|
+#include <stdio.h>
|
|
|
|
+
|
|
|
|
+#define lj_load_c
|
|
|
|
+#define LUA_CORE
|
|
|
|
+
|
|
|
|
+#include "lua.h"
|
|
|
|
+#include "lauxlib.h"
|
|
|
|
+
|
|
|
|
+#include "lj_obj.h"
|
|
|
|
+#include "lj_gc.h"
|
|
|
|
+#include "lj_err.h"
|
|
|
|
+#include "lj_str.h"
|
|
|
|
+#include "lj_func.h"
|
|
|
|
+#include "lj_frame.h"
|
|
|
|
+#include "lj_vm.h"
|
|
|
|
+#include "lj_lex.h"
|
|
|
|
+#include "lj_bcdump.h"
|
|
|
|
+#include "lj_parse.h"
|
|
|
|
+
|
|
|
|
+/* -- Load Lua source code and bytecode ----------------------------------- */
|
|
|
|
+
|
|
|
|
+static TValue *cpparser(lua_State *L, lua_CFunction dummy, void *ud)
|
|
|
|
+{
|
|
|
|
+ LexState *ls = (LexState *)ud;
|
|
|
|
+ GCproto *pt;
|
|
|
|
+ GCfunc *fn;
|
|
|
|
+ int bc;
|
|
|
|
+ UNUSED(dummy);
|
|
|
|
+ cframe_errfunc(L->cframe) = -1; /* Inherit error function. */
|
|
|
|
+ bc = lj_lex_setup(L, ls);
|
|
|
|
+ if (ls->mode && !strchr(ls->mode, bc ? 'b' : 't')) {
|
|
|
|
+ setstrV(L, L->top++, lj_err_str(L, LJ_ERR_XMODE));
|
|
|
|
+ lj_err_throw(L, LUA_ERRSYNTAX);
|
|
|
|
+ }
|
|
|
|
+ pt = bc ? lj_bcread(ls) : lj_parse(ls);
|
|
|
|
+ fn = lj_func_newL_empty(L, pt, tabref(L->env));
|
|
|
|
+ /* Don't combine above/below into one statement. */
|
|
|
|
+ setfuncV(L, L->top++, fn);
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+LUA_API int lua_loadx(lua_State *L, lua_Reader reader, void *data,
|
|
|
|
+ const char *chunkname, const char *mode)
|
|
|
|
+{
|
|
|
|
+ LexState ls;
|
|
|
|
+ int status;
|
|
|
|
+ ls.rfunc = reader;
|
|
|
|
+ ls.rdata = data;
|
|
|
|
+ ls.chunkarg = chunkname ? chunkname : "?";
|
|
|
|
+ ls.mode = mode;
|
|
|
|
+ lj_str_initbuf(&ls.sb);
|
|
|
|
+ status = lj_vm_cpcall(L, NULL, &ls, cpparser);
|
|
|
|
+ lj_lex_cleanup(L, &ls);
|
|
|
|
+ lj_gc_check(L);
|
|
|
|
+ return status;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+LUA_API int lua_load(lua_State *L, lua_Reader reader, void *data,
|
|
|
|
+ const char *chunkname)
|
|
|
|
+{
|
|
|
|
+ return lua_loadx(L, reader, data, chunkname, NULL);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+typedef struct FileReaderCtx {
|
|
|
|
+ FILE *fp;
|
|
|
|
+ char buf[LUAL_BUFFERSIZE];
|
|
|
|
+} FileReaderCtx;
|
|
|
|
+
|
|
|
|
+static const char *reader_file(lua_State *L, void *ud, size_t *size)
|
|
|
|
+{
|
|
|
|
+ FileReaderCtx *ctx = (FileReaderCtx *)ud;
|
|
|
|
+ UNUSED(L);
|
|
|
|
+ if (feof(ctx->fp)) return NULL;
|
|
|
|
+ *size = fread(ctx->buf, 1, sizeof(ctx->buf), ctx->fp);
|
|
|
|
+ return *size > 0 ? ctx->buf : NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename,
|
|
|
|
+ const char *mode)
|
|
|
|
+{
|
|
|
|
+ FileReaderCtx ctx;
|
|
|
|
+ int status;
|
|
|
|
+ const char *chunkname;
|
|
|
|
+ if (filename) {
|
|
|
|
+ ctx.fp = fopen(filename, "rb");
|
|
|
|
+ if (ctx.fp == NULL) {
|
|
|
|
+ lua_pushfstring(L, "cannot open %s: %s", filename, strerror(errno));
|
|
|
|
+ return LUA_ERRFILE;
|
|
|
|
+ }
|
|
|
|
+ chunkname = lua_pushfstring(L, "@%s", filename);
|
|
|
|
+ } else {
|
|
|
|
+ ctx.fp = stdin;
|
|
|
|
+ chunkname = "=stdin";
|
|
|
|
+ }
|
|
|
|
+ status = lua_loadx(L, reader_file, &ctx, chunkname, mode);
|
|
|
|
+ if (ferror(ctx.fp)) {
|
|
|
|
+ L->top -= filename ? 2 : 1;
|
|
|
|
+ lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(errno));
|
|
|
|
+ if (filename)
|
|
|
|
+ fclose(ctx.fp);
|
|
|
|
+ return LUA_ERRFILE;
|
|
|
|
+ }
|
|
|
|
+ if (filename) {
|
|
|
|
+ L->top--;
|
|
|
|
+ copyTV(L, L->top-1, L->top);
|
|
|
|
+ fclose(ctx.fp);
|
|
|
|
+ }
|
|
|
|
+ return status;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+LUALIB_API int luaL_loadfile(lua_State *L, const char *filename)
|
|
|
|
+{
|
|
|
|
+ return luaL_loadfilex(L, filename, NULL);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+typedef struct StringReaderCtx {
|
|
|
|
+ const char *str;
|
|
|
|
+ size_t size;
|
|
|
|
+} StringReaderCtx;
|
|
|
|
+
|
|
|
|
+static const char *reader_string(lua_State *L, void *ud, size_t *size)
|
|
|
|
+{
|
|
|
|
+ StringReaderCtx *ctx = (StringReaderCtx *)ud;
|
|
|
|
+ UNUSED(L);
|
|
|
|
+ if (ctx->size == 0) return NULL;
|
|
|
|
+ *size = ctx->size;
|
|
|
|
+ ctx->size = 0;
|
|
|
|
+ return ctx->str;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buf, size_t size,
|
|
|
|
+ const char *name, const char *mode)
|
|
|
|
+{
|
|
|
|
+ StringReaderCtx ctx;
|
|
|
|
+ ctx.str = buf;
|
|
|
|
+ ctx.size = size;
|
|
|
|
+ return lua_loadx(L, reader_string, &ctx, name, mode);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+LUALIB_API int luaL_loadbuffer(lua_State *L, const char *buf, size_t size,
|
|
|
|
+ const char *name)
|
|
|
|
+{
|
|
|
|
+ return luaL_loadbufferx(L, buf, size, name, NULL);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+LUALIB_API int luaL_loadstring(lua_State *L, const char *s)
|
|
|
|
+{
|
|
|
|
+ return luaL_loadbuffer(L, s, strlen(s), s);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* -- Dump bytecode ------------------------------------------------------- */
|
|
|
|
+
|
|
|
|
+LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data)
|
|
|
|
+{
|
|
|
|
+ cTValue *o = L->top-1;
|
|
|
|
+ api_check(L, L->top > L->base);
|
|
|
|
+ if (tvisfunc(o) && isluafunc(funcV(o)))
|
|
|
|
+ return lj_bcwrite(L, funcproto(funcV(o)), writer, data, 0);
|
|
|
|
+ else
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|