diff options
Diffstat (limited to 'src/lj_err.c')
-rw-r--r-- | src/lj_err.c | 70 |
1 files changed, 32 insertions, 38 deletions
diff --git a/src/lj_err.c b/src/lj_err.c index 6d8519bb..9ac0c988 100644 --- a/src/lj_err.c +++ b/src/lj_err.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include "lj_ff.h" | 16 | #include "lj_ff.h" |
17 | #include "lj_trace.h" | 17 | #include "lj_trace.h" |
18 | #include "lj_vm.h" | 18 | #include "lj_vm.h" |
19 | #include "lj_strfmt.h" | ||
19 | 20 | ||
20 | /* | 21 | /* |
21 | ** LuaJIT can either use internal or external frame unwinding: | 22 | ** LuaJIT can either use internal or external frame unwinding: |
@@ -98,14 +99,14 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
98 | TValue *top = restorestack(L, -nres); | 99 | TValue *top = restorestack(L, -nres); |
99 | if (frame < top) { /* Frame reached? */ | 100 | if (frame < top) { /* Frame reached? */ |
100 | if (errcode) { | 101 | if (errcode) { |
101 | L->cframe = cframe_prev(cf); | ||
102 | L->base = frame+1; | 102 | L->base = frame+1; |
103 | L->cframe = cframe_prev(cf); | ||
103 | unwindstack(L, top); | 104 | unwindstack(L, top); |
104 | } | 105 | } |
105 | return cf; | 106 | return cf; |
106 | } | 107 | } |
107 | } | 108 | } |
108 | if (frame <= tvref(L->stack)) | 109 | if (frame <= tvref(L->stack)+LJ_FR2) |
109 | break; | 110 | break; |
110 | switch (frame_typep(frame)) { | 111 | switch (frame_typep(frame)) { |
111 | case FRAME_LUA: /* Lua frame. */ | 112 | case FRAME_LUA: /* Lua frame. */ |
@@ -113,14 +114,12 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
113 | frame = frame_prevl(frame); | 114 | frame = frame_prevl(frame); |
114 | break; | 115 | break; |
115 | case FRAME_C: /* C frame. */ | 116 | case FRAME_C: /* C frame. */ |
116 | #if LJ_HASFFI | ||
117 | unwind_c: | 117 | unwind_c: |
118 | #endif | ||
119 | #if LJ_UNWIND_EXT | 118 | #if LJ_UNWIND_EXT |
120 | if (errcode) { | 119 | if (errcode) { |
121 | L->cframe = cframe_prev(cf); | ||
122 | L->base = frame_prevd(frame) + 1; | 120 | L->base = frame_prevd(frame) + 1; |
123 | unwindstack(L, frame); | 121 | L->cframe = cframe_prev(cf); |
122 | unwindstack(L, frame - LJ_FR2); | ||
124 | } else if (cf != stopcf) { | 123 | } else if (cf != stopcf) { |
125 | cf = cframe_prev(cf); | 124 | cf = cframe_prev(cf); |
126 | frame = frame_prevd(frame); | 125 | frame = frame_prevd(frame); |
@@ -143,16 +142,14 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
143 | return cf; | 142 | return cf; |
144 | } | 143 | } |
145 | if (errcode) { | 144 | if (errcode) { |
146 | L->cframe = cframe_prev(cf); | ||
147 | L->base = frame_prevd(frame) + 1; | 145 | L->base = frame_prevd(frame) + 1; |
148 | unwindstack(L, frame); | 146 | L->cframe = cframe_prev(cf); |
147 | unwindstack(L, frame - LJ_FR2); | ||
149 | } | 148 | } |
150 | return cf; | 149 | return cf; |
151 | case FRAME_CONT: /* Continuation frame. */ | 150 | case FRAME_CONT: /* Continuation frame. */ |
152 | #if LJ_HASFFI | 151 | if (frame_iscont_fficb(frame)) |
153 | if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) | ||
154 | goto unwind_c; | 152 | goto unwind_c; |
155 | #endif | ||
156 | case FRAME_VARG: /* Vararg frame. */ | 153 | case FRAME_VARG: /* Vararg frame. */ |
157 | frame = frame_prevd(frame); | 154 | frame = frame_prevd(frame); |
158 | break; | 155 | break; |
@@ -165,8 +162,8 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
165 | } | 162 | } |
166 | if (frame_typep(frame) == FRAME_PCALL) | 163 | if (frame_typep(frame) == FRAME_PCALL) |
167 | hook_leave(G(L)); | 164 | hook_leave(G(L)); |
168 | L->cframe = cf; | ||
169 | L->base = frame_prevd(frame) + 1; | 165 | L->base = frame_prevd(frame) + 1; |
166 | L->cframe = cf; | ||
170 | unwindstack(L, L->base); | 167 | unwindstack(L, L->base); |
171 | } | 168 | } |
172 | return (void *)((intptr_t)cf | CFRAME_UNWIND_FF); | 169 | return (void *)((intptr_t)cf | CFRAME_UNWIND_FF); |
@@ -174,8 +171,8 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
174 | } | 171 | } |
175 | /* No C frame. */ | 172 | /* No C frame. */ |
176 | if (errcode) { | 173 | if (errcode) { |
174 | L->base = tvref(L->stack)+1+LJ_FR2; | ||
177 | L->cframe = NULL; | 175 | L->cframe = NULL; |
178 | L->base = tvref(L->stack)+1; | ||
179 | unwindstack(L, L->base); | 176 | unwindstack(L, L->base); |
180 | if (G(L)->panic) | 177 | if (G(L)->panic) |
181 | G(L)->panic(L); | 178 | G(L)->panic(L); |
@@ -454,7 +451,7 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode) | |||
454 | { | 451 | { |
455 | global_State *g = G(L); | 452 | global_State *g = G(L); |
456 | lj_trace_abort(g); | 453 | lj_trace_abort(g); |
457 | setgcrefnull(g->jit_L); | 454 | setmref(g->jit_base, NULL); |
458 | L->status = 0; | 455 | L->status = 0; |
459 | #if LJ_UNWIND_EXT | 456 | #if LJ_UNWIND_EXT |
460 | err_raise_ext(errcode); | 457 | err_raise_ext(errcode); |
@@ -499,7 +496,7 @@ LJ_NOINLINE void lj_err_mem(lua_State *L) | |||
499 | /* Find error function for runtime errors. Requires an extra stack traversal. */ | 496 | /* Find error function for runtime errors. Requires an extra stack traversal. */ |
500 | static ptrdiff_t finderrfunc(lua_State *L) | 497 | static ptrdiff_t finderrfunc(lua_State *L) |
501 | { | 498 | { |
502 | cTValue *frame = L->base-1, *bot = tvref(L->stack); | 499 | cTValue *frame = L->base-1, *bot = tvref(L->stack)+LJ_FR2; |
503 | void *cf = L->cframe; | 500 | void *cf = L->cframe; |
504 | while (frame > bot && cf) { | 501 | while (frame > bot && cf) { |
505 | while (cframe_nres(cframe_raw(cf)) < 0) { /* cframe without frame? */ | 502 | while (cframe_nres(cframe_raw(cf)) < 0) { /* cframe without frame? */ |
@@ -523,10 +520,8 @@ static ptrdiff_t finderrfunc(lua_State *L) | |||
523 | frame = frame_prevd(frame); | 520 | frame = frame_prevd(frame); |
524 | break; | 521 | break; |
525 | case FRAME_CONT: | 522 | case FRAME_CONT: |
526 | #if LJ_HASFFI | 523 | if (frame_iscont_fficb(frame)) |
527 | if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) | ||
528 | cf = cframe_prev(cf); | 524 | cf = cframe_prev(cf); |
529 | #endif | ||
530 | frame = frame_prevd(frame); | 525 | frame = frame_prevd(frame); |
531 | break; | 526 | break; |
532 | case FRAME_CP: | 527 | case FRAME_CP: |
@@ -537,8 +532,8 @@ static ptrdiff_t finderrfunc(lua_State *L) | |||
537 | break; | 532 | break; |
538 | case FRAME_PCALL: | 533 | case FRAME_PCALL: |
539 | case FRAME_PCALLH: | 534 | case FRAME_PCALLH: |
540 | if (frame_ftsz(frame) >= (ptrdiff_t)(2*sizeof(TValue))) /* xpcall? */ | 535 | if (frame_func(frame_prevd(frame))->c.ffid == FF_xpcall) |
541 | return savestack(L, frame-1); /* Point to xpcall's errorfunc. */ | 536 | return savestack(L, frame_prevd(frame)+1); /* xpcall's errorfunc. */ |
542 | return 0; | 537 | return 0; |
543 | default: | 538 | default: |
544 | lua_assert(0); | 539 | lua_assert(0); |
@@ -561,8 +556,9 @@ LJ_NOINLINE void lj_err_run(lua_State *L) | |||
561 | lj_err_throw(L, LUA_ERRERR); | 556 | lj_err_throw(L, LUA_ERRERR); |
562 | } | 557 | } |
563 | L->status = LUA_ERRERR; | 558 | L->status = LUA_ERRERR; |
564 | copyTV(L, top, top-1); | 559 | copyTV(L, top+LJ_FR2, top-1); |
565 | copyTV(L, top-1, errfunc); | 560 | copyTV(L, top-1, errfunc); |
561 | if (LJ_FR2) setnilV(top++); | ||
566 | L->top = top+1; | 562 | L->top = top+1; |
567 | lj_vm_call(L, top, 1+1); /* Stack: |errfunc|msg| -> |msg| */ | 563 | lj_vm_call(L, top, 1+1); /* Stack: |errfunc|msg| -> |msg| */ |
568 | } | 564 | } |
@@ -576,7 +572,7 @@ LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...) | |||
576 | va_list argp; | 572 | va_list argp; |
577 | va_start(argp, em); | 573 | va_start(argp, em); |
578 | if (curr_funcisL(L)) L->top = curr_topL(L); | 574 | if (curr_funcisL(L)) L->top = curr_topL(L); |
579 | msg = lj_str_pushvf(L, err2msg(em), argp); | 575 | msg = lj_strfmt_pushvf(L, err2msg(em), argp); |
580 | va_end(argp); | 576 | va_end(argp); |
581 | lj_debug_addloc(L, msg, L->base-1, NULL); | 577 | lj_debug_addloc(L, msg, L->base-1, NULL); |
582 | lj_err_run(L); | 578 | lj_err_run(L); |
@@ -594,11 +590,11 @@ LJ_NOINLINE void lj_err_lex(lua_State *L, GCstr *src, const char *tok, | |||
594 | { | 590 | { |
595 | char buff[LUA_IDSIZE]; | 591 | char buff[LUA_IDSIZE]; |
596 | const char *msg; | 592 | const char *msg; |
597 | lj_debug_shortname(buff, src); | 593 | lj_debug_shortname(buff, src, line); |
598 | msg = lj_str_pushvf(L, err2msg(em), argp); | 594 | msg = lj_strfmt_pushvf(L, err2msg(em), argp); |
599 | msg = lj_str_pushf(L, "%s:%d: %s", buff, line, msg); | 595 | msg = lj_strfmt_pushf(L, "%s:%d: %s", buff, line, msg); |
600 | if (tok) | 596 | if (tok) |
601 | lj_str_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tok); | 597 | lj_strfmt_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tok); |
602 | lj_err_throw(L, LUA_ERRSYNTAX); | 598 | lj_err_throw(L, LUA_ERRSYNTAX); |
603 | } | 599 | } |
604 | 600 | ||
@@ -637,8 +633,9 @@ LJ_NOINLINE void lj_err_optype_call(lua_State *L, TValue *o) | |||
637 | const BCIns *pc = cframe_Lpc(L); | 633 | const BCIns *pc = cframe_Lpc(L); |
638 | if (((ptrdiff_t)pc & FRAME_TYPE) != FRAME_LUA) { | 634 | if (((ptrdiff_t)pc & FRAME_TYPE) != FRAME_LUA) { |
639 | const char *tname = lj_typename(o); | 635 | const char *tname = lj_typename(o); |
636 | if (LJ_FR2) o++; | ||
640 | setframe_pc(o, pc); | 637 | setframe_pc(o, pc); |
641 | setframe_gc(o, obj2gco(L)); | 638 | setframe_gc(o, obj2gco(L), LJ_TTHREAD); |
642 | L->top = L->base = o+1; | 639 | L->top = L->base = o+1; |
643 | err_msgv(L, LJ_ERR_BADCALL, tname); | 640 | err_msgv(L, LJ_ERR_BADCALL, tname); |
644 | } | 641 | } |
@@ -653,13 +650,10 @@ LJ_NOINLINE void lj_err_callermsg(lua_State *L, const char *msg) | |||
653 | if (frame_islua(frame)) { | 650 | if (frame_islua(frame)) { |
654 | pframe = frame_prevl(frame); | 651 | pframe = frame_prevl(frame); |
655 | } else if (frame_iscont(frame)) { | 652 | } else if (frame_iscont(frame)) { |
656 | #if LJ_HASFFI | 653 | if (frame_iscont_fficb(frame)) { |
657 | if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) { | ||
658 | pframe = frame; | 654 | pframe = frame; |
659 | frame = NULL; | 655 | frame = NULL; |
660 | } else | 656 | } else { |
661 | #endif | ||
662 | { | ||
663 | pframe = frame_prevd(frame); | 657 | pframe = frame_prevd(frame); |
664 | #if LJ_HASFFI | 658 | #if LJ_HASFFI |
665 | /* Remove frame for FFI metamethods. */ | 659 | /* Remove frame for FFI metamethods. */ |
@@ -682,7 +676,7 @@ LJ_NOINLINE void lj_err_callerv(lua_State *L, ErrMsg em, ...) | |||
682 | const char *msg; | 676 | const char *msg; |
683 | va_list argp; | 677 | va_list argp; |
684 | va_start(argp, em); | 678 | va_start(argp, em); |
685 | msg = lj_str_pushvf(L, err2msg(em), argp); | 679 | msg = lj_strfmt_pushvf(L, err2msg(em), argp); |
686 | va_end(argp); | 680 | va_end(argp); |
687 | lj_err_callermsg(L, msg); | 681 | lj_err_callermsg(L, msg); |
688 | } | 682 | } |
@@ -702,9 +696,9 @@ LJ_NORET LJ_NOINLINE static void err_argmsg(lua_State *L, int narg, | |||
702 | if (narg < 0 && narg > LUA_REGISTRYINDEX) | 696 | if (narg < 0 && narg > LUA_REGISTRYINDEX) |
703 | narg = (int)(L->top - L->base) + narg + 1; | 697 | narg = (int)(L->top - L->base) + narg + 1; |
704 | if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */ | 698 | if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */ |
705 | msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg); | 699 | msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg); |
706 | else | 700 | else |
707 | msg = lj_str_pushf(L, err2msg(LJ_ERR_BADARG), narg, fname, msg); | 701 | msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_BADARG), narg, fname, msg); |
708 | lj_err_callermsg(L, msg); | 702 | lj_err_callermsg(L, msg); |
709 | } | 703 | } |
710 | 704 | ||
@@ -714,7 +708,7 @@ LJ_NOINLINE void lj_err_argv(lua_State *L, int narg, ErrMsg em, ...) | |||
714 | const char *msg; | 708 | const char *msg; |
715 | va_list argp; | 709 | va_list argp; |
716 | va_start(argp, em); | 710 | va_start(argp, em); |
717 | msg = lj_str_pushvf(L, err2msg(em), argp); | 711 | msg = lj_strfmt_pushvf(L, err2msg(em), argp); |
718 | va_end(argp); | 712 | va_end(argp); |
719 | err_argmsg(L, narg, msg); | 713 | err_argmsg(L, narg, msg); |
720 | } | 714 | } |
@@ -744,7 +738,7 @@ LJ_NOINLINE void lj_err_argtype(lua_State *L, int narg, const char *xname) | |||
744 | TValue *o = narg < 0 ? L->top + narg : L->base + narg-1; | 738 | TValue *o = narg < 0 ? L->top + narg : L->base + narg-1; |
745 | tname = o < L->top ? lj_typename(o) : lj_obj_typename[0]; | 739 | tname = o < L->top ? lj_typename(o) : lj_obj_typename[0]; |
746 | } | 740 | } |
747 | msg = lj_str_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname); | 741 | msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname); |
748 | err_argmsg(L, narg, msg); | 742 | err_argmsg(L, narg, msg); |
749 | } | 743 | } |
750 | 744 | ||
@@ -794,7 +788,7 @@ LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...) | |||
794 | const char *msg; | 788 | const char *msg; |
795 | va_list argp; | 789 | va_list argp; |
796 | va_start(argp, fmt); | 790 | va_start(argp, fmt); |
797 | msg = lj_str_pushvf(L, fmt, argp); | 791 | msg = lj_strfmt_pushvf(L, fmt, argp); |
798 | va_end(argp); | 792 | va_end(argp); |
799 | lj_err_callermsg(L, msg); | 793 | lj_err_callermsg(L, msg); |
800 | return 0; /* unreachable */ | 794 | return 0; /* unreachable */ |