Replace g_frame_stack with call_stack used by ScriptProfiler

This commit is contained in:
Tim Wojtulewicz 2025-10-07 21:44:52 -07:00
parent 75422b5d21
commit 4e2debf173
10 changed files with 96 additions and 91 deletions

View file

@ -303,17 +303,16 @@ void DbgBreakpoint::PrintHitMsg() {
case BP_FUNC: case BP_FUNC:
case BP_LINE: { case BP_LINE: {
ODesc d; ODesc d;
Frame* f = g_frame_stack.back(); const auto& f = call_stack.back().frame;
const ScriptFunc* func = f->GetFunction();
if ( func ) if ( const Func* func = f->GetFunction() )
func->DescribeDebug(&d, f->GetFuncArgs()); func->DescribeDebug(&d, f->GetFuncArgs());
const Location* loc = at_stmt->GetLocationInfo(); const Location* loc = at_stmt->GetLocationInfo();
debug_msg("Breakpoint %d, %s at %s:%d\n", GetID(), d.Description(), loc->FileName(), loc->FirstLine()); debug_msg("Breakpoint %d, %s at %s:%d\n", GetID(), d.Description(), loc->FileName(), loc->FirstLine());
}
return; return;
}
case BP_TIME: assert(false); case BP_TIME: assert(false);

View file

@ -143,15 +143,13 @@ int TraceState::LogTrace(const char* fmt, ...) {
const Stmt* stmt; const Stmt* stmt;
Location loc; Location loc;
if ( g_frame_stack.size() > 0 && g_frame_stack.back() ) { if ( ! call_stack.empty() ) {
stmt = g_frame_stack.back()->GetNextStmt(); const auto& frame = call_stack.back().frame;
stmt = frame->GetNextStmt();
if ( stmt ) if ( stmt )
loc = *stmt->GetLocationInfo(); loc = *stmt->GetLocationInfo();
else { else if ( const Func* f = frame->GetFunction() )
const ScriptFunc* f = g_frame_stack.back()->GetFunction(); loc = *f->GetLocationInfo();
if ( f )
loc = *f->GetLocationInfo();
}
} }
if ( ! loc.FileName() ) { if ( ! loc.FileName() ) {
@ -163,7 +161,7 @@ int TraceState::LogTrace(const char* fmt, ...) {
fprintf(trace_file, "%s:%d", loc.FileName(), loc.LastLine()); fprintf(trace_file, "%s:%d", loc.FileName(), loc.LastLine());
// Each stack frame is indented. // Each stack frame is indented.
for ( int i = 0; i < int(g_frame_stack.size()); ++i ) for ( const auto& call : call_stack )
fprintf(trace_file, "\t"); fprintf(trace_file, "\t");
retval = vfprintf(trace_file, fmt, args); retval = vfprintf(trace_file, fmt, args);
@ -589,16 +587,18 @@ static int dbg_dispatch_cmd(DebugCmd cmd_code, const vector<string>& args) {
case dcQuit: debug_msg("Program Terminating\n"); exit(0); case dcQuit: debug_msg("Program Terminating\n"); exit(0);
case dcNext: case dcNext: {
g_frame_stack.back()->BreakBeforeNextStmt(true); Frame* frame = call_stack.back().frame;
frame->BreakBeforeNextStmt(true);
step_or_next_pending = true; step_or_next_pending = true;
last_frame = g_frame_stack.back(); last_frame = frame;
break; break;
}
case dcStep: case dcStep:
g_debugger_state.BreakBeforeNextStmt(true); g_debugger_state.BreakBeforeNextStmt(true);
step_or_next_pending = true; step_or_next_pending = true;
last_frame = g_frame_stack.back(); last_frame = call_stack.back().frame;
break; break;
case dcContinue: case dcContinue:
@ -607,7 +607,7 @@ static int dbg_dispatch_cmd(DebugCmd cmd_code, const vector<string>& args) {
break; break;
case dcFinish: case dcFinish:
g_frame_stack.back()->BreakOnReturn(true); call_stack.back().frame->BreakOnReturn(true);
g_debugger_state.BreakBeforeNextStmt(false); g_debugger_state.BreakBeforeNextStmt(false);
break; break;
@ -663,7 +663,7 @@ static char* get_prompt(bool reset_counter = false) {
string get_context_description(const Stmt* stmt, const Frame* frame) { string get_context_description(const Stmt* stmt, const Frame* frame) {
ODesc d; ODesc d;
const ScriptFunc* func = frame ? frame->GetFunction() : nullptr; const Func* func = frame ? frame->GetFunction() : nullptr;
if ( func ) if ( func )
func->DescribeDebug(&d, frame->GetFuncArgs()); func->DescribeDebug(&d, frame->GetFuncArgs());
@ -698,9 +698,8 @@ int dbg_handle_debug_input() {
g_debugger_state.BreakFromSignal(false); g_debugger_state.BreakFromSignal(false);
} }
Frame* curr_frame = g_frame_stack.back(); auto curr_frame = call_stack.back().frame;
const ScriptFunc* func = curr_frame->GetFunction(); if ( const Func* func = curr_frame->GetFunction() )
if ( func )
current_module = extract_module_name(func->GetName().c_str()); current_module = extract_module_name(func->GetName().c_str());
else else
current_module = GLOBAL_MODULE_NAME; current_module = GLOBAL_MODULE_NAME;
@ -711,8 +710,8 @@ int dbg_handle_debug_input() {
const Location loc = *stmt->GetLocationInfo(); const Location loc = *stmt->GetLocationInfo();
if ( ! step_or_next_pending || g_frame_stack.back() != last_frame ) { if ( ! step_or_next_pending || call_stack.back().frame != last_frame ) {
string context = get_context_description(stmt, g_frame_stack.back()); string context = get_context_description(stmt, call_stack.back().frame);
debug_msg("%s\n", context.c_str()); debug_msg("%s\n", context.c_str());
} }
@ -848,16 +847,16 @@ ValPtr dbg_eval_expr(const char* expr) {
// Push the current frame's associated scope. // Push the current frame's associated scope.
// Note: g_debugger_state.curr_frame_idx is the user-visible number, // Note: g_debugger_state.curr_frame_idx is the user-visible number,
// while the array index goes in the opposite direction // while the array index goes in the opposite direction
int frame_idx = (g_frame_stack.size() - 1) - g_debugger_state.curr_frame_idx; int frame_idx = (call_stack.size() - 1) - g_debugger_state.curr_frame_idx;
if ( ! (frame_idx >= 0 && (unsigned)frame_idx < g_frame_stack.size()) ) if ( ! (frame_idx >= 0 && static_cast<size_t>(frame_idx) < call_stack.size()) )
reporter->InternalError("Assertion failed: frame_idx >= 0 && (unsigned) frame_idx < g_frame_stack.size()"); reporter->InternalError("Assertion failed: frame_idx >= 0 && (unsigned) frame_idx < call_stack.size()");
Frame* frame = g_frame_stack[frame_idx]; const auto& frame = call_stack[frame_idx].frame;
if ( ! (frame) ) if ( ! frame )
reporter->InternalError("Assertion failed: frame"); reporter->InternalError("Assertion failed: frame");
const ScriptFunc* func = frame->GetFunction(); const Func* func = frame->GetFunction();
if ( func ) if ( func )
push_existing_scope(func->GetScope()); push_existing_scope(func->GetScope());

View file

@ -173,7 +173,7 @@ int find_all_matching_cmds(const string& prefix, const char* array_of_matches[])
// Start, end bounds of which frame numbers to print // Start, end bounds of which frame numbers to print
static int dbg_backtrace_internal(int start, int end) { static int dbg_backtrace_internal(int start, int end) {
if ( start < 0 || end < 0 || (unsigned)start >= g_frame_stack.size() || (unsigned)end >= g_frame_stack.size() ) if ( start < 0 || end < 0 || (unsigned)start >= call_stack.size() || (unsigned)end >= call_stack.size() )
reporter->InternalError("Invalid stack frame index in DbgBacktraceInternal\n"); reporter->InternalError("Invalid stack frame index in DbgBacktraceInternal\n");
if ( start < end ) { if ( start < end ) {
@ -183,11 +183,11 @@ static int dbg_backtrace_internal(int start, int end) {
} }
for ( int i = start; i >= end; --i ) { for ( int i = start; i >= end; --i ) {
const Frame* f = g_frame_stack[i]; const auto& f = call_stack[i].frame;
const Stmt* stmt = f ? f->GetNextStmt() : nullptr; const Stmt* stmt = f ? f->GetNextStmt() : nullptr;
string context = get_context_description(stmt, f); string context = get_context_description(stmt, f);
debug_msg("#%d %s\n", int(g_frame_stack.size() - 1 - i), context.c_str()); debug_msg("#%d %s\n", int(call_stack.size() - 1 - i), context.c_str());
}; };
return 1; return 1;
@ -196,7 +196,7 @@ static int dbg_backtrace_internal(int start, int end) {
// Returns 0 for illegal arguments, or 1 on success. // Returns 0 for illegal arguments, or 1 on success.
int dbg_cmd_backtrace(DebugCmd cmd, const vector<string>& args) { int dbg_cmd_backtrace(DebugCmd cmd, const vector<string>& args) {
assert(cmd == dcBacktrace); assert(cmd == dcBacktrace);
assert(g_frame_stack.size() > 0); assert(! call_stack.empty());
unsigned int start_iter; unsigned int start_iter;
int end_iter; int end_iter;
@ -210,20 +210,20 @@ int dbg_cmd_backtrace(DebugCmd cmd, const vector<string>& args) {
} }
if ( how_many > 0 ) { // innermost N frames if ( how_many > 0 ) { // innermost N frames
start_iter = g_frame_stack.size() - 1; start_iter = call_stack.size() - 1;
end_iter = start_iter - how_many + 1; end_iter = start_iter - how_many + 1;
if ( end_iter < 0 ) if ( end_iter < 0 )
end_iter = 0; end_iter = 0;
} }
else { // outermost N frames else { // outermost N frames
start_iter = how_many - 1; start_iter = how_many - 1;
if ( start_iter + 1 > g_frame_stack.size() ) if ( start_iter + 1 > call_stack.size() )
start_iter = g_frame_stack.size() - 1; start_iter = call_stack.size() - 1;
end_iter = 0; end_iter = 0;
} }
} }
else { else {
start_iter = g_frame_stack.size() - 1; start_iter = call_stack.size() - 1;
end_iter = 0; end_iter = 0;
} }
@ -248,7 +248,7 @@ int dbg_cmd_frame(DebugCmd cmd, const vector<string>& args) {
return 0; return 0;
} }
if ( idx < 0 || (unsigned int)idx >= g_frame_stack.size() ) { if ( idx < 0 || (unsigned int)idx >= call_stack.size() ) {
debug_msg("No frame %d", idx); debug_msg("No frame %d", idx);
return 0; return 0;
} }
@ -267,7 +267,7 @@ int dbg_cmd_frame(DebugCmd cmd, const vector<string>& args) {
} }
else if ( cmd == dcUp ) { else if ( cmd == dcUp ) {
if ( (unsigned int)(g_debugger_state.curr_frame_idx + 1) == g_frame_stack.size() ) { if ( (unsigned int)(g_debugger_state.curr_frame_idx + 1) == call_stack.size() ) {
debug_msg("Outermost frame already selected\n"); debug_msg("Outermost frame already selected\n");
return 0; return 0;
} }
@ -275,11 +275,11 @@ int dbg_cmd_frame(DebugCmd cmd, const vector<string>& args) {
++g_debugger_state.curr_frame_idx; ++g_debugger_state.curr_frame_idx;
} }
int user_frame_number = g_frame_stack.size() - 1 - g_debugger_state.curr_frame_idx; int user_frame_number = call_stack.size() - 1 - g_debugger_state.curr_frame_idx;
// Set the current location to the new frame being looked at // Set the current location to the new frame being looked at
// for 'list', 'break', etc. // for 'list', 'break', etc.
const Stmt* stmt = g_frame_stack[user_frame_number]->GetNextStmt(); const Stmt* stmt = call_stack[user_frame_number].frame->GetNextStmt();
if ( ! stmt ) if ( ! stmt )
reporter->InternalError("Assertion failed: stmt is null"); reporter->InternalError("Assertion failed: stmt is null");
@ -310,9 +310,9 @@ int dbg_cmd_break(DebugCmd cmd, const vector<string>& args) {
int cond_index = -1; // at which argument pos. does bp condition start? int cond_index = -1; // at which argument pos. does bp condition start?
if ( args.empty() || args[0] == "if" ) { // break on next stmt if ( args.empty() || args[0] == "if" ) { // break on next stmt
int user_frame_number = g_frame_stack.size() - 1 - g_debugger_state.curr_frame_idx; int user_frame_number = call_stack.size() - 1 - g_debugger_state.curr_frame_idx;
Stmt* stmt = g_frame_stack[user_frame_number]->GetNextStmt(); Stmt* stmt = call_stack[user_frame_number].frame->GetNextStmt();
if ( ! stmt ) if ( ! stmt )
reporter->InternalError("Assertion failed: stmt is null"); reporter->InternalError("Assertion failed: stmt is null");

View file

@ -11,13 +11,12 @@
#include "zeek/Val.h" #include "zeek/Val.h"
#include "zeek/broker/Data.h" #include "zeek/broker/Data.h"
std::vector<zeek::detail::Frame*> g_frame_stack;
namespace zeek::detail { namespace zeek::detail {
Frame::Frame(int arg_size, const ScriptFunc* func, const zeek::Args* fn_args) { Frame::Frame(int arg_size, const Func* func, const zeek::Args* fn_args) {
size = arg_size; size = arg_size;
frame = std::make_unique<Element[]>(size); if ( size > 0 )
frame = std::make_unique<Element[]>(size);
function = func; function = func;
func_args = fn_args; func_args = fn_args;
@ -26,8 +25,11 @@ Frame::Frame(int arg_size, const ScriptFunc* func, const zeek::Args* fn_args) {
// enable execution of the function, and its captures frame won't // enable execution of the function, and its captures frame won't
// go away until the function itself goes away, which can only be // go away until the function itself goes away, which can only be
// after this frame does. // after this frame does.
captures = function ? function->GetCapturesFrame() : nullptr; if ( function && function->GetKind() == Func::SCRIPT_FUNC ) {
captures_offset_map = function ? function->GetCapturesOffsetMap() : nullptr; auto* sf = static_cast<const ScriptFunc*>(function);
captures = sf->GetCapturesFrame();
captures_offset_map = sf->GetCapturesOffsetMap();
}
} }
void Frame::SetElement(int n, ValPtr v) { void Frame::SetElement(int n, ValPtr v) {

View file

@ -20,11 +20,11 @@ using ValPtr = IntrusivePtr<Val>;
class BrokerListView; class BrokerListView;
class BrokerData; class BrokerData;
class Func;
namespace detail { namespace detail {
class CallExpr; class CallExpr;
class ScriptFunc;
using IDPtr = IntrusivePtr<ID>; using IDPtr = IntrusivePtr<ID>;
namespace trigger { namespace trigger {
@ -47,7 +47,7 @@ public:
* @param func the function that is creating this frame * @param func the function that is creating this frame
* @param fn_args the arguments being passed to that function. * @param fn_args the arguments being passed to that function.
*/ */
Frame(int size, const ScriptFunc* func, const zeek::Args* fn_args); Frame(int size, const Func* func, const zeek::Args* fn_args);
/** /**
* Returns the size of the frame. * Returns the size of the frame.
@ -117,7 +117,7 @@ public:
/** /**
* @return the function that the frame is associated with. * @return the function that the frame is associated with.
*/ */
const ScriptFunc* GetFunction() const { return function; } const Func* GetFunction() const { return function; }
/** /**
* @return the arguments passed to the function that this frame * @return the arguments passed to the function that this frame
@ -130,7 +130,7 @@ public:
* *
* @param func the function for the frame to be associated with. * @param func the function for the frame to be associated with.
*/ */
void SetFunction(ScriptFunc* func) { function = func; } void SetFunction(Func* func) { function = func; }
/** /**
* Sets the next statement to be executed in the context of the frame. * Sets the next statement to be executed in the context of the frame.
@ -239,7 +239,7 @@ private:
const OffsetMap* captures_offset_map = nullptr; const OffsetMap* captures_offset_map = nullptr;
/** The function this frame is associated with. */ /** The function this frame is associated with. */
const ScriptFunc* function = nullptr; const Func* function = nullptr;
// The following is only needed for the debugger. // The following is only needed for the debugger.
/** The arguments to the function that this Frame is associated with. */ /** The arguments to the function that this Frame is associated with. */
@ -266,4 +266,4 @@ private:
* DebugFrame which provides the information that the debugger uses. See: * DebugFrame which provides the information that the debugger uses. See:
* https://stackoverflow.com/a/16211097 * https://stackoverflow.com/a/16211097
*/ */
extern std::vector<zeek::detail::Frame*> g_frame_stack; // extern std::vector<zeek::detail::Frame*> g_frame_stack;

View file

@ -93,10 +93,11 @@ std::string render_call_stack() {
if ( lvl > 0 ) if ( lvl > 0 )
rval += " | "; rval += " | ";
const auto& name = ci.func->GetName(); const auto& name = ci.frame->GetFunction()->GetName();
std::string arg_desc; std::string arg_desc;
for ( const auto& arg : ci.args ) { const auto& args = ci.frame->GetFuncArgs();
for ( const auto& arg : *args ) {
ODesc d; ODesc d;
d.SetShort(); d.SetShort();
arg->Describe(&d); arg->Describe(&d);
@ -331,17 +332,16 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const {
return Flavor() == FUNC_FLAVOR_HOOK ? val_mgr->True() : nullptr; return Flavor() == FUNC_FLAVOR_HOOK ? val_mgr->True() : nullptr;
} }
auto f = make_intrusive<Frame>(frame_size, this, args); Frame f{static_cast<int>(frame_size), this, args};
// Hand down any trigger. // Hand down any trigger.
if ( parent ) { if ( parent ) {
f->SetTrigger({NewRef{}, parent->GetTrigger()}); f.SetTrigger({NewRef{}, parent->GetTrigger()});
f->SetTriggerAssoc(parent->GetTriggerAssoc()); f.SetTriggerAssoc(parent->GetTriggerAssoc());
} }
g_frame_stack.push_back(f.get()); // used for backtracing
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr; const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
call_stack.emplace_back(CallInfo{call_expr, this, *args}); call_stack.emplace_back(call_expr, &f);
// If a script function is ever invoked with more arguments than it has // If a script function is ever invoked with more arguments than it has
// parameters log an error and return. Most likely a "variadic function" // parameters log an error and return. Most likely a "variadic function"
@ -374,24 +374,23 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const {
for ( auto j = 0u; j < args->size(); ++j ) { for ( auto j = 0u; j < args->size(); ++j ) {
const auto& arg = (*args)[j]; const auto& arg = (*args)[j];
if ( f->GetElement(j) != arg ) if ( f.GetElement(j) != arg )
// Either not yet set, or somebody reassigned the frame slot. // Either not yet set, or somebody reassigned the frame slot.
f->SetElement(j, arg); f.SetElement(j, arg);
} }
if ( spm ) if ( spm )
spm->StartInvocation(this, body.stmts); spm->StartInvocation(this, body.stmts);
f->Reset(args->size()); f.Reset(args->size());
try { try {
result = body.stmts->Exec(f.get(), flow); result = body.stmts->Exec(&f, flow);
} }
catch ( InterpreterException& e ) { catch ( InterpreterException& e ) {
// Already reported, but now determine whether to unwind further. // Already reported, but now determine whether to unwind further.
if ( Flavor() == FUNC_FLAVOR_FUNCTION ) { if ( Flavor() == FUNC_FLAVOR_FUNCTION ) {
g_frame_stack.pop_back();
call_stack.pop_back(); call_stack.pop_back();
// Result not set b/c exception was thrown // Result not set b/c exception was thrown
throw; throw;
@ -404,7 +403,7 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const {
if ( spm ) if ( spm )
spm->EndInvocation(); spm->EndInvocation();
if ( f->HasDelayed() ) { if ( f.HasDelayed() ) {
assert(! result); assert(! result);
assert(parent); assert(parent);
parent->SetDelayed(); parent->SetDelayed();
@ -424,8 +423,6 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const {
} }
} }
call_stack.pop_back();
if ( Flavor() == FUNC_FLAVOR_HOOK ) { if ( Flavor() == FUNC_FLAVOR_HOOK ) {
if ( ! result ) if ( ! result )
result = val_mgr->True(); result = val_mgr->True();
@ -438,7 +435,7 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const {
// the function without an explicit return, or without a value. // the function without an explicit return, or without a value.
else if ( GetType()->Yield() && GetType()->Yield()->Tag() != TYPE_VOID && ! GetType()->ExpressionlessReturnOkay() && else if ( GetType()->Yield() && GetType()->Yield()->Tag() != TYPE_VOID && ! GetType()->ExpressionlessReturnOkay() &&
(flow != FLOW_RETURN /* we fell off the end */ || ! result /* explicit return with no result */) && (flow != FLOW_RETURN /* we fell off the end */ || ! result /* explicit return with no result */) &&
! f->HasDelayed() ) ! f.HasDelayed() )
reporter->Warning("non-void function returning without a value: %s", GetName().c_str()); reporter->Warning("non-void function returning without a value: %s", GetName().c_str());
if ( result && g_trace_state.DoTrace() ) { if ( result && g_trace_state.DoTrace() ) {
@ -448,7 +445,7 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const {
g_trace_state.LogTrace("Function return: %s\n", d.Description()); g_trace_state.LogTrace("Function return: %s\n", d.Description());
} }
g_frame_stack.pop_back(); call_stack.pop_back();
return result; return result;
} }
@ -733,8 +730,10 @@ ValPtr BuiltinFunc::Invoke(Args* args, Frame* parent) const {
g_trace_state.LogTrace("\tBuiltin Function called: %s\n", d.Description()); g_trace_state.LogTrace("\tBuiltin Function called: %s\n", d.Description());
} }
Frame f{0, this, args};
const CallExpr* call_expr = parent ? parent->GetCall() : nullptr; const CallExpr* call_expr = parent ? parent->GetCall() : nullptr;
call_stack.emplace_back(CallInfo{call_expr, this, *args}); call_stack.emplace_back(call_expr, &f);
auto result = func(parent, args); auto result = func(parent, args);
call_stack.pop_back(); call_stack.pop_back();
@ -937,15 +936,15 @@ zeek::VectorValPtr get_current_script_backtrace() {
auto cs_copy = zeek::detail::call_stack; auto cs_copy = zeek::detail::call_stack;
for ( const auto& ci : std::ranges::reverse_view(cs_copy) ) { for ( const auto& ci : std::ranges::reverse_view(cs_copy) ) {
if ( ! ci.func ) if ( ! ci.frame->GetFunction() )
// This happens for compiled code. // This happens for compiled code and BIFs.
continue; continue;
const auto& params = ci.func->GetType()->Params(); const auto& params = ci.frame->GetFunction()->GetType()->Params();
auto args = MakeCallArgumentVector(ci.args, params); auto args = MakeCallArgumentVector(*ci.frame->GetFuncArgs(), params);
auto elem = auto elem = make_backtrace_element(ci.frame->GetFunction()->GetName(), std::move(args),
make_backtrace_element(ci.func->GetName(), std::move(args), ci.call ? ci.call->GetLocationInfo() : nullptr); ci.call ? ci.call->GetLocationInfo() : nullptr);
rval->Append(std::move(elem)); rval->Append(std::move(elem));
} }
@ -990,7 +989,7 @@ static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind) {
return; return;
} }
auto last_call = call_stack.back(); const auto& last_call = call_stack.back();
if ( call_stack.size() < 2 ) { if ( call_stack.size() < 2 ) {
// Don't need to check for wrapper function like "<module>::__<func>" // Don't need to check for wrapper function like "<module>::__<func>"
@ -998,10 +997,13 @@ static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind) {
return; return;
} }
if ( ! last_call.frame->GetFunction() )
return;
auto starts_with_double_underscore = [](const std::string& name) -> bool { auto starts_with_double_underscore = [](const std::string& name) -> bool {
return name.size() > 2 && name[0] == '_' && name[1] == '_'; return name.size() > 2 && name[0] == '_' && name[1] == '_';
}; };
const std::string& last_func = last_call.func->GetName(); const std::string& last_func = last_call.frame->GetFunction()->GetName();
auto pos = last_func.find_first_of("::"); auto pos = last_func.find_first_of("::");
std::string wrapper_func; std::string wrapper_func;
@ -1027,7 +1029,10 @@ static void emit_builtin_error_common(const char* msg, Obj* arg, bool unwind) {
} }
auto parent_call = call_stack[call_stack.size() - 2]; auto parent_call = call_stack[call_stack.size() - 2];
const auto& parent_func = parent_call.func->GetName();
std::string parent_func;
if ( const auto* pcf = parent_call.frame->GetFunction() )
parent_func = pcf->GetName();
if ( wrapper_func == parent_func ) if ( wrapper_func == parent_func )
emit(parent_call.call); emit(parent_call.call);

View file

@ -348,8 +348,7 @@ extern bool check_built_in_call(BuiltinFunc* f, CallExpr* call);
struct CallInfo { struct CallInfo {
const CallExpr* call = nullptr; const CallExpr* call = nullptr;
const Func* func = nullptr; Frame* frame = nullptr;
const zeek::Args& args;
}; };
// Class that collects all the specifics defining a Func. // Class that collects all the specifics defining a Func.

View file

@ -7,6 +7,7 @@
#include "zeek/Desc.h" #include "zeek/Desc.h"
#include "zeek/Expr.h" #include "zeek/Expr.h"
#include "zeek/Frame.h"
#include "zeek/Func.h" #include "zeek/Func.h"
#include "zeek/IntrusivePtr.h" #include "zeek/IntrusivePtr.h"
#include "zeek/Reporter.h" #include "zeek/Reporter.h"
@ -136,7 +137,7 @@ std::string_view determine_script_location() {
ssize_t sidx = static_cast<ssize_t>(zeek::detail::call_stack.size()) - 1; ssize_t sidx = static_cast<ssize_t>(zeek::detail::call_stack.size()) - 1;
while ( sidx >= 0 ) { while ( sidx >= 0 ) {
const auto* func = zeek::detail::call_stack[sidx].func; const auto* func = zeek::detail::call_stack[sidx].frame->GetFunction();
const auto* ce = zeek::detail::call_stack[sidx].call; const auto* ce = zeek::detail::call_stack[sidx].call;
// Cached? // Cached?

View file

@ -41,12 +41,12 @@ eval auto& v = $$;
internal-op Load-Capture internal-op Load-Capture
class Vi class Vi
eval $$ = Z_FRAME->GetFunction()->GetCapturesVec()[$1]; eval $$ = static_cast<const ScriptFunc*>(Z_FRAME->GetFunction())->GetCapturesVec()[$1];
internal-op Load-Managed-Capture internal-op Load-Managed-Capture
class Vi class Vi
eval auto& lhs = $$; eval auto& lhs = $$;
auto& rhs = Z_FRAME->GetFunction()->GetCapturesVec()[$1]; auto& rhs = static_cast<const ScriptFunc*>(Z_FRAME->GetFunction())->GetCapturesVec()[$1];
zeek::Ref(rhs.ManagedVal()); zeek::Ref(rhs.ManagedVal());
ZVal::DeleteManagedType(lhs); ZVal::DeleteManagedType(lhs);
lhs = rhs; lhs = rhs;
@ -62,12 +62,12 @@ eval GlobalID($1)->SetVal(GlobalVal($1).ToVal(Z_TYPE));
internal-op Store-Capture internal-op Store-Capture
op1-read op1-read
class Vi class Vi
eval Z_FRAME->GetFunction()->GetCapturesVec()[$2] = $1; eval static_cast<const ScriptFunc*>(Z_FRAME->GetFunction())->GetCapturesVec()[$2] = $1;
internal-op Store-Managed-Capture internal-op Store-Managed-Capture
op1-read op1-read
class Vi class Vi
eval auto& lhs = Z_FRAME->GetFunction()->GetCapturesVec()[$2]; eval auto& lhs = static_cast<const ScriptFunc*>(Z_FRAME->GetFunction())->GetCapturesVec()[$2];
auto& rhs = $1; auto& rhs = $1;
zeek::Ref(rhs.ManagedVal()); zeek::Ref(rhs.ManagedVal());
ZVal::DeleteManagedType(lhs); ZVal::DeleteManagedType(lhs);

View file

@ -1054,7 +1054,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) {
auto [body, scope] = get_global_stmts(); auto [body, scope] = get_global_stmts();
StmtFlowType flow; StmtFlowType flow;
Frame f(scope->Length(), nullptr, nullptr); Frame f(scope->Length(), nullptr, nullptr);
g_frame_stack.push_back(&f); call_stack.emplace_back(nullptr, &f);
try { try {
body->Exec(&f, flow); body->Exec(&f, flow);
@ -1062,7 +1062,7 @@ SetupResult setup(int argc, char** argv, Options* zopts) {
reporter->FatalError("failed to execute script statements at top-level scope"); reporter->FatalError("failed to execute script statements at top-level scope");
} }
g_frame_stack.pop_back(); call_stack.pop_back();
} }
clear_script_analysis(); clear_script_analysis();