I've just discovered the Fan programming language, and I have to say that I am pretty amazed by what you have achieved here! :)
In order to try and contribute, I'd like to add a compilation target that will produce LLVM bytecode in order to be able to compile Fan programs as native programs. I currently see two approaches to do this: 1 - Generate the whole LLVM bytecode from the AST. It seems it is the approach that has been chosen for the JavaScript target. 2 - Write a program that reads FCode and translate it to LLVM bytecode (like it is done for the Java and .Net targets I believe)
The first approach seems better to me, and will probably produce more efficient bytecode, but I'd like to have your opinion before starting to investigate.
Another problem I'll probably met is how to interface Fan code with C libraries. It seems there would be two ways to do that with the current architecture: 1 - with the "native" keyword and a Peer-like mecanism 2 - with a using [C] libHeader.h mecanism
The second one seems to be the approach to follow according to the doc, but I can't find where this is used in existing pods. Searching for using [java] only gives results in sample-codes, but I still can't see how this approach can be used to have a class have an implementation for Java, another implementation for .Net, and another one for C.
Thanks for your great work! :)
brianSun 4 Oct 2009
A LLVM backend for Fan would be pretty awesome!
I think you raised two different issues:
should backend target AST or Fcode
should C libraries be interfaced by natives or FFI
AST vs Fcode
For the first question, I would recommend that the backend work off FCode, not AST. This has a couple of advantages. First the FCode has a much smaller surface area and is extremely stable since it serves as the interface between the compiler and runtime. If you target the AST, the LLVM backend will be interwined with the source language itself and the huge surface area of the compiler. If it is a question of optimization, I would be more inclined to say we should add "hints" to the FCode.
Another reason, if that is you target AST, then the LLVM will not be an available option unless source is available. I would assume that often only the fcode would be available. We choose AST for JavaScript because it was a source-to-source compiler, but I don't think a LLVM backend would have all the same problems we had with JavaScript.
But the best reason to have LLVM backend target FCode is that it is the beginning of a stand alone Fan VM. If the LLVM can accept pre-compiled pods and their fcode, then essentially we have a new Fan VM runtime as an alternative to the JVM or CLR. Over time, it certainly seems feasible that a LLVM Fan VM could rival the Fan JVM runtime, but with a much smaller footprint.
Native vs FFI
The main difference between native and FFI is that native is designed to have multiple back-end implementations. For example the entire sys pod is assumed native. So a LLVM runtime would be required to provide a C implementation of every native method (such as inet, fwt, etc) and all the sys APIs.
You might also provide a C FFI so that non-portable code could call out to C methods directly. But by definition code which uses a Java, .NET, JavaScript, or C FFI is non-portable because it assumes a specific runtime.
Originally I desired to unify native methods and FFI interfaces. But I am beginning to think that maybe they serve two different purposes.
andreySun 4 Oct 2009
Cool idea! Will this extend Fan areal to the iPhone and embedded devices at large? ;)
Apple also uses LLVM in the OpenGL stack in Leopard, leveraging its virtual machine concept of common IR to emulate OpenGL hardware features on Macs that lack the actual silicon to interpret that code. Code is instead interpreted or JIT on the CPU. ... Apple is also using LLVM in iPhone development, as the project's modular architecture makes it easier to add support for other architectures such as ARM, now supported in LLVM 2.0 thanks to work done by Nokia's INdT.
If this were done, and if you really could read C and C++ headers directly instead of having to make glue, it would make Fan a LOT easier for me to use for some of the use cases I need right now.
filgoodTue 1 Dec 2009
Has any work been done on implementing LLVM as a target?
MoOmWed 2 Dec 2009
I've started to work on it recently. I still have nothing to show though. I'll put the code on a google-code page as soon as the program can run some samples.
The good thing is that the opcodes of Fantom have been really well thought in order to be totally platform-agnostic and it should be possible to generate efficient LLVM bytecode from it.
My two main concerns right now are Func.call() which I don't see how to implement efficiently, and parametized types such as List and Map.
No, I haven't done any progress on this recently. This is still a project that I'd like to work on, but I haven't found time or motivation to work on this lately. Sorry about that...
go4Sat 12 Nov 2011
Do you have idea to deal with exception and garbage collection in LLVM.
MoOmSat 12 Nov 2011
For exception handling, I chose the setjmp/longjmp solution instead of zero-cost exception handling. Setjmp/longjmp allows to write exception-handling in C code too and is more portable (there is no zero-cost exception-handling on the iPhone for example). But with the setjmp/longjmp method, the cost of a try is more important (you need to save all the registers, whereas with zero-cost EH, there is nothing to do).
About garbage collection, at first I wanted to use Boehm garbage collector, but now, I'd be in favor to use reference-counting instead as latency is pretty important for me (as I wanted LLVM backend to be able to use Fantom for iPhone games/applications mainly). The cycle-reference problem would be solved with a @WeakRef facet to mark fields that should not have ownership on the object. But I haven't started to work on the garbarge collection yet.
My main problem with the LLVM backend for now is the amount of native code to port to have a "bootable" sys pod. That's why I would really like if most of sys was written directly in Fantom. And that would be great for maintenancy too.
go4Sat 12 Nov 2011
Thanks, What about converting Fantom code to C source?
DanielFathSat 12 Nov 2011
Thanks, What about converting Fantom code to C source?
That's quite a leap. I mean one is object oriented the other is procedural coding.
MoOmSat 12 Nov 2011
Thanks, What about converting Fantom code to C source?
Translating from Fantom code would not be a good idea as it would require important modifications to the Fantom compiler. Everytime a new feature is added, the C code-generation would need to be updated. Fcode is a much more friendly representation to generate low level bitcode as almost every Fcode instructions has a 1-to-1 translation into an LLVM opcode, and it evolves a lot less often than the compiler.
As for translating to C source, I would not gain much from that (except for better portability). I would loose the ability to add debug infos to be able to debug Fantom code with GDB and I would loose the ability to have a fine control over generated code. Pods could no longer be loaded and JITed at runtime. And converting FCode to C isn't really a good idea as FCode is much more low-level than C.
brianSun 13 Nov 2011
My main problem with the LLVM backend for now is the amount of native code to port to have a "bootable" sys pod. That's why I would really like if most of sys was written directly in Fantom. And that would be great for maintenancy too.
Yeah this is a tough problem. Originally sys and compiler had to be written in Java to bootstrap the whole system. Eventually I went back and rewrote compiler from Java into Fantom. But doing the rewrite of sys is a big project and will be very messy and ugly. Plus you would loose lots of hand coded optimization that I often do in low-level sys classes.
MoOmSun 13 Nov 2011
Yeah this is a tough problem. Originally sys and compiler had to be written in Java to bootstrap the whole system. Eventually I went back and rewrote compiler from Java into Fantom. But doing the rewrite of sys is a big project and will be very messy and ugly. Plus you would loose lots of hand coded optimization that I often do in low-level sys classes.
That is part of the reason why I wanted extra value-types (i.e. Int32, Float32...) and arrays. Without these, many classes of sys just cannot be written in pure Fantom (or it'll be really sub-optimized). But I agree with you that this is definitely not an easy task and I'm not sure it's actually worth it. I've already written an important part of of sys in C so I'll probably continue this way and we could maybe rethink about this when there is a running proof of concept... :)
go4Sun 11 Dec 2011
Hi MoOm. How to contact you? Maybe I can do some help.
Why don't you use Mercurial? I have a dozen reasons to drop the SVN. And thanks fantom chosen a modern VCS.
XanFri 23 Mar 2012
Any progress on that? I like very much the idea of having llvm generating code of fantom
LightDyeTue 25 Jun 2013
It's probably worth to revisit this topic since nowadays there are alternatives to run Java code in iOS. This article is more than 3 months old now but it points to very interesting tools.
MoOm Sun 4 Oct 2009
I've just discovered the Fan programming language, and I have to say that I am pretty amazed by what you have achieved here! :)
In order to try and contribute, I'd like to add a compilation target that will produce LLVM bytecode in order to be able to compile Fan programs as native programs. I currently see two approaches to do this: 1 - Generate the whole LLVM bytecode from the AST. It seems it is the approach that has been chosen for the JavaScript target. 2 - Write a program that reads FCode and translate it to LLVM bytecode (like it is done for the Java and .Net targets I believe)
The first approach seems better to me, and will probably produce more efficient bytecode, but I'd like to have your opinion before starting to investigate.
Another problem I'll probably met is how to interface Fan code with C libraries. It seems there would be two ways to do that with the current architecture: 1 - with the "native" keyword and a Peer-like mecanism 2 - with a
using [C] libHeader.h
mecanismThe second one seems to be the approach to follow according to the doc, but I can't find where this is used in existing pods. Searching for
using [java]
only gives results in sample-codes, but I still can't see how this approach can be used to have a class have an implementation for Java, another implementation for .Net, and another one for C.Thanks for your great work! :)
brian Sun 4 Oct 2009
A LLVM backend for Fan would be pretty awesome!
I think you raised two different issues:
AST vs Fcode
For the first question, I would recommend that the backend work off FCode, not AST. This has a couple of advantages. First the FCode has a much smaller surface area and is extremely stable since it serves as the interface between the compiler and runtime. If you target the AST, the LLVM backend will be interwined with the source language itself and the huge surface area of the compiler. If it is a question of optimization, I would be more inclined to say we should add "hints" to the FCode.
Another reason, if that is you target AST, then the LLVM will not be an available option unless source is available. I would assume that often only the fcode would be available. We choose AST for JavaScript because it was a source-to-source compiler, but I don't think a LLVM backend would have all the same problems we had with JavaScript.
But the best reason to have LLVM backend target FCode is that it is the beginning of a stand alone Fan VM. If the LLVM can accept pre-compiled pods and their fcode, then essentially we have a new Fan VM runtime as an alternative to the JVM or CLR. Over time, it certainly seems feasible that a LLVM Fan VM could rival the Fan JVM runtime, but with a much smaller footprint.
Native vs FFI
The main difference between native and FFI is that native is designed to have multiple back-end implementations. For example the entire
sys
pod is assumed native. So a LLVM runtime would be required to provide a C implementation of every native method (such as inet, fwt, etc) and all the sys APIs.You might also provide a C FFI so that non-portable code could call out to C methods directly. But by definition code which uses a Java, .NET, JavaScript, or C FFI is non-portable because it assumes a specific runtime.
Originally I desired to unify native methods and FFI interfaces. But I am beginning to think that maybe they serve two different purposes.
andrey Sun 4 Oct 2009
Cool idea! Will this extend Fan areal to the iPhone and embedded devices at large? ;)
Full story at http://www.appleinsider.com/articles/08/06/20/apples_other_open_secret_the_llvm_complier.html
tompalmer Tue 6 Oct 2009
If this were done, and if you really could read C and C++ headers directly instead of having to make glue, it would make Fan a LOT easier for me to use for some of the use cases I need right now.
filgood Tue 1 Dec 2009
Has any work been done on implementing LLVM as a target?
MoOm Wed 2 Dec 2009
I've started to work on it recently. I still have nothing to show though. I'll put the code on a google-code page as soon as the program can run some samples.
The good thing is that the opcodes of Fantom have been really well thought in order to be totally platform-agnostic and it should be possible to generate efficient LLVM bytecode from it.
My two main concerns right now are Func.call() which I don't see how to implement efficiently, and parametized types such as List and Map.
tactics Wed 2 Dec 2009
I'd love to see what you come up with MoOm!
katox Sun 19 Sep 2010
ping
Edit: a google search result: http://code.google.com/p/fan-llvm/source/browse/
adaman Fri 11 Nov 2011
Any updates on this ?
MoOm Sat 12 Nov 2011
No, I haven't done any progress on this recently. This is still a project that I'd like to work on, but I haven't found time or motivation to work on this lately. Sorry about that...
go4 Sat 12 Nov 2011
Do you have idea to deal with exception and garbage collection in LLVM.
MoOm Sat 12 Nov 2011
For exception handling, I chose the setjmp/longjmp solution instead of zero-cost exception handling. Setjmp/longjmp allows to write exception-handling in C code too and is more portable (there is no zero-cost exception-handling on the iPhone for example). But with the setjmp/longjmp method, the cost of a
try
is more important (you need to save all the registers, whereas with zero-cost EH, there is nothing to do).About garbage collection, at first I wanted to use Boehm garbage collector, but now, I'd be in favor to use reference-counting instead as latency is pretty important for me (as I wanted LLVM backend to be able to use Fantom for iPhone games/applications mainly). The cycle-reference problem would be solved with a @WeakRef facet to mark fields that should not have ownership on the object. But I haven't started to work on the garbarge collection yet.
My main problem with the LLVM backend for now is the amount of native code to port to have a "bootable"
sys
pod. That's why I would really like if most ofsys
was written directly in Fantom. And that would be great for maintenancy too.go4 Sat 12 Nov 2011
Thanks, What about converting Fantom code to C source?
DanielFath Sat 12 Nov 2011
That's quite a leap. I mean one is object oriented the other is procedural coding.
MoOm Sat 12 Nov 2011
Translating from Fantom code would not be a good idea as it would require important modifications to the Fantom compiler. Everytime a new feature is added, the C code-generation would need to be updated. Fcode is a much more friendly representation to generate low level bitcode as almost every Fcode instructions has a 1-to-1 translation into an LLVM opcode, and it evolves a lot less often than the compiler.
As for translating to C source, I would not gain much from that (except for better portability). I would loose the ability to add debug infos to be able to debug Fantom code with GDB and I would loose the ability to have a fine control over generated code. Pods could no longer be loaded and JITed at runtime. And converting FCode to C isn't really a good idea as FCode is much more low-level than C.
brian Sun 13 Nov 2011
Yeah this is a tough problem. Originally sys and compiler had to be written in Java to bootstrap the whole system. Eventually I went back and rewrote compiler from Java into Fantom. But doing the rewrite of sys is a big project and will be very messy and ugly. Plus you would loose lots of hand coded optimization that I often do in low-level sys classes.
MoOm Sun 13 Nov 2011
That is part of the reason why I wanted extra value-types (i.e. Int32, Float32...) and arrays. Without these, many classes of sys just cannot be written in pure Fantom (or it'll be really sub-optimized). But I agree with you that this is definitely not an easy task and I'm not sure it's actually worth it. I've already written an important part of of sys in C so I'll probably continue this way and we could maybe rethink about this when there is a running proof of concept... :)
go4 Sun 11 Dec 2011
Hi MoOm. How to contact you? Maybe I can do some help.
Why don't you use Mercurial? I have a dozen reasons to drop the SVN. And thanks fantom chosen a modern VCS.
Xan Fri 23 Mar 2012
Any progress on that? I like very much the idea of having llvm generating code of fantom
LightDye Tue 25 Jun 2013
It's probably worth to revisit this topic since nowadays there are alternatives to run Java code in iOS. This article is more than 3 months old now but it points to very interesting tools.
Open source Java iOS tools compared
I've been dreaming with writing mobile apps using Fantom. Is this dream going to become reality any time soon?
andy Tue 25 Jun 2013
Thanks for the link - was not aware of any of these projects. RoboVM looks particularly interesting.
LightDye Tue 25 Jun 2013
You are welcome. If any of those projects serves as a base, or even just as an inspiration to do something similar for Fantom, that would be awesome.