foolang icon indicating copy to clipboard operation
foolang copied to clipboard

FFI / shared object interface

Open nikodemus opened this issue 4 years ago • 1 comments

FFI code is always accessed through the System object.

foo --extension=foo/ext/network

loads foo/ext/network.foo, initializes it by Extension load: system, and makes it available as system network.

Sketch:

-- TimeVal new
-- TimeVal sec: <Integer> usec: <Integer>
define TimeVal
    Alien struct: { sec: Alien time_t,
                    usec: Alien suseconds_t }
end

-- TimeZone new
-- TimeZone minuteswest: <Integer> dsttime: <Integer>
define TimeZone
    Alien struct: { minuteswest: Alien int,
                    dsttime: Alien int }
end

class Stuff { library }
    method sin: x
         let sin = Alien
            name: "sin"
            type: [Alien double] -> Alien double
            library: library.
         sin value: x

    method gettimeofday
        let gettimeofday = Alien
            name: "gettimeofday"
            type: [*TimeVal, *TimeZone] -> Alien int
            library: library.
        let tv = TimeVal new.
        let tz = TimeZone new.
        gettimeofday value: tv value: tz.
        [tv, tz]
end

class Extension {}
    class method load: system
        Stuff library: (system libraries libc)

This should do for now: I'm hesitant to introduce methods that require more syntax or allow circumventing System.

Complication

  1. Rust's libffi crate on Windows needs a built-from source LLVM, as http://llvm.org's installer doesn't bundle llvm-config.
  2. Cranelift doesn't support fastcall yet. (Or maybe it does? Looking at this again.)

Both mean the same thing: need to find another backend for doing FFI in the evaluator.

Alternatives:

  • https://crates.io/crates/dynasm
  • https://crates.io/crates/lua-jit-sys
  • https://crates.io/crates/lightning-sys
  • https://github.com/TomBebbington/jit.rs
  • https://github.com/lemonrock/predicator
  • https://crates.io/crates/gccjit
  • https://crates.io/crates/libtcc
  • https://crates.io/crates/assembler

Finally, one option is to support a sufficiently impoverished number of foreign types that I can just write the glue code by hand.

nikodemus avatar Apr 04 '20 15:04 nikodemus

Need to rewrite this for self-hosting.

Could I require that extensions are compiled first? That would work, but it would be irritating to develop with.

nikodemus avatar Aug 03 '21 14:08 nikodemus