[m-rev.] Fwd: for review: fix obsolete tcl-tk code in extras/graphics/mercury_tcltk
Fabrice Nicol
fabrnicol at gmail.com
Wed Jan 5 23:32:12 AEDT 2022
Yes, Julien, you are (theoretically) right. You will find attached a new
patch that takes your review into account.
Practically yet, for reasons I still poorly understand, using the setter
functions (Tcl_SetResult or Tcl_SetObjResult) as you indicate in your
review causes a runtime crash on using the 'calc' executable built with
the tcltk library code fixed along these lines, __unless the TCL_STATIC
memory management flag__ is set in the third argument of the setters.
There may be some C-memory management issue, as the TCL-TK setter
functions perform C-style memory allocation under the hood. I guess that
the dynamic version (TCL_DYNAMIC, which is often the preferred option)
is somehow incompatible with the Mercury GC, and I am not quite sure
that using TCL_STATIC releases all tcl-tk-allocated memory on exit.
Oddly enough, 'calc' works just fine (for all arithmetic operations) if
the getter function Tcl_GetStringResult is used instead of the setters,
as in my earlier proposed patch. This may be caused by the fact that the
underlying 'interp' structures are not strictly write-protected (this is
not C++ code), which may explain why the getter function is optimized
away by the compiler as an alias for the 'result' field of 'interp', as
in prior code. This may be a case of efficient, yet unclean coding.
Fabrice
>
> Hi Fabrice,
>
> On Wed, 5 Jan 2022, Fabrice Nicol wrote:
>
>> As a modest proposal for review by anyone.
>>
>> ----------------------------------------------------------
>>
>> Bug issue (fixed): building libmercury_tcltk crashes with current
>> tcl-tk releases (8.6+).
>>
>> As a consequence, samples/calc cannot be built either.
>
> ...
>
>> diff --git a/extras/graphics/mercury_tcltk/mtcltk.m
>> b/extras/graphics/mercury_tcltk/mtcltk.m
>> index 483f89c82..238a26cdc 100644
>> --- a/extras/graphics/mercury_tcltk/mtcltk.m
>> +++ b/extras/graphics/mercury_tcltk/mtcltk.m
>> @@ -224,7 +224,7 @@ Tcl_AppInit(Tcl_Interp *interp)
>> MR_fatal_error(""Tcl_Eval returned neither TCL_OK or
>> TCL_ERROR"");
>> }
>>
>> - Result = mtcltk_strdup(Interp->result);
>> + Result = mtcltk_strdup(Tcl_GetStringResult(Interp));
>> ").
>>
>> :- pragma foreign_code("C", "
>> @@ -284,8 +284,9 @@ mtcltk_do_callback(ClientData clientData,
>> Tcl_Interp *interp,
>> (MR_Word) args);
>> }
>>
>> + char* s = Tcl_GetStringResult(interp);
>> mtcltk_call_mercury_closure((MR_Word) clientData, interp,
>> - args, &status, &interp->result);
>> + args, &status, &s);
>
> That second part doesn't look correct.
> The call to mtcltk_call_mercury_closure() sets 's' to point to a string
> (i.e. it's an output argument) and this code should _set_ interp->result
> to that string. So rather than calling Tcl_GetStringResults() before
> the call, I think there should be a call to Tcl_SetResult() or
> Tcl_SetObjResult() somewhere after it.
>
> Julien.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Fix-mercury_tcltk-obsolete-result-fields.patch
Type: text/x-patch
Size: 1589 bytes
Desc: not available
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20220105/be38325e/attachment.bin>
More information about the reviews
mailing list