[foreign] RFR: Fix UndefinedLayoutException exception message

Jorn Vernee jbvernee at xs4all.nl
Tue Jan 29 17:41:39 UTC 2019


Maurizio Cimadamore schreef op 2019-01-29 17:09:
> On 29/01/2019 15:57, Jorn Vernee wrote:
>> Maurizio Cimadamore schreef op 2019-01-29 16:46:
>>> On 29/01/2019 15:19, Jorn Vernee wrote:
>>>> Maurizio Cimadamore schreef op 2019-01-29 15:59:
>>>>> Resolving references across interfaces is not expected to work
>>>>> reliably. This is the primary reason which sends us towards an
>>>>> extraction model that is library-centric, rather than 
>>>>> header-centric,
>>>>> so that all references in a library should be self-contained.
>>>> 
>>>> I've been using a mitigating patch that also scans methods of a 
>>>> Struct implementation in LayoutResolver when scanning a struct. 
>>>> Under the assumption that a type's layout is defined on that type 
>>>> itself.
>>>> 
>>>>> As for your test, it seems like you can get the same exception 
>>>>> simply
>>>>> by having a single struct interface whose layout has some dandling
>>>>> unresolved layout (e.g. an unresolved layout whose layout 
>>>>> expression
>>>>> is not defined anywhere)?
>>>> 
>>>> The tricky part is triggering the resolution of the layout through 
>>>> the public API. Trying to allocate a struct will not resolve the 
>>>> struct's layout. The only place I found that does this is either the 
>>>> test case I've used, where the dangling layout is in a 
>>>> @NativeFunction descriptor, or in StructImplGenerator's constructor, 
>>>> which is called when de referencing a pointer to a struct.
>>> 
>>> So, I guess what I'm saying is:
>>> 
>>> @NativeStruct("[ ${foo}(foo) ]")
>>> interface BadStruct extends Struct<BadStruct> {
>>>     @NativeGetter("foo")
>>>     Foo foo();
>>> 
>>>     interface Foo { }
>>> }
>>> 
>>> Shouldn't this fail when trying to generate the struct 
>>> implementation?
>>> (e.g. Scope.allocateStruct(BadStruct.class))
>> 
>> No, that will fail with "UnsupportedOperationException: bitsSize on 
>> Unresolved"
> 
> Then try with
> 
> scope.allocate(LayoutType.ofStruct(BadStruct.class)).get().foo()

Same there, that also calls allocateInternal.

Another way to trigger the exception could be something like;

```
try (var scope = Scope.newNativeScope()) {
     Pointer<?> ptr = scope.allocate(NativeTypes.VOID);
     ptr.cast(LayoutType.ofStruct(BasStruct.class)).get(); // trigger 
resolution
}
```

But that didn't seem like a realistic enough test. So, I went with the 
case in which I was seeing the exception; which is a cross-header layout 
reference.

Jorn

> Maurizio
> 
>> 
>> Scope.allocateStruct(BadStruct.class) will call allocateInternal first 
>> which throws that UOE, only after that would the implementation be 
>> generated when calling get() on the returned pointer;
>> 
>> ```
>> private <T> BoundedPointer<T> allocateInternal(LayoutType<T> type, 
>> long count, int align) {
>>     ...
>>     long size = Util.alignUp(type.bytesSize(), align); // !!! calling 
>> bitSize() on Unresolved throws UOE
>>     ...
>> }
>> 
>> @Override
>> public <T extends Struct<T>> T allocateStruct(Class<T> clazz) {
>>     // FIXME: is this alignment needed?
>>     return allocate(LayoutType.ofStruct(clazz), 8).get(); // call to 
>> 'get()' triggers struct generation, and resolution of struct's layout.
>> }
>> ```
>> 
>> Jorn
>> 
>>> Maurizio
>>> 
>>>> 
>>>> Of course, I could also just use 
>>>> `LayoutResolver.get(Object.class).resolve(Layout.of("${Undefined}"));`. 
>>>> Would that be good enough?
>>>> 
>>>> Jorn
>>>> 
>>>>> Maurizio
>>>>> 
>>>>> On 28/01/2019 14:52, Jorn Vernee wrote:
>>>>>> Ok, it took a while to find a good test case. I was seeing the 
>>>>>> exception due to a cross-header layout reference, so that's also 
>>>>>> the test case I added. It seems that that is currently the only 
>>>>>> realistic use-case where this exception is being thrown. I believe 
>>>>>> not being able to resolve cross-header layout references is a 
>>>>>> known issue as well?
>>>>>> 
>>>>>> Updated webrev: 
>>>>>> http://cr.openjdk.java.net/~jvernee/panama/webrevs/fixmessage/webrev.01/ 
>>>>>> Jorn
>>>>>> 
>>>>>> Jorn Vernee schreef op 2019-01-28 14:16:
>>>>>>> Yes, I will do that. (wasn't sure if it was useful enough).
>>>>>>> 
>>>>>>> Jorn
>>>>>>> 
>>>>>>> Sundararajan Athijegannathan schreef op 2019-01-28 14:12:
>>>>>>>> Is it possible to add a test with invalid (unresolvable) name
>>>>>>>> reference in a layout descriptor and check the exception 
>>>>>>>> message?
>>>>>>>> 
>>>>>>>> -Sundar
>>>>>>>> 
>>>>>>>> On 28/01/19, 6:36 PM, Jorn Vernee wrote:
>>>>>>>>> Hi,
>>>>>>>>> 
>>>>>>>>> JDK-8217245 changed the syntax for Unresolved layouts from 
>>>>>>>>> `$(Name)` to `${Name}`. This also means Unresolved now has a 
>>>>>>>>> dedicated `layoutExpression` field instead of relying on the 
>>>>>>>>> name annotation.
>>>>>>>>> 
>>>>>>>>> LayoutResolver.UndefinedLayoutException is still using the name 
>>>>>>>>> annotation in the exception message, which is now incorrect. 
>>>>>>>>> This small patch fixes that, and changes it to use 
>>>>>>>>> Unresolved::layoutExpression().
>>>>>>>>> 
>>>>>>>>> Please review.
>>>>>>>>> 
>>>>>>>>> Webrev: 
>>>>>>>>> http://cr.openjdk.java.net/~jvernee/panama/webrevs/fixmessage/webrev.00/ 
>>>>>>>>> Cheers,
>>>>>>>>> Jorn


More information about the panama-dev mailing list