poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC] Indexing array values with offsets, and constructing arrays by


From: Jose E. Marchesi
Subject: Re: [RFC] Indexing array values with offsets, and constructing arrays by size
Date: Thu, 18 Feb 2021 00:47:06 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Hi Indu.

> On 2/17/21 10:12 AM, Jose E. Marchesi wrote:
>> In the recent work with btf.pk that David Faust did, we have
>> something
>> like this:
>> type BTF_Section =
>>    struct
>>    {
>>      [...]
>>      string[header.str_len] strings @ str_off;
>>      /* Given an offset into the BTF strings section, return the
>> string.  */
>>      method get_string = (offset<uint<32>,B> off) string:
>>        {
>>          return string @ strings'offset + off;
>>        }
>>    };
>> i.e. the string table in the BTF section can be comfortably
>> expressed as
>> an array of strings.
>> But then, in the BTF world strings are referred using an offset
>> relative
>> to the string table, and not the ordinal order of the string in the
>> table.  This is similar to other string tables in other formats like
>> ELF.
>> The method above works, but it has a problem: it is not what I call
>> "agnostic" Poke code.  This means that the code needs assumes the data
>> is mapped.  In this case, the method only works when invoked in a BTF
>> section that is mapped.
>> Most Poke code should be agnostic if needed, so I am proposing two
>> additions to the language:
>> 1) Indexing array values with offsets.
>>     We shall support indexing arrays, both mapped and non-mapped,
>> with an
>>     offset value.  Like in:
>>     var a = [1,2,3];
>>     a[0#B] -> 1
>>     a[4#B] -> 2
>>     a[8#B] -> 3
>>     The provided offset should match the offset of some particular
>>     element in the array.  Otherwise, we get an E_out_of_bounds
>>     exception:
>>     a[5#B] -> raises E_out_of_bounds
>>     a[10#Kb] -> raises E_out_of_bounds
>>     Using this support, we don't need the `get_string' method above.
>>     Given an offset into the string table the user can just do:
>>     section.strings[OFFSET]
>>     which would be agnostic Poke code: it would work as well with
>> both
>>     mapped and non-mapped BTF sections.
>> 
>
> It makes sense to consolidate the semantics for array access using
> offset for both mapped and non-mapped arrays.
>
> Regarding the error: as a user, a first reaction when I see a
> E_out_of_bounds for a[5#B] is confusing because the access is within 
> bounds, it just happens to be an invalid one.
>
> How about :
>    a[5#B] -> raises E_invalid_access
>    a[10#Kb] -> raises E_out_of_bounds

Ok, you are definitely right in that out_of_bounds is confusing for the
first case.

Then again, why having two exceptions?  We can just use an
E_invalid_index for every invalid indexation, regardless of the nature
of the index.

>> 2) Constructing arrays by size.
>>     Currently we can create array values in Poke using three
>> different
>>     ways:
>>     - Using an array literal: [1,2,3], ["foo", "bar"], etc.
>>     - Using an array constructor:
>>        int[] (3)  -> [0,0,0] of type int[]
>>        int[3] (3) -> [0,0,0] of type int[3]
>>        string (2) -> ["",""]
>>     - Mapping an array:
>>       + Unbounded: int[] @ OFFSET -> maps until EOF or constraint
>> failure.
>>       + Bounded by number of elements: int[3] @ OFFSET -> [1,2,3]
>>       + Bounded by size: int[12#B] @ OFFSET -> [1,2,3]
>>     I am proposing to add the possibility of constructing an array
>> by
>>     size as well, like in:
>>        int[] (12#B) -> [0,0,0]
>>        int[] (0#B) -> []
>> 
>
> Hmm..speaking of syntax, something is amiss. E.g., What syntax do we
> follow if we want to initialize the array as well ?
>
> int [] (12#B) (4)  --> [4,4,4]  --> This looks fine.
> offset<int,B>[] (8#B) (16#b) --> [2#B,2#B]
>
> Without imposing an order between (size), and (init-value) in poke,
> the second example will not work (AFAIU). And even after imposing an
> order, the syntax is prone to ugly bugs for user.
>
> Also, will we then have two ways of specifying the same thing - like
> int[12#B] (4) and int [] (12#B) (4) ?

My fault.

The actual syntax is: int[BOUND] (INITVAL) -> [INITVAL, INITVAL ... ]

So, for a size BOUND would be an offset, not an integral:

  int[2] (3)    -> [3,3]
  int[12#B] (3) -> [3,3,3]

>>     The question with this is: what exception to raise when the given
>>     size doesn't span for a whole number of the elements of the array
>>     type?  Currently, that situation when mapping arrays by size raises
>>     E_map_bounds.  I think in the case of constructing by size we should
>>     raise E_out_of_bounds instead.
>> 
>
> IMO, on first look, E_out_of_bounds looks acceptable here.
>
> I have a question though (applicable to both these proposals) - Will
> the user get E_map_bounds/E_out_of_bounds depending on whether the
> element is mapped or not ?

Hmmm, yes, and that is not agnostic :/
What about just renaming E_map_bounds to E_out_of_bounds?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]