[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