[foreign] Pulling the string on Scope

Jorn Vernee jbvernee at xs4all.nl
Fri Dec 21 16:26:42 UTC 2018


Nvm, I see what you mean now.

i.e. tie the pointer to the scope of the struct any ways, and then 
someone has to manually correct this in the counter example case I gave.

Jorn

Jorn Vernee schreef op 2018-12-21 16:42:
> Maurizio Cimadamore schreef op 2018-12-20 21:59:
>> On 20/12/2018 13:54, Jorn Vernee wrote:
>>> The above example does not actually throw an exception. There is a 
>>> solution for this problem for Callbacks; if you have a 
>>> Pointer<Callback<...>> then when the pointer is de-referenced the 
>>> callback is added to the Scope of the enclosing Pointer, and in the 
>>> case of struct fields this just happens to be the same scope that the 
>>> struct belongs to, but this seems like an unwanted side-effect. If 
>>> the Callback was not in the same scope as the Pointer we 
>>> inadvertently add it to the wrong scope. The right way to solve this 
>>> seems to be to track the Scope of a Struct's field when setting it, 
>>> and then setting it again when getting. But, we can't ask native code 
>>> to do that, so maybe the only solution is to say that when you get a 
>>> struct's field it does not belong to any scope, and the missing 
>>> exception in the above example is intended behavior. Adding a 
>>> resource field to the scope of the enclosing struct when getting 
>>> seems to make sense for nested structs and fused arrays only, since 
>>> you can say for sure that when the struct is freed so are it's 
>>> contents.
>> 
>> I think a sensible behavior here is to tie the scope of whatever
>> pointer we get back from a struct to the struct itself. We can't do
>> much better than that, but I think it's a start, and, once we have a
>> way to transfer pointer ownership, the user will be able to 'expand'
>> the lifecycle of the pointer if he chooses to do so.
> 
> So, this is only a good solution if the pointer we get back actually
> points to the memory region of the struct.
> 
> To give a counter example;
> 
>     @NativeStruct("[" +
>             "   u64(get=getPtr)(set=setPtr):i32" +
>             "](MyStruct)")
>     interface MyStruct extends Struct<MyStruct> {
>         Pointer<Integer> getPtr();
>         void setPtr(Pointer<Integer> ptr);
>     }
> 
>     public static void main(String[] args) {
>         Scope scope1 = Scope.newNativeScope();
>         Pointer<Integer> myPointer = 
> scope1.allocated(NativeTypes.INT32);
>         Pointer<Integer> outside;
>         try(Scope scope2 = Scope.newNativeScope()) {
>             MyStruct struct = scope2.allocateStruct(MyStruct.class);
>             struct.setPtr(myPointer));
>             outside = struct.getPtr(); // returned pointer tied to
> scope of struct
>         } // struct scope closed, and thus scope of 'outside'
>         int i = outside.get(); // should work, but will throw
>     }
> 
> If a getter of a struct ties a returned pointer to the scope of the
> struct, it will get closed too soon in this case, and the example
> above will throw, even though it's safe.
> 
> However, if we get back a pointer that points to the internals of a
> struct I think we can safely tie it to the struct's scope.
> 
> Jorn
> 
>> In the past I've looked into other solutions so that the binder could
>> somehow reify all the scopes of all the pointer fields, but it seemed
>> overkill (think of cases where you  have Pointer<Pointer<Pointer...>>>
>> )
>> 
>> Maurizio


More information about the panama-dev mailing list