diff options
Diffstat (limited to 'src/lj_err.c')
-rw-r--r-- | src/lj_err.c | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/src/lj_err.c b/src/lj_err.c index 081bfde4..4f134941 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,13 +114,11 @@ 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; |
121 | L->cframe = cframe_prev(cf); | ||
123 | unwindstack(L, frame); | 122 | unwindstack(L, frame); |
124 | } else if (cf != stopcf) { | 123 | } else if (cf != stopcf) { |
125 | cf = cframe_prev(cf); | 124 | cf = cframe_prev(cf); |
@@ -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; |
146 | L->cframe = cframe_prev(cf); | ||
148 | unwindstack(L, frame); | 147 | unwindstack(L, frame); |
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); |
@@ -452,7 +449,7 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode) | |||
452 | { | 449 | { |
453 | global_State *g = G(L); | 450 | global_State *g = G(L); |
454 | lj_trace_abort(g); | 451 | lj_trace_abort(g); |
455 | setgcrefnull(g->jit_L); | 452 | setmref(g->jit_base, NULL); |
456 | L->status = 0; | 453 | L->status = 0; |
457 | #if LJ_UNWIND_EXT | 454 | #if LJ_UNWIND_EXT |
458 | err_raise_ext(errcode); | 455 | err_raise_ext(errcode); |
@@ -497,7 +494,7 @@ LJ_NOINLINE void lj_err_mem(lua_State *L) | |||
497 | /* Find error function for runtime errors. Requires an extra stack traversal. */ | 494 | /* Find error function for runtime errors. Requires an extra stack traversal. */ |
498 | static ptrdiff_t finderrfunc(lua_State *L) | 495 | static ptrdiff_t finderrfunc(lua_State *L) |
499 | { | 496 | { |
500 | cTValue *frame = L->base-1, *bot = tvref(L->stack); | 497 | cTValue *frame = L->base-1, *bot = tvref(L->stack)+LJ_FR2; |
501 | void *cf = L->cframe; | 498 | void *cf = L->cframe; |
502 | while (frame > bot && cf) { | 499 | while (frame > bot && cf) { |
503 | while (cframe_nres(cframe_raw(cf)) < 0) { /* cframe without frame? */ | 500 | while (cframe_nres(cframe_raw(cf)) < 0) { /* cframe without frame? */ |
@@ -521,10 +518,8 @@ static ptrdiff_t finderrfunc(lua_State *L) | |||
521 | frame = frame_prevd(frame); | 518 | frame = frame_prevd(frame); |
522 | break; | 519 | break; |
523 | case FRAME_CONT: | 520 | case FRAME_CONT: |
524 | #if LJ_HASFFI | 521 | if (frame_iscont_fficb(frame)) |
525 | if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) | ||
526 | cf = cframe_prev(cf); | 522 | cf = cframe_prev(cf); |
527 | #endif | ||
528 | frame = frame_prevd(frame); | 523 | frame = frame_prevd(frame); |
529 | break; | 524 | break; |
530 | case FRAME_CP: | 525 | case FRAME_CP: |
@@ -535,8 +530,8 @@ static ptrdiff_t finderrfunc(lua_State *L) | |||
535 | break; | 530 | break; |
536 | case FRAME_PCALL: | 531 | case FRAME_PCALL: |
537 | case FRAME_PCALLH: | 532 | case FRAME_PCALLH: |
538 | if (frame_ftsz(frame) >= (ptrdiff_t)(2*sizeof(TValue))) /* xpcall? */ | 533 | if (frame_func(frame_prevd(frame))->c.ffid == FF_xpcall) |
539 | return savestack(L, frame-1); /* Point to xpcall's errorfunc. */ | 534 | return savestack(L, frame_prevd(frame)+1); /* xpcall's errorfunc. */ |
540 | return 0; | 535 | return 0; |
541 | default: | 536 | default: |
542 | lua_assert(0); | 537 | lua_assert(0); |
@@ -559,8 +554,9 @@ LJ_NOINLINE void lj_err_run(lua_State *L) | |||
559 | lj_err_throw(L, LUA_ERRERR); | 554 | lj_err_throw(L, LUA_ERRERR); |
560 | } | 555 | } |
561 | L->status = LUA_ERRERR; | 556 | L->status = LUA_ERRERR; |
562 | copyTV(L, top, top-1); | 557 | copyTV(L, top+LJ_FR2, top-1); |
563 | copyTV(L, top-1, errfunc); | 558 | copyTV(L, top-1, errfunc); |
559 | if (LJ_FR2) setnilV(top++); | ||
564 | L->top = top+1; | 560 | L->top = top+1; |
565 | lj_vm_call(L, top, 1+1); /* Stack: |errfunc|msg| -> |msg| */ | 561 | lj_vm_call(L, top, 1+1); /* Stack: |errfunc|msg| -> |msg| */ |
566 | } | 562 | } |
@@ -574,7 +570,7 @@ LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...) | |||
574 | va_list argp; | 570 | va_list argp; |
575 | va_start(argp, em); | 571 | va_start(argp, em); |
576 | if (curr_funcisL(L)) L->top = curr_topL(L); | 572 | if (curr_funcisL(L)) L->top = curr_topL(L); |
577 | msg = lj_str_pushvf(L, err2msg(em), argp); | 573 | msg = lj_strfmt_pushvf(L, err2msg(em), argp); |
578 | va_end(argp); | 574 | va_end(argp); |
579 | lj_debug_addloc(L, msg, L->base-1, NULL); | 575 | lj_debug_addloc(L, msg, L->base-1, NULL); |
580 | lj_err_run(L); | 576 | lj_err_run(L); |
@@ -592,11 +588,11 @@ LJ_NOINLINE void lj_err_lex(lua_State *L, GCstr *src, const char *tok, | |||
592 | { | 588 | { |
593 | char buff[LUA_IDSIZE]; | 589 | char buff[LUA_IDSIZE]; |
594 | const char *msg; | 590 | const char *msg; |
595 | lj_debug_shortname(buff, src); | 591 | lj_debug_shortname(buff, src, line); |
596 | msg = lj_str_pushvf(L, err2msg(em), argp); | 592 | msg = lj_strfmt_pushvf(L, err2msg(em), argp); |
597 | msg = lj_str_pushf(L, "%s:%d: %s", buff, line, msg); | 593 | msg = lj_strfmt_pushf(L, "%s:%d: %s", buff, line, msg); |
598 | if (tok) | 594 | if (tok) |
599 | lj_str_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tok); | 595 | lj_strfmt_pushf(L, err2msg(LJ_ERR_XNEAR), msg, tok); |
600 | lj_err_throw(L, LUA_ERRSYNTAX); | 596 | lj_err_throw(L, LUA_ERRSYNTAX); |
601 | } | 597 | } |
602 | 598 | ||
@@ -635,8 +631,9 @@ LJ_NOINLINE void lj_err_optype_call(lua_State *L, TValue *o) | |||
635 | const BCIns *pc = cframe_Lpc(L); | 631 | const BCIns *pc = cframe_Lpc(L); |
636 | if (((ptrdiff_t)pc & FRAME_TYPE) != FRAME_LUA) { | 632 | if (((ptrdiff_t)pc & FRAME_TYPE) != FRAME_LUA) { |
637 | const char *tname = lj_typename(o); | 633 | const char *tname = lj_typename(o); |
634 | if (LJ_FR2) o++; | ||
638 | setframe_pc(o, pc); | 635 | setframe_pc(o, pc); |
639 | setframe_gc(o, obj2gco(L)); | 636 | setframe_gc(o, obj2gco(L), LJ_TTHREAD); |
640 | L->top = L->base = o+1; | 637 | L->top = L->base = o+1; |
641 | err_msgv(L, LJ_ERR_BADCALL, tname); | 638 | err_msgv(L, LJ_ERR_BADCALL, tname); |
642 | } | 639 | } |
@@ -651,13 +648,10 @@ LJ_NOINLINE void lj_err_callermsg(lua_State *L, const char *msg) | |||
651 | if (frame_islua(frame)) { | 648 | if (frame_islua(frame)) { |
652 | pframe = frame_prevl(frame); | 649 | pframe = frame_prevl(frame); |
653 | } else if (frame_iscont(frame)) { | 650 | } else if (frame_iscont(frame)) { |
654 | #if LJ_HASFFI | 651 | if (frame_iscont_fficb(frame)) { |
655 | if ((frame-1)->u32.lo == LJ_CONT_FFI_CALLBACK) { | ||
656 | pframe = frame; | 652 | pframe = frame; |
657 | frame = NULL; | 653 | frame = NULL; |
658 | } else | 654 | } else { |
659 | #endif | ||
660 | { | ||
661 | pframe = frame_prevd(frame); | 655 | pframe = frame_prevd(frame); |
662 | #if LJ_HASFFI | 656 | #if LJ_HASFFI |
663 | /* Remove frame for FFI metamethods. */ | 657 | /* Remove frame for FFI metamethods. */ |
@@ -680,7 +674,7 @@ LJ_NOINLINE void lj_err_callerv(lua_State *L, ErrMsg em, ...) | |||
680 | const char *msg; | 674 | const char *msg; |
681 | va_list argp; | 675 | va_list argp; |
682 | va_start(argp, em); | 676 | va_start(argp, em); |
683 | msg = lj_str_pushvf(L, err2msg(em), argp); | 677 | msg = lj_strfmt_pushvf(L, err2msg(em), argp); |
684 | va_end(argp); | 678 | va_end(argp); |
685 | lj_err_callermsg(L, msg); | 679 | lj_err_callermsg(L, msg); |
686 | } | 680 | } |
@@ -700,9 +694,9 @@ LJ_NORET LJ_NOINLINE static void err_argmsg(lua_State *L, int narg, | |||
700 | if (narg < 0 && narg > LUA_REGISTRYINDEX) | 694 | if (narg < 0 && narg > LUA_REGISTRYINDEX) |
701 | narg = (int)(L->top - L->base) + narg + 1; | 695 | narg = (int)(L->top - L->base) + narg + 1; |
702 | if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */ | 696 | if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */ |
703 | msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg); | 697 | msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg); |
704 | else | 698 | else |
705 | msg = lj_str_pushf(L, err2msg(LJ_ERR_BADARG), narg, fname, msg); | 699 | msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_BADARG), narg, fname, msg); |
706 | lj_err_callermsg(L, msg); | 700 | lj_err_callermsg(L, msg); |
707 | } | 701 | } |
708 | 702 | ||
@@ -712,7 +706,7 @@ LJ_NOINLINE void lj_err_argv(lua_State *L, int narg, ErrMsg em, ...) | |||
712 | const char *msg; | 706 | const char *msg; |
713 | va_list argp; | 707 | va_list argp; |
714 | va_start(argp, em); | 708 | va_start(argp, em); |
715 | msg = lj_str_pushvf(L, err2msg(em), argp); | 709 | msg = lj_strfmt_pushvf(L, err2msg(em), argp); |
716 | va_end(argp); | 710 | va_end(argp); |
717 | err_argmsg(L, narg, msg); | 711 | err_argmsg(L, narg, msg); |
718 | } | 712 | } |
@@ -742,7 +736,7 @@ LJ_NOINLINE void lj_err_argtype(lua_State *L, int narg, const char *xname) | |||
742 | TValue *o = narg < 0 ? L->top + narg : L->base + narg-1; | 736 | TValue *o = narg < 0 ? L->top + narg : L->base + narg-1; |
743 | tname = o < L->top ? lj_typename(o) : lj_obj_typename[0]; | 737 | tname = o < L->top ? lj_typename(o) : lj_obj_typename[0]; |
744 | } | 738 | } |
745 | msg = lj_str_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname); | 739 | msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname); |
746 | err_argmsg(L, narg, msg); | 740 | err_argmsg(L, narg, msg); |
747 | } | 741 | } |
748 | 742 | ||
@@ -792,7 +786,7 @@ LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...) | |||
792 | const char *msg; | 786 | const char *msg; |
793 | va_list argp; | 787 | va_list argp; |
794 | va_start(argp, fmt); | 788 | va_start(argp, fmt); |
795 | msg = lj_str_pushvf(L, fmt, argp); | 789 | msg = lj_strfmt_pushvf(L, fmt, argp); |
796 | va_end(argp); | 790 | va_end(argp); |
797 | lj_err_callermsg(L, msg); | 791 | lj_err_callermsg(L, msg); |
798 | return 0; /* unreachable */ | 792 | return 0; /* unreachable */ |