summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile2
-rw-r--r--src/Makefile.dep69
-rw-r--r--src/lib_base.c5
-rw-r--r--src/lib_jit.c6
-rw-r--r--src/lj_api.c27
-rw-r--r--src/lj_debug.c429
-rw-r--r--src/lj_debug.h23
-rw-r--r--src/lj_dispatch.c5
-rw-r--r--src/lj_err.c392
-rw-r--r--src/lj_err.h5
-rw-r--r--src/lj_gdbjit.c7
-rw-r--r--src/lj_trace.c7
-rw-r--r--src/ljamalg.c1
13 files changed, 521 insertions, 457 deletions
diff --git a/src/Makefile b/src/Makefile
index c99d8577..84f9d42f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -358,7 +358,7 @@ LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \
358LJLIB_C= $(LJLIB_O:.o=.c) 358LJLIB_C= $(LJLIB_O:.o=.c)
359 359
360LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o \ 360LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o \
361 lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o \ 361 lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \
362 lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o lj_api.o \ 362 lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o lj_api.o \
363 lj_lex.o lj_parse.o \ 363 lj_lex.o lj_parse.o \
364 lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \ 364 lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \
diff --git a/src/Makefile.dep b/src/Makefile.dep
index d3dec2be..5e7f11dc 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -13,9 +13,9 @@ buildvm_peobj.o: buildvm_peobj.c buildvm.h lj_def.h lua.h luaconf.h \
13lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \ 13lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
14 lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_lib.h lj_alloc.h 14 lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_lib.h lj_alloc.h
15lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ 15lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
16 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h \ 16 lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \
17 lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h lj_ffdef.h \ 17 lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \
18 lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_lib.h lj_libdef.h 18 lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_lib.h lj_libdef.h
19lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ 19lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
20 lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_lib.h lj_libdef.h 20 lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_lib.h lj_libdef.h
21lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ 21lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
@@ -30,9 +30,10 @@ lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
30 lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h \ 30 lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h \
31 lj_libdef.h 31 lj_libdef.h
32lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \ 32lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \
33 lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_bc.h lj_ir.h \ 33 lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
34 lj_jit.h lj_ircall.h lj_iropt.h lj_target.h lj_target_*.h \ 34 lj_bc.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_target.h \
35 lj_dispatch.h lj_vm.h lj_vmevent.h lj_lib.h luajit.h lj_libdef.h 35 lj_target_*.h lj_dispatch.h lj_vm.h lj_vmevent.h lj_lib.h luajit.h \
36 lj_libdef.h
36lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ 37lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
37 lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_libdef.h 38 lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_libdef.h
38lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ 39lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
@@ -47,9 +48,9 @@ lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
47 lj_libdef.h 48 lj_libdef.h
48lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h 49lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h
49lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ 50lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
50 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_udata.h lj_meta.h \ 51 lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
51 lj_state.h lj_bc.h lj_frame.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \ 52 lj_meta.h lj_state.h lj_bc.h lj_frame.h lj_trace.h lj_jit.h lj_ir.h \
52 lj_traceerr.h lj_vm.h lj_lex.h lj_parse.h 53 lj_dispatch.h lj_traceerr.h lj_vm.h lj_lex.h lj_parse.h
53lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ 54lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
54 lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h \ 55 lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h \
55 lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h lj_traceerr.h \ 56 lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h lj_traceerr.h \
@@ -83,11 +84,14 @@ lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
83 lj_ffrecord.h lj_crecord.h 84 lj_ffrecord.h lj_crecord.h
84lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 85lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
85 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h 86 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h
87lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
88 lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_state.h lj_frame.h lj_bc.h
86lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 89lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
87 lj_err.h lj_errmsg.h lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h \ 90 lj_err.h lj_errmsg.h lj_debug.h lj_state.h lj_frame.h lj_bc.h lj_ff.h \
88 lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h lj_traceerr.h lj_vm.h luajit.h 91 lj_ffdef.h lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h lj_traceerr.h \
92 lj_vm.h luajit.h
89lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \ 93lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
90 lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_state.h lj_frame.h lj_bc.h \ 94 lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
91 lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \ 95 lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
92 lj_traceerr.h lj_vm.h 96 lj_traceerr.h lj_vm.h
93lj_ffrecord.o: lj_ffrecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 97lj_ffrecord.o: lj_ffrecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
@@ -103,8 +107,8 @@ lj_gc.o: lj_gc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
103 lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h \ 107 lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h \
104 lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h 108 lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
105lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 109lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
106 lj_gc.h lj_err.h lj_errmsg.h lj_frame.h lj_bc.h lj_jit.h lj_ir.h \ 110 lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_jit.h \
107 lj_dispatch.h 111 lj_ir.h lj_dispatch.h
108lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ 112lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
109 lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \ 113 lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
110 lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h lj_carith.h \ 114 lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h lj_carith.h \
@@ -157,10 +161,10 @@ lj_str.o: lj_str.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
157lj_tab.o: lj_tab.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ 161lj_tab.o: lj_tab.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
158 lj_err.h lj_errmsg.h lj_tab.h 162 lj_err.h lj_errmsg.h lj_tab.h
159lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 163lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
160 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_frame.h lj_bc.h lj_state.h \ 164 lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_frame.h lj_bc.h \
161 lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h \ 165 lj_state.h lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h \
162 lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h lj_vm.h \ 166 lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \
163 lj_vmevent.h lj_target.h lj_target_*.h 167 lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h
164lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 168lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
165 lj_gc.h lj_udata.h 169 lj_gc.h lj_udata.h
166lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 170lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
@@ -172,18 +176,19 @@ ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
172 lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h \ 176 lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h \
173 lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h \ 177 lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h \
174 lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_err.c \ 178 lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_err.c \
175 lj_ff.h lj_ffdef.h lj_char.c lj_char.h lj_bc.c lj_bcdef.h lj_obj.c \ 179 lj_debug.h lj_ff.h lj_ffdef.h lj_char.c lj_char.h lj_bc.c lj_bcdef.h \
176 lj_str.c lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_state.c lj_lex.h \ 180 lj_obj.c lj_str.c lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_debug.c \
177 lj_alloc.h lj_dispatch.c luajit.h lj_vmevent.c lj_vmevent.h lj_vmmath.c \ 181 lj_state.c lj_lex.h lj_alloc.h lj_dispatch.c luajit.h lj_vmevent.c \
178 lj_api.c lj_parse.h lj_lex.c lualib.h lj_parse.c lj_ctype.c lj_cdata.c \ 182 lj_vmevent.h lj_vmmath.c lj_api.c lj_parse.h lj_lex.c lualib.h \
179 lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h lj_carith.c lj_carith.h \ 183 lj_parse.c lj_ctype.c lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c \
180 lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_lib.h lj_ir.c \ 184 lj_ccall.h lj_carith.c lj_carith.h lj_clib.c lj_clib.h lj_cparse.c \
181 lj_ircall.h lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h \ 185 lj_cparse.h lj_lib.c lj_lib.h lj_ir.c lj_ircall.h lj_iropt.h \
182 lj_opt_narrow.c lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c \ 186 lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c lj_opt_dce.c \
183 lj_mcode.c lj_mcode.h lj_snap.c lj_target.h lj_target_*.h lj_record.c \ 187 lj_opt_loop.c lj_snap.h lj_opt_split.c lj_mcode.c lj_mcode.h lj_snap.c \
184 lj_record.h lj_ffrecord.h lj_crecord.c lj_crecord.h lj_ffrecord.c \ 188 lj_target.h lj_target_*.h lj_record.c lj_record.h lj_ffrecord.h \
185 lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h lj_asm_*.h lj_trace.c \ 189 lj_crecord.c lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h \
186 lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c lib_base.c lj_libdef.h \ 190 lj_emit_*.h lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c \
187 lib_math.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c \ 191 lib_aux.c lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c \
188 lib_debug.c lib_bit.c lib_jit.c lib_ffi.c lib_init.c 192 lib_io.c lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c \
193 lib_ffi.c lib_init.c
189luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h 194luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h
diff --git a/src/lib_base.c b/src/lib_base.c
index 8c71ae32..f8975986 100644
--- a/src/lib_base.c
+++ b/src/lib_base.c
@@ -18,6 +18,7 @@
18#include "lj_obj.h" 18#include "lj_obj.h"
19#include "lj_gc.h" 19#include "lj_gc.h"
20#include "lj_err.h" 20#include "lj_err.h"
21#include "lj_debug.h"
21#include "lj_str.h" 22#include "lj_str.h"
22#include "lj_tab.h" 23#include "lj_tab.h"
23#include "lj_meta.h" 24#include "lj_meta.h"
@@ -89,7 +90,7 @@ LJLIB_CF(getfenv)
89 cTValue *o = L->base; 90 cTValue *o = L->base;
90 if (!(o < L->top && tvisfunc(o))) { 91 if (!(o < L->top && tvisfunc(o))) {
91 int level = lj_lib_optint(L, 1, 1); 92 int level = lj_lib_optint(L, 1, 1);
92 o = lj_err_getframe(L, level, &level); 93 o = lj_debug_frame(L, level, &level);
93 if (o == NULL) 94 if (o == NULL)
94 lj_err_arg(L, 1, LJ_ERR_INVLVL); 95 lj_err_arg(L, 1, LJ_ERR_INVLVL);
95 } 96 }
@@ -110,7 +111,7 @@ LJLIB_CF(setfenv)
110 setgcref(L->env, obj2gco(t)); 111 setgcref(L->env, obj2gco(t));
111 return 0; 112 return 0;
112 } 113 }
113 o = lj_err_getframe(L, level, &level); 114 o = lj_debug_frame(L, level, &level);
114 if (o == NULL) 115 if (o == NULL)
115 lj_err_arg(L, 1, LJ_ERR_INVLVL); 116 lj_err_arg(L, 1, LJ_ERR_INVLVL);
116 } 117 }
diff --git a/src/lib_jit.c b/src/lib_jit.c
index 6e16d45b..758835aa 100644
--- a/src/lib_jit.c
+++ b/src/lib_jit.c
@@ -13,6 +13,7 @@
13#include "lj_arch.h" 13#include "lj_arch.h"
14#include "lj_obj.h" 14#include "lj_obj.h"
15#include "lj_err.h" 15#include "lj_err.h"
16#include "lj_debug.h"
16#include "lj_str.h" 17#include "lj_str.h"
17#include "lj_tab.h" 18#include "lj_tab.h"
18#include "lj_bc.h" 19#include "lj_bc.h"
@@ -189,13 +190,12 @@ LJLIB_CF(jit_util_funcinfo)
189 setintfield(L, t, "nconsts", (int32_t)pt->sizekn); 190 setintfield(L, t, "nconsts", (int32_t)pt->sizekn);
190 setintfield(L, t, "upvalues", (int32_t)pt->sizeuv); 191 setintfield(L, t, "upvalues", (int32_t)pt->sizeuv);
191 if (pc < pt->sizebc) 192 if (pc < pt->sizebc)
192 setintfield(L, t, "currentline", 193 setintfield(L, t, "currentline", lj_debug_line(pt, pc));
193 proto_lineinfo(pt) ? proto_line(pt, pc) : 0);
194 lua_pushboolean(L, (pt->flags & PROTO_IS_VARARG)); 194 lua_pushboolean(L, (pt->flags & PROTO_IS_VARARG));
195 lua_setfield(L, -2, "isvararg"); 195 lua_setfield(L, -2, "isvararg");
196 setstrV(L, L->top++, proto_chunkname(pt)); 196 setstrV(L, L->top++, proto_chunkname(pt));
197 lua_setfield(L, -2, "source"); 197 lua_setfield(L, -2, "source");
198 lj_err_pushloc(L, pt, pc); 198 lj_debug_pushloc(L, pt, pc);
199 lua_setfield(L, -2, "loc"); 199 lua_setfield(L, -2, "loc");
200 } else { 200 } else {
201 GCfunc *fn = funcV(L->base); 201 GCfunc *fn = funcV(L->base);
diff --git a/src/lj_api.c b/src/lj_api.c
index 3a8448b5..4e41ccc0 100644
--- a/src/lj_api.c
+++ b/src/lj_api.c
@@ -12,6 +12,7 @@
12#include "lj_obj.h" 12#include "lj_obj.h"
13#include "lj_gc.h" 13#include "lj_gc.h"
14#include "lj_err.h" 14#include "lj_err.h"
15#include "lj_debug.h"
15#include "lj_str.h" 16#include "lj_str.h"
16#include "lj_tab.h" 17#include "lj_tab.h"
17#include "lj_func.h" 18#include "lj_func.h"
@@ -27,7 +28,7 @@
27 28
28/* -- Common helper functions --------------------------------------------- */ 29/* -- Common helper functions --------------------------------------------- */
29 30
30#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) 31#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
31#define api_checkvalidindex(L, i) api_check(L, (i) != niltv(L)) 32#define api_checkvalidindex(L, i) api_check(L, (i) != niltv(L))
32 33
33static TValue *index2adr(lua_State *L, int idx) 34static TValue *index2adr(lua_State *L, int idx)
@@ -832,30 +833,10 @@ LUA_API int lua_next(lua_State *L, int idx)
832 return more; 833 return more;
833} 834}
834 835
835static const char *aux_upvalue(cTValue *f, uint32_t idx, TValue **val)
836{
837 GCfunc *fn;
838 if (!tvisfunc(f)) return NULL;
839 fn = funcV(f);
840 if (isluafunc(fn)) {
841 GCproto *pt = funcproto(fn);
842 if (idx < pt->sizeuv) {
843 *val = uvval(&gcref(fn->l.uvptr[idx])->uv);
844 return strdata(proto_uvname(pt, idx));
845 }
846 } else {
847 if (idx < fn->c.nupvalues) {
848 *val = &fn->c.upvalue[idx];
849 return "";
850 }
851 }
852 return NULL;
853}
854
855LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n) 836LUA_API const char *lua_getupvalue(lua_State *L, int idx, int n)
856{ 837{
857 TValue *val; 838 TValue *val;
858 const char *name = aux_upvalue(index2adr(L, idx), (uint32_t)(n-1), &val); 839 const char *name = lj_debug_uvname(index2adr(L, idx), (uint32_t)(n-1), &val);
859 if (name) { 840 if (name) {
860 copyTV(L, L->top, val); 841 copyTV(L, L->top, val);
861 incr_top(L); 842 incr_top(L);
@@ -1010,7 +991,7 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1010 TValue *val; 991 TValue *val;
1011 const char *name; 992 const char *name;
1012 api_checknelems(L, 1); 993 api_checknelems(L, 1);
1013 name = aux_upvalue(f, (uint32_t)(n-1), &val); 994 name = lj_debug_uvname(f, (uint32_t)(n-1), &val);
1014 if (name) { 995 if (name) {
1015 L->top--; 996 L->top--;
1016 copyTV(L, val, L->top); 997 copyTV(L, val, L->top);
diff --git a/src/lj_debug.c b/src/lj_debug.c
new file mode 100644
index 00000000..a5ffff74
--- /dev/null
+++ b/src/lj_debug.c
@@ -0,0 +1,429 @@
1/*
2** Debugging and introspection.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define lj_debug_c
7#define LUA_CORE
8
9#include "lj_obj.h"
10#include "lj_err.h"
11#include "lj_str.h"
12#include "lj_tab.h"
13#include "lj_state.h"
14#include "lj_frame.h"
15#include "lj_bc.h"
16
17/* -- Frames -------------------------------------------------------------- */
18
19/* Get frame corresponding to a level. */
20cTValue *lj_debug_frame(lua_State *L, int level, int *size)
21{
22 cTValue *frame, *nextframe, *bot = tvref(L->stack);
23 /* Traverse frames backwards. */
24 for (nextframe = frame = L->base-1; frame > bot; ) {
25 if (frame_gc(frame) == obj2gco(L))
26 level++; /* Skip dummy frames. See lj_meta_call(). */
27 if (level-- == 0) {
28 *size = (int)(nextframe - frame);
29 return frame; /* Level found. */
30 }
31 nextframe = frame;
32 if (frame_islua(frame)) {
33 frame = frame_prevl(frame);
34 } else {
35 if (frame_isvarg(frame))
36 level++; /* Skip vararg pseudo-frame. */
37 frame = frame_prevd(frame);
38 }
39 }
40 *size = level;
41 return NULL; /* Level not found. */
42}
43
44/* Invalid bytecode position. */
45#define NO_BCPOS (~(BCPos)0)
46
47/* Return bytecode position for function/frame or NO_BCPOS. */
48static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
49{
50 const BCIns *ins;
51 lua_assert(fn->c.gct == ~LJ_TFUNC || fn->c.gct == ~LJ_TTHREAD);
52 if (!isluafunc(fn)) { /* Cannot derive a PC for non-Lua functions. */
53 return NO_BCPOS;
54 } else if (nextframe == NULL) { /* Lua function on top. */
55 void *cf = cframe_raw(L->cframe);
56 if (cf == NULL || (char *)cframe_pc(cf) == (char *)cframe_L(cf))
57 return NO_BCPOS;
58 ins = cframe_pc(cf); /* Only happens during error/hook handling. */
59 } else {
60 if (frame_islua(nextframe)) {
61 ins = frame_pc(nextframe);
62 } else if (frame_iscont(nextframe)) {
63 ins = frame_contpc(nextframe);
64 } else {
65 /* Lua function below errfunc/gc/hook: find cframe to get the PC. */
66 void *cf = cframe_raw(L->cframe);
67 TValue *f = L->base-1;
68 if (cf == NULL)
69 return NO_BCPOS;
70 while (f > nextframe) {
71 if (frame_islua(f)) {
72 f = frame_prevl(f);
73 } else {
74 if (frame_isc(f))
75 cf = cframe_raw(cframe_prev(cf));
76 f = frame_prevd(f);
77 }
78 }
79 if (cframe_prev(cf))
80 cf = cframe_raw(cframe_prev(cf));
81 ins = cframe_pc(cf);
82 }
83 }
84 return proto_bcpos(funcproto(fn), ins) - 1;
85}
86
87/* -- Line numbers -------------------------------------------------------- */
88
89/* Get line number for a bytecode position. */
90BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc)
91{
92 BCLine *lineinfo = proto_lineinfo(pt);
93 if (pc < pt->sizebc && lineinfo)
94 return lineinfo[pc];
95 return 0;
96}
97
98/* Get line number for function/frame. */
99static BCLine debug_frameline(lua_State *L, GCfunc *fn, cTValue *nextframe)
100{
101 BCPos pc = debug_framepc(L, fn, nextframe);
102 if (pc != NO_BCPOS) {
103 GCproto *pt = funcproto(fn);
104 lua_assert(pc < pt->sizebc);
105 return lj_debug_line(pt, pc);
106 }
107 return -1;
108}
109
110/* -- Variable names ------------------------------------------------------ */
111
112/* Get name of a local variable from slot number and PC. */
113static const char *debug_varname(const GCproto *pt, BCPos pc, BCReg slot)
114{
115 MSize i;
116 VarInfo *vi = proto_varinfo(pt);
117 for (i = 0; i < pt->sizevarinfo && vi[i].startpc <= pc; i++)
118 if (pc < vi[i].endpc && slot-- == 0)
119 return strdata(gco2str(gcref(vi[i].name)));
120 return NULL;
121}
122
123/* Get name of local variable from 1-based slot number and function/frame. */
124static TValue *debug_localname(lua_State *L, const lua_Debug *ar,
125 const char **name, BCReg slot1)
126{
127 uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
128 uint32_t size = (uint32_t)ar->i_ci >> 16;
129 TValue *frame = tvref(L->stack) + offset;
130 TValue *nextframe = size ? frame + size : NULL;
131 GCfunc *fn = frame_func(frame);
132 BCPos pc = debug_framepc(L, fn, nextframe);
133 if (pc != NO_BCPOS &&
134 (*name = debug_varname(funcproto(fn), pc, slot1-1)) != NULL)
135 ;
136 else if (slot1 > 0 && frame + slot1 < (nextframe ? nextframe : L->top))
137 *name = "(*temporary)";
138 else
139 *name = NULL;
140 return frame+slot1;
141}
142
143/* Get name of upvalue. */
144const char *lj_debug_uvname(cTValue *o, uint32_t idx, TValue **tvp)
145{
146 if (tvisfunc(o)) {
147 GCfunc *fn = funcV(o);
148 if (isluafunc(fn)) {
149 GCproto *pt = funcproto(fn);
150 if (idx < pt->sizeuv) {
151 *tvp = uvval(&gcref(fn->l.uvptr[idx])->uv);
152 return strdata(proto_uvname(pt, idx));
153 }
154 } else {
155 if (idx < fn->c.nupvalues) {
156 *tvp = &fn->c.upvalue[idx];
157 return "";
158 }
159 }
160 }
161 return NULL;
162}
163
164/* Deduce name of an object from slot number and PC. */
165const char *lj_debug_slotname(GCproto *pt, const BCIns *ip, BCReg slot,
166 const char **name)
167{
168 const char *lname;
169restart:
170 lname = debug_varname(pt, proto_bcpos(pt, ip), slot);
171 if (lname != NULL) { *name = lname; return "local"; }
172 while (--ip > proto_bc(pt)) {
173 BCIns ins = *ip;
174 BCOp op = bc_op(ins);
175 BCReg ra = bc_a(ins);
176 if (bcmode_a(op) == BCMbase) {
177 if (slot >= ra && (op != BC_KNIL || slot <= bc_d(ins)))
178 return NULL;
179 } else if (bcmode_a(op) == BCMdst && ra == slot) {
180 switch (bc_op(ins)) {
181 case BC_MOV:
182 if (ra == slot) { slot = bc_d(ins); goto restart; }
183 break;
184 case BC_GGET:
185 *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_d(ins))));
186 return "global";
187 case BC_TGETS:
188 *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins))));
189 if (ip > proto_bc(pt)) {
190 BCIns insp = ip[-1];
191 if (bc_op(insp) == BC_MOV && bc_a(insp) == ra+1 &&
192 bc_d(insp) == bc_b(ins))
193 return "method";
194 }
195 return "field";
196 case BC_UGET:
197 *name = strdata(proto_uvname(pt, bc_d(ins)));
198 return "upvalue";
199 default:
200 return NULL;
201 }
202 }
203 }
204 return NULL;
205}
206
207/* Deduce function name from caller of a frame. */
208const char *lj_debug_funcname(lua_State *L, TValue *frame, const char **name)
209{
210 TValue *pframe;
211 GCfunc *fn;
212 BCPos pc;
213 if (frame_isvarg(frame))
214 frame = frame_prevd(frame);
215 pframe = frame_prev(frame);
216 fn = frame_func(pframe);
217 pc = debug_framepc(L, fn, frame);
218 if (pc != NO_BCPOS) {
219 GCproto *pt = funcproto(fn);
220 const BCIns *ip = &proto_bc(pt)[check_exp(pc < pt->sizebc, pc)];
221 MMS mm = bcmode_mm(bc_op(*ip));
222 if (mm == MM_call) {
223 BCReg slot = bc_a(*ip);
224 if (bc_op(*ip) == BC_ITERC) slot -= 3;
225 return lj_debug_slotname(pt, ip, slot, name);
226 } else if (mm != MM__MAX) {
227 *name = strdata(mmname_str(G(L), mm));
228 return "metamethod";
229 }
230 }
231 return NULL;
232}
233
234/* -- Source code locations ----------------------------------------------- */
235
236/* Generate shortened source name. */
237void lj_debug_shortname(char *out, const char *src)
238{
239 if (*src == '=') {
240 strncpy(out, src+1, LUA_IDSIZE); /* remove first char */
241 out[LUA_IDSIZE-1] = '\0'; /* ensures null termination */
242 } else if (*src == '@') { /* out = "source", or "...source" */
243 size_t l = strlen(++src); /* skip the `@' */
244 if (l >= LUA_IDSIZE) {
245 src += l-(LUA_IDSIZE-4); /* get last part of file name */
246 strcpy(out, "...");
247 out += 3;
248 }
249 strcpy(out, src);
250 } else { /* out = [string "string"] */
251 size_t len; /* Length, up to first control char. */
252 for (len = 0; len < LUA_IDSIZE-12; len++)
253 if (((const unsigned char *)src)[len] < ' ') break;
254 strcpy(out, "[string \""); out += 9;
255 if (src[len] != '\0') { /* must truncate? */
256 if (len > LUA_IDSIZE-15) len = LUA_IDSIZE-15;
257 strncpy(out, src, len); out += len;
258 strcpy(out, "..."); out += 3;
259 } else {
260 strcpy(out, src); out += len;
261 }
262 strcpy(out, "\"]");
263 }
264}
265
266/* Add current location of a frame to error message. */
267void lj_debug_addloc(lua_State *L, const char *msg,
268 cTValue *frame, cTValue *nextframe)
269{
270 if (frame) {
271 GCfunc *fn = frame_func(frame);
272 if (isluafunc(fn)) {
273 BCLine line = debug_frameline(L, fn, nextframe);
274 if (line >= 0) {
275 char buf[LUA_IDSIZE];
276 lj_debug_shortname(buf, strdata(proto_chunkname(funcproto(fn))));
277 lj_str_pushf(L, "%s:%d: %s", buf, line, msg);
278 return;
279 }
280 }
281 }
282 lj_str_pushf(L, "%s", msg);
283}
284
285/* Push location string for a bytecode position to Lua stack. */
286void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc)
287{
288 GCstr *name = proto_chunkname(pt);
289 if (name) {
290 const char *s = strdata(name);
291 MSize i, len = name->len;
292 BCLine line = lj_debug_line(pt, pc);
293 if (*s == '@') {
294 s++; len--;
295 for (i = len; i > 0; i--)
296 if (s[i] == '/' || s[i] == '\\') {
297 s += i+1;
298 break;
299 }
300 lj_str_pushf(L, "%s:%d", s, line);
301 } else if (len > 40) {
302 lj_str_pushf(L, "%p:%d", pt, line);
303 } else if (*s == '=') {
304 lj_str_pushf(L, "%s:%d", s+1, line);
305 } else {
306 lj_str_pushf(L, "\"%s\":%d", s, line);
307 }
308 } else {
309 lj_str_pushf(L, "%p:%u", pt, pc);
310 }
311}
312
313/* -- Public debug API ---------------------------------------------------- */
314
315/* lua_getupvalue() and lua_setupvalue() are in lj_api.c. */
316
317LUA_API const char *lua_getlocal(lua_State *L, const lua_Debug *ar, int n)
318{
319 const char *name;
320 TValue *o = debug_localname(L, ar, &name, (BCReg)n);
321 if (name) {
322 copyTV(L, L->top, o);
323 incr_top(L);
324 }
325 return name;
326}
327
328LUA_API const char *lua_setlocal(lua_State *L, const lua_Debug *ar, int n)
329{
330 const char *name;
331 TValue *o = debug_localname(L, ar, &name, (BCReg)n);
332 if (name)
333 copyTV(L, o, L->top-1);
334 L->top--;
335 return name;
336}
337
338LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)
339{
340 int status = 1;
341 TValue *frame = NULL;
342 TValue *nextframe = NULL;
343 GCfunc *fn;
344 if (*what == '>') {
345 TValue *func = L->top - 1;
346 api_check(L, tvisfunc(func));
347 fn = funcV(func);
348 L->top--;
349 what++;
350 } else {
351 uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
352 uint32_t size = (uint32_t)ar->i_ci >> 16;
353 lua_assert(offset != 0);
354 frame = tvref(L->stack) + offset;
355 if (size) nextframe = frame + size;
356 lua_assert(frame <= tvref(L->maxstack) &&
357 (!nextframe || nextframe <= tvref(L->maxstack)));
358 fn = frame_func(frame);
359 lua_assert(fn->c.gct == ~LJ_TFUNC);
360 }
361 for (; *what; what++) {
362 switch (*what) {
363 case 'S':
364 if (isluafunc(fn)) {
365 GCproto *pt = funcproto(fn);
366 ar->source = strdata(proto_chunkname(pt));
367 ar->linedefined = (int)proto_line(pt, 0);
368 ar->lastlinedefined = (int)pt->lastlinedefined;
369 ar->what = ar->linedefined ? "Lua" : "main";
370 } else {
371 ar->source = "=[C]";
372 ar->linedefined = -1;
373 ar->lastlinedefined = -1;
374 ar->what = "C";
375 }
376 lj_debug_shortname(ar->short_src, ar->source);
377 break;
378 case 'l':
379 ar->currentline = frame ? debug_frameline(L, fn, nextframe) : -1;
380 break;
381 case 'u':
382 ar->nups = fn->c.nupvalues;
383 break;
384 case 'n':
385 ar->namewhat = frame ? lj_debug_funcname(L, frame, &ar->name) : NULL;
386 if (ar->namewhat == NULL) {
387 ar->namewhat = "";
388 ar->name = NULL;
389 }
390 break;
391 case 'f':
392 setfuncV(L, L->top, fn);
393 incr_top(L);
394 break;
395 case 'L':
396 if (isluafunc(fn)) {
397 GCtab *t = lj_tab_new(L, 0, 0);
398 GCproto *pt = funcproto(fn);
399 BCLine *lineinfo = proto_lineinfo(pt);
400 MSize i, szl = pt->sizebc;
401 for (i = 1; i < szl; i++)
402 setboolV(lj_tab_setint(L, t, lineinfo[i]), 1);
403 settabV(L, L->top, t);
404 } else {
405 setnilV(L->top);
406 }
407 incr_top(L);
408 break;
409 default:
410 status = 0; /* Bad option. */
411 break;
412 }
413 }
414 return status;
415}
416
417LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar)
418{
419 int size;
420 cTValue *frame = lj_debug_frame(L, level, &size);
421 if (frame) {
422 ar->i_ci = (size << 16) + (int)(frame - tvref(L->stack));
423 return 1;
424 } else {
425 ar->i_ci = level - size;
426 return 0;
427 }
428}
429
diff --git a/src/lj_debug.h b/src/lj_debug.h
new file mode 100644
index 00000000..5a1ddbec
--- /dev/null
+++ b/src/lj_debug.h
@@ -0,0 +1,23 @@
1/*
2** Debugging and introspection.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_DEBUG_H
7#define _LJ_DEBUG_H
8
9#include "lj_obj.h"
10
11LJ_FUNC cTValue *lj_debug_frame(lua_State *L, int level, int *size);
12LJ_FUNC BCLine LJ_FASTCALL lj_debug_line(GCproto *pt, BCPos pc);
13LJ_FUNC const char *lj_debug_uvname(cTValue *o, uint32_t idx, TValue **tvp);
14LJ_FUNC const char *lj_debug_slotname(GCproto *pt, const BCIns *pc,
15 BCReg slot, const char **name);
16LJ_FUNC const char *lj_debug_funcname(lua_State *L, TValue *frame,
17 const char **name);
18LJ_FUNC void lj_debug_shortname(char *out, const char *src);
19LJ_FUNC void lj_debug_addloc(lua_State *L, const char *msg,
20 cTValue *frame, cTValue *nextframe);
21LJ_FUNC void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc);
22
23#endif
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c
index 425eeaa2..5fbc112c 100644
--- a/src/lj_dispatch.c
+++ b/src/lj_dispatch.c
@@ -8,6 +8,7 @@
8 8
9#include "lj_obj.h" 9#include "lj_obj.h"
10#include "lj_err.h" 10#include "lj_err.h"
11#include "lj_debug.h"
11#include "lj_state.h" 12#include "lj_state.h"
12#include "lj_frame.h" 13#include "lj_frame.h"
13#include "lj_bc.h" 14#include "lj_bc.h"
@@ -380,8 +381,8 @@ void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc)
380 if ((g->hookmask & LUA_MASKLINE)) { 381 if ((g->hookmask & LUA_MASKLINE)) {
381 BCPos npc = proto_bcpos(pt, pc) - 1; 382 BCPos npc = proto_bcpos(pt, pc) - 1;
382 BCPos opc = proto_bcpos(pt, oldpc) - 1; 383 BCPos opc = proto_bcpos(pt, oldpc) - 1;
383 BCLine line = proto_line(pt, npc); 384 BCLine line = lj_debug_line(pt, npc);
384 if (pc <= oldpc || opc >= pt->sizebc || line != proto_line(pt, opc)) { 385 if (pc <= oldpc || opc >= pt->sizebc || line != lj_debug_line(pt, opc)) {
385 callhook(L, LUA_HOOKLINE, line); 386 callhook(L, LUA_HOOKLINE, line);
386 L->top = L->base + slots; /* Fix top again. */ 387 L->top = L->base + slots; /* Fix top again. */
387 } 388 }
diff --git a/src/lj_err.c b/src/lj_err.c
index 61178805..8d37af6a 100644
--- a/src/lj_err.c
+++ b/src/lj_err.c
@@ -1,9 +1,6 @@
1/* 1/*
2** Error handling and debugging API. 2** Error handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h 3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4**
5** Portions taken verbatim or adapted from the Lua interpreter.
6** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
7*/ 4*/
8 5
9#define lj_err_c 6#define lj_err_c
@@ -11,12 +8,11 @@
11 8
12#include "lj_obj.h" 9#include "lj_obj.h"
13#include "lj_err.h" 10#include "lj_err.h"
11#include "lj_debug.h"
14#include "lj_str.h" 12#include "lj_str.h"
15#include "lj_tab.h"
16#include "lj_func.h" 13#include "lj_func.h"
17#include "lj_state.h" 14#include "lj_state.h"
18#include "lj_frame.h" 15#include "lj_frame.h"
19#include "lj_bc.h"
20#include "lj_ff.h" 16#include "lj_ff.h"
21#include "lj_trace.h" 17#include "lj_trace.h"
22#include "lj_vm.h" 18#include "lj_vm.h"
@@ -78,355 +74,6 @@ LJ_DATADEF const char *lj_err_allmsg =
78#include "lj_errmsg.h" 74#include "lj_errmsg.h"
79; 75;
80 76
81/* -- Frame and function introspection ------------------------------------ */
82
83static BCPos currentpc(lua_State *L, GCfunc *fn, cTValue *nextframe)
84{
85 const BCIns *ins;
86 lua_assert(fn->c.gct == ~LJ_TFUNC || fn->c.gct == ~LJ_TTHREAD);
87 if (!isluafunc(fn)) { /* Cannot derive a PC for non-Lua functions. */
88 return ~(BCPos)0;
89 } else if (nextframe == NULL) { /* Lua function on top. */
90 void *cf = cframe_raw(L->cframe);
91 if (cf == NULL || (char *)cframe_pc(cf) == (char *)cframe_L(cf))
92 return ~(BCPos)0;
93 ins = cframe_pc(cf); /* Only happens during error/hook handling. */
94 } else {
95 if (frame_islua(nextframe)) {
96 ins = frame_pc(nextframe);
97 } else if (frame_iscont(nextframe)) {
98 ins = frame_contpc(nextframe);
99 } else {
100 /* Lua function below errfunc/gc/hook: find cframe to get the PC. */
101 void *cf = cframe_raw(L->cframe);
102 TValue *f = L->base-1;
103 if (cf == NULL)
104 return ~(BCPos)0;
105 while (f > nextframe) {
106 if (frame_islua(f)) {
107 f = frame_prevl(f);
108 } else {
109 if (frame_isc(f))
110 cf = cframe_raw(cframe_prev(cf));
111 f = frame_prevd(f);
112 }
113 }
114 if (cframe_prev(cf))
115 cf = cframe_raw(cframe_prev(cf));
116 ins = cframe_pc(cf);
117 }
118 }
119 return proto_bcpos(funcproto(fn), ins) - 1;
120}
121
122static BCLine currentline(lua_State *L, GCfunc *fn, cTValue *nextframe)
123{
124 BCPos pc = currentpc(L, fn, nextframe);
125 if (pc != ~(BCPos)0) {
126 GCproto *pt = funcproto(fn);
127 lua_assert(pc < pt->sizebc);
128 return proto_line(pt, pc);
129 } else {
130 return -1;
131 }
132}
133
134static const char *getvarname(const GCproto *pt, BCPos pc, BCReg slot)
135{
136 MSize i;
137 VarInfo *vi = proto_varinfo(pt);
138 for (i = 0; i < pt->sizevarinfo && vi[i].startpc <= pc; i++)
139 if (pc < vi[i].endpc && slot-- == 0)
140 return strdata(gco2str(gcref(vi[i].name)));
141 return NULL;
142}
143
144static const char *getobjname(GCproto *pt, const BCIns *ip, BCReg slot,
145 const char **name)
146{
147 const char *lname;
148restart:
149 lname = getvarname(pt, proto_bcpos(pt, ip), slot);
150 if (lname != NULL) { *name = lname; return "local"; }
151 while (--ip > proto_bc(pt)) {
152 BCIns ins = *ip;
153 BCOp op = bc_op(ins);
154 BCReg ra = bc_a(ins);
155 if (bcmode_a(op) == BCMbase) {
156 if (slot >= ra && (op != BC_KNIL || slot <= bc_d(ins)))
157 return NULL;
158 } else if (bcmode_a(op) == BCMdst && ra == slot) {
159 switch (bc_op(ins)) {
160 case BC_MOV:
161 if (ra == slot) { slot = bc_d(ins); goto restart; }
162 break;
163 case BC_GGET:
164 *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_d(ins))));
165 return "global";
166 case BC_TGETS:
167 *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins))));
168 if (ip > proto_bc(pt)) {
169 BCIns insp = ip[-1];
170 if (bc_op(insp) == BC_MOV && bc_a(insp) == ra+1 &&
171 bc_d(insp) == bc_b(ins))
172 return "method";
173 }
174 return "field";
175 case BC_UGET:
176 *name = strdata(proto_uvname(pt, bc_d(ins)));
177 return "upvalue";
178 default:
179 return NULL;
180 }
181 }
182 }
183 return NULL;
184}
185
186static const char *getfuncname(lua_State *L, TValue *frame, const char **name)
187{
188 MMS mm;
189 const BCIns *ip;
190 TValue *pframe;
191 GCfunc *fn;
192 BCPos pc;
193 if (frame_isvarg(frame))
194 frame = frame_prevd(frame);
195 pframe = frame_prev(frame);
196 fn = frame_func(pframe);
197 pc = currentpc(L, fn, frame);
198 if (pc == ~(BCPos)0)
199 return NULL;
200 lua_assert(pc < funcproto(fn)->sizebc);
201 ip = &proto_bc(funcproto(fn))[pc];
202 mm = bcmode_mm(bc_op(*ip));
203 if (mm == MM_call) {
204 BCReg slot = bc_a(*ip);
205 if (bc_op(*ip) == BC_ITERC) slot -= 3;
206 return getobjname(funcproto(fn), ip, slot, name);
207 } else if (mm != MM__MAX) {
208 *name = strdata(mmname_str(G(L), mm));
209 return "metamethod";
210 } else {
211 return NULL;
212 }
213}
214
215void lj_err_pushloc(lua_State *L, GCproto *pt, BCPos pc)
216{
217 GCstr *name = proto_chunkname(pt);
218 if (name) {
219 const char *s = strdata(name);
220 MSize i, len = name->len;
221 BCLine line = pc < pt->sizebc ? proto_line(pt, pc) : 0;
222 if (*s == '@') {
223 s++; len--;
224 for (i = len; i > 0; i--)
225 if (s[i] == '/' || s[i] == '\\') {
226 s += i+1;
227 break;
228 }
229 lj_str_pushf(L, "%s:%d", s, line);
230 } else if (len > 40) {
231 lj_str_pushf(L, "%p:%d", pt, line);
232 } else if (*s == '=') {
233 lj_str_pushf(L, "%s:%d", s+1, line);
234 } else {
235 lj_str_pushf(L, "\"%s\":%d", s, line);
236 }
237 } else {
238 lj_str_pushf(L, "%p:%u", pt, pc);
239 }
240}
241
242static void err_chunkid(char *out, const char *src)
243{
244 if (*src == '=') {
245 strncpy(out, src+1, LUA_IDSIZE); /* remove first char */
246 out[LUA_IDSIZE-1] = '\0'; /* ensures null termination */
247 } else if (*src == '@') { /* out = "source", or "...source" */
248 size_t l = strlen(++src); /* skip the `@' */
249 if (l >= LUA_IDSIZE) {
250 src += l-(LUA_IDSIZE-4); /* get last part of file name */
251 strcpy(out, "...");
252 out += 3;
253 }
254 strcpy(out, src);
255 } else { /* out = [string "string"] */
256 size_t len; /* Length, up to first control char. */
257 for (len = 0; len < LUA_IDSIZE-12; len++)
258 if (((const unsigned char *)src)[len] < ' ') break;
259 strcpy(out, "[string \""); out += 9;
260 if (src[len] != '\0') { /* must truncate? */
261 if (len > LUA_IDSIZE-15) len = LUA_IDSIZE-15;
262 strncpy(out, src, len); out += len;
263 strcpy(out, "..."); out += 3;
264 } else {
265 strcpy(out, src); out += len;
266 }
267 strcpy(out, "\"]");
268 }
269}
270
271/* -- Public debug API ---------------------------------------------------- */
272
273static TValue *findlocal(lua_State *L, const lua_Debug *ar,
274 const char **name, BCReg slot)
275{
276 uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
277 uint32_t size = (uint32_t)ar->i_ci >> 16;
278 TValue *frame = tvref(L->stack) + offset;
279 TValue *nextframe = size ? frame + size : NULL;
280 GCfunc *fn = frame_func(frame);
281 BCPos pc = currentpc(L, fn, nextframe);
282 if (pc != ~(BCPos)0 &&
283 (*name = getvarname(funcproto(fn), pc, slot-1)) != NULL)
284 ;
285 else if (slot > 0 && frame + slot < (nextframe ? nextframe : L->top))
286 *name = "(*temporary)";
287 else
288 *name = NULL;
289 return frame+slot;
290}
291
292LUA_API const char *lua_getlocal(lua_State *L, const lua_Debug *ar, int n)
293{
294 const char *name;
295 TValue *o = findlocal(L, ar, &name, (BCReg)n);
296 if (name) {
297 copyTV(L, L->top, o);
298 incr_top(L);
299 }
300 return name;
301}
302
303
304LUA_API const char *lua_setlocal(lua_State *L, const lua_Debug *ar, int n)
305{
306 const char *name;
307 TValue *o = findlocal(L, ar, &name, (BCReg)n);
308 if (name)
309 copyTV(L, o, L->top-1);
310 L->top--;
311 return name;
312}
313
314LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar)
315{
316 int status = 1;
317 TValue *frame = NULL;
318 TValue *nextframe = NULL;
319 GCfunc *fn;
320 if (*what == '>') {
321 TValue *func = L->top - 1;
322 api_check(L, tvisfunc(func));
323 fn = funcV(func);
324 L->top--;
325 what++;
326 } else {
327 uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
328 uint32_t size = (uint32_t)ar->i_ci >> 16;
329 lua_assert(offset != 0);
330 frame = tvref(L->stack) + offset;
331 if (size) nextframe = frame + size;
332 lua_assert(frame <= tvref(L->maxstack) &&
333 (!nextframe || nextframe <= tvref(L->maxstack)));
334 fn = frame_func(frame);
335 lua_assert(fn->c.gct == ~LJ_TFUNC);
336 }
337 for (; *what; what++) {
338 switch (*what) {
339 case 'S':
340 if (isluafunc(fn)) {
341 GCproto *pt = funcproto(fn);
342 ar->source = strdata(proto_chunkname(pt));
343 ar->linedefined = (int)proto_line(pt, 0);
344 ar->lastlinedefined = (int)pt->lastlinedefined;
345 ar->what = (ar->linedefined == 0) ? "main" : "Lua";
346 } else {
347 ar->source = "=[C]";
348 ar->linedefined = -1;
349 ar->lastlinedefined = -1;
350 ar->what = "C";
351 }
352 err_chunkid(ar->short_src, ar->source);
353 break;
354 case 'l':
355 ar->currentline = frame ? currentline(L, fn, nextframe) : -1;
356 break;
357 case 'u':
358 ar->nups = fn->c.nupvalues;
359 break;
360 case 'n':
361 ar->namewhat = frame ? getfuncname(L, frame, &ar->name) : NULL;
362 if (ar->namewhat == NULL) {
363 ar->namewhat = "";
364 ar->name = NULL;
365 }
366 break;
367 case 'f':
368 setfuncV(L, L->top, fn);
369 incr_top(L);
370 break;
371 case 'L':
372 if (isluafunc(fn)) {
373 GCtab *t = lj_tab_new(L, 0, 0);
374 GCproto *pt = funcproto(fn);
375 BCLine *lineinfo = proto_lineinfo(pt);
376 MSize i, szl = pt->sizebc;
377 for (i = 1; i < szl; i++)
378 setboolV(lj_tab_setint(L, t, lineinfo[i]), 1);
379 settabV(L, L->top, t);
380 } else {
381 setnilV(L->top);
382 }
383 incr_top(L);
384 break;
385 default:
386 status = 0; /* Bad option. */
387 break;
388 }
389 }
390 return status;
391}
392
393cTValue *lj_err_getframe(lua_State *L, int level, int *size)
394{
395 cTValue *frame, *nextframe, *bot = tvref(L->stack);
396 /* Traverse frames backwards. */
397 for (nextframe = frame = L->base-1; frame > bot; ) {
398 if (frame_gc(frame) == obj2gco(L))
399 level++; /* Skip dummy frames. See lj_meta_call(). */
400 if (level-- == 0) {
401 *size = (int)(nextframe - frame);
402 return frame; /* Level found. */
403 }
404 nextframe = frame;
405 if (frame_islua(frame)) {
406 frame = frame_prevl(frame);
407 } else {
408 if (frame_isvarg(frame))
409 level++; /* Skip vararg pseudo-frame. */
410 frame = frame_prevd(frame);
411 }
412 }
413 *size = level;
414 return NULL; /* Level not found. */
415}
416
417LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar)
418{
419 int size;
420 cTValue *frame = lj_err_getframe(L, level, &size);
421 if (frame) {
422 ar->i_ci = (size << 16) + (int)(frame - tvref(L->stack));
423 return 1;
424 } else {
425 ar->i_ci = level - size;
426 return 0;
427 }
428}
429
430/* -- Internal frame unwinding -------------------------------------------- */ 77/* -- Internal frame unwinding -------------------------------------------- */
431 78
432/* Unwind Lua stack and move error message to new top. */ 79/* Unwind Lua stack and move error message to new top. */
@@ -854,25 +501,6 @@ LJ_NOINLINE void lj_err_run(lua_State *L)
854 lj_err_throw(L, LUA_ERRRUN); 501 lj_err_throw(L, LUA_ERRRUN);
855} 502}
856 503
857/* Add location to error message. */
858LJ_NOINLINE static void err_loc(lua_State *L, const char *msg,
859 cTValue *frame, cTValue *nextframe)
860{
861 if (frame) {
862 GCfunc *fn = frame_func(frame);
863 if (isluafunc(fn)) {
864 char buff[LUA_IDSIZE];
865 BCLine line = currentline(L, fn, nextframe);
866 if (line >= 0) {
867 err_chunkid(buff, strdata(proto_chunkname(funcproto(fn))));
868 lj_str_pushf(L, "%s:%d: %s", buff, line, msg);
869 return;
870 }
871 }
872 }
873 lj_str_pushf(L, "%s", msg);
874}
875
876/* Formatted runtime error message. */ 504/* Formatted runtime error message. */
877LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...) 505LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...)
878{ 506{
@@ -882,7 +510,7 @@ LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...)
882 if (curr_funcisL(L)) L->top = curr_topL(L); 510 if (curr_funcisL(L)) L->top = curr_topL(L);
883 msg = lj_str_pushvf(L, err2msg(em), argp); 511 msg = lj_str_pushvf(L, err2msg(em), argp);
884 va_end(argp); 512 va_end(argp);
885 err_loc(L, msg, L->base-1, NULL); 513 lj_debug_addloc(L, msg, L->base-1, NULL);
886 lj_err_run(L); 514 lj_err_run(L);
887} 515}
888 516
@@ -898,7 +526,7 @@ LJ_NOINLINE void lj_err_lex(lua_State *L, const char *src, const char *tok,
898{ 526{
899 char buff[LUA_IDSIZE]; 527 char buff[LUA_IDSIZE];
900 const char *msg; 528 const char *msg;
901 err_chunkid(buff, src); 529 lj_debug_shortname(buff, src);
902 msg = lj_str_pushvf(L, err2msg(em), argp); 530 msg = lj_str_pushvf(L, err2msg(em), argp);
903 msg = lj_str_pushf(L, "%s:%d: %s", buff, line, msg); 531 msg = lj_str_pushf(L, "%s:%d: %s", buff, line, msg);
904 if (tok) 532 if (tok)
@@ -910,12 +538,12 @@ LJ_NOINLINE void lj_err_lex(lua_State *L, const char *src, const char *tok,
910LJ_NOINLINE void lj_err_optype(lua_State *L, cTValue *o, ErrMsg opm) 538LJ_NOINLINE void lj_err_optype(lua_State *L, cTValue *o, ErrMsg opm)
911{ 539{
912 const char *tname = typename(o); 540 const char *tname = typename(o);
913 const char *oname = NULL;
914 const char *opname = err2msg(opm); 541 const char *opname = err2msg(opm);
915 if (curr_funcisL(L)) { 542 if (curr_funcisL(L)) {
916 GCproto *pt = curr_proto(L); 543 GCproto *pt = curr_proto(L);
917 const BCIns *pc = cframe_Lpc(L) - 1; 544 const BCIns *pc = cframe_Lpc(L) - 1;
918 const char *kind = getobjname(pt, pc, (BCReg)(o - L->base), &oname); 545 const char *oname = NULL;
546 const char *kind = lj_debug_slotname(pt, pc, (BCReg)(o-L->base), &oname);
919 if (kind) 547 if (kind)
920 err_msgv(L, LJ_ERR_BADOPRT, opname, kind, oname, tname); 548 err_msgv(L, LJ_ERR_BADOPRT, opname, kind, oname, tname);
921 } 549 }
@@ -967,7 +595,7 @@ LJ_NOINLINE void lj_err_callermsg(lua_State *L, const char *msg)
967 } 595 }
968#endif 596#endif
969 } 597 }
970 err_loc(L, msg, pframe, frame); 598 lj_debug_addloc(L, msg, pframe, frame);
971 lj_err_run(L); 599 lj_err_run(L);
972} 600}
973 601
@@ -993,7 +621,7 @@ LJ_NORET LJ_NOINLINE static void err_argmsg(lua_State *L, int narg,
993 const char *msg) 621 const char *msg)
994{ 622{
995 const char *fname = "?"; 623 const char *fname = "?";
996 const char *ftype = getfuncname(L, L->base - 1, &fname); 624 const char *ftype = lj_debug_funcname(L, L->base - 1, &fname);
997 if (narg < 0 && narg > LUA_REGISTRYINDEX) 625 if (narg < 0 && narg > LUA_REGISTRYINDEX)
998 narg = (int)(L->top - L->base) + narg + 1; 626 narg = (int)(L->top - L->base) + narg + 1;
999 if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */ 627 if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */
@@ -1066,8 +694,8 @@ LUALIB_API int luaL_typerror(lua_State *L, int narg, const char *xname)
1066LUALIB_API void luaL_where(lua_State *L, int level) 694LUALIB_API void luaL_where(lua_State *L, int level)
1067{ 695{
1068 int size; 696 int size;
1069 cTValue *frame = lj_err_getframe(L, level, &size); 697 cTValue *frame = lj_debug_frame(L, level, &size);
1070 err_loc(L, "", frame, size ? frame+size : NULL); 698 lj_debug_addloc(L, "", frame, size ? frame+size : NULL);
1071} 699}
1072 700
1073LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...) 701LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...)
diff --git a/src/lj_err.h b/src/lj_err.h
index aabbf490..69ede6d6 100644
--- a/src/lj_err.h
+++ b/src/lj_err.h
@@ -1,5 +1,5 @@
1/* 1/*
2** Error handling and debugging support. 2** Error handling.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h 3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/ 4*/
5 5
@@ -38,7 +38,4 @@ LJ_FUNC_NORET void lj_err_argv(lua_State *L, int narg, ErrMsg em, ...);
38LJ_FUNC_NORET void lj_err_argtype(lua_State *L, int narg, const char *xname); 38LJ_FUNC_NORET void lj_err_argtype(lua_State *L, int narg, const char *xname);
39LJ_FUNC_NORET void lj_err_argt(lua_State *L, int narg, int tt); 39LJ_FUNC_NORET void lj_err_argt(lua_State *L, int narg, int tt);
40 40
41LJ_FUNC void lj_err_pushloc(lua_State *L, GCproto *pt, BCPos pc);
42LJ_FUNC cTValue *lj_err_getframe(lua_State *L, int level, int *size);
43
44#endif 41#endif
diff --git a/src/lj_gdbjit.c b/src/lj_gdbjit.c
index 41ee1b33..28e063fb 100644
--- a/src/lj_gdbjit.c
+++ b/src/lj_gdbjit.c
@@ -12,6 +12,7 @@
12 12
13#include "lj_gc.h" 13#include "lj_gc.h"
14#include "lj_err.h" 14#include "lj_err.h"
15#include "lj_debug.h"
15#include "lj_frame.h" 16#include "lj_frame.h"
16#include "lj_jit.h" 17#include "lj_jit.h"
17#include "lj_dispatch.h" 18#include "lj_dispatch.h"
@@ -728,10 +729,8 @@ void lj_gdbjit_addtrace(jit_State *J, GCtrace *T)
728 ctx.spadjp = CFRAME_SIZE_JIT + 729 ctx.spadjp = CFRAME_SIZE_JIT +
729 (MSize)(parent ? traceref(J, parent)->spadjust : 0); 730 (MSize)(parent ? traceref(J, parent)->spadjust : 0);
730 ctx.spadj = CFRAME_SIZE_JIT + T->spadjust; 731 ctx.spadj = CFRAME_SIZE_JIT + T->spadjust;
731 if (startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc) 732 lua_assert(startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc);
732 ctx.lineno = proto_line(pt, proto_bcpos(pt, startpc)); 733 ctx.lineno = lj_debug_line(pt, proto_bcpos(pt, startpc));
733 else
734 ctx.lineno = proto_line(pt, 0); /* Wrong, but better than nothing. */
735 ctx.filename = strdata(proto_chunkname(pt)); 734 ctx.filename = strdata(proto_chunkname(pt));
736 if (*ctx.filename == '@' || *ctx.filename == '=') 735 if (*ctx.filename == '@' || *ctx.filename == '=')
737 ctx.filename++; 736 ctx.filename++;
diff --git a/src/lj_trace.c b/src/lj_trace.c
index bef4558b..6b1dd2f6 100644
--- a/src/lj_trace.c
+++ b/src/lj_trace.c
@@ -12,6 +12,7 @@
12 12
13#include "lj_gc.h" 13#include "lj_gc.h"
14#include "lj_err.h" 14#include "lj_err.h"
15#include "lj_debug.h"
15#include "lj_str.h" 16#include "lj_str.h"
16#include "lj_frame.h" 17#include "lj_frame.h"
17#include "lj_state.h" 18#include "lj_state.h"
@@ -103,10 +104,8 @@ static void perftools_addtrace(GCtrace *T)
103 name++; 104 name++;
104 else 105 else
105 name = "(string)"; 106 name = "(string)";
106 if (startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc) 107 lua_assert(startpc >= proto_bc(pt) && startpc < proto_bc(pt) + pt->sizebc);
107 lineno = proto_line(pt, proto_bcpos(pt, startpc)); 108 lineno = lj_debug_line(pt, proto_bcpos(pt, startpc));
108 else
109 lineno = proto_line(pt, 0); /* Wrong, but better than nothing. */
110 if (!fp) { 109 if (!fp) {
111 char fname[40]; 110 char fname[40];
112 sprintf(fname, "/tmp/perf-%d.map", getpid()); 111 sprintf(fname, "/tmp/perf-%d.map", getpid());
diff --git a/src/ljamalg.c b/src/ljamalg.c
index 3d1f3938..fcfb77ff 100644
--- a/src/ljamalg.c
+++ b/src/ljamalg.c
@@ -38,6 +38,7 @@
38#include "lj_func.c" 38#include "lj_func.c"
39#include "lj_udata.c" 39#include "lj_udata.c"
40#include "lj_meta.c" 40#include "lj_meta.c"
41#include "lj_debug.c"
41#include "lj_state.c" 42#include "lj_state.c"
42#include "lj_dispatch.c" 43#include "lj_dispatch.c"
43#include "lj_vmevent.c" 44#include "lj_vmevent.c"