Haxe C# target up and running.

1,410 views
Skip to first unread message

Ben Cooley

unread,
Jan 5, 2012, 1:40:48 AM1/5/12
to haxe...@googlegroups.com
I've implemented a Haxe C# target, available at git://github.com/benjcooley/haxe.git.

To run-test the target, you'll need to clone the haxe-install repo's gencs branch, then make sure that the git line in the install.ml file will correctly pull the "gencs" haxe branch from my repo during build.

I have not successfully run the haxe unit test suite on this target, but basic features seem to be working.  One addition is support for generating #line directives in the output code via the -lines compiler option to allow source debugging in haxe when running on the .net VM.

There is also a preliminary "haxe" Binding for MonoDevelop in the MonoDevelop repo.

My primary interest in this port is to allow Haxe to target mobile devices in a way that allows easy access to the native platform, better GC behavior, and full IDE tooling support including source level debugging on both simulator and devices.  It seemed to me that being able to target Mono was the easiest path to reach this goal.

Joshua Granick

unread,
Jan 5, 2012, 1:55:02 AM1/5/12
to haxe...@googlegroups.com
Very cool! Have you talked to Caue Waneck at all? He's been tempting us
with his work on a C# target, but I haven't been able to try it.

Wait, so is the haxe binding support for writing Haxe code from
MonoDevelop?

Ideas running through my mind...


1.) Using NME C++ libraries with C#

I always had good experiences working with C# in terms of integration with
Windows. System tray icon? Custom forms and windows? Simple. This is a bit
more difficult from C/C++, but if NME's C++ binary could be loaded and
used from C#, that means the windowing could be handled in C#, and with a
haxe C# target, it could all be invisible to the user, and just handled
all through haxe code. Seems very cool, potentially.


2.) Some kind of Windows Phone target?

Windows Phone has not allowed the use of unmanaged C/C++ code, which has
shot down the possibility of an NME target for the platform. However, with
a haxe C# target, it opens the possibility of running on Windows Phone.
Though it would be a bit of work, a C# target could mean the beginnings of
NME-style support for Windows Phone, or maybe even XBox Live?


3.) IDE support/creation

The last thing that's firing in my head is either the support of Haxe in
MonoDevelop, or if a haxe C# target would make it easier to generate
anything new. We all know that FlashDevelop is an awesome *Windows* IDE,
written in C#, and as much as everyone has asked for a Linux or Mac port,
no one has made it happen. If you have haxe working as a language inside
of MonoDevelop, it may be possible to pull (or share) components from
FlashDevelop and use them in MonoDevelop, or spin things off to make a
FlashDevelop derivative, (perhaps) using cross-platform controls from
MonoDevelop. One of the biggest "gotchas" to porting FlashDevelop has been
Scintilla.NET, but if MonoDevelop's text editor control was used instead,
it might be possible to have an original IDE, basically FlashDevelop, but
using MonoDevelop parts where necessary.


On Wed, 04 Jan 2012 22:40:48 -0800, Ben Cooley <benjc...@gmail.com>
wrote:


--
Using Opera's revolutionary email client: http://www.opera.com/mail/

Ben Cooley

unread,
Jan 5, 2012, 3:14:03 AM1/5/12
to haxe...@googlegroups.com
My interest is in primarily targeting MonoTouch and MonoDroid, which would provide:

1. A very high performance runtime environment in LLVM with full generational garbage collection.
2. Full access to the native iPhone and Android platform API's.
3. Source level debugging on both the simulators and devices.
4. Access to C/C++ libraries through CXXI, and C# modules through standard haxe wrapping.

And the overarching concern which is of course portability to Javascript and HTML5 and Flash.

Philippe Elsass

unread,
Jan 5, 2012, 4:47:25 AM1/5/12
to haxe...@googlegroups.com
Oh debugging is a big question for NME too Joshua - we really need
some tutorials on how to configure xcode/visual studio/etc. for deep
debugging.

> --
> To post to this group haxe...@googlegroups.com
> http://groups.google.com/group/haxelang?hl=en

--
Philippe

Philippe Elsass

unread,
Jan 5, 2012, 4:48:21 AM1/5/12
to haxe...@googlegroups.com
And yes, if you have a MonoDevelop binding then there are probably
pieces in FlashDevelop that can be reused - feel free to dig in :)

--
Philippe

Lars Madson

unread,
Jan 5, 2012, 9:28:37 AM1/5/12
to haxe...@googlegroups.com
Congratulation!!

2012/1/5 Philippe Elsass <philipp...@gmail.com>

Philippe Elsass

unread,
Jan 5, 2012, 9:35:18 AM1/5/12
to haxe...@googlegroups.com
Ben,

I'd understand it might be covered by NDA stuff, but is your company
generally interested in haxe?

Cauê Waneck

unread,
Jan 5, 2012, 10:18:19 AM1/5/12
to haxe...@googlegroups.com
Hi Ben!

Wow, great job!!!
I've been working on the C# target for some time now (actually I'm
past my due time for a release!), and I'm happy to see you've nailed
it.

I haven't been able to look very deeply into it, but it seems that
you're compiling to C# 4.0 with the dynamics support. I chose not to
use the dynamic support of C# for some reasons. Specially because it
uses the DLR which needs to generate assemblies on the fly. This
actually rules out most if not all mobile platforms, as they have a
restricted access to dynamic code generation, and also I think
restricts the use of XNA and Unity.

But I really intended to later support code generation for C# 4.0
using a compiler flag to use the 'native' dynamics, as in some cases
the generated code will be smaller (despite the DLR footprint), and
maybe faster. We can maybe join our code bases so to add an option to
generate code for C# 4.0 + dynamics?

I'm not sure about the speed gain, when I've done some preliminary
benchmarks I found that the way I'm doing reflection is actually
faster, but maybe if you don't change the object reference many times
(which is slow in the DLR as it has to re-generate the bind code), it
might be faster.

I've also seen that you're using Func<> for delegates. Is that right?
There are some difficult problems to solve about using Func<> for
function signatures, even though I don't know if dynamic will be of
help in this case (as I said earlier, my target platform is C# 2.0
without any extension)

The problem is with how Dynamic works in haxe for function types:

Suppose you have a function : var fun = function(a:Int, b:Int) return a + b;
this function can have the following signatures in haxe:

Int->Int->Int
Dynamic->Int->Int
Dynamic->Dynamic->Int
Dynamic->Dynamic->Dynamic

and so on..

I'm not sure if you can cast from Func<int,int,int> to
Func<dynamic,int,dynamic> for example, but I think you can't, so you
might run into some problems there.
The same goes for Type parameters. In C# you can't cast from
Array<object> to Array<int>, for example (and vice versa). Casting
from Array<object> to Array<int> might be needed for e.g.
Serialization, while casting from Array<int> to Array<object> (or
Array<dynamic>) is needed for

Also you might run into some problems with Null<T> type, which most of
the time just means the same as T, but not when T is a basic type. The
obvious solution would be to use it as Nullable<T>, but Nullable<T>
has a constraint where T must always be a basic type. What I've done
was to create a new struct Null<T>, and then detect all implicit
casting between T and Null<T> and vice-versa and make a real cast.
This gave me more work than I bargained for, specially because
sometimes it's really tricky to catch some implicit casting.

Well, you can see most of the solutions I've come up for these
problems in my last year presentation at haxecon here
http://prezi.com/xzvht0y2e-c6/haxe-java-c/ . I'm very close to have
the C# 2.0 target fully working, and the good news is that I've done
90% of the work by manipulating the AST (which actually was an
insanely slow way to code, but Java and C# will be able to share most
of their code), so maybe you can e.g. use how I implemented anonymous
functions and expression unwrap and still use your own implementation
for the rest (actually you wouldn't need to change almost anything in
your code to do that).
What do you think?

Congratulations! And cheers!

Cauê


2012/1/5 Ben Cooley <benjc...@gmail.com>:

Stephane Le Dorze

unread,
Jan 5, 2012, 11:18:03 AM1/5/12
to haxe...@googlegroups.com
Congratulations!

Ben Cooley

unread,
Jan 5, 2012, 1:40:32 PM1/5/12
to haXe
General:

I honestly didn't know there was any effort to do a C# port. Sorry if
I duplicated effort. Hopefully we can combine efforts. The port at
this point is basically functionaly, but not complete (I haven't
successfully run the haxe compiler unit test suite with it). I'm
mainly concentrating on getting some sample code running on mobile
with reasonable tooling support.

C# 4.0:

Yeah, really have no interest in supporting anything below 4.0. I
really don't see any need to do this for what my overall goals are
right now, which is primarily to target mobile with the mono toolchain
debugging, and IDE support.

Dynamic:

As far as I "know" dynamic support does not spider in the DLR. An
assembly using dynamic only requires Microsoft.CSharp.dll which again
"as far as I know" just for implementing call sites, which uses
reflection to cache the call to a local static.

In any case, it'd likely be easier and also a bit more elegant to
patch the mono compiler to avoid emit for dynamic calls than it would
be to forgo using dynamic. I just thought it would be pretty tedious
to add this functionality in haxe vs. exploiting what already exists
in the C# compiler.

Func<> and dynamic:

Honestly haven't run into this yet, as I've only compiled a small bit
of code. The advantage of using Func<> and Action is that it is
extremely fast as the call is strongly typed. I'll look into the
issue you raised and see if wrapping at calling sites with another
anonymous method with the correct signatures will resolve that issue.

Parameterized Types:

The benefit from using parameterized types directly in c# probably
outweighs the cost in having to potentially add casts when they're
used contra-covariantly. Again, I don't have any code which relies on
correct behavior here yet, so I haven't run into that problem.

Combining Efforts:

Where is your code located? I'll grab it and start working on it.
Again my priorities are at this point not complete correctness, but
proof of concept so I may not get to those issues immediately.

Ben

Ken Rogers

unread,
Jan 5, 2012, 5:38:27 PM1/5/12
to haxe...@googlegroups.com
I would definitely use this for writing Sifteo applications, which I am doing now in mono develop.  The only 3rd party dll I use is Ninject for DI.

http://developer.sifteo.com/

Great stuff btw!!

Ken

Ben Cooley

unread,
Jan 5, 2012, 6:40:24 PM1/5/12
to haXe
Also, AFAIK haxe's type parameters are invariant, meaning I think a
cast from any Array<x> to any Array<y> is not allowed unless the haxe
compiler actually permits this in violation of it's own semantics.



Raoul Duke

unread,
Jan 5, 2012, 7:56:23 PM1/5/12
to haxe...@googlegroups.com
On Thu, Jan 5, 2012 at 1:47 AM, Philippe Elsass
<philipp...@gmail.com> wrote:
> Oh debugging is a big question for NME too Joshua - we really need
> some tutorials on how to configure xcode/visual studio/etc. for deep
> debugging.

yeah, rightyho, i think i was just asking about debugging on the
list(s) but only heard crickets. :-(

Cauê Waneck

unread,
Jan 5, 2012, 8:52:13 PM1/5/12
to haxe...@googlegroups.com
Hey Ben!


> I honestly didn't know there was any effort to do a C# port.  Sorry if
> I duplicated effort.  Hopefully we can combine efforts.  The port at
> this point is basically functionaly, but not complete (I haven't
> successfully run the haxe compiler unit test suite with it).  I'm
> mainly concentrating on getting some sample code running on mobile
> with reasonable tooling support.

I'm sure we'll be able to combine our efforts! And don't apologize, I think the more people are working on this the better it will become :) So I'm very happy to see what you've done!
But about running on mobile - I'm afraid on most cases it won't be very effective when using C#'s dynamics: iPhone reportedly doesn't support it (see http://tirania.org/monomac/archive/2011/Apr-06.html ); nor does Windows Phone ( http://stackoverflow.com/questions/4581224/does-windows-phone-7-support-the-dynamic-keyword ), nor XNA ( http://forums.create.msdn.com/forums/t/52904.aspx ). I've seen dubious reports about Android, so I'm not quite sure about its state. Anyway, it would really be a more elegant solution to use C#'s own compiler to generate the dynamics-interfacing code. But if we are going to use native reflection, haxe performance will be unacceptable (specially for mobile)


> C# 4.0:
>
> Yeah, really have no interest in supporting anything below 4.0.  I
> really don't see any need to do this for what my overall goals are
> right now, which is primarily to target mobile with the mono toolchain
> debugging, and IDE support.

Yeah, you're right that it makes little sense nowadays to support C#2.0, but since I intended from start to support both C# and Java, and well, Java is still stuck at C# 2.0 (or less) features, I've been working on the lowest denominator. Also most of C#'s 2+ features are syntatic sugar which wouldn't provide much benefit for haxe as a language (apart from the dynamic keyword), but more as libraries that can be used (e.g. Linq).

> Dynamic:

>
> In any case, it'd likely be easier and also a bit more elegant to
> patch the mono compiler to avoid emit for dynamic calls than it would
> be to forgo using dynamic.  I just thought it would be pretty tedious
> to add this functionality in haxe vs. exploiting what already exists
> in the C# compiler.

It was tedious but fun :) . The great thing is that we can actually have control on what's going on and the performance benefits have been huge. I think we'll have the best performance for dynamics, specially getting/setting fields and creating types.


> Func<> and dynamic:
>
> Honestly haven't run into this yet, as I've only compiled a small bit
> of code.  The advantage of using Func<> and Action is that it is
> extremely fast as the call is strongly typed.  I'll look into the
> issue you raised and see if wrapping at calling sites with another
> anonymous method with the correct signatures will resolve that issue.

The problem is that when you convert it to object you'll lose its actual type signature. So it's impossible to track that a Func<int, int, int> is being cast into Func<int, object, int>, unless you resort to C#'s reflection and dynamically creating generic types, which would be quite slow.


> Parameterized Types:
>
> The benefit from using parameterized types directly in c# probably
> outweighs the cost in having to potentially add casts when they're
> used contra-covariantly.  Again, I don't have any code which relies on
> correct behavior here yet, so I haven't run into that problem.

Yeah, C#'s generics are awesome! I think it's the killer feature from CLR, which distinguishes it from anything else. I'll get about variance later on !


>
> Combining Efforts:
>
> Where is your code located?  I'll grab it and start working on it.
> Again my priorities are at this point not complete correctness, but
> proof of concept so I may not get to those issues immediately.

I still have it privately. I can give you access to our private svn if you want to!


Also, AFAIK haxe's type parameters are invariant, meaning I think a
cast from any Array<x> to any Array<y> is not allowed unless the haxe
compiler actually permits this in violation of it's own semantics.

All generics in haxe are invariant! But there is one case in the specs where casting is allowed: when you cast to/from <Dynamic>

So for example:
var intArray:Array<Int> = [1,2,3];
var dynArray:Array<Dynamic> = intArray;
dynArray.pop();
var otherIntArray:Array<Int> = dynArray;

are all valid operations in haxe.

This case is easily handled by using reflection when accessing Array<Dynamic>'s pop() method. But there is one case where you can't solve this merely by reflection: When you first create an Array<Dynamic>, and then want to convert it to Array<Int> . For example in serialization this is very common.. For this case specially I've made the whole class (whatever it is) be copied by value when it is cast to a more specialized type.Also I'm only using generic types on value types, because for reference types it's the same as if you just wrote Array<object> always and cast it to your needed type. This way this copy by value is only needed when you have an array of structs, or array of basic types, for example!

Cheers ! :)
Cauê

Ben Cooley

unread,
Jan 8, 2012, 2:52:59 PM1/8/12
to haXe
Dynamic support on mobile.

After doing some extensive test on ios, It seems that dynamic will
work on mobile with a minor patch to the mono compiler. There is
nothing about the dynamic system that actually requires dynamic code
generation, and only an issue with the way call sites are generated
that prevents it from being able to work on mobile.

Essentially I am modifying CallSite to be parameterized by the
delegate Target signature. This allows the static Aot compiler to
specialize statically all callsites at compile time such that calls
can be resolved through normal reflection. I've tested this and it
seems to work fine on ios.

This greatly simplifies the target as any differences in semantics can
be resolved through the use of dynamic instead of having to rewrite
the ast. I've already modified the generator to assume all generic
type signatures with a Dynamic type in any slot are dynamic, which
resolves the various issues you noted above. There are some bugs
there yet (generic type params are being detected as dynamic) but it
should work.

The only bit left is to check whether the as3 targets mechanism for
handling statement expressions works in c#. From a glance it looks
like its creating delegates around statement blocks which return
values, but I'm not sure. If your rewrites code s available I can tes
that too.

Fingers crossed that no nasty semantic issues will crop up as I check
with the unit tests.



On Jan 5, 5:52 pm, Cauê Waneck <wan...@gmail.com> wrote:
> Hey Ben!
>
> > I honestly didn't know there was any effort to do a C# port.  Sorry if
> > I duplicated effort.  Hopefully we can combine efforts.  The port at
> > this point is basically functionaly, but not complete (I haven't
> > successfully run the haxe compiler unit test suite with it).  I'm
> > mainly concentrating on getting some sample code running on mobile
> > with reasonable tooling support.
>
> I'm sure we'll be able to combine our efforts! And don't apologize, I think
> the more people are working on this the better it will become :) So I'm
> very happy to see what you've done!
> But about running on mobile - I'm afraid on most cases it won't be very
> effective when using C#'s dynamics: iPhone reportedly doesn't support it
> (seehttp://tirania.org/monomac/archive/2011/Apr-06.html); nor does
> Windows Phone (http://stackoverflow.com/questions/4581224/does-windows-phone-7-suppo...),
> nor XNA (http://forums.create.msdn.com/forums/t/52904.aspx). I've seen dubious

Cauê Waneck

unread,
Jan 8, 2012, 3:32:08 PM1/8/12
to haxe...@googlegroups.com
Wow! That's fantastic news, Ben!!! :)
Ok, keep us updated!

Cheers!
Cauê

2012/1/8 Ben Cooley <benjc...@gmail.com>

Joshua Harlan Lifton

unread,
Jan 8, 2012, 7:56:20 PM1/8/12
to haxe...@googlegroups.com
>> C# 4.0:
>>
>> Yeah, really have no interest in supporting anything below 4.0.  I
>> really don't see any need to do this for what my overall goals are
>> right now, which is primarily to target mobile with the mono toolchain
>> debugging, and IDE support.
>
> Yeah, you're right that it makes little sense nowadays to support C#2.0, but
> since I intended from start to support both C# and Java, and well, Java is
> still stuck at C# 2.0 (or less) features, I've been working on the lowest
> denominator. Also most of C#'s 2+ features are syntatic sugar which wouldn't
> provide much benefit for haxe as a language (apart from the dynamic
> keyword), but more as libraries that can be used (e.g. Linq).

I've had a project waiting in the wings for several months now waiting
for a .NET target, so I'm excited to give it a whirl. My target
platform is a desktop, though I need to do more research before I know
which version of C# I need. In any case, thanks for getting this out.
I'm looking forward to getting started.

Cheers,
JHL

serg...@gmail.com

unread,
Jan 9, 2012, 4:42:50 AM1/9/12
to haxe...@googlegroups.com
That's very good news.
Like many others, I was also running the all web to find Cauê implementation :)
I'm trying now to compile all and test the output to see how it looks.

Working on mobile libs . After a lot of research, Haxe would be the best solution to have multiplatform libs, for web, 2d games, 3games.

Now with c#, we can work on wp7 ( i hope?). 

thx all for this wonderful work.

Ben Cooley

unread,
Jan 10, 2012, 12:00:16 AM1/10/12
to haXe
Not fully baked yet though, so I would wait a bit. On wp7 you could
potentially run into issues with dynamic support, which I think is not
there in the ms platform. You'll need to check the status of c# 4
support there.

Daniel Kuschny

unread,
Jan 18, 2012, 3:19:39 PM1/18/12
to haxe...@googlegroups.com
Great Job. 

One of my projects was waiting for a C# target for a long time too. Too bad I haven't the time to check out your compiler but I'll watch your repo to be up-to-date. My project (http:/www.alphatab.net) is quite big now and could be a good test-suite for a C# compiler. My project consists of:
  • General class model (patterns, complex hierarchical structure)
  • File loading stuff (custom IO framework)
  • Binary file reading and parsing (read class model from binary files)
  • High processor load operations (layouting stuff of the model)
  • Graphical rendering of the model (SVG, HTML5, Direct Graphics)
  • Audio/Midi file generation (IO framework again)
I'd love to see how the generated C# code looks and acts. 

I like Cauê's point of view that importance is very important as my project does a heavy processing job and the music sheets should get rendered as fast as possible. 

Can't wait to check out your effort. 

Cheers 
Daniel 

Daniel Kuschny

unread,
Jan 18, 2012, 3:54:40 PM1/18/12
to haxe...@googlegroups.com
In addition to you:

You might have noticed the language Xtend developed by Itemis (the creators of Xtext). It's a language which gets parsed into a EMF (Eclipse Modeling Framework) Model and serialized to plain Java Code. Xtend adds a lot of syntactic sugar and typing stuff (closures, everything-is-a-expression) that is not available to native Java. You can probably get some ideas of how to deal with unsupported language elements during code generation.


This is the main type hierarchy of the xtend to java compiler (to save you from searching this stuff ;) ):

Cheers
Daniel

Ben Cooley

unread,
Jan 18, 2012, 8:47:37 PM1/18/12
to haxe...@googlegroups.com
I'm relying on C# 4.0 features, which are a proper superset of Actionscript.  This being the case, the existing strategies Haxe is using to target Actionscript should work equally as well for the C# target.

C# has support for closures, dynamic dispatch, etc.   I am at the point where I'm starting to work through the unit tests to verify that everything is actually working.  We'll see if this will be adequate to support haxe.

As noted in other posts, dynamic support currently requires ExpressionTree support.  Luckily the implementation of dynamic itself does not specifically require any reflection.emit, this happens to be just an internal implementation detail.  I've used an alternative Callsite implementation which uses reflection only, without any dynamic code generation and this seems to work fine at least on Mono/iOS.  I've confirmed that dynamic is presently not supported on WP7, but I'm not sure that using my MobileDynamic.cs classes will actually work on WP7.

For other issues in the posts above, just detecting when there are semantic mismatches between static C# code and Haxe and simply dropping to dynamic calls seems to work fine.  This is how many haxe features are implemented in Actionscript, and though it might not be as performant as rewriting the AST to avoid having to use dynamic, unless an inner loop hits the code frequently it should probably be just fine.

Ben Cooley

unread,
Jan 18, 2012, 8:47:37 PM1/18/12
to haxe...@googlegroups.com

Nicolas Cannasse

unread,
Jan 19, 2012, 4:27:58 AM1/19/12
to haxe...@googlegroups.com
Le 19/01/2012 02:47, Ben Cooley a �crit :

> I'm relying on C# 4.0 features, which are a proper superset of
> Actionscript. This being the case, the existing strategies Haxe is using
> to target Actionscript should work equally as well for the C# target.

I think that one important thing to plan for the future (once solved all
the small issues) would be to target CIL instead of C#, this would allow
exact mapping of .hx files positions and I guess remove the expr VS
statements issues.

Best,
Nicolas

Cauê Waneck

unread,
Jan 19, 2012, 8:26:10 AM1/19/12
to haxe...@googlegroups.com
I think that one important thing to plan for the future (once solved all the small issues) would be to target CIL instead of C#, this would allow exact mapping of .hx files positions and I guess remove the expr VS statements issues.

Luckly, C# has support for #line directive, so we can map to .hx files positions well. But I agree that later on it'd be great to have the haxe compiler to generate the bytecode directly, or maybe the IL assembly itself.

Cheers! 
Cauê

Ben Cooley

unread,
Jan 20, 2012, 1:57:03 AM1/20/12
to haxe...@googlegroups.com
I very much agree.  That was the direction I went starting out, but I couldn't verify that I could complete it.  I actually tried two different other approaches before settling on the simpler genas3 to gencs approach that seems to be working out right now:

The direct ILASM approach:

1. that the IL assembler would take source spans and 
2. that I could finish the target in any reasonable amount of time in my spare time
3. I didn't at the time know enough about HaXe or ocaml to even remotely be able to gauge the difficulty of this approach.
4. If I was to go to all this trouble, might as well just make Haxe directly integrate with .NET and generate the target assemblies the old fashioned way.

The HaXe compiler compiled via F# approach:

It's a little known fact that F# is actually a full caml compatible compiler (though not an ocaml compiler**).  Having read that, I though I might just briefly try my hand at compiling the HaXe compiler source via F#.   The reason for this is that it is would be much easier to use the existing .net infrastructure for directly building assemblies, resources, etc. via existing .net libraries such as IKVM.Reflection.Emit and/or Cecil.  Also it would be vastly easier to integrate the parser and completion engine into either FlashDevelop and/or MonoDevelop.

** Microsoft implements the oo portion of F# to target the .NET framework, which is very .NET specific.

I started the C# target with that strategy in mind, and I actually have a port of the Haxe compiler building in F# (Microsoft's .NET Ocaml derivative) but not actually working.  At the start I really didn't know much about the details of ocaml or anything about the HaXe Motion-Twin support libs, so my initial F# port was done incorrectly.  I actually spent the time to patch the code in many places to eliminate the camplp4 preprocessor syntax (which I thought was just due to differences between F# and ocaml), such as optional function params, some corner case issues with non-light syntax, etc.  Turns out just running haxe through the p4 preprocessor gives you code you can directly compile with F# no problem (the same way it works with ocaml), so all of that work turned out to be pointless.   Final issues with that port were the ONE instance where objects were being used in the gencpp.ml file (F# supports all of CAML but it's object system is all .NET based).. lots of warnings about using F# reserved words for class, private, public, etc (all F# keywords).  The caml base lib is supported in F#, but as an add on library, and I did not finish porting the caml extension libs that the HaXe compiler uses.  

I'm guessing that knowing what I know now about ocaml and HaXe, I could probably build a new F# build script that might just take a few patches in a few files and possibly just build and work.  I'm still fairly certain that there are probably more than a few missing modules in the caml compatibility library for F# that HaXe might depend on that I would have to replace, and potentially some other gotchas, but a parallel F# build for HaXe using the same ocaml source is probably not out of the question.  And if that were to be the case, a direct HaXe .NET IL code generator port (as well as deep IDE integration in MonoDevelop and FlashDevelop) would be fairly trivial.

The genas3.ml to gencs.ml approach:

Finally I decided to just go with the C# target starting from the current AS3 target seemed like it was within my modest reach, given what I knew about both AS3 and C#.  The #line directive actually seems to work very well in providing a source debugging experience in Haxe (really almost indistinguishable from native IL compilation really from my tests).  The issues with dynamic on mobile devices are resolvable, so this turned out to be the most direct and fruitful approach.


BTW.. I notice that you have a HaXe repo in github actually created, but don't have it active yet.  Would be nice to be able to pull and send pull requests on github.  Don't know your opinion of Git, but I've gotten to really like it after getting used to it, and I really like Github quite a bit.


Ben Cooley

unread,
Jan 20, 2012, 2:03:22 AM1/20/12
to haxe...@googlegroups.com
Yeah, this definitely works pretty well.

We really should port this to the CPP target as well, as I know that Visual Studio supports source mapped files, and I strongly suspect that XCode does as well.  In the early 90's I spent a few years working with a cross compiler that used C as it's target language via #line directives, and source debugging the original code this way really wasn't that bad, much better than trying to debug the generated C code.

Still, IMO given the nice synergy between what already exists in Mono and the runtime functionality HaXe requires, I think the mono VM is probably a better way to go on mobile than straight C++.  And there is also Unity compatibility to consider as well.

Nicolas Cannasse

unread,
Jan 20, 2012, 2:13:52 AM1/20/12
to haxe...@googlegroups.com
> BTW.. I notice that you have a HaXe repo in github actually created, but
> don't have it active yet. Would be nice to be able to pull and send pull
> requests on github. Don't know your opinion of Git, but I've gotten to
> really like it after getting used to it, and I really like Github quite
> a bit.

It's planned to be a mirror of haXe SVN, not the main repo yet. I might
still accept patches through it. I'm still having issues importing the
whole SVN history into it.

Best,
Nicolas

Cauê Waneck

unread,
Jan 20, 2012, 3:35:09 AM1/20/12
to haxe...@googlegroups.com
Ben,

Compiling to F# is a great idea!
By the way, have you got any idea how to solve the generics issue when creating an empty type ? (e.g. like in the Unserializer) ?

Cheers!
Cauê

2012/1/20 Ben Cooley <benjc...@gmail.com>

Joshua Harlan Lifton

unread,
Jan 21, 2012, 11:12:42 PM1/21/12
to haxe...@googlegroups.com

Yes, please do accept pull requests through Github.

JHL

Ben Cooley

unread,
Jan 22, 2012, 10:40:26 PM1/22/12
to haxe...@googlegroups.com
I looked at the code and I don't see precisely where the problem is yet.  Currently I'm just integrating in building the C# response file and calling the native CS compiler from haxe to make it easy to run the unit tests.  Haven't tried to run Unserializer, so I haven't run into it directly.  From your previous post I think the problem was that Unserializer allowed a cast from an unspecialized generic type to a specialized type, and since c# generics are reified and specialized for value types this won't work.

Strange thing is that, at least for as3, the Vector.<T> type is also specialized at least for int, uint, and Number, so if haxe is relying in being able to cast from Array to Vector.<T>, haxe would also be breaking there as well.  Maybe Vector.<T> just isn't compatible with the Unserializer. ????

I don't see any other way to handle casting from an unspecialized generic type to a specialized generic type than to do a copy.  That seems to be a pretty big issue performance wise, so I'd likely be more inclined to just rewrite Unserializer.hx to encode the correct generic type and instantiate it directly on unserialize (it 'seems' to be doing this right now by using the type stored in the stream and the createEmptyType() method, but I haven't drilled down into it).

In any case, what are your thoughts here?


Ben Cooley

unread,
Jan 22, 2012, 10:44:00 PM1/22/12
to haxe...@googlegroups.com
My repo has the full revision history (though I just pulled in trunk and not the utils folder).  I tried using svn2git ruby script, but gave up as it was crashing continually and just ended up using "git svn fetch" instead, with an authors file with everybody's correct name and email.

If you find all the revision history in my repo to be correct, you could just copy it.  I'd be happy to re-fork.

Nicolas Cannasse

unread,
Jan 23, 2012, 4:53:32 AM1/23/12
to haxe...@googlegroups.com
Le 23/01/2012 04:40, Ben Cooley a �crit :

> I don't see any other way to handle casting from an unspecialized
> generic type to a specialized generic type than to do a copy. That seems
> to be a pretty big issue performance wise, so I'd likely be more
> inclined to just rewrite Unserializer.hx to encode the correct generic
> type and instantiate it directly on unserialize

Sadly on most platforms we don't know the actual generic type. It might
even not be an actual value (structure or function type for instance).

Best,
Nicolas

Nicolas Cannasse

unread,
Jan 23, 2012, 9:40:26 PM1/23/12
to haxe...@googlegroups.com
Le 23/01/2012 10:53, Nicolas Cannasse a �crit :

What could be done however is to unserialize the first item for standard
containers (Array/List/Hash/IntHash) and create the container based on
this type. That would need additional code also in case the first type
is too much precise (such as [new B(),new A()]).

Then when transforming a Dynamic value into generic instance, you can
check if the type is already correct and if it's not perform a
conversion. That seems reasonable to me.

Best,
Nicolas

Ben Cooley

unread,
Jan 24, 2012, 7:21:18 AM1/24/12
to haxe...@googlegroups.com
The latest version now is capable of directly building an executable or DLL.  This makes it easy now to add the -cs target to the unit tests and run them in order to shake out the remaining issues.

--cs-cmd - The c# compiler command for your os (either dmcs for mono or csc for Microsoft).
--cs-refs - A comma delimited list of assembly references to use (also will be used to auto generate haxe bindings if they do not already exist).
--cs-out - The output dll or exe file to generate.
--cs-options - Additional options to pass to the C# compiler.

Remember that the -lines option will turn on source debugging directly in haxe .hx files for the final output exe or dll.

Haxe will compile to the haxe out folder, adding a Build.rsp C# compiler response file at the top level of the output folder.  Then if the --cs-cmd option has been set, the C# compiler will be run on that Build.rsp file to build the final executable/dll.

I've also done a few minor fixes to cs/Array.hx, but it is by no means complete.  The C# Array.hx class derives directly from  Essentially the platform specific bits of the base library for C#, minus Array.hx and it's default iterator do not yet exist.

Sample:

haxe -cs cs -main MyProgram --cs-cmd dmcs --cs-out cs/MyProgram.exe --cs-options "-nologo" MyProgram.hx
mono cs/MyProgram.exe






Philippe Elsass

unread,
Jan 24, 2012, 8:30:04 AM1/24/12
to haxe...@googlegroups.com
Ben,

this calls for a sample :)
How do you use the source debugging? Debugging in VS?

--
Philippe

Franco Ponticelli

unread,
Jan 24, 2012, 8:35:17 AM1/24/12
to haxe...@googlegroups.com
Fantastic news!

Raphael Harmel

unread,
Jan 24, 2012, 8:41:39 AM1/24/12
to haxe...@googlegroups.com
Bravo !

Raph


2012/1/24 Franco Ponticelli <franco.p...@gmail.com>

Ben Cooley

unread,
Jan 24, 2012, 12:06:49 PM1/24/12
to haxe...@googlegroups.com
I've been working entirely on OSX so far, though I have both a Windows machine and a Mac here at home.  To test source debugging you just add the "-lines" directive to your hxml or command line.  That dramatically changes the generated output (it's no longer as readable), but it makes the generated code map to the .hx files so you can set breakpoints and debug in haxe instead of C#.

I'm nearing the point where I will be starting to fill out the platform "cs" libs and try to successfully run the unit tests.  Array is more or less implemented over the top of List<T>, etc.  But there's a decent amount missing.

I'm also certain some of the more complex classes are likely to fail to compile still due to incorrectly implemented bits in the target, so both implementing the base classes and running the unit tests should reveal what's left.

Now that it's compiling directly, it's really pretty fun to try out, as you can compile and then run the .exe file (on osx, "mono MyProgram.exe").  It also is now easy to shake out the C# bugs in the base classes.

Ben Cooley

unread,
Jan 26, 2012, 2:21:54 PM1/26/12
to haxe...@googlegroups.com
Hey Cauê,

I'm at the point that I need to rewrite expression blocks.  If you have that rewriter working and you think it's efficient and a good solution, I'd like to incorporate it.  If you think there are issues with it that need to be resolved maybe we can talk about how to refactor it.  There are other ways to do it (including stack based text insertion, dynamic output reordering) that might work as well, but I don't want to re-invent what already works.  I was actually thinking that if the rewriter pass was efficient, it could just be moved into the codegen.ml module and be turned on when needed.

If you're comfortable publishing your work, I'd encourage you to push it to github so that we could more easily collaborate.  If not you can email my personal address (not the gmail one which I never check, same name benjcooley but on hotmail.com).

Thanks.. 

Ben

Raphael Harmel

unread,
Jan 28, 2012, 12:19:38 PM1/28/12
to haxe...@googlegroups.com
Hi Ben

Would it be possible for you to provide the haxe binary file needed to
compile for the C# target ?
At least the windows haxe.exe would be of great help.

Raph

2012/1/26 Ben Cooley <benjc...@gmail.com>:

Ben Cooley

unread,
Jan 28, 2012, 2:22:21 PM1/28/12
to haxe...@googlegroups.com
Will do.

Ben Cooley

unread,
Jan 28, 2012, 2:23:09 PM1/28/12
to haxe...@googlegroups.com
Presently the compiler will generate invalid code for expression blocks (including inlined expression methods).  Just an FYI.

Ben Cooley

unread,
Feb 1, 2012, 1:07:31 PM2/1/12
to haxe...@googlegroups.com
Okay.. latest drop now seems to be getting closer to 100% as far as compilation goes.  Still most of the base lib is unimplemented.

1. Fixed expression statements.  Expression switch, etc. now work (currently using lambdas).
2. Fixed throwing exceptions.
3. Fixed correctly placing semicolons after initializers.
4. Fixed all $ temporaries to be correct C# temporaries.
5. Fixed dynamic object initializers to be Dictionary<string,object> instead of anonymous classes (anon classes are faster, but semantically different).
6. Fixed inlining for methods returning "void".  Still some problems with methods returning other values (({ block ... } as int) for example.
7. Fixed stray semicolon on array accessors (i.e. blah[xxx]; = 100)

The end result is that most of the base class library classes now seems to be compiling fine with the c# target now, with a few remaining exceptions:

Remaining issues:

1. C# does not have the >>> unsigned right shift.  Just need to catch this and turn it into ((uint)x >> y);
2. Remaining inlining issues mentioned above in #6.

These two issues seem to occur rarely in current lib code (one instance of #1, one or two instances of #2).

I'm sure there are more remaining issues, but these are the ones I'm encountering just trying to call some base lib methods.

The end game:

1. Fix some of these remaining issues.
2. Complete the unimplemented std lib classes for "cs" haxe lib (concurrent with #1).
3. Complete the C# assembly to .hx dump utility.  The compiler options right now are structured such that this utility should be able to be called on the fly to generate bindings dynamically when assemblies are referenced.
4. Add patch to "Mono" compiler to use static CallSite<T1,T2,T3> classes to support "dynamic" on MonoTouch, MonoDroid (sorry WP7).  Make sure code is working on Mobile.
5. Generate .csproj files based on template files for MonoDevelop, VisualStudio.

Remaining issues:

- For performance, the C# target is using "inline" and @:native() extern classes to wrap String, StringBuf, Array.  The common practice of using fields instead of properties for "length" on these classes doesn't permit inlining of the length value.   I've modified the base lib to use inlined properties in all cases (including for Neko, C++, and other platforms).
- Best practices for what haxe methods to inline vs what methods to call as static "helper" methods (inline charCodeAt() vs call StringHelper._charCodeAt(s, v)).

I'll try to make a build of the current compiler for both windows/mac and make it available with the modified class libs sometime in the next day or two.  There's a lot of low hanging issues that can be resolved with the class libs so I'd kind of like to resolve those before building.

Ben



Nicolas Cannasse

unread,
Feb 1, 2012, 1:13:21 PM2/1/12
to haxe...@googlegroups.com
Le 01/02/2012 19:07, Ben Cooley a �crit :

> Okay.. latest drop now seems to be getting closer to 100% as far as
> compilation goes. Still most of the base lib is unimplemented.

That's very nice to see two people (you and Caue) working on C# target,
I hope you will be able at some point to merge both of your efforts so
we can have one single official C# code generator as part of the haxe
standard distribution, with two potential contributors / bug fixers :D

Best,
Nicolas

Ben Cooley

unread,
Feb 1, 2012, 6:39:46 PM2/1/12
to haxe...@googlegroups.com
I feel that my as3 based generator, while perfectly acceptable performance and code wise, would probably be much better off being a direct IL generator.  

But since I'm interested in actually having something working very soon, this seems like a good way to go for the time being.

Ben Cooley

unread,
Feb 1, 2012, 11:54:00 PM2/1/12
to haxe...@googlegroups.com
Also, agreed on having a single target.  We need to merge at some point.  My generator is very much a derivative of the as3 generator, so If Caue's is working and generates better code (particularly for expression statements) I think I'd like to take that instead of the as3 approach (which uses closures).

Ben Cooley

unread,
Feb 6, 2012, 4:55:01 PM2/6/12
to haxe...@googlegroups.com
Major update to C# target.

Binary release at:


This includes the OSX binary only for now. (Haven't had time to switch to my windows box to build the Win binary yet).

Includes in the cslibs folder the complete platform libs for mono-4.0, mono android 1.5, and monotouch.  These are mostly correct but not yet guaranteed to actually fully work.  I've only done some basic tests on lib compatibility.

This also includes a binary of the cslibgen.exe utility that can be run with "mono cslibgen.exe" to generate haxe bindings for C# libs.

-----

The "cslibgen" project is a C# haxe library generator which takes various C# assemblies and automatically generates the haxe lib bindings for them.  The generator can take a full set of assemblies (say all of the assemblies for monotouch), and generate a full lib folder with all haxe extern classes.  Most features should be implemented correctly at this point.


-----

Major update to the C# target to support native C# arrays, fix the multiple namespace warning issues, allow the C# target to correctly load extern classes with  C# overloaded methods and complex implicit interface implementations (which violate Haxe's class validators, but are perfectly valid C# classes).

Added NativeArray<T> and NativeEvent<T> classes to handle native arrays and native events.

-----

Remaining todos:

- A patched version of the mono compiler which supports non-Reflection.Emit dependent code for "dynamic".  Have some of this code, but not finished yet.
- Add a "haxe.dll" assembly which contains code for Array, and other haxe classes better/more easily implemented in C# vs Haxe.
- Add "csproj" updating from the haxe compiler to automatically populate "monotouch" and "mandroid" csproj files with the correct generated set of .cs files (so that haxe can be easily used in MonoDevelop).
- Fix some (many?) remaining target issues ( >>> operator, inlining of methods not returning Void, anything else that comes up not working in the unit tests).

------

Questions?

- Does haxe have parameterized methods?  It seems to compile them, but I don't see any documentation.  This could be an approach to converting C#'s parameterized methods (which are currently being punted to use dynamic params).
- Isses with support for NativeEvent<>, need the event lambda signature as well as the C# eventhandler class id.  Need to figure out how this will work.
- Haxe generic type names being non-unique vs. C#'s being unique.  The cslibgen tool handles this right now by making unique names when it needs to, but this could be error prone.

Ben


Still missing a good portion of t

Tinlyx

unread,
Jul 23, 2012, 1:34:13 AM7/23/12
to haxe...@googlegroups.com
Hi Ben,

I was wondering if you could post binaries for Linux as well.  I found that the C# code your generator produces are nicer than what's in 2.10 when it comes to templated code.  So I tried to compile the code following the instructions under Ubuntu 12.04 LTS,

There was problems downloading repos (maybe due to change of haxe main depo) but if use the trunk svn version of ocaml libs (i.e. extlib, etc), I got other errors.

Thanks a lot

Tinlyx.

On Thursday, January 5, 2012 1:40:48 AM UTC-5, Ben Cooley wrote:
I've implemented a Haxe C# target, available at git://github.com/benjcooley/haxe.git.

To run-test the target, you'll need to clone the haxe-install repo's gencs branch, then make sure that the git line in the install.ml file will correctly pull the "gencs" haxe branch from my repo during build.

I have not successfully run the haxe unit test suite on this target, but basic features seem to be working.  One addition is support for generating #line directives in the output code via the -lines compiler option to allow source debugging in haxe when running on the .net VM.

There is also a preliminary "haxe" Binding for MonoDevelop in the MonoDevelop repo.

My primary interest in this port is to allow Haxe to target mobile devices in a way that allows easy access to the native platform, better GC behavior, and full IDE tooling support including source level debugging on both simulator and devices.  It seemed to me that being able to target Mono was the easiest path to reach this goal.
Reply all
Reply to author
Forward
0 new messages