 Hello everyone, so I've got to present a project I've been working on the last month because I have time since we started. So the content of this talk, I'll just say a bit of who am I once, a function for interface. How we can do that with 4C, with Clang and AVM, a small demo if we have the time, about what's next. So my name is Adrian, I'm working on Crosslab with the two previous guys and we're working on AVM base of skaters as you have seen. So about the subject, what's an EFI file? So the Wikipedia definition is pretty straightforward. It says it's a mechanism by which program we turn in one language, we can call routines in another language. So in our cases, we want to be able to call C functions and AV compiles them from any language. So for instance, if we are in Python, we like to say, okay, there's this put S definition, and I just want to declare a function and close it and the magic happens and everything works. So what's the big deal, why is it hard to do that? When we want to call C functions from a higher level language, that's because we're using most preferences, but C functions are compiled for a specific IBI, application binary interface. There is just one ABI to the standard, there's one ABI per system, per architecture, whatever you want. It's kind of a mess if you try really to understand every ABI, you just don't want to do it, so you don't want to do it, so you want someone or a library to do it for you, and that's what you try to do. So the reference library, which is quite, really works well, which is called lib.ffi. It promotes a lot of various IBI, and there's a C API to use it. So for instance here, it's the IBI to code the hello world on put S. So it's placed right forward. And there's C.ffi, which is a Python library, which uses lib.ffi to do that from Python, and it uses p3 parser to parse definitions. So why would we want to do another one if this library exists? So there are some issues, for instance, for lib.ffi. It's not that trivial to insert a new IBI, you have to do Android return assembly, you've got to understand the whole ABI. So for instance on our Linux, the MSIBI doesn't exist. So for C.ffi, pyc parser can parse anything. For instance, you want to inclinify, it just doesn't work. If you have some custom attributes on a function, it doesn't work anymore. And I want to be able to use my library headers out of the box, and I want to modify them, I want to maintain two versions of them, I just want to use them and it works. So that's why we started to try to do that using ClientElevium. So what's nice with Client for that? Client can parse SQL, it's a good C parser. You won't have issues with attributes and stuff like that. There are two parts for lots of IBI, so you don't have to do it yourself. And LVM can compile the whole thing, but it puts everything together and it works, right? But it's not that easy. One thing you need to do is to find the right type of abstraction. Because we will parse C functions, we need to get these types and to work with them. So for instance, if we take the ClientST, if we've got a structure here, we see that the ClientST will just give us the name of the type of the fields. But we don't have anything about the padding, about the layout, so we don't need them to do our bindings. If we do that at the LVM level, it's a bit too low level because it's LVM. And for instance, 64 bytes on Intel, we won't have any, on Discord, we won't have any structure at all because of structure collapsing. I won't say in English. Yeah, thanks. So basically here, the structure is passed by only a register, it just doesn't exist in the IR, so it's too low level. If you want us to see how it can change, 32 bytes on Intel, here the structure is here because the IB is different, so you've got a different code. And in this case, it can work, but it's not universal. So one way which is nice to have is to use Dwarf DBA information. It happens to be the right level we want. If we take this code and we compare with DBA information, we see it tells us the structure, it says the name, the number of bytes is the type and there's the size and the half set here. So the structure, the layout, which is specific to the IB, is all coded with these informations. So what we did is that we take this Dwarf metadata, which will send them into our own system types. Why we did that is because we wanted our library to be free from LLVM headers, so you don't need to use the LLVM headers to compare, to use the library. And there's other things that we want also to have our type code qualified. We don't need all the stuff from Dwarf, so we need something in between. So, and to currency function, we got this issue stream we need to generate the dark code which called function from any kind of ambulance. So what we do is a kind of hike, but it works. We generate this wrapper for every function type. The wrapper takes a function pointer and it takes a pointer to the return value and a pointer to your list of pointers. And then you cast it on in this wrapper and client generates the IR, which is okay for the AI, but you don't have to do it and everything works like that. Some issues where we claim the main one is that if you have unused declaration in your code, for instance, here we've got print a and the structure is used by nothing else. If you compile this to LLVM IR, even with some flag which is called emit all decks, you won't emit all declarations. So you need to have some acts to for the stuff to be used. It's not really nice to see. So one small demo. So here it's using a Python, five minutes left. This is the Python bindings. So here, for instance, I've got this function foo. It compiles it using jitter and codes it to four and five and four plus five is nine. Here I can include a cdlib and use h2f from this library. Everything goes as it seems. Here I've got this structure point with two integers and two functions. So this function get() it will create me an object I can use directly from Python and I can go through the numbers and it goes as it should go. I can have memory views on these objects. So here it's two integers in the internal engine in memory. So this one and four. I can modify this one and re-print it. It will give me eight because the memory is directly modified. I can create a new point and use this multiply by two function and then I get the good point. And if I go a bit forward here, it's an example using openj and readjf from the libc. So I include j and I've got all my functions that I need. I can call openj and I can work in c in the end. Try the parameterization and everything. I just want this for instance and we make an implementation of ls which is very simple. This one is a bit more complex. It's for lib archive, lib archive is C library which is used for every we support a lot of archive formats and here it's really a mapping of the example you have in the library is the documentation to Python. I just want it the same way and I'll have the exception of that way. Anyway, the terms are wrong. So what's next? If you look at the binary generated for Python it's 55 megabytes, it's a bit huge. We've got more things we can try removing the same words trying to do this with ICO and stuff like that. Try to force claim to image type definitions that are not used. Relative to the talk, one game we can use easyj to jit the whole thing from Python to C. So for now we're evaluating our type 3 and then we could say okay for this function, this code is jitted you just do the only thing he needs to do. It actually works on milk it should take time to make it work on the system windows. Something that some people say on the Internet is that we could pass the debug information with sharp libraries and so it should work because we our main entry point is the draft information so maybe we even don't need to hellify it in some case and it can also be a basis for even in C++ for the people who have been there in Saint-Jose last October one guy from LG showed how we could make even in C++ and maybe it's a basis to do that. It was a leds on by the way if you want to show it. So that's it, that's all for me if you have questions. Yeah. So you can't always, the thing to remember this has been something, there's all sorts of complications you get a struck and passed by which one this was so I doubt that your... But the draft information has... I should think the Dwarf name is a bit too... And the programmer was good enough to mark things Yeah, sure, sure. Two things, we need the cost-qualified thing because in Python for instance strings are immutable so if you're in your IPI you've got a cost-sharp star you can say okay if my buffer view is really and I've got a cost-imparator I can't make this mapping because I've got the right to if in C I've got a sharp star I can do it and it works actually that's why yeah that's why I've got because Clang generates the good things so in Clang I've got the whole information and actually if you take this whatever is the problem in the test suite there is a part of stuff like that and it really works because Clang does the good thing and yeah, time's up, sorry if you have questions please