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