[m-rev.] for tryout: type_spec_constrained_preds

Julien Fischer jfischer at opturion.com
Fri Feb 2 01:49:33 AEDT 2024


Hi Zoltan,

On Thu, 1 Feb 2024, Zoltan Somogyi wrote:

> On 2024-02-01 14:08 +11:00 AEDT, "Zoltan Somogyi" <zoltan.somogyi at runbox.com> wrote:
>>
>> On 2024-02-01 01:06 +11:00 AEDT, "Julien Fischer" <jfischer at opturion.com> wrote:
>>> I will post something regarding the JSON library tomorrow or Friday;
>>> it's the more interesting of the two.
>>
>> If you have not yet started on this, then don't. I know what is causing
>> at least the first compiler error with your csv program, and I should have
>> a fix in the next couple of hours. When I do, I will post it here.
>
> The fix updates just one file; it is attached. With it, the csv program now
> compiles, both with and without the new pragma applying to superclasses.

Yes, it also compiles for me; the fix also resolves what was probably
the same issue with the JSON library. The next issue I have encountered
concerns that:

Source: https://github.com/juliensf/mercury-json

There are currently three opportunities for using
type_spec_constrained_preds. (There will shortly also be a fourth.)

The three are:

1. Reading JSON from a string using the various string conversion
    predicates (e.g. from_string/{2,3}.).

2. Writing JSON to a text output file stream.

3. Writing JSON to a string (i.e. stringifying it).

For (1) we can add the following pragma:

:- pragma type_spec_constrained_preds(
         [stream.line_oriented(Stream, State),
             stream.unboxed_reader(Stream, char, State, Error),
             stream.putback(Stream, char, State, Error)],
         apply_to_superclasses,
         [
             subst([Stream = string_reader,
             State = string_reader_state,
             Error = string_reader_error])]).

That compiles successfully at the standard optimisation level; with
--intermodule-optimization enabled, we trip over what I suspect is
an existing bug:

In predicate
   `TypeSpecOf__pred__make_error_context__[Stream =
json.string_reader.string_reader, State =
json.string_reader.string_reader_state, Error =
json.string_reader.string_reader_error]'/4:
   purity error: predicate is impure.
   It must be declared `impure' or promised pure.
In predicate
   `TypeSpecOf__pred__make_syntax_error__[Stream =
json.string_reader.string_reader, State =
json.string_reader.string_reader_state, Error =
json.string_reader.string_reader_error]'/6:
   purity error: predicate is impure.
   It must be declared `impure' or promised pure.
In predicate
   `TypeSpecOf__pred__make_unexpected_eof_error__[Stream =
json.string_reader.string_reader, State =
json.string_reader.string_reader_state, Error =
json.string_reader.string_reader_error]'/5:
   purity error: predicate is impure.
   It must be declared `impure' or promised pure.
Mercury/asm_fast.gc/x86_64-pc-linux-gnu/Mercury/opts/json.opt:345: In
predicate
Mercury/asm_fast.gc/x86_64-pc-linux-gnu/Mercury/opts/json.opt:345:
`TypeSpecOf__pred__make_error_context__[Stream =
json.string_reader.string_reader, State =
json.string_reader.string_reader_state, Error =
json.string_reader.string_reader_error]'/4:
Mercury/asm_fast.gc/x86_64-pc-linux-gnu/Mercury/opts/json.opt:345:
purity

For (2) and (3) we can add the following pragmas:

:- pragma type_spec_constrained_preds(
         [
          stream.writer(Stream, string, State)
         ],
         apply_to_superclasses,
         [subst([
            Stream = io.text_output_stream,
            State = io.state])]).

:- pragma type_spec_constrained_preds(
         [
          stream.writer(Stream, char, State),
          stream.writer(Stream, string, State)
         ],
         apply_to_superclasses,
         [subst([
             Stream = string.builder.handle,
             State = string.builder.state])]).

Each of these works by itself, but both of them being present results in
the following abort during parse tree -> HLDS conversion.

    Uncaught Mercury exception:
    Software Error: predicate `one_or_more.det_list_to_one_or_more'/2:
    Unexpected: empty list
    Stack dump not available in this grade.
    ** Error making
    `Mercury/asm_fast.gc/x86_64-pc-linux-gnu/Mercury/opts/json.writer.opt'.

(A similar thing occurs when --intermodule-optimization is disabled.)

The same thing occurs with (1) if add the pragma as well:

:- pragma type_spec_constrained_preds(
         [stream.line_oriented(Stream, State),
             stream.unboxed_reader(Stream, char, State, Error),
             stream.putback(Stream, char, State, Error)],
         apply_to_superclasses,
         [subst([Stream = io.input_stream,
             State = io.state, Error = io.error])]).

In the cases that succeed, the specialisations I would expect are
present in the generated C code, although I have not looked at how
effective they are.

Julien.


More information about the reviews mailing list