From 7c7d092337ce729b25b05a5ffc96fc6918ffdf64 Mon Sep 17 00:00:00 2001 From: SD Asif Hossein Date: Thu, 1 Aug 2024 01:17:10 +0600 Subject: [PATCH 1/5] Userside boilerplate reduction --- examples/fibonacci/module.c | 60 ++++++------ lib/ptracer.h | 25 +++++ run-lint | 46 ---------- run-tests | 2 - spec/tracebacks/anon_lua/main.lua | 1 - spec/tracebacks/anon_lua/module.c | 46 ++++------ spec/tracebacks/depth_recursion/main.lua | 3 - spec/tracebacks/depth_recursion/module.c | 52 ++++------- spec/tracebacks/dispatch/main.lua | 3 - spec/tracebacks/dispatch/module.c | 56 +++++------- spec/tracebacks/multimod/main.lua | 3 - spec/tracebacks/multimod/module_a.c | 49 ++++------ spec/tracebacks/multimod/module_b.c | 49 ++++------ spec/tracebacks/psoverflow/main.lua | 2 - spec/tracebacks/psoverflow/module.c | 45 ++++----- spec/tracebacks/singular/main.lua | 3 - spec/tracebacks/singular/module.c | 49 ++++------ spec/tracebacks_spec.lua | 112 +++++++++++------------ 18 files changed, 242 insertions(+), 364 deletions(-) delete mode 100755 run-lint diff --git a/examples/fibonacci/module.c b/examples/fibonacci/module.c index 2467767..65e377c 100644 --- a/examples/fibonacci/module.c +++ b/examples/fibonacci/module.c @@ -9,60 +9,52 @@ #include #ifdef MODULE_DEBUG -/* ---------------- FOR LUA INTERFACE FUNCTIONS ---------------- */ -/* The finalizer fn will run whenever out of scope. */ -#define PREPARE_FINALIZER() \ - int _base = lua_gettop(L); \ - lua_pushvalue(L, lua_upvalueindex(2)); \ - lua_toclose(L, -1) - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - pt_frame_t _frame = \ - PALLENE_TRACER_LUA_FRAME(fnptr); \ - pallene_tracer_frameenter(L, fnstack, &_frame); \ - PREPARE_FINALIZER() - -/* Nothing to do here. */ -#define MODULE_LUA_FRAMEEXIT() - -/* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ +/* ---------------- LUA INTERFACE ---------------- */ + +#define MODULE_LUA_FRAMEENTER(fnptr) \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)); \ + int _base = lua_gettop(L); \ + PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ + lua_upvalueindex(2), _frame) + +/* ---------------- LUA INTERFACE END ---------------- */ + +/* ---------------- C INTERFACE ---------------- */ + #define MODULE_C_PROTO(signature, ...) signature(pt_fnstack_t *fnstack, __VA_ARGS__) #define MODULE_C_CALL(fn_name, ...) fn_name(fnstack, __VA_ARGS__) -#define MODULE_C_FRAMEENTER() \ - static pt_fn_details_t _details = \ - PALLENE_TRACER_FN_DETAILS(__func__, __FILE__); \ - pt_frame_t _frame = \ - PALLENE_TRACER_C_FRAME(_details); \ - pallene_tracer_frameenter(L, fnstack, &_frame) +#define MODULE_C_FRAMEENTER() \ + PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) -#define MODULE_C_SETLINE() \ +#define MODULE_C_SETLINE() \ pallene_tracer_setline(fnstack, __LINE__ + 1) -#define MODULE_C_FRAMEEXIT() \ +#define MODULE_C_FRAMEEXIT() \ pallene_tracer_frameexit(fnstack) + +/* ---------------- C INTERFACE END ---------------- */ + #else -/* ---------------- FOR LUA INTERFACE FUNCTIONS ---------------- */ +/* ---------------- LUA INTERFACE ---------------- */ #define MODULE_LUA_FRAMEENTER(_) int _base = lua_gettop(L); -#define MODULE_LUA_FRAMEEXIT() -/* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ +/* ---------------- C INTERFACE ---------------- */ + #define MODULE_C_PROTO(signature, ...) signature(__VA_ARGS__) #define MODULE_C_CALL(fn_name, ...) fn_name(__VA_ARGS__) #define MODULE_C_FRAMEENTER() #define MODULE_C_SETLINE() #define MODULE_C_FRAMEEXIT() + +/* ---------------- C INTERFACE END ---------------- */ #endif // MODULE_DEBUG #define MODULE_C_RET(expression) \ MODULE_C_FRAMEEXIT(); \ return (expression) -#define MODULE_LUA_RET(expression) \ - MODULE_LUA_FRAMEEXIT(); \ - return (expression) MODULE_C_PROTO(int fib, lua_State *L, int n) { MODULE_C_FRAMEENTER(); @@ -92,7 +84,7 @@ int fib_lua(lua_State *L) { int result = MODULE_C_CALL(fib, L, lua_tointeger(L, -1)); lua_pushinteger(L, result); - MODULE_LUA_RET(1); + return 1; } int luaopen_module(lua_State *L) { diff --git a/lib/ptracer.h b/lib/ptracer.h index d60a06c..dbe46ab 100644 --- a/lib/ptracer.h +++ b/lib/ptracer.h @@ -84,6 +84,31 @@ /* ---- DATA-STRUCTURE HELPER MACROS END ---- */ +/* ---- API HELPER MACROS ---- */ + +/* Use this macro the bypass some frameenter boilerplates for Lua interface frames. */ +/* Note: `location` is where the finalizer object is in the stack, acquired from + `pallene_tracer_init()` function. If the object is passed to Lua C functions as an + upvalue, this should be `lua_upvalueindex(n)`. Otherwise, it should just be a number + denoting the parameter index where the object is found if passed as a plain parameter + to the functon. */ +/* The `var_name` indicates the name of the frame structure variable. */ +#define PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, location, var_name) \ +pt_frame_t var_name = PALLENE_TRACER_LUA_FRAME(fnptr); \ +pallene_tracer_frameenter(L, fnstack, &var_name); \ +lua_pushvalue(L, (location)); \ +lua_toclose(L, -1); + +/* Use this macro the bypass some frameenter boilerplates for C interface frames. */ +/* The `var_name` indicates the name of the frame structure variable. */ +#define PALLENE_TRACER_C_FRAMEENTER(L, fnstack, fn_name, filename, var_name) \ +pt_fn_details_t var_name##_details = \ + PALLENE_TRACER_FN_DETAILS(fn_name, filename); \ +pt_frame_t var_name = PALLENE_TRACER_C_FRAME(var_name##_details); \ +pallene_tracer_frameenter(L, fnstack, &var_name); + +/* ---- API HELPER MACROS END ---- */ + /* ---------------- MACRO DEFINITIONS END ---------------- */ /* ---------------- DATA STRUCTURES ---------------- */ diff --git a/run-lint b/run-lint deleted file mode 100755 index cb3ea67..0000000 --- a/run-lint +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh - -space=' ' -tab=' ' - -red='\033[1;31m' -green='\033[1;32m' -reset='\033[0m' - -ok=yes - -error() { - printf "${red}ERROR${reset} %s\n" "$*" - ok=no -} - -echo "--- Lua Lint ---" -luacheck src/misc/ spec/ examples/ "$@" || error "Luacheck found problems" -echo - -echo "--- Other checks ---" -for file in \ - src/bin/pallene-debug -do - if grep --line-number "[$space$tab]$" "$file"; then - # Forbid trailing whitespace because some editors like to automatically delete it. - # Such whitespace can cause spurious diffs later down the road, when someone is working on - # an unrelated pull request and their editor "helpfully" deletes the trailing whitespace. - error "File $file has a line that ends in whitespace" - fi - - if grep --line-number "^$space*$tab" "$file"; then - # Standardize on spaces because mixing tabs and spaces is endless pain. - error "File $file has tab-based indentation" - fi - - if ! grep --line-number --quiet 'SPDX-License-Identifier' "$file"; then - error "File $file is missing a copyright header" - fi -done - -if [ "$ok" != yes ]; then - exit 1 -fi - -printf "${green}OK${reset}\n" diff --git a/run-tests b/run-tests index 4eeee63..9375e53 100755 --- a/run-tests +++ b/run-tests @@ -28,8 +28,6 @@ if [ "$#" -eq 0 ]; then echo "GNU Parallel is not installed. Running the test suite in single threaded mode..." busted "${FLAGS[@]}" fi - # By default, also run the linter because the CI cares about that. - ./run-lint --quiet else # If we are running tests for a single spec file, then we do not use GNU Parallel. This way the # progress updates after each test, instead of all at once at end. diff --git a/spec/tracebacks/anon_lua/main.lua b/spec/tracebacks/anon_lua/main.lua index 9460013..89c9ade 100644 --- a/spec/tracebacks/anon_lua/main.lua +++ b/spec/tracebacks/anon_lua/main.lua @@ -13,5 +13,4 @@ local function wrapper() module.module_fn_1(lua_callee_1) end --- luacheck: globals pallene_tracer_debug_traceback xpcall(wrapper, pallene_tracer_debug_traceback) diff --git a/spec/tracebacks/anon_lua/module.c b/spec/tracebacks/anon_lua/module.c index 4a55f5e..36e1353 100644 --- a/spec/tracebacks/anon_lua/module.c +++ b/spec/tracebacks/anon_lua/module.c @@ -9,38 +9,30 @@ #define PT_IMPLEMENTATION #include -/* ---------------- FOR LUA INTERFACE FUNCTIONS ---------------- */ -/* The finalizer fn will run whenever out of scope. */ -#define PREPARE_FINALIZER() \ - int _base = lua_gettop(L); \ - lua_pushvalue(L, lua_upvalueindex(2)); \ - lua_toclose(L, -1) - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - pt_frame_t _frame = \ - PALLENE_TRACER_LUA_FRAME(fnptr); \ - pallene_tracer_frameenter(L, fnstack, &_frame); \ - PREPARE_FINALIZER() - -#define MODULE_LUA_FRAMEEXIT() \ - lua_settop(L, _base) +/* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_LUA_FRAMEENTER(fnptr) \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)); \ + int _base = lua_gettop(L); \ + PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ + lua_upvalueindex(2), _frame) + +/* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ /* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ -#define MODULE_C_FRAMEENTER() \ - static pt_fn_details_t _details = \ - PALLENE_TRACER_FN_DETAILS(__func__, __FILE__); \ - pt_frame_t _frame = \ - PALLENE_TRACER_C_FRAME(_details); \ - pallene_tracer_frameenter(L, fnstack, &_frame) - -#define MODULE_SETLINE() \ + +#define MODULE_C_FRAMEENTER() \ + PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) + +#define MODULE_SETLINE() \ pallene_tracer_setline(fnstack, __LINE__ + 1) -#define MODULE_C_FRAMEEXIT() \ +#define MODULE_C_FRAMEEXIT() \ pallene_tracer_frameexit(fnstack) +/* ---------------- FOR C INTERFACE FUNCTIONS END ---------------- */ + void some_untracked_c_function(lua_State *L, pt_fnstack_t *fnstack) { MODULE_C_FRAMEENTER(); @@ -79,7 +71,6 @@ int module_fn_1_lua(lua_State *L) { /* Now dispatch to an actual C function. */ module_fn_1(L, fnstack); - MODULE_LUA_FRAMEEXIT(); return 0; } @@ -102,7 +93,6 @@ int module_fn_2_lua(lua_State *L) { /* Dispatch. */ module_fn_2(L, fnstack); - MODULE_LUA_FRAMEEXIT(); return 0; } diff --git a/spec/tracebacks/depth_recursion/main.lua b/spec/tracebacks/depth_recursion/main.lua index f0e7e41..de8d4e2 100644 --- a/spec/tracebacks/depth_recursion/main.lua +++ b/spec/tracebacks/depth_recursion/main.lua @@ -5,7 +5,6 @@ local module = require "module" --- luacheck: globals lua_fn function lua_fn(depth) if depth == 0 then error "Depth reached 0!" @@ -16,10 +15,8 @@ end -- Should be local. -- Making it global so that it is visible in the traceback. --- luacheck: globals wrapper function wrapper() lua_fn(10) end --- luacheck: globals pallene_tracer_debug_traceback xpcall(wrapper, pallene_tracer_debug_traceback) diff --git a/spec/tracebacks/depth_recursion/module.c b/spec/tracebacks/depth_recursion/module.c index 80caccc..9c86ab7 100644 --- a/spec/tracebacks/depth_recursion/module.c +++ b/spec/tracebacks/depth_recursion/module.c @@ -9,46 +9,29 @@ #define PT_IMPLEMENTATION #include -/* ---------------- FOR LUA INTERFACE FUNCTIONS ---------------- */ -/* The finalizer fn will run whenever out of scope. */ -#define PREPARE_FINALIZER() \ - int _base = lua_gettop(L); \ - lua_pushvalue(L, lua_upvalueindex(2)); \ - lua_toclose(L, -1) - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - pt_frame_t _frame = \ - PALLENE_TRACER_LUA_FRAME(fnptr); \ - pallene_tracer_frameenter(L, fnstack, &_frame); \ - PREPARE_FINALIZER() - -#define MODULE_LUA_FRAMEEXIT() \ - lua_settop(L, _base) +/* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_LUA_FRAMEENTER(fnptr) \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)); \ + int _base = lua_gettop(L); \ + PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ + lua_upvalueindex(2), _frame) + +/* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ /* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ -#define MODULE_C_FRAMEENTER() \ - static pt_fn_details_t _details = \ - PALLENE_TRACER_FN_DETAILS(__func__, __FILE__); \ - pt_frame_t _frame = \ - PALLENE_TRACER_C_FRAME(_details); \ - pallene_tracer_frameenter(L, fnstack, &_frame) - -#define MODULE_SETLINE() \ - pallene_tracer_setline(fnstack, __LINE__ + 1) -#define MODULE_C_FRAMEEXIT() \ - pallene_tracer_frameexit(fnstack) +#define MODULE_C_FRAMEENTER() \ + PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) -void some_untracked_c_function(lua_State *L, pt_fnstack_t *fnstack) { - MODULE_C_FRAMEENTER(); +#define MODULE_SETLINE() \ + pallene_tracer_setline(fnstack, __LINE__ + 1) - MODULE_SETLINE(); - luaL_error(L, "Error from an untracked C function, which has no trace in Lua callstack!"); +#define MODULE_C_FRAMEEXIT() \ + pallene_tracer_frameexit(fnstack) - MODULE_C_FRAMEEXIT(); -} +/* ---------------- FOR C INTERFACE FUNCTIONS END ---------------- */ void module_fn(lua_State *L, pt_fnstack_t *fnstack, int depth) { MODULE_C_FRAMEENTER(); @@ -87,7 +70,6 @@ int module_fn_lua(lua_State *L) { /* Dispatch. */ module_fn(L, fnstack, depth); - MODULE_LUA_FRAMEEXIT(); return 0; } diff --git a/spec/tracebacks/dispatch/main.lua b/spec/tracebacks/dispatch/main.lua index d560b73..07b46ab 100644 --- a/spec/tracebacks/dispatch/main.lua +++ b/spec/tracebacks/dispatch/main.lua @@ -5,15 +5,12 @@ local module = require "module" --- luacheck: globals lua_callee_1 function lua_callee_1() module.module_fn_2() end --- luacheck: globals wrapper function wrapper() module.module_fn_1(lua_callee_1) end --- luacheck: globals pallene_tracer_debug_traceback xpcall(wrapper, pallene_tracer_debug_traceback) diff --git a/spec/tracebacks/dispatch/module.c b/spec/tracebacks/dispatch/module.c index 4a55f5e..946e936 100644 --- a/spec/tracebacks/dispatch/module.c +++ b/spec/tracebacks/dispatch/module.c @@ -9,43 +9,35 @@ #define PT_IMPLEMENTATION #include -/* ---------------- FOR LUA INTERFACE FUNCTIONS ---------------- */ -/* The finalizer fn will run whenever out of scope. */ -#define PREPARE_FINALIZER() \ - int _base = lua_gettop(L); \ - lua_pushvalue(L, lua_upvalueindex(2)); \ - lua_toclose(L, -1) - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - pt_frame_t _frame = \ - PALLENE_TRACER_LUA_FRAME(fnptr); \ - pallene_tracer_frameenter(L, fnstack, &_frame); \ - PREPARE_FINALIZER() - -#define MODULE_LUA_FRAMEEXIT() \ - lua_settop(L, _base) - -/* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ -#define MODULE_C_FRAMEENTER() \ - static pt_fn_details_t _details = \ - PALLENE_TRACER_FN_DETAILS(__func__, __FILE__); \ - pt_frame_t _frame = \ - PALLENE_TRACER_C_FRAME(_details); \ - pallene_tracer_frameenter(L, fnstack, &_frame) - -#define MODULE_SETLINE() \ +/* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_LUA_FRAMEENTER(fnptr) \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)); \ + int _base = lua_gettop(L); \ + PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ + lua_upvalueindex(2), _frame) + +/* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ + +/* ---------------- C INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_C_FRAMEENTER() \ + PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) + +#define MODULE_SETLINE() \ pallene_tracer_setline(fnstack, __LINE__ + 1) -#define MODULE_C_FRAMEEXIT() \ +#define MODULE_C_FRAMEEXIT() \ pallene_tracer_frameexit(fnstack) -void some_untracked_c_function(lua_State *L, pt_fnstack_t *fnstack) { +/* ---------------- C INTERFACE FUNCTIONS END ---------------- */ + +void some_oblivious_c_function(lua_State *L, pt_fnstack_t *fnstack) { MODULE_C_FRAMEENTER(); MODULE_SETLINE(); - luaL_error(L, "Error from an untracked C function, which has no trace in Lua callstack!"); + luaL_error(L, "Error from a C function, which has no trace in Lua callstack!"); MODULE_C_FRAMEEXIT(); } @@ -79,7 +71,6 @@ int module_fn_1_lua(lua_State *L) { /* Now dispatch to an actual C function. */ module_fn_1(L, fnstack); - MODULE_LUA_FRAMEEXIT(); return 0; } @@ -89,7 +80,7 @@ void module_fn_2(lua_State *L, pt_fnstack_t *fnstack) { // Other code... MODULE_SETLINE(); - some_untracked_c_function(L, fnstack); + some_oblivious_c_function(L, fnstack); // Other code... @@ -102,7 +93,6 @@ int module_fn_2_lua(lua_State *L) { /* Dispatch. */ module_fn_2(L, fnstack); - MODULE_LUA_FRAMEEXIT(); return 0; } diff --git a/spec/tracebacks/multimod/main.lua b/spec/tracebacks/multimod/main.lua index 52c3899..4897de7 100644 --- a/spec/tracebacks/multimod/main.lua +++ b/spec/tracebacks/multimod/main.lua @@ -6,15 +6,12 @@ local mod_a = require "module_a" local mod_b = require "module_b" --- luacheck: globals some_lua_fn function some_lua_fn() mod_b.another_mod_fn() end --- luacheck: globals wrapper function wrapper() mod_a.some_mod_fn(some_lua_fn) end --- luacheck: globals pallene_tracer_debug_traceback xpcall(wrapper, pallene_tracer_debug_traceback) diff --git a/spec/tracebacks/multimod/module_a.c b/spec/tracebacks/multimod/module_a.c index fa39c6e..2f6cd51 100644 --- a/spec/tracebacks/multimod/module_a.c +++ b/spec/tracebacks/multimod/module_a.c @@ -8,38 +8,30 @@ /* This time we would be doing dynamic linking. */ #include -/* ---------------- FOR LUA INTERFACE FUNCTIONS ---------------- */ -/* The finalizer fn will run whenever out of scope. */ -#define PREPARE_FINALIZER() \ - int _base = lua_gettop(L); \ - lua_pushvalue(L, lua_upvalueindex(2)); \ - lua_toclose(L, -1) - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - pt_frame_t _frame = \ - PALLENE_TRACER_LUA_FRAME(fnptr); \ - pallene_tracer_frameenter(L, fnstack, &_frame); \ - PREPARE_FINALIZER() - -#define MODULE_LUA_FRAMEEXIT() \ - lua_settop(L, _base) - -/* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ -#define MODULE_C_FRAMEENTER() \ - static pt_fn_details_t _details = \ - PALLENE_TRACER_FN_DETAILS(__func__, __FILE__); \ - pt_frame_t _frame = \ - PALLENE_TRACER_C_FRAME(_details); \ - pallene_tracer_frameenter(L, fnstack, &_frame) - -#define MODULE_SETLINE() \ +/* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_LUA_FRAMEENTER(fnptr) \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)); \ + int _base = lua_gettop(L); \ + PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ + lua_upvalueindex(2), _frame) + +/* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ + +/* ---------------- C INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_C_FRAMEENTER() \ + PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) + +#define MODULE_SETLINE() \ pallene_tracer_setline(fnstack, __LINE__ + 1) -#define MODULE_C_FRAMEEXIT() \ +#define MODULE_C_FRAMEEXIT() \ pallene_tracer_frameexit(fnstack) +/* ---------------- C INTERFACE FUNCTIONS END ---------------- */ + void some_mod_fn(lua_State *L, pt_fnstack_t *fnstack) { MODULE_C_FRAMEENTER(); @@ -67,7 +59,6 @@ int some_mod_fn_lua(lua_State *L) { /* Dispatch. */ some_mod_fn(L, fnstack); - MODULE_LUA_FRAMEEXIT(); return 0; } diff --git a/spec/tracebacks/multimod/module_b.c b/spec/tracebacks/multimod/module_b.c index 3526036..17ea3d6 100644 --- a/spec/tracebacks/multimod/module_b.c +++ b/spec/tracebacks/multimod/module_b.c @@ -8,38 +8,30 @@ /* This time we would be doing dynamic linking. */ #include -/* ---------------- FOR LUA INTERFACE FUNCTIONS ---------------- */ -/* The finalizer fn will run whenever out of scope. */ -#define PREPARE_FINALIZER() \ - int _base = lua_gettop(L); \ - lua_pushvalue(L, lua_upvalueindex(2)); \ - lua_toclose(L, -1) - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - pt_frame_t _frame = \ - PALLENE_TRACER_LUA_FRAME(fnptr); \ - pallene_tracer_frameenter(L, fnstack, &_frame); \ - PREPARE_FINALIZER() - -#define MODULE_LUA_FRAMEEXIT() \ - lua_settop(L, _base) - -/* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ -#define MODULE_C_FRAMEENTER() \ - static pt_fn_details_t _details = \ - PALLENE_TRACER_FN_DETAILS(__func__, __FILE__); \ - pt_frame_t _frame = \ - PALLENE_TRACER_C_FRAME(_details); \ - pallene_tracer_frameenter(L, fnstack, &_frame) - -#define MODULE_SETLINE() \ +/* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_LUA_FRAMEENTER(fnptr) \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)); \ + int _base = lua_gettop(L); \ + PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ + lua_upvalueindex(2), _frame) + +/* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ + +/* ---------------- C INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_C_FRAMEENTER() \ + PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) + +#define MODULE_SETLINE() \ pallene_tracer_setline(fnstack, __LINE__ + 1) -#define MODULE_C_FRAMEEXIT() \ +#define MODULE_C_FRAMEEXIT() \ pallene_tracer_frameexit(fnstack) +/* ---------------- C INTERFACE FUNCTIONS END ---------------- */ + void another_mod_fn(lua_State *L, pt_fnstack_t *fnstack) { MODULE_C_FRAMEENTER(); @@ -59,7 +51,6 @@ int another_mod_fn_lua(lua_State *L) { /* Dispatch. */ another_mod_fn(L, fnstack); - MODULE_LUA_FRAMEEXIT(); return 0; } diff --git a/spec/tracebacks/psoverflow/main.lua b/spec/tracebacks/psoverflow/main.lua index dad35dd..184bc4e 100644 --- a/spec/tracebacks/psoverflow/main.lua +++ b/spec/tracebacks/psoverflow/main.lua @@ -5,10 +5,8 @@ local module = require "module" --- luacheck: globals wrapper function wrapper() module.module_fn() end --- luacheck: globals pallene_tracer_debug_traceback xpcall(wrapper, pallene_tracer_debug_traceback) diff --git a/spec/tracebacks/psoverflow/module.c b/spec/tracebacks/psoverflow/module.c index 543b48b..46ae2fb 100644 --- a/spec/tracebacks/psoverflow/module.c +++ b/spec/tracebacks/psoverflow/module.c @@ -9,38 +9,30 @@ #define PT_IMPLEMENTATION #include -/* ---------------- FOR LUA INTERFACE FUNCTIONS ---------------- */ -/* The finalizer fn will run whenever out of scope. */ -#define PREPARE_FINALIZER() \ - int _base = lua_gettop(L); \ - lua_pushvalue(L, lua_upvalueindex(2)); \ - lua_toclose(L, -1) - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - pt_frame_t _frame = \ - PALLENE_TRACER_LUA_FRAME(fnptr); \ - pallene_tracer_frameenter(L, fnstack, &_frame); \ - PREPARE_FINALIZER() - -#define MODULE_LUA_FRAMEEXIT() \ - lua_settop(L, _base) +/* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_LUA_FRAMEENTER(fnptr) \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)); \ + int _base = lua_gettop(L); \ + PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ + lua_upvalueindex(2), _frame) + +/* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ /* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ -#define MODULE_C_FRAMEENTER() \ - static pt_fn_details_t _details = \ - PALLENE_TRACER_FN_DETAILS(__func__, __FILE__); \ - pt_frame_t _frame = \ - PALLENE_TRACER_C_FRAME(_details); \ - pallene_tracer_frameenter(L, fnstack, &_frame) - -#define MODULE_SETLINE() \ + +#define MODULE_C_FRAMEENTER() \ + PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) + +#define MODULE_SETLINE() \ pallene_tracer_setline(fnstack, __LINE__ + 1) -#define MODULE_C_FRAMEEXIT() \ +#define MODULE_C_FRAMEEXIT() \ pallene_tracer_frameexit(fnstack) +/* ---------------- FOR C INTERFACE FUNCTIONS END ---------------- */ + void trigger_pallene_stack_overflow(lua_State *L, pt_fnstack_t *fnstack, int count) { MODULE_C_FRAMEENTER(); @@ -73,7 +65,6 @@ int module_fn_lua(lua_State *L) { /* Dispatch */ module_fn(L, fnstack); - MODULE_LUA_FRAMEEXIT(); return 0; } diff --git a/spec/tracebacks/singular/main.lua b/spec/tracebacks/singular/main.lua index 6c99fb5..c722f73 100644 --- a/spec/tracebacks/singular/main.lua +++ b/spec/tracebacks/singular/main.lua @@ -5,15 +5,12 @@ local module = require "module" --- luacheck: globals some_lua_fn function some_lua_fn() module.singular_fn_1() end --- luacheck: globals wrapper function wrapper() some_lua_fn() end --- luacheck: globals pallene_tracer_debug_traceback xpcall(wrapper, pallene_tracer_debug_traceback) diff --git a/spec/tracebacks/singular/module.c b/spec/tracebacks/singular/module.c index 24c3ba6..507d63d 100644 --- a/spec/tracebacks/singular/module.c +++ b/spec/tracebacks/singular/module.c @@ -10,39 +10,29 @@ #include /* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ -#define MODULE_C_FRAMEENTER() \ - static pt_fn_details_t _details = \ - PALLENE_TRACER_FN_DETAILS(__func__, __FILE__); \ - pt_frame_t _frame_c = \ - PALLENE_TRACER_C_FRAME(_details); \ - pallene_tracer_frameenter(L, fnstack, &_frame_c) - -#define MODULE_SETLINE() \ + +#define MODULE_C_FRAMEENTER() \ + PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame_c) + +#define MODULE_SETLINE() \ pallene_tracer_setline(fnstack, __LINE__ + 1) -#define MODULE_C_FRAMEEXIT() \ +#define MODULE_C_FRAMEEXIT() \ pallene_tracer_frameexit(fnstack) -/* ---------------- FOR LUA INTERFACE FUNCTIONS ---------------- */ -/* The finalizer fn will run whenever out of scope. */ -#define PREPARE_FINALIZER() \ - int _base = lua_gettop(L); \ - lua_pushvalue(L, lua_upvalueindex(2)); \ - lua_toclose(L, -1) - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - pt_frame_t _frame_lua = \ - PALLENE_TRACER_LUA_FRAME(fnptr); \ - pallene_tracer_frameenter(L, fnstack, &_frame_lua); \ - MODULE_C_FRAMEENTER(); \ - PREPARE_FINALIZER() - -/* The finalizer will get rid of all the C interface frames - as well. */ -#define MODULE_LUA_FRAMEEXIT() \ - lua_settop(L, _base) +/* ---------------- FOR C INTERFACE FUNCTIONS END ---------------- */ + +/* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_LUA_FRAMEENTER(fnptr) \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)); \ + int _base = lua_gettop(L); \ + PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ + lua_upvalueindex(2), _frame_lua) \ + MODULE_C_FRAMEENTER() + +/* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ void lifes_good_fn(lua_State *L, pt_fnstack_t *fnstack) { MODULE_C_FRAMEENTER(); @@ -60,7 +50,6 @@ int singular_fn_1(lua_State *L) { MODULE_SETLINE(); lifes_good_fn(L, fnstack); - MODULE_LUA_FRAMEEXIT(); return 0; } diff --git a/spec/tracebacks_spec.lua b/spec/tracebacks_spec.lua index 6f9a154..8c98517 100644 --- a/spec/tracebacks_spec.lua +++ b/spec/tracebacks_spec.lua @@ -17,29 +17,29 @@ end it("Dispatch", function() assert_example("dispatch", [[ -Runtime error: main.lua:10: Error from an untracked C function, which has no trace in Lua callstack! +Runtime error: main.lua:9: Error from a C function, which has no trace in Lua callstack! Stack traceback: - module.c:48: in function 'some_untracked_c_function' - module.c:92: in function 'module_fn_2' - main.lua:10: in function 'lua_callee_1' - module.c:61: in function 'module_fn_1' - main.lua:15: in function 'wrapper' + module.c:40: in function 'some_oblivious_c_function' + module.c:83: in function 'module_fn_2' + main.lua:9: in function 'lua_callee_1' + module.c:53: in function 'module_fn_1' + main.lua:13: in function 'wrapper' C: in function 'xpcall' - main.lua:19: in
+ main.lua:16: in
C: in function '' ]]) end) it("Singular", function() assert_example("singular", [[ -Runtime error: main.lua:10: Life's !good +Runtime error: main.lua:9: Life's !good Stack traceback: - module.c:51: in function 'lifes_good_fn' - module.c:61: in function 'singular_fn_1' - main.lua:10: in function 'some_lua_fn' - main.lua:15: in function 'wrapper' + module.c:41: in function 'lifes_good_fn' + module.c:51: in function 'singular_fn_1' + main.lua:9: in function 'some_lua_fn' + main.lua:13: in function 'wrapper' C: in function 'xpcall' - main.lua:19: in
+ main.lua:16: in
C: in function '' ]]) end) @@ -47,67 +47,67 @@ end) it("Multi-module", function() assert_example("multimod", [[ -Runtime error: main.lua:11: Error from another module! +Runtime error: main.lua:10: Error from another module! Stack traceback: - module_b.c:49: in function 'another_mod_fn' - main.lua:11: in function 'some_lua_fn' - module_a.c:49: in function 'some_mod_fn' - main.lua:16: in function 'wrapper' + module_b.c:41: in function 'another_mod_fn' + main.lua:10: in function 'some_lua_fn' + module_a.c:41: in function 'some_mod_fn' + main.lua:14: in function 'wrapper' C: in function 'xpcall' - main.lua:20: in
+ main.lua:17: in
C: in function '' ]]) end) it("Pallene Stack Overflow", function() assert_example("psoverflow", [[ -Runtime error: main.lua:10: pallene callstack overflow +Runtime error: main.lua:9: pallene callstack overflow Stack traceback: - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' ... (Skipped 99983 frames) ... - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:53: in function 'trigger_pallene_stack_overflow' - module.c:65: in function 'module_fn' - main.lua:10: in function 'wrapper' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:57: in function 'module_fn' + main.lua:9: in function 'wrapper' C: in function 'xpcall' - main.lua:14: in
+ main.lua:12: in
C: in function '' ]]) end) it("Depth recursion", function() assert_example("depth_recursion", [[ -Runtime error: main.lua:11: Depth reached 0! +Runtime error: main.lua:10: Depth reached 0! Stack traceback: C: in function 'error' - main.lua:11: in function 'lua_fn' - module.c:63: in function 'module_fn' - main.lua:14: in function 'lua_fn' - module.c:63: in function 'module_fn' - main.lua:14: in function 'lua_fn' - module.c:63: in function 'module_fn' - main.lua:14: in function 'lua_fn' - module.c:63: in function 'module_fn' - main.lua:14: in function 'lua_fn' - module.c:63: in function 'module_fn' - main.lua:14: in function 'lua_fn' - main.lua:21: in function 'wrapper' + main.lua:10: in function 'lua_fn' + module.c:46: in function 'module_fn' + main.lua:13: in function 'lua_fn' + module.c:46: in function 'module_fn' + main.lua:13: in function 'lua_fn' + module.c:46: in function 'module_fn' + main.lua:13: in function 'lua_fn' + module.c:46: in function 'module_fn' + main.lua:13: in function 'lua_fn' + module.c:46: in function 'module_fn' + main.lua:13: in function 'lua_fn' + main.lua:19: in function 'wrapper' C: in function 'xpcall' - main.lua:25: in
+ main.lua:22: in
C: in function '' ]]) end) @@ -116,13 +116,13 @@ it("Anonymous Lua Fn", function() assert_example("anon_lua", [[ Runtime error: main.lua:9: Error from an untracked C function, which has no trace in Lua callstack! Stack traceback: - module.c:48: in function 'some_untracked_c_function' - module.c:92: in function 'module_fn_2' + module.c:40: in function 'some_untracked_c_function' + module.c:83: in function 'module_fn_2' main.lua:9: in function '' - module.c:61: in function 'module_fn_1' + module.c:53: in function 'module_fn_1' main.lua:13: in function '' C: in function 'xpcall' - main.lua:17: in
+ main.lua:16: in
C: in function '' ]]) end) From a6b950acb69eb62186374e70a408b4100255ef24 Mon Sep 17 00:00:00 2001 From: SD Asif Hossein Date: Thu, 1 Aug 2024 01:42:42 +0600 Subject: [PATCH 2/5] Fix Github CI script --- .github/workflows/ci.yml | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 816b2e5..529c3e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,44 +18,15 @@ name: Github Actions CI # - both events: runs the same checks twice, wasting compute time on: push: - branches: [ master ] + branches: [ main ] pull_request: - branches: [ master ] + branches: [ main ] env: LUA_VERSION: 5.4.6-2 LUAROCKS_VERSION: 3.9.0 jobs: - lint: - name: Lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Install Lua - run: | - wget -O - https://github.com/pallene-lang/lua-internals/archive/refs/tags/${{env.LUA_VERSION}}.tar.gz | tar xzf - - cd lua-internals-${{env.LUA_VERSION}} - make linux - sudo make install - - - name: Install Luarocks - run: | - wget -O - https://luarocks.org/releases/luarocks-${{env.LUAROCKS_VERSION}}.tar.gz | tar xzf - - cd luarocks-${{env.LUAROCKS_VERSION}} - ./configure --with-lua=/usr/local - make - sudo make install - - - name: Install Luacheck - run: luarocks install --local luacheck - - - name: Run Luacheck - run: | - eval "$(luarocks path)" - ./run-lint - test: name: Test runs-on: ubuntu-latest From d7475d21ad8402f9d559d07c4927ac795265602c Mon Sep 17 00:00:00 2001 From: SD Asif Hossein Date: Thu, 1 Aug 2024 01:59:37 +0600 Subject: [PATCH 3/5] Working GitHub CI script --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 529c3e5..8e7d788 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,9 @@ jobs: sudo make install - name: Build - run: luarocks --local make + run: | + sudo make install + luarocks --local make - name: Install Busted run: luarocks --local install busted From 782f1dddbea9a72332bbeba5a6d469d2d3c270ba Mon Sep 17 00:00:00 2001 From: SD Asif Hossein Date: Fri, 2 Aug 2024 21:18:23 +0600 Subject: [PATCH 4/5] Clipping more boilerplates enhancing UX --- examples/fibonacci/Makefile | 4 +- examples/fibonacci/fibonacci.c | 93 ++++++++++++++++++ examples/fibonacci/main.lua | 6 +- examples/fibonacci/module.c | 113 ---------------------- lib/ptracer.h | 49 ++++++++-- spec/tracebacks/anon_lua/Makefile | 2 +- spec/tracebacks/anon_lua/module.c | 54 ++++++----- spec/tracebacks/depth_recursion/Makefile | 2 +- spec/tracebacks/depth_recursion/module.c | 42 ++++---- spec/tracebacks/dispatch/Makefile | 2 +- spec/tracebacks/dispatch/module.c | 55 ++++++----- spec/tracebacks/multimod/Makefile | 4 +- spec/tracebacks/multimod/module_a.c | 41 ++------ spec/tracebacks/multimod/module_b.c | 33 +------ spec/tracebacks/multimod/module_include.h | 38 ++++++++ spec/tracebacks/psoverflow/Makefile | 2 +- spec/tracebacks/psoverflow/module.c | 36 ++++--- spec/tracebacks/singular/Makefile | 2 +- spec/tracebacks/singular/main.lua | 2 +- spec/tracebacks/singular/module.c | 42 ++++---- spec/tracebacks_spec.lua | 64 ++++++------ 21 files changed, 368 insertions(+), 318 deletions(-) create mode 100644 examples/fibonacci/fibonacci.c delete mode 100644 examples/fibonacci/module.c create mode 100644 spec/tracebacks/multimod/module_include.h diff --git a/examples/fibonacci/Makefile b/examples/fibonacci/Makefile index 20043bd..c307b10 100644 --- a/examples/fibonacci/Makefile +++ b/examples/fibonacci/Makefile @@ -9,7 +9,7 @@ CC := gcc .SILENT: all: - $(CC) -fPIC $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC $(CFLAGS) -shared fibonacci.c -o fibonacci.so debug: - $(CC) -fPIC $(CFLAGS) -DMODULE_DEBUG -shared module.c -o module.so + $(CC) -fPIC $(CFLAGS) -DPALLENE_TRACER_DEBUG -shared fibonacci.c -o fibonacci.so diff --git a/examples/fibonacci/fibonacci.c b/examples/fibonacci/fibonacci.c new file mode 100644 index 0000000..89473e3 --- /dev/null +++ b/examples/fibonacci/fibonacci.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024, The Pallene Developers + * Pallene Tracer is licensed under the MIT license. + * Please refer to the LICENSE and AUTHORS files for details + * SPDX-License-Identifier: MIT + */ + +#define PT_IMPLEMENTATION +#include + +/* User specific macros when Pallene Tracer debug mode is enabled. */ +#ifdef PALLENE_TRACER_DEBUG +#define FIB_GET_FNSTACK \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)) + +#else +#define FIB_GET_FNSTACK +#endif // PALLENE_TRACER_DEBUG + +/* ---------------- PALLENE TRACER LUA INERFACE ---------------- */ +#define FIB_LUA_FRAMEENTER(fnptr) \ + FIB_GET_FNSTACK; \ + PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ + lua_upvalueindex(2), _frame) +/* ---------------- PALLENE TRACER LUA INERFACE END ---------------- */ + +/* ---------------- PALLENE TRACER C INTERFACE ---------------- */ + +#define FIB_C_FRAMEENTER() \ + FIB_GET_FNSTACK; \ + PALLENE_TRACER_GENERIC_C_FRAMEENTER(L, fnstack, _frame) + +#define FIB_C_SETLINE() \ + PALLENE_TRACER_GENERIC_C_SETLINE(fnstack) + +#define FIB_C_FRAMEEXIT() \ + PALLENE_TRACER_FRAMEEXIT(fnstack) + +/* ---------------- PALLENE TRACER C INTERFACE END ---------------- */ + +int fib(lua_State *L, int n) { + FIB_C_FRAMEENTER(); + + if(n <= 1) { + FIB_C_FRAMEEXIT(); + return n; + } + + FIB_C_SETLINE(); + int result = fib(L, n - 1) + fib(L, n - 2); + FIB_C_FRAMEEXIT(); + return result; +} + +int fib_lua(lua_State *L) { + int top = lua_gettop(L); + FIB_LUA_FRAMEENTER(fib_lua); + + /* In Lua interface frames, we always have a finalizer object pushed to the stack by + `FIB_LUA_FRAMEENTER()`. */ + if(luai_unlikely(top < 1)) { + luaL_error(L, "Expected atleast 1 parameter"); + } + + if(luai_unlikely(lua_isinteger(L, 1) == 0)) { + luaL_error(L, "Expected the first argument to be an integer"); + } + + /* Dispatch. */ + int result = fib(L, lua_tointeger(L, 1)); + lua_pushinteger(L, result); + + return 1; +} + +int luaopen_fibonacci(lua_State *L) { + pt_fnstack_t *fnstack = pallene_tracer_init(L); + + lua_newtable(L); + int table = lua_gettop(L); + + /* ---- fib ---- */ + /* One very good way to integrate our stack userdatum and finalizer + object is by using Lua upvalues. */ + lua_pushlightuserdata(L, fnstack); + /* `pallene_tracer_init` function pushes the frameexit finalizer to the stack. */ + lua_pushvalue(L, -3); + lua_pushcclosure(L, fib_lua, 2); + lua_setfield(L, table, "fib"); + + return 1; +} diff --git a/examples/fibonacci/main.lua b/examples/fibonacci/main.lua index a85a1a6..95dca0d 100644 --- a/examples/fibonacci/main.lua +++ b/examples/fibonacci/main.lua @@ -3,7 +3,7 @@ -- Please refer to the LICENSE and AUTHORS files for details -- SPDX-License-Identifier: MIT -local mod = require "module" -print(mod.fib(40)) +local fibonacci = require "fibonacci" +print(fibonacci.fib(40)) -- Uncomment this and trigger an error. You can debug using the 'pallene-debug' script. --- print(mod.fib(40.0)) +-- print(fibonacci.fib(40.0)) diff --git a/examples/fibonacci/module.c b/examples/fibonacci/module.c deleted file mode 100644 index 65e377c..0000000 --- a/examples/fibonacci/module.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2024, The Pallene Developers - * Pallene Tracer is licensed under the MIT license. - * Please refer to the LICENSE and AUTHORS files for details - * SPDX-License-Identifier: MIT - */ - -#define PT_IMPLEMENTATION -#include - -#ifdef MODULE_DEBUG -/* ---------------- LUA INTERFACE ---------------- */ - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - int _base = lua_gettop(L); \ - PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ - lua_upvalueindex(2), _frame) - -/* ---------------- LUA INTERFACE END ---------------- */ - -/* ---------------- C INTERFACE ---------------- */ - -#define MODULE_C_PROTO(signature, ...) signature(pt_fnstack_t *fnstack, __VA_ARGS__) -#define MODULE_C_CALL(fn_name, ...) fn_name(fnstack, __VA_ARGS__) - -#define MODULE_C_FRAMEENTER() \ - PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) - -#define MODULE_C_SETLINE() \ - pallene_tracer_setline(fnstack, __LINE__ + 1) - -#define MODULE_C_FRAMEEXIT() \ - pallene_tracer_frameexit(fnstack) - -/* ---------------- C INTERFACE END ---------------- */ - -#else -/* ---------------- LUA INTERFACE ---------------- */ -#define MODULE_LUA_FRAMEENTER(_) int _base = lua_gettop(L); - -/* ---------------- C INTERFACE ---------------- */ - -#define MODULE_C_PROTO(signature, ...) signature(__VA_ARGS__) -#define MODULE_C_CALL(fn_name, ...) fn_name(__VA_ARGS__) - -#define MODULE_C_FRAMEENTER() -#define MODULE_C_SETLINE() -#define MODULE_C_FRAMEEXIT() - -/* ---------------- C INTERFACE END ---------------- */ -#endif // MODULE_DEBUG - -#define MODULE_C_RET(expression) \ - MODULE_C_FRAMEEXIT(); \ - return (expression) - -MODULE_C_PROTO(int fib, lua_State *L, int n) { - MODULE_C_FRAMEENTER(); - - if(n <= 1) { - MODULE_C_RET(n); - } - - MODULE_C_SETLINE(); - MODULE_C_RET(MODULE_C_CALL(fib, L, n - 1) + MODULE_C_CALL(fib, L, n - 2)); -} - -int fib_lua(lua_State *L) { - MODULE_LUA_FRAMEENTER(fib_lua); - - /* Check the macro definitions for '_base'. */ - if(_base < 1) { - luaL_error(L, "Expected atleast 1 parameter"); - } - - lua_pushvalue(L, 1); - if(luai_unlikely(lua_isinteger(L, -1) == 0)) { - luaL_error(L, "Expected the first argument to be an integer"); - } - - /* Dispatch. */ - int result = MODULE_C_CALL(fib, L, lua_tointeger(L, -1)); - lua_pushinteger(L, result); - - return 1; -} - -int luaopen_module(lua_State *L) { -#ifdef MODULE_DEBUG - /* Our stack. */ - pt_fnstack_t *fnstack = pallene_tracer_init(L); -#endif // MODULE_DEBUG - - lua_newtable(L); - int table = lua_gettop(L); - - /* ---- fib ---- */ -#ifdef MODULE_DEBUG - /* One very good way to integrate our stack userdatum and finalizer - object is by using Lua upvalues. */ - lua_pushlightuserdata(L, fnstack); - /* `pallene_tracer_init` function pushes the frameexit finalizer to the stack. */ - lua_pushvalue(L, -3); - lua_pushcclosure(L, fib_lua, 2); -#else - lua_pushcfunction(L, fib_lua); -#endif // MODULE_DEBUG - lua_setfield(L, table, "fib"); - - return 1; -} diff --git a/lib/ptracer.h b/lib/ptracer.h index dbe46ab..9f73bfb 100644 --- a/lib/ptracer.h +++ b/lib/ptracer.h @@ -59,6 +59,27 @@ do it like this. */ #define PALLENE_TRACEBACK_BOTTOM_THRESHOLD 8 +/* API wrapper macros. Using these wrappers instead is raw functions + * are highly recommended. */ +#ifdef PALLENE_TRACER_DEBUG +#define PALLENE_TRACER_FRAMEENTER(L, fnstack, frame) pallene_tracer_frameenter(L, fnstack, frame) +#define PALLENE_TRACER_SETLINE(fnstack, line) pallene_tracer_setline(fnstack, line) +#define PALLENE_TRACER_FRAMEEXIT(fnstack) pallene_tracer_frameexit(fnstack) + +#else +#define PALLENE_TRACER_FRAMEENTER(L, fnstack, frame) +#define PALLENE_TRACER_SETLINE(fnstack, line) +#define PALLENE_TRACER_FRAMEEXIT(fnstack) +#endif // PALLENE_TRACER_DEBUG + +/* Not part of the API. */ +#ifdef PALLENE_TRACER_DEBUG +#define _PALLENE_TRACER_FINALIZER(L, location) lua_pushvalue(L, (location)); \ + lua_toclose(L, -1); +#else +#define _PALLENE_TRACER_FINALIZER(L, location) +#endif + /* ---- DATA-STRUCTURE HELPER MACROS ---- */ /* Use this macro to fill in the details structure. */ @@ -92,20 +113,28 @@ upvalue, this should be `lua_upvalueindex(n)`. Otherwise, it should just be a number denoting the parameter index where the object is found if passed as a plain parameter to the functon. */ -/* The `var_name` indicates the name of the frame structure variable. */ +/* The `var_name` indicates the name of the `pt_frame_t` structure variable. */ #define PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, location, var_name) \ pt_frame_t var_name = PALLENE_TRACER_LUA_FRAME(fnptr); \ -pallene_tracer_frameenter(L, fnstack, &var_name); \ -lua_pushvalue(L, (location)); \ -lua_toclose(L, -1); +PALLENE_TRACER_FRAMEENTER(L, fnstack, &var_name); \ +_PALLENE_TRACER_FINALIZER(L, location) /* Use this macro the bypass some frameenter boilerplates for C interface frames. */ -/* The `var_name` indicates the name of the frame structure variable. */ +/* The `var_name` indicates the name of the `pt_frame_t` structure variable. */ #define PALLENE_TRACER_C_FRAMEENTER(L, fnstack, fn_name, filename, var_name) \ pt_fn_details_t var_name##_details = \ PALLENE_TRACER_FN_DETAILS(fn_name, filename); \ pt_frame_t var_name = PALLENE_TRACER_C_FRAME(var_name##_details); \ -pallene_tracer_frameenter(L, fnstack, &var_name); +PALLENE_TRACER_FRAMEENTER(L, fnstack, &var_name); + +/* -- GENERIC MACROS -- */ + +/* FOR NORMAL C MODULES THESE MACROS SHOULD SUFFICE. */ +#define PALLENE_TRACER_GENERIC_C_FRAMEENTER(L, fnstack, var_name) \ + PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, var_name) + +#define PALLENE_TRACER_GENERIC_C_SETLINE(fnstack) \ + PALLENE_TRACER_SETLINE(fnstack, __LINE__ + 1) /* ---- API HELPER MACROS END ---- */ @@ -332,7 +361,10 @@ static int _pallene_tracer_free_resources(lua_State *L) { /* This function must only be called from Lua module entry point. */ /* NOTE: Pushes the finalizer object to the stack. The object has to be closed everytime you are in a Lua C function using `lua_toclose(L, idx)`. */ +/* ALSO NOTE: The stack and finalizer object would be returned if and only if `PALLENE_TRACER_DEBUG` + is set. Otherwise, a NULL pointer would be returned alongside a NIL value pushed onto the stack. */ pt_fnstack_t *pallene_tracer_init(lua_State *L) { +#ifdef PALLENE_TRACER_DEBUG pt_fnstack_t *fnstack = NULL; /* Try getting the userdata. */ @@ -377,6 +409,11 @@ pt_fnstack_t *pallene_tracer_init(lua_State *L) { } return fnstack; +#else + /* No debug mode, no stack and finalizer object. Regardless we need to fill in the blanks. */ + lua_pushnil(L); + return NULL; +#endif // PALLENE_TRACER_DEBUG } /* Pushes a frame to the stack. The frame structure is self-managed for every function. */ diff --git a/spec/tracebacks/anon_lua/Makefile b/spec/tracebacks/anon_lua/Makefile index 970bb70..8c07bdf 100644 --- a/spec/tracebacks/anon_lua/Makefile +++ b/spec/tracebacks/anon_lua/Makefile @@ -9,4 +9,4 @@ CC := gcc .SILENT: all: - $(CC) -fPIC $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module.c -o module.so diff --git a/spec/tracebacks/anon_lua/module.c b/spec/tracebacks/anon_lua/module.c index 36e1353..6ea4df2 100644 --- a/spec/tracebacks/anon_lua/module.c +++ b/spec/tracebacks/anon_lua/module.c @@ -9,12 +9,19 @@ #define PT_IMPLEMENTATION #include +/* Here goes user specifc macros when Pallene Tracer debug mode is active. */ +#ifdef PALLENE_TRACER_DEBUG +#define MODULE_GET_FNSTACK \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)) +#else +#define MODULE_GET_FNSTACK +#endif // PALLENE_TRACER_DEBUG + /* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ #define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - int _base = lua_gettop(L); \ + MODULE_GET_FNSTACK; \ PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ lua_upvalueindex(2), _frame) @@ -23,33 +30,34 @@ /* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ #define MODULE_C_FRAMEENTER() \ - PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) + MODULE_GET_FNSTACK; \ + PALLENE_TRACER_GENERIC_C_FRAMEENTER(L, fnstack, _frame) -#define MODULE_SETLINE() \ - pallene_tracer_setline(fnstack, __LINE__ + 1) +#define MODULE_C_SETLINE() \ + PALLENE_TRACER_GENERIC_C_SETLINE(fnstack) #define MODULE_C_FRAMEEXIT() \ - pallene_tracer_frameexit(fnstack) + PALLENE_TRACER_FRAMEEXIT(fnstack) /* ---------------- FOR C INTERFACE FUNCTIONS END ---------------- */ -void some_untracked_c_function(lua_State *L, pt_fnstack_t *fnstack) { +void some_oblivious_c_function(lua_State *L) { MODULE_C_FRAMEENTER(); - MODULE_SETLINE(); - luaL_error(L, "Error from an untracked C function, which has no trace in Lua callstack!"); + MODULE_C_SETLINE(); + luaL_error(L, "Error from a C function, which has no trace in Lua callstack!"); MODULE_C_FRAMEEXIT(); } -void module_fn_1(lua_State *L, pt_fnstack_t *fnstack) { +void module_fn_1(lua_State *L) { MODULE_C_FRAMEENTER(); - // Other code... + lua_pushvalue(L, 1); /* Set line number to current active frame in the Pallene callstack and call the function which is already in the Lua stack. */ - MODULE_SETLINE(); + MODULE_C_SETLINE(); lua_call(L, 0, 0); // Other code... @@ -58,29 +66,30 @@ void module_fn_1(lua_State *L, pt_fnstack_t *fnstack) { } int module_fn_1_lua(lua_State *L) { + int top = lua_gettop(L); MODULE_LUA_FRAMEENTER(module_fn_1_lua); - /* Peep at the macro defintion for `_base`. */ - if(luai_unlikely(_base < 1)) + /* In Lua interface frames, we always have a finalizer object pushed to the stack by + `FIB_LUA_FRAMEENTER()`. */ + if(luai_unlikely(top < 1)) luaL_error(L, "Expected atleast 1 parameters"); - lua_pushvalue(L, 1); - if(luai_unlikely(lua_isfunction(L, -1) == 0)) + if(luai_unlikely(lua_isfunction(L, 1) == 0)) luaL_error(L, "Expected parameter 1 to be a function"); /* Now dispatch to an actual C function. */ - module_fn_1(L, fnstack); + module_fn_1(L); return 0; } -void module_fn_2(lua_State *L, pt_fnstack_t *fnstack) { +void module_fn_2(lua_State *L) { MODULE_C_FRAMEENTER(); // Other code... - MODULE_SETLINE(); - some_untracked_c_function(L, fnstack); + MODULE_C_SETLINE(); + some_oblivious_c_function(L); // Other code... @@ -91,7 +100,7 @@ int module_fn_2_lua(lua_State *L) { MODULE_LUA_FRAMEENTER(module_fn_2_lua); /* Dispatch. */ - module_fn_2(L, fnstack); + module_fn_2(L); return 0; } @@ -120,3 +129,4 @@ int luaopen_module(lua_State *L) { return 1; } + diff --git a/spec/tracebacks/depth_recursion/Makefile b/spec/tracebacks/depth_recursion/Makefile index 970bb70..8c07bdf 100644 --- a/spec/tracebacks/depth_recursion/Makefile +++ b/spec/tracebacks/depth_recursion/Makefile @@ -9,4 +9,4 @@ CC := gcc .SILENT: all: - $(CC) -fPIC $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module.c -o module.so diff --git a/spec/tracebacks/depth_recursion/module.c b/spec/tracebacks/depth_recursion/module.c index 9c86ab7..00f79df 100644 --- a/spec/tracebacks/depth_recursion/module.c +++ b/spec/tracebacks/depth_recursion/module.c @@ -9,12 +9,19 @@ #define PT_IMPLEMENTATION #include +/* Here goes user specific macros when Pallene Tracer debug mode is active. */ +#ifdef PALLENE_TRACER_DEBUG +#define MODULE_GET_FNSTACK \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)) +#else +#define MODULE_GET_FNSTACK +#endif // PALLENE_TRACER_DEBUG + /* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ #define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - int _base = lua_gettop(L); \ + MODULE_GET_FNSTACK; \ PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ lua_upvalueindex(2), _frame) @@ -23,52 +30,53 @@ /* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ #define MODULE_C_FRAMEENTER() \ - PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) + MODULE_GET_FNSTACK; \ + PALLENE_TRACER_GENERIC_C_FRAMEENTER(L, fnstack, _frame) -#define MODULE_SETLINE() \ - pallene_tracer_setline(fnstack, __LINE__ + 1) +#define MODULE_C_SETLINE() \ + PALLENE_TRACER_GENERIC_C_SETLINE(fnstack) #define MODULE_C_FRAMEEXIT() \ - pallene_tracer_frameexit(fnstack) + PALLENE_TRACER_FRAMEEXIT(fnstack) /* ---------------- FOR C INTERFACE FUNCTIONS END ---------------- */ -void module_fn(lua_State *L, pt_fnstack_t *fnstack, int depth) { +void module_fn(lua_State *L, int depth) { MODULE_C_FRAMEENTER(); + lua_pushvalue(L, 1); + if(depth == 0) lua_pushinteger(L, depth); else lua_pushinteger(L, depth - 1); /* Set line number to current active frame in the Pallene callstack and call the function which is already in the Lua stack. */ - MODULE_SETLINE(); + MODULE_C_SETLINE(); lua_call(L, 1, 0); MODULE_C_FRAMEEXIT(); } int module_fn_lua(lua_State *L) { + int top = lua_gettop(L); MODULE_LUA_FRAMEENTER(module_fn_lua); /* Look at the macro definitions. */ - if(luai_unlikely(_base < 2)) + if(luai_unlikely(top < 2)) luaL_error(L, "Expected atleast 2 parameters"); /* ---- `lua_fn` ---- */ - lua_pushvalue(L, 1); - if(luai_unlikely(lua_isfunction(L, -1) == 0)) + if(luai_unlikely(lua_isfunction(L, 1) == 0)) luaL_error(L, "Expected the first parameter to be a function"); - lua_pushvalue(L, 2); - if(luai_unlikely(lua_isinteger(L, -1) == 0)) + if(luai_unlikely(lua_isinteger(L, 2) == 0)) luaL_error(L, "Expected the second parameter to be an integer"); - int depth = lua_tointeger(L, -1); - lua_pop(L, 1); + int depth = lua_tointeger(L, 2); /* Dispatch. */ - module_fn(L, fnstack, depth); + module_fn(L, depth); return 0; } diff --git a/spec/tracebacks/dispatch/Makefile b/spec/tracebacks/dispatch/Makefile index 970bb70..8c07bdf 100644 --- a/spec/tracebacks/dispatch/Makefile +++ b/spec/tracebacks/dispatch/Makefile @@ -9,4 +9,4 @@ CC := gcc .SILENT: all: - $(CC) -fPIC $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module.c -o module.so diff --git a/spec/tracebacks/dispatch/module.c b/spec/tracebacks/dispatch/module.c index 946e936..cdbe2b0 100644 --- a/spec/tracebacks/dispatch/module.c +++ b/spec/tracebacks/dispatch/module.c @@ -9,47 +9,55 @@ #define PT_IMPLEMENTATION #include +/* Here goes user specific macros when Pallene Tracer debug mode is active. */ +#ifdef PALLENE_TRACER_DEBUG +#define MODULE_GET_FNSTACK \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)) +#else +#define MODULE_GET_FNSTACK +#endif // PALLENE_TRACER_DEBUG + /* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ #define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - int _base = lua_gettop(L); \ + MODULE_GET_FNSTACK; \ PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ lua_upvalueindex(2), _frame) /* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ -/* ---------------- C INTERFACE FUNCTIONS ---------------- */ +/* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ #define MODULE_C_FRAMEENTER() \ - PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) + MODULE_GET_FNSTACK; \ + PALLENE_TRACER_GENERIC_C_FRAMEENTER(L, fnstack, _frame) -#define MODULE_SETLINE() \ - pallene_tracer_setline(fnstack, __LINE__ + 1) +#define MODULE_C_SETLINE() \ + PALLENE_TRACER_GENERIC_C_SETLINE(fnstack) #define MODULE_C_FRAMEEXIT() \ - pallene_tracer_frameexit(fnstack) + PALLENE_TRACER_FRAMEEXIT(fnstack) -/* ---------------- C INTERFACE FUNCTIONS END ---------------- */ +/* ---------------- FOR C INTERFACE FUNCTIONS END ---------------- */ -void some_oblivious_c_function(lua_State *L, pt_fnstack_t *fnstack) { +void some_oblivious_c_function(lua_State *L) { MODULE_C_FRAMEENTER(); - MODULE_SETLINE(); + MODULE_C_SETLINE(); luaL_error(L, "Error from a C function, which has no trace in Lua callstack!"); MODULE_C_FRAMEEXIT(); } -void module_fn_1(lua_State *L, pt_fnstack_t *fnstack) { +void module_fn_1(lua_State *L) { MODULE_C_FRAMEENTER(); - // Other code... + lua_pushvalue(L, 1); /* Set line number to current active frame in the Pallene callstack and call the function which is already in the Lua stack. */ - MODULE_SETLINE(); + MODULE_C_SETLINE(); lua_call(L, 0, 0); // Other code... @@ -58,29 +66,30 @@ void module_fn_1(lua_State *L, pt_fnstack_t *fnstack) { } int module_fn_1_lua(lua_State *L) { + int top = lua_gettop(L); MODULE_LUA_FRAMEENTER(module_fn_1_lua); - /* Peep at the macro defintion for `_base`. */ - if(luai_unlikely(_base < 1)) + /* In Lua interface frames, we always have a finalizer object pushed to the stack by + `FIB_LUA_FRAMEENTER()`. */ + if(luai_unlikely(top < 1)) luaL_error(L, "Expected atleast 1 parameters"); - lua_pushvalue(L, 1); - if(luai_unlikely(lua_isfunction(L, -1) == 0)) + if(luai_unlikely(lua_isfunction(L, 1) == 0)) luaL_error(L, "Expected parameter 1 to be a function"); /* Now dispatch to an actual C function. */ - module_fn_1(L, fnstack); + module_fn_1(L); return 0; } -void module_fn_2(lua_State *L, pt_fnstack_t *fnstack) { +void module_fn_2(lua_State *L) { MODULE_C_FRAMEENTER(); // Other code... - MODULE_SETLINE(); - some_oblivious_c_function(L, fnstack); + MODULE_C_SETLINE(); + some_oblivious_c_function(L); // Other code... @@ -91,7 +100,7 @@ int module_fn_2_lua(lua_State *L) { MODULE_LUA_FRAMEENTER(module_fn_2_lua); /* Dispatch. */ - module_fn_2(L, fnstack); + module_fn_2(L); return 0; } diff --git a/spec/tracebacks/multimod/Makefile b/spec/tracebacks/multimod/Makefile index 8bc14d3..24558ac 100644 --- a/spec/tracebacks/multimod/Makefile +++ b/spec/tracebacks/multimod/Makefile @@ -10,5 +10,5 @@ LIB_DIR := /usr/local/lib .SILENT: all: - $(CC) -fPIC $(CFLAGS) -shared module_a.c -o module_a.so -lptracer -Wl,-rpath=$(LIB_DIR) -L$(LIB_DIR) - $(CC) -fPIC $(CFLAGS) -shared module_b.c -o module_b.so -lptracer -Wl,-rpath=$(LIB_DIR) -L$(LIB_DIR) + $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module_a.c -o module_a.so -lptracer -Wl,-rpath=$(LIB_DIR) -L$(LIB_DIR) + $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module_b.c -o module_b.so -lptracer -Wl,-rpath=$(LIB_DIR) -L$(LIB_DIR) diff --git a/spec/tracebacks/multimod/module_a.c b/spec/tracebacks/multimod/module_a.c index 2f6cd51..de6acd1 100644 --- a/spec/tracebacks/multimod/module_a.c +++ b/spec/tracebacks/multimod/module_a.c @@ -6,38 +6,15 @@ */ /* This time we would be doing dynamic linking. */ -#include +#include "module_include.h" -/* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - int _base = lua_gettop(L); \ - PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ - lua_upvalueindex(2), _frame) - -/* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ - -/* ---------------- C INTERFACE FUNCTIONS ---------------- */ - -#define MODULE_C_FRAMEENTER() \ - PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) - -#define MODULE_SETLINE() \ - pallene_tracer_setline(fnstack, __LINE__ + 1) - -#define MODULE_C_FRAMEEXIT() \ - pallene_tracer_frameexit(fnstack) - -/* ---------------- C INTERFACE FUNCTIONS END ---------------- */ - -void some_mod_fn(lua_State *L, pt_fnstack_t *fnstack) { +void some_mod_fn(lua_State *L) { MODULE_C_FRAMEENTER(); - // Other code... + /* The lua function which is passed to us. */ + lua_pushvalue(L, 1); - MODULE_SETLINE(); + MODULE_C_SETLINE(); lua_call(L, 0, 0); // Other code... @@ -46,18 +23,18 @@ void some_mod_fn(lua_State *L, pt_fnstack_t *fnstack) { } int some_mod_fn_lua(lua_State *L) { + int top = lua_gettop(L); MODULE_LUA_FRAMEENTER(some_mod_fn_lua); /* Look at the macro definition. */ - if(_base < 1) + if(luai_unlikely(top < 1)) luaL_error(L, "Expected atleast 1 argument"); - lua_pushvalue(L, 1); - if(luai_unlikely(lua_isfunction(L, -1) == 0)) + if(luai_unlikely(lua_isfunction(L, 1) == 0)) luaL_error(L, "Expected the first argument to be a function"); /* Dispatch. */ - some_mod_fn(L, fnstack); + some_mod_fn(L); return 0; } diff --git a/spec/tracebacks/multimod/module_b.c b/spec/tracebacks/multimod/module_b.c index 17ea3d6..252fe83 100644 --- a/spec/tracebacks/multimod/module_b.c +++ b/spec/tracebacks/multimod/module_b.c @@ -5,39 +5,14 @@ * SPDX-License-Identifier: MIT */ -/* This time we would be doing dynamic linking. */ -#include +#include "module_include.h" -/* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ - -#define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - int _base = lua_gettop(L); \ - PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ - lua_upvalueindex(2), _frame) - -/* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ - -/* ---------------- C INTERFACE FUNCTIONS ---------------- */ - -#define MODULE_C_FRAMEENTER() \ - PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) - -#define MODULE_SETLINE() \ - pallene_tracer_setline(fnstack, __LINE__ + 1) - -#define MODULE_C_FRAMEEXIT() \ - pallene_tracer_frameexit(fnstack) - -/* ---------------- C INTERFACE FUNCTIONS END ---------------- */ - -void another_mod_fn(lua_State *L, pt_fnstack_t *fnstack) { +void another_mod_fn(lua_State *L) { MODULE_C_FRAMEENTER(); // Other code... - MODULE_SETLINE(); + MODULE_C_SETLINE(); luaL_error(L, "Error from another module!"); // Other code... @@ -49,7 +24,7 @@ int another_mod_fn_lua(lua_State *L) { MODULE_LUA_FRAMEENTER(another_mod_fn_lua); /* Dispatch. */ - another_mod_fn(L, fnstack); + another_mod_fn(L); return 0; } diff --git a/spec/tracebacks/multimod/module_include.h b/spec/tracebacks/multimod/module_include.h new file mode 100644 index 0000000..04a56a5 --- /dev/null +++ b/spec/tracebacks/multimod/module_include.h @@ -0,0 +1,38 @@ +#ifndef MODULE_INCLUDE_HEADER +#define MODULE_INCLUDE_HEADER + +#include + +/* Here goes user specific macros when Pallene Tracer debug mode is active. */ +#ifdef PALLENE_TRACER_DEBUG +#define MODULE_GET_FNSTACK \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)) +#else +#define MODULE_GET_FNSTACK +#endif // PALLENE_TRACER_DEBUG + +/* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_LUA_FRAMEENTER(fnptr) \ + MODULE_GET_FNSTACK; \ + PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ + lua_upvalueindex(2), _frame) + +/* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ + +/* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ + +#define MODULE_C_FRAMEENTER() \ + MODULE_GET_FNSTACK; \ + PALLENE_TRACER_GENERIC_C_FRAMEENTER(L, fnstack, _frame) + +#define MODULE_C_SETLINE() \ + PALLENE_TRACER_GENERIC_C_SETLINE(fnstack) + +#define MODULE_C_FRAMEEXIT() \ + PALLENE_TRACER_FRAMEEXIT(fnstack) + +/* ---------------- FOR C INTERFACE FUNCTIONS END ---------------- */ + +#endif // MODULE_INCLUDE_HEADER diff --git a/spec/tracebacks/psoverflow/Makefile b/spec/tracebacks/psoverflow/Makefile index 970bb70..8c07bdf 100644 --- a/spec/tracebacks/psoverflow/Makefile +++ b/spec/tracebacks/psoverflow/Makefile @@ -9,4 +9,4 @@ CC := gcc .SILENT: all: - $(CC) -fPIC $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module.c -o module.so diff --git a/spec/tracebacks/psoverflow/module.c b/spec/tracebacks/psoverflow/module.c index 46ae2fb..e30645f 100644 --- a/spec/tracebacks/psoverflow/module.c +++ b/spec/tracebacks/psoverflow/module.c @@ -9,12 +9,19 @@ #define PT_IMPLEMENTATION #include +/* Here goes user specific macros when Pallene Tracer debug mode is active. */ +#ifdef PALLENE_TRACER_DEBUG +#define MODULE_GET_FNSTACK \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)) +#else +#define MODULE_GET_FNSTACK +#endif // PALLENE_TRACER_DEBUG + /* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ #define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - int _base = lua_gettop(L); \ + MODULE_GET_FNSTACK; \ PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ lua_upvalueindex(2), _frame) @@ -23,17 +30,18 @@ /* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ #define MODULE_C_FRAMEENTER() \ - PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame) + MODULE_GET_FNSTACK; \ + PALLENE_TRACER_GENERIC_C_FRAMEENTER(L, fnstack, _frame) -#define MODULE_SETLINE() \ - pallene_tracer_setline(fnstack, __LINE__ + 1) +#define MODULE_C_SETLINE() \ + PALLENE_TRACER_GENERIC_C_SETLINE(fnstack) #define MODULE_C_FRAMEEXIT() \ - pallene_tracer_frameexit(fnstack) + PALLENE_TRACER_FRAMEEXIT(fnstack) /* ---------------- FOR C INTERFACE FUNCTIONS END ---------------- */ -void trigger_pallene_stack_overflow(lua_State *L, pt_fnstack_t *fnstack, int count) { +void trigger_pallene_stack_overflow(lua_State *L, int count) { MODULE_C_FRAMEENTER(); /* We are not supposed to use this macro. */ @@ -41,20 +49,20 @@ void trigger_pallene_stack_overflow(lua_State *L, pt_fnstack_t *fnstack, int cou warnings for infinite recursion as we are deliberately triggering the callstack error. */ if(count < PALLENE_TRACER_MAX_CALLSTACK) { - MODULE_SETLINE(); - trigger_pallene_stack_overflow(L, fnstack, count + 1); + MODULE_C_SETLINE(); + trigger_pallene_stack_overflow(L, count + 1); } MODULE_C_FRAMEEXIT(); } -void module_fn(lua_State *L, pt_fnstack_t *fnstack) { +void module_fn(lua_State *L) { MODULE_C_FRAMEENTER(); /* Set line number to current active frame in the Pallene callstack and call the function which is already in the Lua stack. */ - MODULE_SETLINE(); - trigger_pallene_stack_overflow(L, fnstack, 0); + MODULE_C_SETLINE(); + trigger_pallene_stack_overflow(L, 0); MODULE_C_FRAMEEXIT(); } @@ -63,7 +71,7 @@ int module_fn_lua(lua_State *L) { MODULE_LUA_FRAMEENTER(module_fn_lua); /* Dispatch */ - module_fn(L, fnstack); + module_fn(L); return 0; } diff --git a/spec/tracebacks/singular/Makefile b/spec/tracebacks/singular/Makefile index 970bb70..8c07bdf 100644 --- a/spec/tracebacks/singular/Makefile +++ b/spec/tracebacks/singular/Makefile @@ -9,4 +9,4 @@ CC := gcc .SILENT: all: - $(CC) -fPIC $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module.c -o module.so diff --git a/spec/tracebacks/singular/main.lua b/spec/tracebacks/singular/main.lua index c722f73..8d6e5f4 100644 --- a/spec/tracebacks/singular/main.lua +++ b/spec/tracebacks/singular/main.lua @@ -6,7 +6,7 @@ local module = require "module" function some_lua_fn() - module.singular_fn_1() + module.singular_fn() end function wrapper() diff --git a/spec/tracebacks/singular/module.c b/spec/tracebacks/singular/module.c index 507d63d..07677c6 100644 --- a/spec/tracebacks/singular/module.c +++ b/spec/tracebacks/singular/module.c @@ -9,46 +9,54 @@ #define PT_IMPLEMENTATION #include +/* Here goes user specific macros when Pallene Tracer debug mode is active. */ +#ifdef PALLENE_TRACER_DEBUG +#define MODULE_GET_FNSTACK \ + pt_fnstack_t *fnstack = lua_touserdata(L, \ + lua_upvalueindex(1)) +#else +#define MODULE_GET_FNSTACK +#endif // PALLENE_TRACER_DEBUG + /* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */ #define MODULE_C_FRAMEENTER() \ - PALLENE_TRACER_C_FRAMEENTER(L, fnstack, __func__, __FILE__, _frame_c) + MODULE_GET_FNSTACK; \ + PALLENE_TRACER_GENERIC_C_FRAMEENTER(L, fnstack, _frame) -#define MODULE_SETLINE() \ - pallene_tracer_setline(fnstack, __LINE__ + 1) +#define MODULE_C_SETLINE() \ + PALLENE_TRACER_GENERIC_C_SETLINE(fnstack) #define MODULE_C_FRAMEEXIT() \ - pallene_tracer_frameexit(fnstack) + PALLENE_TRACER_FRAMEEXIT(fnstack) /* ---------------- FOR C INTERFACE FUNCTIONS END ---------------- */ /* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ #define MODULE_LUA_FRAMEENTER(fnptr) \ - pt_fnstack_t *fnstack = lua_touserdata(L, \ - lua_upvalueindex(1)); \ - int _base = lua_gettop(L); \ + MODULE_GET_FNSTACK; \ PALLENE_TRACER_LUA_FRAMEENTER(L, fnstack, fnptr, \ lua_upvalueindex(2), _frame_lua) \ - MODULE_C_FRAMEENTER() + PALLENE_TRACER_GENERIC_C_FRAMEENTER(L, fnstack, _frame_c) /* ---------------- LUA INTERFACE FUNCTIONS END ---------------- */ -void lifes_good_fn(lua_State *L, pt_fnstack_t *fnstack) { +void lifes_good_fn(lua_State *L) { MODULE_C_FRAMEENTER(); - MODULE_SETLINE(); + MODULE_C_SETLINE(); luaL_error(L, "Life's !good"); MODULE_C_FRAMEEXIT(); } -int singular_fn_1(lua_State *L) { - MODULE_LUA_FRAMEENTER(singular_fn_1); +int singular_fn(lua_State *L) { + MODULE_LUA_FRAMEENTER(singular_fn); /* Call some C function. */ - MODULE_SETLINE(); - lifes_good_fn(L, fnstack); + MODULE_C_SETLINE(); + lifes_good_fn(L); return 0; } @@ -61,12 +69,12 @@ int luaopen_module(lua_State *L) { /* One very good way to integrate our stack userdatum and finalizer object is by using Lua upvalues. */ - /* ---- singular_fn_1 ---- */ + /* ---- singular_fn ---- */ lua_pushlightuserdata(L, fnstack); /* `pallene_tracer_init` function pushes the frameexit finalizer to the stack. */ lua_pushvalue(L, -3); - lua_pushcclosure(L, singular_fn_1, 2); - lua_setfield(L, -2, "singular_fn_1"); + lua_pushcclosure(L, singular_fn, 2); + lua_setfield(L, -2, "singular_fn"); return 1; } diff --git a/spec/tracebacks_spec.lua b/spec/tracebacks_spec.lua index 8c98517..d9fc653 100644 --- a/spec/tracebacks_spec.lua +++ b/spec/tracebacks_spec.lua @@ -19,10 +19,10 @@ it("Dispatch", function() assert_example("dispatch", [[ Runtime error: main.lua:9: Error from a C function, which has no trace in Lua callstack! Stack traceback: - module.c:40: in function 'some_oblivious_c_function' - module.c:83: in function 'module_fn_2' + module.c:48: in function 'some_oblivious_c_function' + module.c:92: in function 'module_fn_2' main.lua:9: in function 'lua_callee_1' - module.c:53: in function 'module_fn_1' + module.c:61: in function 'module_fn_1' main.lua:13: in function 'wrapper' C: in function 'xpcall' main.lua:16: in
@@ -34,8 +34,8 @@ it("Singular", function() assert_example("singular", [[ Runtime error: main.lua:9: Life's !good Stack traceback: - module.c:41: in function 'lifes_good_fn' - module.c:51: in function 'singular_fn_1' + module.c:49: in function 'lifes_good_fn' + module.c:59: in function 'singular_fn' main.lua:9: in function 'some_lua_fn' main.lua:13: in function 'wrapper' C: in function 'xpcall' @@ -49,9 +49,9 @@ it("Multi-module", function() assert_example("multimod", [[ Runtime error: main.lua:10: Error from another module! Stack traceback: - module_b.c:41: in function 'another_mod_fn' + module_b.c:16: in function 'another_mod_fn' main.lua:10: in function 'some_lua_fn' - module_a.c:41: in function 'some_mod_fn' + module_a.c:18: in function 'some_mod_fn' main.lua:14: in function 'wrapper' C: in function 'xpcall' main.lua:17: in
@@ -63,25 +63,25 @@ it("Pallene Stack Overflow", function() assert_example("psoverflow", [[ Runtime error: main.lua:9: pallene callstack overflow Stack traceback: - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' ... (Skipped 99983 frames) ... - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:45: in function 'trigger_pallene_stack_overflow' - module.c:57: in function 'module_fn' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:53: in function 'trigger_pallene_stack_overflow' + module.c:65: in function 'module_fn' main.lua:9: in function 'wrapper' C: in function 'xpcall' main.lua:12: in
@@ -95,15 +95,15 @@ Runtime error: main.lua:10: Depth reached 0! Stack traceback: C: in function 'error' main.lua:10: in function 'lua_fn' - module.c:46: in function 'module_fn' + module.c:56: in function 'module_fn' main.lua:13: in function 'lua_fn' - module.c:46: in function 'module_fn' + module.c:56: in function 'module_fn' main.lua:13: in function 'lua_fn' - module.c:46: in function 'module_fn' + module.c:56: in function 'module_fn' main.lua:13: in function 'lua_fn' - module.c:46: in function 'module_fn' + module.c:56: in function 'module_fn' main.lua:13: in function 'lua_fn' - module.c:46: in function 'module_fn' + module.c:56: in function 'module_fn' main.lua:13: in function 'lua_fn' main.lua:19: in function 'wrapper' C: in function 'xpcall' @@ -114,12 +114,12 @@ end) it("Anonymous Lua Fn", function() assert_example("anon_lua", [[ -Runtime error: main.lua:9: Error from an untracked C function, which has no trace in Lua callstack! +Runtime error: main.lua:9: Error from a C function, which has no trace in Lua callstack! Stack traceback: - module.c:40: in function 'some_untracked_c_function' - module.c:83: in function 'module_fn_2' + module.c:48: in function 'some_oblivious_c_function' + module.c:92: in function 'module_fn_2' main.lua:9: in function '' - module.c:53: in function 'module_fn_1' + module.c:61: in function 'module_fn_1' main.lua:13: in function '' C: in function 'xpcall' main.lua:16: in
From 21d8845ff50849890af12e9820b2ada446884b29 Mon Sep 17 00:00:00 2001 From: SD Asif Hossein Date: Fri, 2 Aug 2024 22:17:36 +0600 Subject: [PATCH 5/5] CI update and some bug fixes --- .github/workflows/ci.yml | 7 ++++--- Makefile | 2 +- examples/fibonacci/Makefile | 2 +- examples/fibonacci/fibonacci.c | 4 ++-- lib/ptracer.h | 21 +++++++++++---------- ptinit/ptinit.c | 1 + spec/tracebacks/anon_lua/Makefile | 2 +- spec/tracebacks/anon_lua/module.c | 4 ++-- spec/tracebacks/depth_recursion/Makefile | 2 +- spec/tracebacks/depth_recursion/module.c | 4 ++-- spec/tracebacks/dispatch/Makefile | 2 +- spec/tracebacks/dispatch/module.c | 4 ++-- spec/tracebacks/multimod/Makefile | 4 ++-- spec/tracebacks/multimod/module_include.h | 4 ++-- spec/tracebacks/psoverflow/Makefile | 2 +- spec/tracebacks/psoverflow/module.c | 4 ++-- spec/tracebacks/singular/Makefile | 2 +- spec/tracebacks/singular/module.c | 4 ++-- 18 files changed, 39 insertions(+), 36 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e7d788..f96c051 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ on: branches: [ main ] env: - LUA_VERSION: 5.4.6-2 + LUA_VERSION: 5.4.7 LUAROCKS_VERSION: 3.9.0 jobs: @@ -35,8 +35,8 @@ jobs: - name: Install Lua run: | - wget -O - https://github.com/pallene-lang/lua-internals/archive/refs/tags/${{env.LUA_VERSION}}.tar.gz | tar xzf - - cd lua-internals-${{env.LUA_VERSION}} + wget -O - https://www.lua.org/ftp/lua-${{env.LUA_VERSION}}.tar.gz | tar xzf - + cd lua-${{env.LUA_VERSION}} make linux sudo make install @@ -60,3 +60,4 @@ jobs: run: | eval "$(luarocks path)" busted -o gtest -v ./spec + diff --git a/Makefile b/Makefile index 4dd52f3..109f60f 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ ptracer_header: cp lib/ptracer.h $(INSTALL_INCDIR) libptracer: - $(CC) -fPIC -O2 -shared src/ptracer.c -o libptracer.so + $(CC) -fPIC -DPT_DEBUG -O2 -shared src/ptracer.c -o libptracer.so uninstall: rm -rf $(INSTALL_INCDIR)/ptracer.h diff --git a/examples/fibonacci/Makefile b/examples/fibonacci/Makefile index c307b10..b91c6f0 100644 --- a/examples/fibonacci/Makefile +++ b/examples/fibonacci/Makefile @@ -12,4 +12,4 @@ all: $(CC) -fPIC $(CFLAGS) -shared fibonacci.c -o fibonacci.so debug: - $(CC) -fPIC $(CFLAGS) -DPALLENE_TRACER_DEBUG -shared fibonacci.c -o fibonacci.so + $(CC) -fPIC $(CFLAGS) -DPT_DEBUG -shared fibonacci.c -o fibonacci.so diff --git a/examples/fibonacci/fibonacci.c b/examples/fibonacci/fibonacci.c index 89473e3..f676a7b 100644 --- a/examples/fibonacci/fibonacci.c +++ b/examples/fibonacci/fibonacci.c @@ -9,14 +9,14 @@ #include /* User specific macros when Pallene Tracer debug mode is enabled. */ -#ifdef PALLENE_TRACER_DEBUG +#ifdef PT_DEBUG #define FIB_GET_FNSTACK \ pt_fnstack_t *fnstack = lua_touserdata(L, \ lua_upvalueindex(1)) #else #define FIB_GET_FNSTACK -#endif // PALLENE_TRACER_DEBUG +#endif // PT_DEBUG /* ---------------- PALLENE TRACER LUA INERFACE ---------------- */ #define FIB_LUA_FRAMEENTER(fnptr) \ diff --git a/lib/ptracer.h b/lib/ptracer.h index 9f73bfb..91607d2 100644 --- a/lib/ptracer.h +++ b/lib/ptracer.h @@ -10,7 +10,6 @@ #include #include -#include #include #include @@ -24,8 +23,10 @@ #if defined(__GNUC__) || defined(__clang__) #define PALLENE_TRACER_UNREACHABLE __builtin_unreachable() +#define pt_noret __attribute__((noreturn)) void #elif defined(_MSC_VER) // MSVC #define PALLENE_TRACER_UNREACHABLE __assume(false) +#define pt_noret __declspec(noreturn) void #endif #ifdef PT_BUILD_AS_DLL @@ -61,7 +62,7 @@ /* API wrapper macros. Using these wrappers instead is raw functions * are highly recommended. */ -#ifdef PALLENE_TRACER_DEBUG +#ifdef PT_DEBUG #define PALLENE_TRACER_FRAMEENTER(L, fnstack, frame) pallene_tracer_frameenter(L, fnstack, frame) #define PALLENE_TRACER_SETLINE(fnstack, line) pallene_tracer_setline(fnstack, line) #define PALLENE_TRACER_FRAMEEXIT(fnstack) pallene_tracer_frameexit(fnstack) @@ -70,15 +71,15 @@ #define PALLENE_TRACER_FRAMEENTER(L, fnstack, frame) #define PALLENE_TRACER_SETLINE(fnstack, line) #define PALLENE_TRACER_FRAMEEXIT(fnstack) -#endif // PALLENE_TRACER_DEBUG +#endif // PT_DEBUG /* Not part of the API. */ -#ifdef PALLENE_TRACER_DEBUG +#ifdef PT_DEBUG #define _PALLENE_TRACER_FINALIZER(L, location) lua_pushvalue(L, (location)); \ lua_toclose(L, -1); #else #define _PALLENE_TRACER_FINALIZER(L, location) -#endif +#endif // PT_DEBUG /* ---- DATA-STRUCTURE HELPER MACROS ---- */ @@ -211,7 +212,7 @@ PT_API int pallene_tracer_debug_traceback(lua_State *L); PT_API int pallene_tracer_finalizer(lua_State *L); /* Runtime error to invoke when Pallene call-stack overflowed. */ -l_noret pallene_tracer_runtime_callstack_overflow_error(lua_State *L); +pt_noret pallene_tracer_runtime_callstack_overflow_error(lua_State *L); #ifdef __cplusplus } @@ -361,10 +362,10 @@ static int _pallene_tracer_free_resources(lua_State *L) { /* This function must only be called from Lua module entry point. */ /* NOTE: Pushes the finalizer object to the stack. The object has to be closed everytime you are in a Lua C function using `lua_toclose(L, idx)`. */ -/* ALSO NOTE: The stack and finalizer object would be returned if and only if `PALLENE_TRACER_DEBUG` +/* ALSO NOTE: The stack and finalizer object would be returned if and only if `PT_DEBUG` is set. Otherwise, a NULL pointer would be returned alongside a NIL value pushed onto the stack. */ pt_fnstack_t *pallene_tracer_init(lua_State *L) { -#ifdef PALLENE_TRACER_DEBUG +#ifdef PT_DEBUG pt_fnstack_t *fnstack = NULL; /* Try getting the userdata. */ @@ -413,7 +414,7 @@ pt_fnstack_t *pallene_tracer_init(lua_State *L) { /* No debug mode, no stack and finalizer object. Regardless we need to fill in the blanks. */ lua_pushnil(L); return NULL; -#endif // PALLENE_TRACER_DEBUG +#endif // PT_DEBUG } /* Pushes a frame to the stack. The frame structure is self-managed for every function. */ @@ -564,7 +565,7 @@ int pallene_tracer_finalizer(lua_State *L) { } /* Runtime error to invoke when Pallene call-stack overflowed. */ -l_noret pallene_tracer_runtime_callstack_overflow_error(lua_State *L) { +pt_noret pallene_tracer_runtime_callstack_overflow_error(lua_State *L) { luaL_error(L, "pallene callstack overflow"); PALLENE_TRACER_UNREACHABLE; } diff --git a/ptinit/ptinit.c b/ptinit/ptinit.c index c11f629..56e0b52 100644 --- a/ptinit/ptinit.c +++ b/ptinit/ptinit.c @@ -6,6 +6,7 @@ */ #define PT_IMPLEMENTATION +#define PT_DEBUG #include int luaopen_ptinit(lua_State *L) { diff --git a/spec/tracebacks/anon_lua/Makefile b/spec/tracebacks/anon_lua/Makefile index 8c07bdf..25aa3f4 100644 --- a/spec/tracebacks/anon_lua/Makefile +++ b/spec/tracebacks/anon_lua/Makefile @@ -9,4 +9,4 @@ CC := gcc .SILENT: all: - $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC -DPT_DEBUG $(CFLAGS) -shared module.c -o module.so diff --git a/spec/tracebacks/anon_lua/module.c b/spec/tracebacks/anon_lua/module.c index 6ea4df2..6384839 100644 --- a/spec/tracebacks/anon_lua/module.c +++ b/spec/tracebacks/anon_lua/module.c @@ -10,13 +10,13 @@ #include /* Here goes user specifc macros when Pallene Tracer debug mode is active. */ -#ifdef PALLENE_TRACER_DEBUG +#ifdef PT_DEBUG #define MODULE_GET_FNSTACK \ pt_fnstack_t *fnstack = lua_touserdata(L, \ lua_upvalueindex(1)) #else #define MODULE_GET_FNSTACK -#endif // PALLENE_TRACER_DEBUG +#endif // PT_DEBUG /* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ diff --git a/spec/tracebacks/depth_recursion/Makefile b/spec/tracebacks/depth_recursion/Makefile index 8c07bdf..25aa3f4 100644 --- a/spec/tracebacks/depth_recursion/Makefile +++ b/spec/tracebacks/depth_recursion/Makefile @@ -9,4 +9,4 @@ CC := gcc .SILENT: all: - $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC -DPT_DEBUG $(CFLAGS) -shared module.c -o module.so diff --git a/spec/tracebacks/depth_recursion/module.c b/spec/tracebacks/depth_recursion/module.c index 00f79df..0bff1e5 100644 --- a/spec/tracebacks/depth_recursion/module.c +++ b/spec/tracebacks/depth_recursion/module.c @@ -10,13 +10,13 @@ #include /* Here goes user specific macros when Pallene Tracer debug mode is active. */ -#ifdef PALLENE_TRACER_DEBUG +#ifdef PT_DEBUG #define MODULE_GET_FNSTACK \ pt_fnstack_t *fnstack = lua_touserdata(L, \ lua_upvalueindex(1)) #else #define MODULE_GET_FNSTACK -#endif // PALLENE_TRACER_DEBUG +#endif // PT_DEBUG /* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ diff --git a/spec/tracebacks/dispatch/Makefile b/spec/tracebacks/dispatch/Makefile index 8c07bdf..25aa3f4 100644 --- a/spec/tracebacks/dispatch/Makefile +++ b/spec/tracebacks/dispatch/Makefile @@ -9,4 +9,4 @@ CC := gcc .SILENT: all: - $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC -DPT_DEBUG $(CFLAGS) -shared module.c -o module.so diff --git a/spec/tracebacks/dispatch/module.c b/spec/tracebacks/dispatch/module.c index cdbe2b0..16f5a55 100644 --- a/spec/tracebacks/dispatch/module.c +++ b/spec/tracebacks/dispatch/module.c @@ -10,13 +10,13 @@ #include /* Here goes user specific macros when Pallene Tracer debug mode is active. */ -#ifdef PALLENE_TRACER_DEBUG +#ifdef PT_DEBUG #define MODULE_GET_FNSTACK \ pt_fnstack_t *fnstack = lua_touserdata(L, \ lua_upvalueindex(1)) #else #define MODULE_GET_FNSTACK -#endif // PALLENE_TRACER_DEBUG +#endif // PT_DEBUG /* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ diff --git a/spec/tracebacks/multimod/Makefile b/spec/tracebacks/multimod/Makefile index 24558ac..3d1db71 100644 --- a/spec/tracebacks/multimod/Makefile +++ b/spec/tracebacks/multimod/Makefile @@ -10,5 +10,5 @@ LIB_DIR := /usr/local/lib .SILENT: all: - $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module_a.c -o module_a.so -lptracer -Wl,-rpath=$(LIB_DIR) -L$(LIB_DIR) - $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module_b.c -o module_b.so -lptracer -Wl,-rpath=$(LIB_DIR) -L$(LIB_DIR) + $(CC) -fPIC -DPT_DEBUG $(CFLAGS) -shared module_a.c -o module_a.so -lptracer -Wl,-rpath=$(LIB_DIR) -L$(LIB_DIR) + $(CC) -fPIC -DPT_DEBUG $(CFLAGS) -shared module_b.c -o module_b.so -lptracer -Wl,-rpath=$(LIB_DIR) -L$(LIB_DIR) diff --git a/spec/tracebacks/multimod/module_include.h b/spec/tracebacks/multimod/module_include.h index 04a56a5..618d09e 100644 --- a/spec/tracebacks/multimod/module_include.h +++ b/spec/tracebacks/multimod/module_include.h @@ -4,13 +4,13 @@ #include /* Here goes user specific macros when Pallene Tracer debug mode is active. */ -#ifdef PALLENE_TRACER_DEBUG +#ifdef PT_DEBUG #define MODULE_GET_FNSTACK \ pt_fnstack_t *fnstack = lua_touserdata(L, \ lua_upvalueindex(1)) #else #define MODULE_GET_FNSTACK -#endif // PALLENE_TRACER_DEBUG +#endif // PT_DEBUG /* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ diff --git a/spec/tracebacks/psoverflow/Makefile b/spec/tracebacks/psoverflow/Makefile index 8c07bdf..25aa3f4 100644 --- a/spec/tracebacks/psoverflow/Makefile +++ b/spec/tracebacks/psoverflow/Makefile @@ -9,4 +9,4 @@ CC := gcc .SILENT: all: - $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC -DPT_DEBUG $(CFLAGS) -shared module.c -o module.so diff --git a/spec/tracebacks/psoverflow/module.c b/spec/tracebacks/psoverflow/module.c index e30645f..e9b0488 100644 --- a/spec/tracebacks/psoverflow/module.c +++ b/spec/tracebacks/psoverflow/module.c @@ -10,13 +10,13 @@ #include /* Here goes user specific macros when Pallene Tracer debug mode is active. */ -#ifdef PALLENE_TRACER_DEBUG +#ifdef PT_DEBUG #define MODULE_GET_FNSTACK \ pt_fnstack_t *fnstack = lua_touserdata(L, \ lua_upvalueindex(1)) #else #define MODULE_GET_FNSTACK -#endif // PALLENE_TRACER_DEBUG +#endif // PT_DEBUG /* ---------------- LUA INTERFACE FUNCTIONS ---------------- */ diff --git a/spec/tracebacks/singular/Makefile b/spec/tracebacks/singular/Makefile index 8c07bdf..25aa3f4 100644 --- a/spec/tracebacks/singular/Makefile +++ b/spec/tracebacks/singular/Makefile @@ -9,4 +9,4 @@ CC := gcc .SILENT: all: - $(CC) -fPIC -DPALLENE_TRACER_DEBUG $(CFLAGS) -shared module.c -o module.so + $(CC) -fPIC -DPT_DEBUG $(CFLAGS) -shared module.c -o module.so diff --git a/spec/tracebacks/singular/module.c b/spec/tracebacks/singular/module.c index 07677c6..cd35ef3 100644 --- a/spec/tracebacks/singular/module.c +++ b/spec/tracebacks/singular/module.c @@ -10,13 +10,13 @@ #include /* Here goes user specific macros when Pallene Tracer debug mode is active. */ -#ifdef PALLENE_TRACER_DEBUG +#ifdef PT_DEBUG #define MODULE_GET_FNSTACK \ pt_fnstack_t *fnstack = lua_touserdata(L, \ lua_upvalueindex(1)) #else #define MODULE_GET_FNSTACK -#endif // PALLENE_TRACER_DEBUG +#endif // PT_DEBUG /* ---------------- FOR C INTERFACE FUNCTIONS ---------------- */