[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?