[foreign] Pulling the string on Scope
Jorn Vernee
jbvernee at xs4all.nl
Fri Dec 21 15:42:13 UTC 2018
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