@@ -539,7 +539,15 @@ asIDBCache::ResolveSubExpression(asIDBVariable::WeakPtr var,
539539 if (globals->expanded )
540540 return ;
541541
542- auto main = ctx->GetFunction (0 )->GetModule ();
542+ auto fn = ctx->GetFunction (0 );
543+ if (fn == nullptr ) {
544+ return ;
545+ }
546+
547+ auto main = fn->GetModule ();
548+ if (main == nullptr ) {
549+ return ;
550+ }
543551
544552 for (asUINT n = 0 ; n < main->GetGlobalVarCount (); n++) {
545553 const char *name;
@@ -1073,16 +1081,14 @@ std::string asIDBFileWorkspace::SectionSource(const std::string_view v) const {
10731081}
10741082
10751083void asIDBFileWorkspace::CompileScriptSources () {
1076- for (auto &engine : engines) {
1077- for (size_t i = 0 ; i < engine->GetModuleCount (); i++) {
1078- auto module = engine->GetModuleByIndex (i);
1079-
1080- for (size_t f = 0 ; f < module ->GetFunctionCount (); f++) {
1081- const char *section;
1082- module ->GetFunctionByIndex (f)->GetDeclaredAt (§ion, nullptr ,
1083- nullptr );
1084- AddSection (section);
1085- }
1084+ for (size_t i = 0 ; i < engine->GetModuleCount (); i++) {
1085+ auto module = engine->GetModuleByIndex (i);
1086+
1087+ for (size_t f = 0 ; f < module ->GetFunctionCount (); f++) {
1088+ const char *section;
1089+ module ->GetFunctionByIndex (f)->GetDeclaredAt (§ion, nullptr ,
1090+ nullptr );
1091+ AddSection (section);
10861092 }
10871093 }
10881094}
@@ -1100,27 +1106,25 @@ void asIDBFileWorkspace::CompileBreakpointPositions() {
11001106 }
11011107 };
11021108
1103- for (auto &engine : engines) {
1104- for (size_t i = 0 ; i < engine->GetModuleCount (); i++) {
1105- asIScriptModule *module = engine->GetModuleByIndex (i);
1109+ for (size_t i = 0 ; i < engine->GetModuleCount (); i++) {
1110+ asIScriptModule *module = engine->GetModuleByIndex (i);
11061111
1107- for (size_t f = 0 ; f < module ->GetFunctionCount (); f++)
1108- addFunctionBreakpointLocations (module ->GetFunctionByIndex (f));
1112+ for (size_t f = 0 ; f < module ->GetFunctionCount (); f++)
1113+ addFunctionBreakpointLocations (module ->GetFunctionByIndex (f));
11091114
1110- for (size_t t = 0 ; t < module ->GetObjectTypeCount (); t++) {
1111- asITypeInfo *type = module ->GetObjectTypeByIndex (t);
1115+ for (size_t t = 0 ; t < module ->GetObjectTypeCount (); t++) {
1116+ asITypeInfo *type = module ->GetObjectTypeByIndex (t);
11121117
1113- for (size_t m = 0 ; m < type->GetMethodCount (); m++)
1114- addFunctionBreakpointLocations (
1115- type->GetMethodByIndex (m, false ));
1118+ for (size_t m = 0 ; m < type->GetMethodCount (); m++)
1119+ addFunctionBreakpointLocations (
1120+ type->GetMethodByIndex (m, false ));
11161121
1117- for (size_t m = 0 ; m < type->GetBehaviourCount (); m++)
1118- addFunctionBreakpointLocations (
1119- type->GetBehaviourByIndex (m, nullptr ));
1122+ for (size_t m = 0 ; m < type->GetBehaviourCount (); m++)
1123+ addFunctionBreakpointLocations (
1124+ type->GetBehaviourByIndex (m, nullptr ));
11201125
1121- for (size_t m = 0 ; m < type->GetFactoryCount (); m++)
1122- addFunctionBreakpointLocations (type->GetFactoryByIndex (m));
1123- }
1126+ for (size_t m = 0 ; m < type->GetFactoryCount (); m++)
1127+ addFunctionBreakpointLocations (type->GetFactoryByIndex (m));
11241128 }
11251129 }
11261130}
@@ -1130,6 +1134,22 @@ void asIDBFileWorkspace::CompileBreakpointPositions() {
11301134 if (debugger->internal_execution )
11311135 return ;
11321136
1137+ if (debugger->onLineCallBack ) {
1138+ auto r = debugger->onLineCallBack (ctx);
1139+ if (!r) {
1140+ // cancelled
1141+ return ;
1142+ }
1143+ }
1144+
1145+ const char *section = nullptr ;
1146+ int col;
1147+ int row = ctx->GetLineNumber (0 , &col, §ion);
1148+
1149+ if (debugger->onLineCallBackExec ) {
1150+ debugger->onLineCallBackExec (row, col, section);
1151+ }
1152+
11331153 // we might not have an action - functions called from within
11341154 // the debugger will never have this set.
11351155 if (debugger->action != asIDBAction::None) {
@@ -1159,19 +1179,47 @@ void asIDBFileWorkspace::CompileBreakpointPositions() {
11591179 // breakpoint can be hit by multiple things on the same
11601180 // line.
11611181 bool break_from_bp = false ;
1162- const char *section = nullptr ;
1163- int col;
1164- int row = ctx->GetLineNumber (0 , &col, §ion);
11651182
11661183 if (section) {
11671184 std::scoped_lock lock (debugger->mutex );
11681185
11691186 if (auto entries = debugger->breakpoints .find (section);
11701187 entries != debugger->breakpoints .end ()) {
1171- for (auto &lines : entries->second ) {
1172- if (row == lines.line ) {
1173- if (!lines.column .has_value () ||
1174- lines.column .value () == col) {
1188+ // Did we move into a new function?
1189+ asIScriptFunction *func = ctx->GetFunction ();
1190+
1191+ if (debugger->_lastFunction != func) {
1192+ // Check if any breakpoints need adjusting
1193+ for (auto &bp : entries->second ) {
1194+ // We need to check for a breakpoint at entering the
1195+ // function
1196+
1197+ // Check if a given breakpoint fall on a line with code or
1198+ // else adjust it to the next line
1199+ if (bp.needAdjust ) {
1200+ int line = func->FindNextLineWithCode (bp.line );
1201+ if (line >= 0 ) {
1202+ bp.needAdjust = false ;
1203+ if (line != bp.line ) {
1204+ // Moving break point to next line with code
1205+ auto old = bp.line ;
1206+ // Move the breakpoint to the next line
1207+ bp.line = line;
1208+
1209+ if (debugger->onAdjustBreakPoint ) {
1210+ debugger->onAdjustBreakPoint (old, line,
1211+ section);
1212+ }
1213+ }
1214+ }
1215+ }
1216+ }
1217+ debugger->_lastFunction = func;
1218+ }
1219+
1220+ for (auto &bp : entries->second ) {
1221+ if (row == bp.line ) {
1222+ if (!bp.column .has_value () || bp.column .value () == col) {
11751223 break_from_bp = true ;
11761224 break ;
11771225 }
@@ -1205,10 +1253,17 @@ void asIDBFileWorkspace::CompileBreakpointPositions() {
12051253}
12061254
12071255void asIDBDebugger::HookContext (asIScriptContext *ctx, bool has_work) {
1256+ if (ctx == nullptr ) {
1257+ return ;
1258+ }
1259+
1260+ if (!cache) {
1261+ cache = CreateCache (ctx);
1262+ }
1263+
12081264 // TODO: is this safe to be called even if
12091265 // the context is being switched?
1210- if (ctx->GetState () != asEXECUTION_EXCEPTION &&
1211- workspace->engines .find (ctx->GetEngine ()) != workspace->engines .end ()) {
1266+ if (ctx->GetState () != asEXECUTION_EXCEPTION) {
12121267 if (has_work)
12131268 ctx->SetLineCallback (asFUNCTION (asIDBDebugger::LineCallback), this ,
12141269 asCALL_CDECL);
@@ -1218,12 +1273,12 @@ void asIDBDebugger::HookContext(asIScriptContext *ctx, bool has_work) {
12181273}
12191274
12201275void asIDBDebugger::DebugBreak (asIScriptContext *ctx) {
1221- if (workspace-> engines . find ( ctx->GetEngine ()) == workspace->engines . end () )
1276+ if (ctx->GetEngine () != workspace->engine )
12221277 return ;
12231278
12241279 {
12251280 std::scoped_lock lock (mutex);
1226- action = asIDBAction::None ;
1281+ action = asIDBAction::Pause ;
12271282 std::unique_ptr<asIDBCache> new_cache = CreateCache (ctx);
12281283
12291284 if (cache)
@@ -1232,7 +1287,13 @@ void asIDBDebugger::DebugBreak(asIScriptContext *ctx) {
12321287 std::swap (cache, new_cache);
12331288 }
12341289
1290+ if (onDebugBreak) {
1291+ onDebugBreak ();
1292+ }
1293+
1294+ // rehook
12351295 HookContext (ctx, true );
1296+
12361297 Suspend ();
12371298}
12381299
@@ -1258,32 +1319,11 @@ void asIDBDebugger::SetAction(asIDBAction new_action) {
12581319
12591320 if (new_action != asIDBAction::Continue) {
12601321 std::scoped_lock lock (mutex);
1261- action = new_action;
12621322
12631323 if (cache)
12641324 stack_size = cache->ctx ->GetCallstackSize ();
12651325 }
1326+ action = new_action;
12661327
12671328 Resume ();
12681329}
1269-
1270- bool asIDBDebugger::ToggleBreakpoint (std::string_view section, int line) {
1271- auto it = breakpoints.find (section);
1272-
1273- if (it == breakpoints.end ())
1274- it = breakpoints.emplace (section, asIDBSectionBreakpoints{}).first ;
1275-
1276- for (auto lit = it->second .begin (); lit != it->second .end (); lit++) {
1277- if (lit->line == line) {
1278- it->second .erase (lit);
1279-
1280- if (it->second .empty ())
1281- breakpoints.erase (it);
1282-
1283- return false ;
1284- }
1285- }
1286-
1287- it->second .push_back ({line});
1288- return true ;
1289- }
0 commit comments