Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 0d0501e

Browse files
Use object handles for breakpoints and watched vars
1 parent 34bf1f2 commit 0d0501e

4 files changed

Lines changed: 97 additions & 66 deletions

File tree

engine/src/debug.cpp

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ void MCB_trace(MCExecContext &ctxt, uint2 line, uint2 pos)
291291
t_parentscript = ctxt . GetParentScript();
292292
if ((t_parentscript == NULL && MCbreakpoints[i].object == ctxt.GetObject()) ||
293293
(t_parentscript != NULL && MCbreakpoints[i].object == t_parentscript -> GetParent() -> GetObject()))
294-
MCB_prepmessage(ctxt, MCM_trace_break, line, pos, 0, MCbreakpoints[i].info);
294+
MCB_prepmessage(ctxt, MCM_trace_break, line, pos, 0, *MCbreakpoints[i].info);
295295
}
296296
}
297297
}
@@ -378,17 +378,18 @@ void MCB_setvalue(MCExecContext &ctxt, MCExecValue p_value, MCNameRef name)
378378

379379
void MCB_clearbreaks(MCObject *p_for_object)
380380
{
381-
for(unsigned int n = 0; n < MCnbreakpoints; ++n)
382-
if (p_for_object == NULL || MCbreakpoints[n] . object == p_for_object)
381+
for(size_t n = 0; n < MCnbreakpoints; ++n)
382+
{
383+
if (p_for_object == nil || MCbreakpoints[n].object == p_for_object)
383384
{
384-
MCbreakpoints[n] . object = NULL;
385-
MCValueAssign(MCbreakpoints[n] . info, kMCEmptyString);
385+
MCbreakpoints[n].Clear();
386386
}
387+
}
387388

388-
if (p_for_object == NULL)
389+
if (p_for_object == nil && MCbreakpoints != nil)
389390
{
390391
MCnbreakpoints = 0;
391-
free(MCbreakpoints);
392+
MCMemoryDestroy(MCbreakpoints);
392393
MCbreakpoints = nil;
393394
}
394395
}
@@ -407,7 +408,7 @@ bool MCB_unparsebreaks(MCStringRef& r_value)
407408
// MW-2005-06-26: Fix breakpoint crash issue - ignore any breakpoints with NULL object
408409
for (uint32_t i = 0 ; i < MCnbreakpoints ; i++)
409410
{
410-
if (MCbreakpoints[i] . object != NULL)
411+
if (MCbreakpoints[i].object)
411412
{
412413
MCAutoListRef t_breakpoint;
413414
t_success = MCListCreateMutable(',', &t_breakpoint);
@@ -426,9 +427,9 @@ bool MCB_unparsebreaks(MCStringRef& r_value)
426427
MCListAppend(*t_breakpoint, *t_line);
427428
}
428429

429-
if (t_success && !MCStringIsEmpty(MCbreakpoints[i] . info))
430+
if (t_success && !MCStringIsEmpty(*MCbreakpoints[i].info))
430431
{
431-
t_success = MCListAppend(*t_breakpoint, MCbreakpoints[i] . info);
432+
t_success = MCListAppend(*t_breakpoint, *MCbreakpoints[i].info);
432433
}
433434

434435
if (t_success)
@@ -518,15 +519,12 @@ void MCB_parsebreaks(MCExecContext& ctxt, MCStringRef p_input)
518519
if (t_valid_break)
519520
{
520521
Breakpoint *t_new_breakpoints;
521-
t_new_breakpoints = (Breakpoint *)realloc(MCbreakpoints, sizeof(Breakpoint) * (MCnbreakpoints + 1));
522-
if (t_new_breakpoints != nil)
523-
{
524-
MCbreakpoints = t_new_breakpoints;
525-
MCbreakpoints[MCnbreakpoints] . object = t_object . object;
526-
MCbreakpoints[MCnbreakpoints] . line = (uint32_t)t_line;
527-
MCbreakpoints[MCnbreakpoints] . info = MCValueRetain(*t_info);
528-
MCnbreakpoints++;
529-
}
522+
if (!MCMemoryReallocate(MCbreakpoints, sizeof(Breakpoint) * (MCnbreakpoints + 1), t_new_breakpoints))
523+
break;
524+
525+
MCbreakpoints = t_new_breakpoints;
526+
new (&MCbreakpoints[MCnbreakpoints]) Breakpoint(t_object.object->GetHandle(), t_line, *t_info);
527+
MCnbreakpoints++;
530528
}
531529
}
532530
t_last_offset = t_return_offset + 1;
@@ -537,16 +535,17 @@ void MCB_parsebreaks(MCExecContext& ctxt, MCStringRef p_input)
537535

538536
void MCB_clearwatches(void)
539537
{
540-
while (MCnwatchedvars--)
538+
for (size_t i = 0; i < MCnwatchedvars; i++)
541539
{
542-
MCNameDelete(MCwatchedvars[MCnwatchedvars].handlername);
543-
MCNameDelete(MCwatchedvars[MCnwatchedvars].varname);
544-
MCValueRelease(MCwatchedvars[MCnwatchedvars].expression);
540+
MCwatchedvars[i].Clear();
545541
}
546-
MCnwatchedvars = 0;
547542

548-
free(MCwatchedvars);
549-
MCwatchedvars = nil;
543+
if (MCwatchedvars != nil)
544+
{
545+
MCnwatchedvars = 0;
546+
MCMemoryDestroy(MCwatchedvars);
547+
MCwatchedvars = nil;
548+
}
550549
}
551550

552551
void MCB_parsewatches(MCExecContext& ctxt, MCStringRef p_input)
@@ -615,23 +614,25 @@ void MCB_parsewatches(MCExecContext& ctxt, MCStringRef p_input)
615614
t_object . object != nil)
616615
{
617616
Watchvar *t_new_watches;
618-
t_new_watches = (Watchvar *)realloc(MCwatchedvars, sizeof(Watchvar) * (MCnwatchedvars + 1));
619-
if (t_new_watches != nil)
620-
{
621-
MCwatchedvars = t_new_watches;
622-
if (t_resolved_object)
623-
MCwatchedvars[MCnwatchedvars] . object = t_object . object;
624-
else
625-
MCwatchedvars[MCnwatchedvars] . object = nil;
626-
627-
if (MCStringGetLength(*t_hname) != 0)
628-
/* UNCHECKED */ MCNameCreate(*t_hname, MCwatchedvars[MCnwatchedvars] . handlername);
629-
else
630-
MCwatchedvars[MCnwatchedvars] . handlername = nil;
631-
/* UNCHECKED */ MCNameCreate(*t_vname, MCwatchedvars[MCnwatchedvars] . varname);
632-
MCwatchedvars[MCnwatchedvars] . expression = MCValueRetain(*t_express);
633-
MCnwatchedvars++;
634-
}
617+
if (!MCMemoryReallocate(MCwatchedvars, sizeof(Watchvar) * (MCnwatchedvars + 1), t_new_watches))
618+
{
619+
t_success = false;
620+
break;
621+
}
622+
623+
MCObjectHandle t_objecthandle;
624+
MCNewAutoNameRef t_handlername;
625+
MCNewAutoNameRef t_varname;
626+
627+
if (t_resolved_object)
628+
t_objecthandle = t_object.object;
629+
630+
/* UNCHECKED */ MCNameCreate(*t_hname, &t_handlername);
631+
/* UNCHECKED */ MCNameCreate(*t_vname, &t_varname);
632+
633+
MCwatchedvars = t_new_watches;
634+
new (&MCwatchedvars[MCnwatchedvars]) Watchvar(t_objecthandle, *t_handlername, *t_varname, *t_express);
635+
MCnwatchedvars++;
635636
}
636637
}
637638
t_last_offset = t_return_offset + 1;
@@ -656,7 +657,7 @@ bool MCB_unparsewatches(MCStringRef &r_watches)
656657

657658
if (t_success)
658659
{
659-
if (MCwatchedvars[i] . object != NULL)
660+
if (MCwatchedvars[i].object)
660661
{
661662
MCAutoValueRef t_var_id;
662663
t_success = MCwatchedvars[i] . object -> names(P_LONG_ID, &t_var_id) &&
@@ -668,18 +669,18 @@ bool MCB_unparsewatches(MCStringRef &r_watches)
668669

669670
if (t_success)
670671
{
671-
if (MCwatchedvars[i] . handlername == NULL)
672+
if (!MCwatchedvars[i].handlername.IsSet())
672673
t_success = MCListAppend(*t_watched_var, kMCEmptyString);
673674
else
674-
t_success = MCListAppend(*t_watched_var, MCwatchedvars[i].handlername);
675+
t_success = MCListAppend(*t_watched_var, *MCwatchedvars[i].handlername);
675676
}
676677

677678
if (t_success)
678-
t_success = MCListAppend(*t_watched_var, MCwatchedvars[i].varname);
679+
t_success = MCListAppend(*t_watched_var, *MCwatchedvars[i].varname);
679680

680681
// SN-2014-09-18: [[ Bug 13453 ]] A watched variable's expression is never nil
681682
if (t_success)
682-
t_success = MCListAppend(*t_watched_var, MCwatchedvars[i].expression);
683+
t_success = MCListAppend(*t_watched_var, *MCwatchedvars[i].expression);
683684

684685
if (t_success)
685686
t_success = MCListAppend(*t_watches_list, *t_watched_var);

engine/src/debug.h

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,49 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
2727
// MW-2009-11-03: Add an 'info' field to the breakpoints
2828
struct Breakpoint
2929
{
30-
MCObject *object;
30+
Breakpoint(MCObjectHandle p_object, uint32_t p_line, MCStringRef p_info) :
31+
object(p_object),
32+
line(p_line),
33+
info(p_info)
34+
{
35+
}
36+
37+
void Clear()
38+
{
39+
object = nil;
40+
line = 0;
41+
info.Reset();
42+
}
43+
44+
MCObjectHandle object;
3145
uint4 line;
32-
MCStringRef info;
46+
MCAutoStringRef info;
3347
};
3448

3549
// set the breakpoints to "button 1, 3"
3650

3751
struct Watchvar
3852
{
39-
MCObject *object;
40-
MCNameRef handlername;
41-
MCNameRef varname;
42-
MCStringRef expression;
53+
Watchvar(MCObjectHandle p_object, MCNameRef p_handlername, MCNameRef p_varname, MCStringRef p_expression) :
54+
object(p_object),
55+
handlername(p_handlername),
56+
varname(p_varname),
57+
expression(p_expression)
58+
{
59+
}
60+
61+
void Clear()
62+
{
63+
object = nil;
64+
handlername.Reset();
65+
varname.Reset();
66+
expression.Reset();
67+
}
68+
69+
MCObjectHandle object;
70+
MCNewAutoNameRef handlername;
71+
MCNewAutoNameRef varname;
72+
MCAutoStringRef expression;
4373
};
4474

4575
// set the watchedvariables to "button 1, somehandler, somevar, someexp"

engine/src/variable.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,21 +1086,21 @@ void MCVariable::synchronize(MCExecContext& ctxt, bool p_notify)
10861086
uint2 i;
10871087
for (i = 0 ; i < MCnwatchedvars ; i++)
10881088
{
1089-
if ((MCwatchedvars[i].object == NULL || MCwatchedvars[i].object == ctxt . GetObject()) &&
1090-
(MCwatchedvars[i].handlername == NULL || ctxt . GetHandler() -> hasname(MCwatchedvars[i].handlername)) &&
1091-
hasname(MCwatchedvars[i].varname))
1089+
if ((!MCwatchedvars[i].object.IsBound() || MCwatchedvars[i].object == ctxt.GetObject()) &&
1090+
(!MCwatchedvars[i].handlername.IsSet() || ctxt.GetHandler()->hasname(*MCwatchedvars[i].handlername)) &&
1091+
hasname(*MCwatchedvars[i].varname))
10921092
{
10931093
// If this is a global watch (object == handlername == nil) then
10941094
// check that this var is a global - if not carry on the search.
1095-
if (MCwatchedvars[i] . object == NULL &&
1096-
MCwatchedvars[i] . handlername == NULL &&
1095+
if (!MCwatchedvars[i].object.IsBound() &&
1096+
!MCwatchedvars[i].handlername.IsSet() &&
10971097
!is_global)
10981098
continue;
10991099

1100-
if (MCwatchedvars[i].expression != nil && !MCStringIsEmpty(MCwatchedvars[i].expression))
1100+
if (MCwatchedvars[i].expression.IsSet() && !MCStringIsEmpty(*MCwatchedvars[i].expression))
11011101
{
11021102
MCAutoValueRef t_val;
1103-
ctxt.eval(ctxt, MCwatchedvars[i].expression, &t_val);
1103+
ctxt.eval(ctxt, *MCwatchedvars[i].expression, &t_val);
11041104

11051105
MCAutoBooleanRef t_bool;
11061106
if (!ctxt.HasError() && ctxt.ConvertToBoolean(*t_val, &t_bool) && *t_bool == kMCTrue)

libfoundation/include/foundation-auto.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,18 @@ template<typename T> class MCAutoValueRefBase
8080
return m_value;
8181
}
8282

83+
bool IsSet() const
84+
{
85+
return m_value != nil;
86+
}
87+
8388
void Reset(T value = nil)
8489
{
8590
if (m_value)
8691
MCValueRelease(m_value);
8792
m_value = (value) ? (T)MCValueRetain(value) : NULL;
8893
}
8994

90-
inline T& operator ! (void)
91-
{
92-
return m_value;
93-
}
94-
9595
// The give method places the given value into the container without
9696
// retaining it - the auto container is considered to now own the value.
9797
inline void Give(T value)

0 commit comments

Comments
 (0)