diff options
Diffstat (limited to 'src/lj_load.c')
-rw-r--r-- | src/lj_load.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/lj_load.c b/src/lj_load.c new file mode 100644 index 00000000..e30421e6 --- /dev/null +++ b/src/lj_load.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | ** Load and dump code. | ||
3 | ** Copyright (C) 2005-2012 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_str.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_str_initbuf(&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 | api_check(L, L->top > L->base); | ||
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 | |||