Skip to content

[vm/ffi] Disallow user methods on Structs #40291

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
dcharkes opened this issue Jan 23, 2020 · 3 comments
Open

[vm/ffi] Disallow user methods on Structs #40291

dcharkes opened this issue Jan 23, 2020 · 3 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi

Comments

@dcharkes
Copy link
Contributor

Structs are really a view on top of memory. They do not have constructors, their instances are invented by the VM in the FFI. Those instances happen to implement the abstract interface of the struct. They do not have normal fields, only the getters and setters to C memory. They cannot be sub typed.

However, currently we do allow methods on those classes. But they add nothing over extension methods from a user point of view, because they work based on the core interface, and we do not allow sub typing. But they do add complexity.

@dcharkes dcharkes added area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi labels Jan 23, 2020
@mqnfred
Copy link

mqnfred commented Jan 26, 2020

Hello @dcharkes,

I am currently working on a rust <-> dart ffi conversion tool. The goal is to generate a dart API based on a rust API, to consume through ffi. I want to provide an idiomatic dart API which hides ffi concepts such as ffi.Pointer indirections etc.

It is very handy to be able to give methods to classes which extend ffi.Struct. I have in mind, for example:

  • Some kind of allocate factory as a constructor
  • Some kind of free factory to free the memory behind the reference
  • Some cool stuff like getters on ffi.Pointer<Utf8> that return Strings

I do not know if the ability to add methods is inherently an anti-pattern, but I sure know it is convenient. I am guessing that if it went away, I would need to wrap all my API's objects, which feels inefficient and bloat-y.

Here is an example of generated code:

class Coordinate extends ffi.Struct {
        ffi.Pointer<Degree> _latitude;
        Degree get latitude => _latitude[0];

        ffi.Pointer<Degree> _longitude;
        Degree get longitude => _longitude[0];

        factory Coordinate.malloc(Degree latitude, Degree longitude) {
                return mallocCoordinate(latitude.addressOf, longitude.addressOf).ref;
        }
        void free() { freeCoordinate(addressOf); }
}

I am not extremely familiar with dart yet, could you provide an adapted example of this using extension methods and the like?

@dcharkes
Copy link
Contributor Author

@mqnfred you can just make it all extension methods.

class Coordinate extends ffi.Struct {
        ffi.Pointer<Degree> _latitude;
        ffi.Pointer<Degree> _longitude;
}

extension CoordinateMethods on Coordinate {
        Degree get latitude => _latitude[0];

        Degree get longitude => _longitude[0];

        factory Coordinate.malloc(Degree latitude, Degree longitude) {
                return mallocCoordinate(latitude.addressOf, longitude.addressOf).ref;
        }
        void free() { freeCoordinate(addressOf); }
}

Does this work for you?

@mqnfred
Copy link

mqnfred commented Jan 29, 2020

Thank you very much!

This is great, I was not expecting every type of function/methods to transfer so seamlessly. I now see why the issue is relevant, as we can dedicate the class extending ffi.Struct to being ffi data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi
Projects
None yet
Development

No branches or pull requests

2 participants