diff options
Diffstat (limited to 'libraries/luajit-2.0/src/lj_err.c')
-rw-r--r-- | libraries/luajit-2.0/src/lj_err.c | 736 |
1 files changed, 0 insertions, 736 deletions
diff --git a/libraries/luajit-2.0/src/lj_err.c b/libraries/luajit-2.0/src/lj_err.c deleted file mode 100644 index b0f3e5c..0000000 --- a/libraries/luajit-2.0/src/lj_err.c +++ /dev/null | |||
@@ -1,736 +0,0 @@ | |||
1 | /* | ||
2 | ** Error handling. | ||
3 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | */ | ||
5 | |||
6 | #define lj_err_c | ||
7 | #define LUA_CORE | ||
8 | |||
9 | #include "lj_obj.h" | ||
10 | #include "lj_err.h" | ||
11 | #include "lj_debug.h" | ||
12 | #include "lj_str.h" | ||
13 | #include "lj_func.h" | ||
14 | #include "lj_state.h" | ||
15 | #include "lj_frame.h" | ||
16 | #include "lj_ff.h" | ||
17 | #include "lj_trace.h" | ||
18 | #include "lj_vm.h" | ||
19 | |||
20 | /* | ||
21 | ** LuaJIT can either use internal or external frame unwinding: | ||
22 | ** | ||
23 | ** - Internal frame unwinding (INT) is free-standing and doesn't require | ||
24 | ** any OS or library support. | ||
25 | ** | ||
26 | ** - External frame unwinding (EXT) uses the system-provided unwind handler. | ||
27 | ** | ||
28 | ** Pros and Cons: | ||
29 | ** | ||
30 | ** - EXT requires unwind tables for *all* functions on the C stack between | ||
31 | ** the pcall/catch and the error/throw. This is the default on x64, | ||
32 | ** but needs to be manually enabled on x86/PPC for non-C++ code. | ||
33 | ** | ||
34 | ** - INT is faster when actually throwing errors (but this happens rarely). | ||
35 | ** Setting up error handlers is zero-cost in any case. | ||
36 | ** | ||
37 | ** - EXT provides full interoperability with C++ exceptions. You can throw | ||
38 | ** Lua errors or C++ exceptions through a mix of Lua frames and C++ frames. | ||
39 | ** C++ destructors are called as needed. C++ exceptions caught by pcall | ||
40 | ** are converted to the string "C++ exception". Lua errors can be caught | ||
41 | ** with catch (...) in C++. | ||
42 | ** | ||
43 | ** - INT has only limited support for automatically catching C++ exceptions | ||
44 | ** on POSIX systems using DWARF2 stack unwinding. Other systems may use | ||
45 | ** the wrapper function feature. Lua errors thrown through C++ frames | ||
46 | ** cannot be caught by C++ code and C++ destructors are not run. | ||
47 | ** | ||
48 | ** EXT is the default on x64 systems, INT is the default on all other systems. | ||
49 | ** | ||
50 | ** EXT can be manually enabled on POSIX systems using GCC and DWARF2 stack | ||
51 | ** unwinding with -DLUAJIT_UNWIND_EXTERNAL. *All* C code must be compiled | ||
52 | ** with -funwind-tables (or -fexceptions). This includes LuaJIT itself (set | ||
53 | ** TARGET_CFLAGS), all of your C/Lua binding code, all loadable C modules | ||
54 | ** and all C libraries that have callbacks which may be used to call back | ||
55 | ** into Lua. C++ code must *not* be compiled with -fno-exceptions. | ||
56 | ** | ||
57 | ** EXT cannot be enabled on WIN32 since system exceptions use code-driven SEH. | ||
58 | ** EXT is mandatory on WIN64 since the calling convention has an abundance | ||
59 | ** of callee-saved registers (rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15). | ||
60 | ** EXT is mandatory on POSIX/x64 since the interpreter doesn't save r12/r13. | ||
61 | */ | ||
62 | |||
63 | #if defined(__GNUC__) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) | ||
64 | #define LJ_UNWIND_EXT 1 | ||
65 | #elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS | ||
66 | #define LJ_UNWIND_EXT 1 | ||
67 | #endif | ||
68 | |||
69 | /* -- Error messages ------------------------------------------------------ */ | ||
70 | |||
71 | /* Error message strings. */ | ||
72 | LJ_DATADEF const char *lj_err_allmsg = | ||
73 | #define ERRDEF(name, msg) msg "\0" | ||
74 | #include "lj_errmsg.h" | ||
75 | ; | ||
76 | |||
77 | /* -- Internal frame unwinding -------------------------------------------- */ | ||
78 | |||
79 | /* Unwind Lua stack and move error message to new top. */ | ||
80 | LJ_NOINLINE static void unwindstack(lua_State *L, TValue *top) | ||
81 | { | ||
82 | lj_func_closeuv(L, top); | ||
83 | if (top < L->top-1) { | ||
84 | copyTV(L, top, L->top-1); | ||
85 | L->top = top+1; | ||
86 | } | ||
87 | lj_state_relimitstack(L); | ||
88 | } | ||
89 | |||
90 | /* Unwind until stop frame. Optionally cleanup frames. */ | ||
91 | static void *err_unwind(lua_State *L, void *stopcf, int errcode) | ||
92 | { | ||
93 | TValue *frame = L->base-1; | ||
94 | void *cf = L->cframe; | ||
95 | while (cf) { | ||
96 | int32_t nres = cframe_nres(cframe_raw(cf)); | ||
97 | if (nres < 0) { /* C frame without Lua frame? */ | ||
98 | TValue *top = restorestack(L, -nres); | ||
99 | if (frame < top) { /* Frame reached? */ | ||
100 | if (errcode) { | ||
101 | L->cframe = cframe_prev(cf); | ||
102 | L->base = frame+1; | ||
103 | unwindstack(L, top); | ||
104 | } | ||
105 | return cf; | ||
106 | } | ||
107 | } | ||
108 | if (frame <= tvref(L->stack)) | ||
109 | break; | ||
110 | switch (frame_typep(frame)) { | ||
111 | case FRAME_LUA: /* Lua frame. */ | ||
112 | case FRAME_LUAP: | ||
113 | frame = frame_prevl(frame); | ||
114 | break; | ||
115 | case FRAME_C: /* C frame. */ | ||
116 | #if LJ_HASFFI | ||
117 | unwind_c: | ||
118 | #endif | ||
119 | #if LJ_UNWIND_EXT | ||
120 | if (errcode) { | ||
121 | L->cframe = cframe_prev(cf); | ||
122 | L->base = frame_prevd(frame) + 1; | ||
123 | unwindstack(L, frame); | ||
124 | } else if (cf != stopcf) { | ||
125 | cf = cframe_prev(cf); | ||
126 | frame = frame_prevd(frame); | ||
127 | break; | ||
128 | } | ||
129 | return NULL; /* Continue unwinding. */ | ||
130 | #else | ||
131 | UNUSED(stopcf); | ||
132 | cf = cframe_prev(cf); | ||
133 | frame = frame_prevd(frame); | ||
134 | break; | ||
135 | #endif | ||
136 | case FRAME_CP: /* Protected C frame. */ | ||
137 | if (cframe_canyield(cf)) { /* Resume? */ | ||
138 | if (errcode) { | ||
139 | L->cframe = NULL; | ||
140 | L->status = (uint8_t)errcode; | ||
141 | } | ||
142 | return cf; | ||
143 | } | ||
144 | if (errcode) { | ||
145 | L->cframe = cframe_prev(cf); | ||
146 | L->base = frame_prevd(frame) + 1; | ||
147 | unwindstack(L, frame); | ||
148 | } | ||
149 | return cf; | ||
150 | case FRAME_CONT: /* Continuation frame. */ | ||
151 | #if LJ_HASFFI | ||
152 | if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) | ||
153 | goto unwind_c; | ||
154 | #endif | ||
155 | case FRAME_VARG: /* Vararg frame. */ | ||
156 | frame = frame_prevd(frame); | ||
157 | break; | ||
158 | case FRAME_PCALL: /* FF pcall() frame. */ | ||
159 | case FRAME_PCALLH: /* FF pcall() frame inside hook. */ | ||
160 | if (errcode) { | ||
161 | if (errcode == LUA_YIELD) { | ||
162 | frame = frame_prevd(frame); | ||
163 | break; | ||
164 | } | ||
165 | if (frame_typep(frame) == FRAME_PCALL) | ||
166 | hook_leave(G(L)); | ||
167 | L->cframe = cf; | ||
168 | L->base = frame_prevd(frame) + 1; | ||
169 | unwindstack(L, L->base); | ||
170 | } | ||
171 | return (void *)((intptr_t)cf | CFRAME_UNWIND_FF); | ||
172 | } | ||
173 | } | ||
174 | /* No C frame. */ | ||
175 | if (errcode) { | ||
176 | L->cframe = NULL; | ||
177 | L->base = tvref(L->stack)+1; | ||
178 | unwindstack(L, L->base); | ||
179 | if (G(L)->panic) | ||
180 | G(L)->panic(L); | ||
181 | exit(EXIT_FAILURE); | ||
182 | } | ||
183 | return L; /* Anything non-NULL will do. */ | ||
184 | } | ||
185 | |||
186 | /* -- External frame unwinding -------------------------------------------- */ | ||
187 | |||
188 | #if defined(__GNUC__) && !defined(LUAJIT_NO_UNWIND) | ||
189 | |||
190 | #ifdef __clang__ | ||
191 | /* http://llvm.org/bugs/show_bug.cgi?id=8703 */ | ||
192 | #define __unwind_word__ word | ||
193 | #endif | ||
194 | |||
195 | #include <unwind.h> | ||
196 | |||
197 | #if !LJ_TARGET_ARM | ||
198 | |||
199 | #define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */ | ||
200 | #define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (uint64_t)(c)) | ||
201 | #define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff) | ||
202 | #define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff)) | ||
203 | |||
204 | /* DWARF2 personality handler referenced from interpreter .eh_frame. */ | ||
205 | LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, | ||
206 | uint64_t uexclass, struct _Unwind_Exception *uex, | ||
207 | struct _Unwind_Context *ctx) | ||
208 | { | ||
209 | void *cf; | ||
210 | lua_State *L; | ||
211 | if (version != 1) | ||
212 | return _URC_FATAL_PHASE1_ERROR; | ||
213 | UNUSED(uexclass); | ||
214 | cf = (void *)_Unwind_GetCFA(ctx); | ||
215 | L = cframe_L(cf); | ||
216 | if ((actions & _UA_SEARCH_PHASE)) { | ||
217 | #if LJ_UNWIND_EXT | ||
218 | if (err_unwind(L, cf, 0) == NULL) | ||
219 | return _URC_CONTINUE_UNWIND; | ||
220 | #endif | ||
221 | if (!LJ_UEXCLASS_CHECK(uexclass)) { | ||
222 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); | ||
223 | } | ||
224 | return _URC_HANDLER_FOUND; | ||
225 | } | ||
226 | if ((actions & _UA_CLEANUP_PHASE)) { | ||
227 | int errcode; | ||
228 | if (LJ_UEXCLASS_CHECK(uexclass)) { | ||
229 | errcode = LJ_UEXCLASS_ERRCODE(uexclass); | ||
230 | } else { | ||
231 | if ((actions & _UA_HANDLER_FRAME)) | ||
232 | _Unwind_DeleteException(uex); | ||
233 | errcode = LUA_ERRRUN; | ||
234 | } | ||
235 | #if LJ_UNWIND_EXT | ||
236 | cf = err_unwind(L, cf, errcode); | ||
237 | if ((actions & _UA_FORCE_UNWIND)) { | ||
238 | return _URC_CONTINUE_UNWIND; | ||
239 | } else if (cf) { | ||
240 | _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode); | ||
241 | _Unwind_SetIP(ctx, (uintptr_t)(cframe_unwind_ff(cf) ? | ||
242 | lj_vm_unwind_ff_eh : | ||
243 | lj_vm_unwind_c_eh)); | ||
244 | return _URC_INSTALL_CONTEXT; | ||
245 | } | ||
246 | #if LJ_TARGET_X86ORX64 | ||
247 | else if ((actions & _UA_HANDLER_FRAME)) { | ||
248 | /* Workaround for ancient libgcc bug. Still present in RHEL 5.5. :-/ | ||
249 | ** Real fix: http://gcc.gnu.org/viewcvs/trunk/gcc/unwind-dw2.c?r1=121165&r2=124837&pathrev=153877&diff_format=h | ||
250 | */ | ||
251 | _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode); | ||
252 | _Unwind_SetIP(ctx, (uintptr_t)lj_vm_unwind_rethrow); | ||
253 | return _URC_INSTALL_CONTEXT; | ||
254 | } | ||
255 | #endif | ||
256 | #else | ||
257 | /* This is not the proper way to escape from the unwinder. We get away with | ||
258 | ** it on x86/PPC because the interpreter restores all callee-saved regs. | ||
259 | */ | ||
260 | lj_err_throw(L, errcode); | ||
261 | #endif | ||
262 | } | ||
263 | return _URC_CONTINUE_UNWIND; | ||
264 | } | ||
265 | |||
266 | #if LJ_UNWIND_EXT | ||
267 | #if LJ_TARGET_OSX | ||
268 | /* Sorry, no thread safety for OSX. Complain to Apple, not me. */ | ||
269 | static struct _Unwind_Exception static_uex; | ||
270 | #else | ||
271 | static __thread struct _Unwind_Exception static_uex; | ||
272 | #endif | ||
273 | |||
274 | /* Raise DWARF2 exception. */ | ||
275 | static void err_raise_ext(int errcode) | ||
276 | { | ||
277 | static_uex.exception_class = LJ_UEXCLASS_MAKE(errcode); | ||
278 | static_uex.exception_cleanup = NULL; | ||
279 | _Unwind_RaiseException(&static_uex); | ||
280 | } | ||
281 | #endif | ||
282 | |||
283 | #else | ||
284 | |||
285 | /* ARM unwinder personality handler referenced from interpreter .ARM.extab. */ | ||
286 | LJ_FUNCA _Unwind_Reason_Code lj_err_unwind_arm(_Unwind_State state, | ||
287 | _Unwind_Control_Block *ucb, | ||
288 | _Unwind_Context *ctx) | ||
289 | { | ||
290 | void *cf = (void *)_Unwind_GetGR(ctx, 13); | ||
291 | lua_State *L = cframe_L(cf); | ||
292 | if ((state & _US_ACTION_MASK) == _US_VIRTUAL_UNWIND_FRAME) { | ||
293 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); | ||
294 | return _URC_HANDLER_FOUND; | ||
295 | } | ||
296 | if ((state&(_US_ACTION_MASK|_US_FORCE_UNWIND)) == _US_UNWIND_FRAME_STARTING) { | ||
297 | _Unwind_DeleteException(ucb); | ||
298 | _Unwind_SetGR(ctx, 15, (_Unwind_Word)(void *)lj_err_throw); | ||
299 | _Unwind_SetGR(ctx, 0, (_Unwind_Word)L); | ||
300 | _Unwind_SetGR(ctx, 1, (_Unwind_Word)LUA_ERRRUN); | ||
301 | return _URC_INSTALL_CONTEXT; | ||
302 | } | ||
303 | if (__gnu_unwind_frame(ucb, ctx) != _URC_OK) | ||
304 | return _URC_FAILURE; | ||
305 | return _URC_CONTINUE_UNWIND; | ||
306 | } | ||
307 | |||
308 | #endif | ||
309 | |||
310 | #elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS | ||
311 | |||
312 | /* | ||
313 | ** Someone in Redmond owes me several days of my life. A lot of this is | ||
314 | ** undocumented or just plain wrong on MSDN. Some of it can be gathered | ||
315 | ** from 3rd party docs or must be found by trial-and-error. They really | ||
316 | ** don't want you to write your own language-specific exception handler | ||
317 | ** or to interact gracefully with MSVC. :-( | ||
318 | ** | ||
319 | ** Apparently MSVC doesn't call C++ destructors for foreign exceptions | ||
320 | ** unless you compile your C++ code with /EHa. Unfortunately this means | ||
321 | ** catch (...) also catches things like access violations. The use of | ||
322 | ** _set_se_translator doesn't really help, because it requires /EHa, too. | ||
323 | */ | ||
324 | |||
325 | #define WIN32_LEAN_AND_MEAN | ||
326 | #include <windows.h> | ||
327 | |||
328 | /* Taken from: http://www.nynaeve.net/?p=99 */ | ||
329 | typedef struct UndocumentedDispatcherContext { | ||
330 | ULONG64 ControlPc; | ||
331 | ULONG64 ImageBase; | ||
332 | PRUNTIME_FUNCTION FunctionEntry; | ||
333 | ULONG64 EstablisherFrame; | ||
334 | ULONG64 TargetIp; | ||
335 | PCONTEXT ContextRecord; | ||
336 | PEXCEPTION_ROUTINE LanguageHandler; | ||
337 | PVOID HandlerData; | ||
338 | PUNWIND_HISTORY_TABLE HistoryTable; | ||
339 | ULONG ScopeIndex; | ||
340 | ULONG Fill0; | ||
341 | } UndocumentedDispatcherContext; | ||
342 | |||
343 | #ifdef _MSC_VER | ||
344 | /* Another wild guess. */ | ||
345 | extern __DestructExceptionObject(EXCEPTION_RECORD *rec, int nothrow); | ||
346 | #endif | ||
347 | |||
348 | #define LJ_MSVC_EXCODE ((DWORD)0xe06d7363) | ||
349 | |||
350 | #define LJ_EXCODE ((DWORD)0xe24c4a00) | ||
351 | #define LJ_EXCODE_MAKE(c) (LJ_EXCODE | (DWORD)(c)) | ||
352 | #define LJ_EXCODE_CHECK(cl) (((cl) ^ LJ_EXCODE) <= 0xff) | ||
353 | #define LJ_EXCODE_ERRCODE(cl) ((int)((cl) & 0xff)) | ||
354 | |||
355 | /* Win64 exception handler for interpreter frame. */ | ||
356 | LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec, | ||
357 | void *cf, CONTEXT *ctx, UndocumentedDispatcherContext *dispatch) | ||
358 | { | ||
359 | lua_State *L = cframe_L(cf); | ||
360 | int errcode = LJ_EXCODE_CHECK(rec->ExceptionCode) ? | ||
361 | LJ_EXCODE_ERRCODE(rec->ExceptionCode) : LUA_ERRRUN; | ||
362 | if ((rec->ExceptionFlags & 6)) { /* EH_UNWINDING|EH_EXIT_UNWIND */ | ||
363 | /* Unwind internal frames. */ | ||
364 | err_unwind(L, cf, errcode); | ||
365 | } else { | ||
366 | void *cf2 = err_unwind(L, cf, 0); | ||
367 | if (cf2) { /* We catch it, so start unwinding the upper frames. */ | ||
368 | if (rec->ExceptionCode == LJ_MSVC_EXCODE) { | ||
369 | #ifdef _MSC_VER | ||
370 | __DestructExceptionObject(rec, 1); | ||
371 | #endif | ||
372 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); | ||
373 | } else if (!LJ_EXCODE_CHECK(rec->ExceptionCode)) { | ||
374 | /* Don't catch access violations etc. */ | ||
375 | return ExceptionContinueSearch; | ||
376 | } | ||
377 | /* Unwind the stack and call all handlers for all lower C frames | ||
378 | ** (including ourselves) again with EH_UNWINDING set. Then set | ||
379 | ** rsp = cf, rax = errcode and jump to the specified target. | ||
380 | */ | ||
381 | RtlUnwindEx(cf, (void *)((cframe_unwind_ff(cf2) && errcode != LUA_YIELD) ? | ||
382 | lj_vm_unwind_ff_eh : | ||
383 | lj_vm_unwind_c_eh), | ||
384 | rec, (void *)errcode, ctx, dispatch->HistoryTable); | ||
385 | /* RtlUnwindEx should never return. */ | ||
386 | } | ||
387 | } | ||
388 | return ExceptionContinueSearch; | ||
389 | } | ||
390 | |||
391 | /* Raise Windows exception. */ | ||
392 | static void err_raise_ext(int errcode) | ||
393 | { | ||
394 | RaiseException(LJ_EXCODE_MAKE(errcode), 1 /* EH_NONCONTINUABLE */, 0, NULL); | ||
395 | } | ||
396 | |||
397 | #endif | ||
398 | |||
399 | /* -- Error handling ------------------------------------------------------ */ | ||
400 | |||
401 | /* Throw error. Find catch frame, unwind stack and continue. */ | ||
402 | LJ_NOINLINE void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode) | ||
403 | { | ||
404 | global_State *g = G(L); | ||
405 | lj_trace_abort(g); | ||
406 | setgcrefnull(g->jit_L); | ||
407 | L->status = 0; | ||
408 | #if LJ_UNWIND_EXT | ||
409 | err_raise_ext(errcode); | ||
410 | /* | ||
411 | ** A return from this function signals a corrupt C stack that cannot be | ||
412 | ** unwound. We have no choice but to call the panic function and exit. | ||
413 | ** | ||
414 | ** Usually this is caused by a C function without unwind information. | ||
415 | ** This should never happen on x64, but may happen if you've manually | ||
416 | ** enabled LUAJIT_UNWIND_EXTERNAL and forgot to recompile *every* | ||
417 | ** non-C++ file with -funwind-tables. | ||
418 | */ | ||
419 | if (G(L)->panic) | ||
420 | G(L)->panic(L); | ||
421 | #else | ||
422 | { | ||
423 | void *cf = err_unwind(L, NULL, errcode); | ||
424 | if (cframe_unwind_ff(cf)) | ||
425 | lj_vm_unwind_ff(cframe_raw(cf)); | ||
426 | else | ||
427 | lj_vm_unwind_c(cframe_raw(cf), errcode); | ||
428 | } | ||
429 | #endif | ||
430 | exit(EXIT_FAILURE); | ||
431 | } | ||
432 | |||
433 | /* Return string object for error message. */ | ||
434 | LJ_NOINLINE GCstr *lj_err_str(lua_State *L, ErrMsg em) | ||
435 | { | ||
436 | return lj_str_newz(L, err2msg(em)); | ||
437 | } | ||
438 | |||
439 | /* Out-of-memory error. */ | ||
440 | LJ_NOINLINE void lj_err_mem(lua_State *L) | ||
441 | { | ||
442 | if (L->status == LUA_ERRERR+1) /* Don't touch the stack during lua_open. */ | ||
443 | lj_vm_unwind_c(L->cframe, LUA_ERRMEM); | ||
444 | L->top = L->base; | ||
445 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM)); | ||
446 | lj_err_throw(L, LUA_ERRMEM); | ||
447 | } | ||
448 | |||
449 | /* Find error function for runtime errors. Requires an extra stack traversal. */ | ||
450 | static ptrdiff_t finderrfunc(lua_State *L) | ||
451 | { | ||
452 | cTValue *frame = L->base-1, *bot = tvref(L->stack); | ||
453 | void *cf = L->cframe; | ||
454 | while (frame > bot) { | ||
455 | lua_assert(cf != NULL); | ||
456 | while (cframe_nres(cframe_raw(cf)) < 0) { /* cframe without frame? */ | ||
457 | if (frame >= restorestack(L, -cframe_nres(cf))) | ||
458 | break; | ||
459 | if (cframe_errfunc(cf) >= 0) /* Error handler not inherited (-1)? */ | ||
460 | return cframe_errfunc(cf); | ||
461 | cf = cframe_prev(cf); /* Else unwind cframe and continue searching. */ | ||
462 | if (cf == NULL) | ||
463 | return 0; | ||
464 | } | ||
465 | switch (frame_typep(frame)) { | ||
466 | case FRAME_LUA: | ||
467 | case FRAME_LUAP: | ||
468 | frame = frame_prevl(frame); | ||
469 | break; | ||
470 | case FRAME_C: | ||
471 | cf = cframe_prev(cf); | ||
472 | /* fallthrough */ | ||
473 | case FRAME_CONT: | ||
474 | #if LJ_HASFFI | ||
475 | if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) | ||
476 | cf = cframe_prev(cf); | ||
477 | #endif | ||
478 | case FRAME_VARG: | ||
479 | frame = frame_prevd(frame); | ||
480 | break; | ||
481 | case FRAME_CP: | ||
482 | if (cframe_canyield(cf)) return 0; | ||
483 | if (cframe_errfunc(cf) >= 0) | ||
484 | return cframe_errfunc(cf); | ||
485 | frame = frame_prevd(frame); | ||
486 | break; | ||
487 | case FRAME_PCALL: | ||
488 | case FRAME_PCALLH: | ||
489 | if (frame_ftsz(frame) >= (ptrdiff_t)(2*sizeof(TValue))) /* xpcall? */ | ||
490 | return savestack(L, frame-1); /* Point to xpcall's errorfunc. */ | ||
491 | return 0; | ||
492 | default: | ||
493 | lua_assert(0); | ||
494 | return 0; | ||
495 | } | ||
496 | } | ||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | /* Runtime error. */ | ||
501 | LJ_NOINLINE void lj_err_run(lua_State *L) | ||
502 | { | ||
503 | ptrdiff_t ef = finderrfunc(L); | ||
504 | if (ef) { | ||
505 | TValue *errfunc = restorestack(L, ef); | ||
506 | TValue *top = L->top; | ||
507 | lj_trace_abort(G(L)); | ||
508 | if (!tvisfunc(errfunc) || L->status == LUA_ERRERR) { | ||
509 | setstrV(L, top-1, lj_err_str(L, LJ_ERR_ERRERR)); | ||
510 | lj_err_throw(L, LUA_ERRERR); | ||
511 | } | ||
512 | L->status = LUA_ERRERR; | ||
513 | copyTV(L, top, top-1); | ||
514 | copyTV(L, top-1, errfunc); | ||
515 | L->top = top+1; | ||
516 | lj_vm_call(L, top, 1+1); /* Stack: |errfunc|msg| -> |msg| */ | ||
517 | } | ||
518 | lj_err_throw(L, LUA_ERRRUN); | ||
519 | } | ||
520 | |||
521 | /* Formatted runtime error message. */ | ||
522 | LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...) | ||
523 | { | ||
524 | const char *msg; | ||
525 | va_list argp; | ||
526 | va_start(argp, em); | ||
527 | if (curr_funcisL(L)) L->top = curr_topL(L); | ||
528 | msg = lj_str_pushvf(L, err2msg(em), argp); | ||
529 | va_end(argp); | ||
530 | lj_debug_addloc(L, msg, L->base-1, NULL); | ||
531 | lj_err_run(L); | ||
532 | } | ||
533 | |||
534 | /* Non-vararg variant for better calling conventions. */ | ||
535 | LJ_NOINLINE void lj_err_msg(lua_State *L, ErrMsg em) | ||
536 | { | ||
537 | err_msgv(L, em); | ||
538 | } | ||
539 | |||
540 | /* Lexer error. */ | ||
541 | LJ_NOINLINE void lj_err_lex(lua_State *L, GCstr *src, const char *tok, | ||
542 | BCLine line, ErrMsg em, va_list argp) | ||
543 | { | ||
544 | char buff[LUA_IDSIZE]; | ||
545 | const char *msg; | ||
546 | lj_debug_shortname(buff, src); | ||
547 | msg = lj_str_pushvf(L, err2msg(em), argp); | ||
548 | msg = lj_str_pushf(L, "%s:%d: %s", buff, line, msg); | ||
549 | if (tok) | ||
550 | lj_str_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tok); | ||
551 | lj_err_throw(L, LUA_ERRSYNTAX); | ||
552 | } | ||
553 | |||
554 | /* Typecheck error for operands. */ | ||
555 | LJ_NOINLINE void lj_err_optype(lua_State *L, cTValue *o, ErrMsg opm) | ||
556 | { | ||
557 | const char *tname = typename(o); | ||
558 | const char *opname = err2msg(opm); | ||
559 | if (curr_funcisL(L)) { | ||
560 | GCproto *pt = curr_proto(L); | ||
561 | const BCIns *pc = cframe_Lpc(L) - 1; | ||
562 | const char *oname = NULL; | ||
563 | const char *kind = lj_debug_slotname(pt, pc, (BCReg)(o-L->base), &oname); | ||
564 | if (kind) | ||
565 | err_msgv(L, LJ_ERR_BADOPRT, opname, kind, oname, tname); | ||
566 | } | ||
567 | err_msgv(L, LJ_ERR_BADOPRV, opname, tname); | ||
568 | } | ||
569 | |||
570 | /* Typecheck error for ordered comparisons. */ | ||
571 | LJ_NOINLINE void lj_err_comp(lua_State *L, cTValue *o1, cTValue *o2) | ||
572 | { | ||
573 | const char *t1 = typename(o1); | ||
574 | const char *t2 = typename(o2); | ||
575 | err_msgv(L, t1 == t2 ? LJ_ERR_BADCMPV : LJ_ERR_BADCMPT, t1, t2); | ||
576 | /* This assumes the two "boolean" entries are commoned by the C compiler. */ | ||
577 | } | ||
578 | |||
579 | /* Typecheck error for __call. */ | ||
580 | LJ_NOINLINE void lj_err_optype_call(lua_State *L, TValue *o) | ||
581 | { | ||
582 | /* Gross hack if lua_[p]call or pcall/xpcall fail for a non-callable object: | ||
583 | ** L->base still points to the caller. So add a dummy frame with L instead | ||
584 | ** of a function. See lua_getstack(). | ||
585 | */ | ||
586 | const BCIns *pc = cframe_Lpc(L); | ||
587 | if (((ptrdiff_t)pc & FRAME_TYPE) != FRAME_LUA) { | ||
588 | const char *tname = typename(o); | ||
589 | setframe_pc(o, pc); | ||
590 | setframe_gc(o, obj2gco(L)); | ||
591 | L->top = L->base = o+1; | ||
592 | err_msgv(L, LJ_ERR_BADCALL, tname); | ||
593 | } | ||
594 | lj_err_optype(L, o, LJ_ERR_OPCALL); | ||
595 | } | ||
596 | |||
597 | /* Error in context of caller. */ | ||
598 | LJ_NOINLINE void lj_err_callermsg(lua_State *L, const char *msg) | ||
599 | { | ||
600 | TValue *frame = L->base-1; | ||
601 | TValue *pframe = NULL; | ||
602 | if (frame_islua(frame)) { | ||
603 | pframe = frame_prevl(frame); | ||
604 | } else if (frame_iscont(frame)) { | ||
605 | #if LJ_HASFFI | ||
606 | if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) { | ||
607 | pframe = frame; | ||
608 | frame = NULL; | ||
609 | } else | ||
610 | #endif | ||
611 | { | ||
612 | pframe = frame_prevd(frame); | ||
613 | #if LJ_HASFFI | ||
614 | /* Remove frame for FFI metamethods. */ | ||
615 | if (frame_func(frame)->c.ffid >= FF_ffi_meta___index && | ||
616 | frame_func(frame)->c.ffid <= FF_ffi_meta___tostring) { | ||
617 | L->base = pframe+1; | ||
618 | L->top = frame; | ||
619 | } | ||
620 | #endif | ||
621 | } | ||
622 | } | ||
623 | lj_debug_addloc(L, msg, pframe, frame); | ||
624 | lj_err_run(L); | ||
625 | } | ||
626 | |||
627 | /* Formatted error in context of caller. */ | ||
628 | LJ_NOINLINE void lj_err_callerv(lua_State *L, ErrMsg em, ...) | ||
629 | { | ||
630 | const char *msg; | ||
631 | va_list argp; | ||
632 | va_start(argp, em); | ||
633 | msg = lj_str_pushvf(L, err2msg(em), argp); | ||
634 | va_end(argp); | ||
635 | lj_err_callermsg(L, msg); | ||
636 | } | ||
637 | |||
638 | /* Error in context of caller. */ | ||
639 | LJ_NOINLINE void lj_err_caller(lua_State *L, ErrMsg em) | ||
640 | { | ||
641 | lj_err_callermsg(L, err2msg(em)); | ||
642 | } | ||
643 | |||
644 | /* Argument error message. */ | ||
645 | LJ_NORET LJ_NOINLINE static void err_argmsg(lua_State *L, int narg, | ||
646 | const char *msg) | ||
647 | { | ||
648 | const char *fname = "?"; | ||
649 | const char *ftype = lj_debug_funcname(L, L->base - 1, &fname); | ||
650 | if (narg < 0 && narg > LUA_REGISTRYINDEX) | ||
651 | narg = (int)(L->top - L->base) + narg + 1; | ||
652 | if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */ | ||
653 | msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg); | ||
654 | else | ||
655 | msg = lj_str_pushf(L, err2msg(LJ_ERR_BADARG), narg, fname, msg); | ||
656 | lj_err_callermsg(L, msg); | ||
657 | } | ||
658 | |||
659 | /* Formatted argument error. */ | ||
660 | LJ_NOINLINE void lj_err_argv(lua_State *L, int narg, ErrMsg em, ...) | ||
661 | { | ||
662 | const char *msg; | ||
663 | va_list argp; | ||
664 | va_start(argp, em); | ||
665 | msg = lj_str_pushvf(L, err2msg(em), argp); | ||
666 | va_end(argp); | ||
667 | err_argmsg(L, narg, msg); | ||
668 | } | ||
669 | |||
670 | /* Argument error. */ | ||
671 | LJ_NOINLINE void lj_err_arg(lua_State *L, int narg, ErrMsg em) | ||
672 | { | ||
673 | err_argmsg(L, narg, err2msg(em)); | ||
674 | } | ||
675 | |||
676 | /* Typecheck error for arguments. */ | ||
677 | LJ_NOINLINE void lj_err_argtype(lua_State *L, int narg, const char *xname) | ||
678 | { | ||
679 | TValue *o = L->base + narg-1; | ||
680 | const char *tname = o < L->top ? typename(o) : lj_obj_typename[0]; | ||
681 | const char *msg = lj_str_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname); | ||
682 | err_argmsg(L, narg, msg); | ||
683 | } | ||
684 | |||
685 | /* Typecheck error for arguments. */ | ||
686 | LJ_NOINLINE void lj_err_argt(lua_State *L, int narg, int tt) | ||
687 | { | ||
688 | lj_err_argtype(L, narg, lj_obj_typename[tt+1]); | ||
689 | } | ||
690 | |||
691 | /* -- Public error handling API ------------------------------------------- */ | ||
692 | |||
693 | LUA_API lua_CFunction lua_atpanic(lua_State *L, lua_CFunction panicf) | ||
694 | { | ||
695 | lua_CFunction old = G(L)->panic; | ||
696 | G(L)->panic = panicf; | ||
697 | return old; | ||
698 | } | ||
699 | |||
700 | /* Forwarders for the public API (C calling convention and no LJ_NORET). */ | ||
701 | LUA_API int lua_error(lua_State *L) | ||
702 | { | ||
703 | lj_err_run(L); | ||
704 | return 0; /* unreachable */ | ||
705 | } | ||
706 | |||
707 | LUALIB_API int luaL_argerror(lua_State *L, int narg, const char *msg) | ||
708 | { | ||
709 | err_argmsg(L, narg, msg); | ||
710 | return 0; /* unreachable */ | ||
711 | } | ||
712 | |||
713 | LUALIB_API int luaL_typerror(lua_State *L, int narg, const char *xname) | ||
714 | { | ||
715 | lj_err_argtype(L, narg, xname); | ||
716 | return 0; /* unreachable */ | ||
717 | } | ||
718 | |||
719 | LUALIB_API void luaL_where(lua_State *L, int level) | ||
720 | { | ||
721 | int size; | ||
722 | cTValue *frame = lj_debug_frame(L, level, &size); | ||
723 | lj_debug_addloc(L, "", frame, size ? frame+size : NULL); | ||
724 | } | ||
725 | |||
726 | LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...) | ||
727 | { | ||
728 | const char *msg; | ||
729 | va_list argp; | ||
730 | va_start(argp, fmt); | ||
731 | msg = lj_str_pushvf(L, fmt, argp); | ||
732 | va_end(argp); | ||
733 | lj_err_callermsg(L, msg); | ||
734 | return 0; /* unreachable */ | ||
735 | } | ||
736 | |||