For all its flaws (and there are quite a few) it was a very interesting learning exercise, and it worked better than I ever really expected ;)
I don't really intend to ever do any more work on it, especially now that there are open source "real" implementations.
But it's been nice to see it used in Blazor :)
But I'm fairly sure the hardest part to implement was the support for generic types/methods. It made all the code that handles types way more complex (as expected I suppose!), and there's definitely a bug or two remaining. Correctly handling open/closed generic types and construction of types from generic arguments was painful. It didn't help that I initially implemented only non-generic type support, then had to hack generics into it. Were I to start again I'd implement the whole thing in a generic-first way.
The design of classes/structs and they they interact with generics is nice. And the `constained` IL prefix is a really neat optimization to avoid boxing.
The use of type-agnostic CIL instructions (e.g. `add` can work on int, float, ...) is also a nice touch.
JIT literally stands for "Just In Time". It doesn't say what it's actually doing just-in-time ;)
So (in my opinion) JIT.c is correct. It's translating CIL opcodes to dna-internal opcodes, which it does just-in-time just before a method is executed for the first time.
The reason it does this at all is because there are many things to resolve when working from CIL that it's much better to do just once rather than every time a method is executed. A simple example is method references, which are by name in CIL, but are a simple pointer in dna-internal opcodes.
This may be a selfish request but would you consider moving the original repo to it's own organization? The canonical repo gets a higher placement in search results and for link juice.
Plus if you were to move it to it's own repo/organization, it would allow the forks to submit their changes upstream and have one master repo instead of multiple forks with their own changes.
The main reason i move from c# to “typescript js” because c# not working on client side web. I love c#, maybe if dotNetAnywhere is ready for production, i start using c# again. Keep the good work. Maybe someday aspcore, xamarin and dotNetAnywhere. It would be awesome
But because those are weekend projects. There are enough microsoft or microsoft-related people getting excited about it that I hope microsoft will put its strength behind a production version. That would certainly make a lot of sense.
There are a couple partial .NET runtimes reimplemented in JavaScript rather than compiled to WebAssembly; they are usually tied in with C# -> JavaScript generators.
https://github.com/SharpKit/SharpKit went the other way and is now open source, but original L/GPL/references to licensing for commercial use may have limited growth; it is now MIT.
http://jsil.org/ mostly demonstrates games, and focuses on translating MSIL bytecode rather than any specific language or runtime.
Had I read an article opening with the sentence: «Here is a .NET runtime alternative which is however 100 times slower…», I would have quickly dismissed it, shame on me. This article is right, the DotNetAnywhere code really seems a gem, well worth to study!
> Had I read an article opening with the sentence: «Here is a .NET runtime alternative which is however 100 times slower…», I would have quickly dismissed it
I deliberately didn't start with Benchmarks, pretty much for that reason! Plus I put a huge caveat in before I showed the results.
> This article is right, the DotNetAnywhere code really seems a gem, well worth to study!
Glad you think so as well, that's exactly the reason that I wrote about it. It's relatively unknown and if nothing else it's a really useful resource (whether it's suitable for production is another matter)
Great suggestion, this is probably the killer app for this. I heard that the Mono and .NET teams are working on a new linker that should also help bring down the bloat, and help make .NET via WebAssembly less ridiculous in terms of overhead.
I have no idea if it would be compatible with DotNetAnywhere
Yeah, trusting the GC - reading the original author's comments on it:
> Mind you, the whole heap code really needs a rewrite to reduce per-object memory overhead, and to remove the need for the binary tree of allocations. Not really thinking of a generational GC, that would probably add to much code. This was something I vaguely intended to do, but never got around to. The current heap code was just the simplest thing to get GC working quickly. The very initial implementation did no GC at all. It was beautifully fast, but ran out of memory rather too quickly.
>What I find most impressive about the DotNetAnywhere runtime is that it was developed by one person and is less that 40,000 lines of code!! For a comparison the .NET framework Garbage Collector is almost 37,000 lines.
Keeping the code base small is a double edged sword. The trouble with everything going web-based these days is that script kiddies (myself included) should have some awareness of how memory is being managed and when to worry about holding IEnumerables in memory. Your write-up here is interesting and it's the first I've heard of Blazor. This is all very fascinating you have me reading the codebase now.
For all its flaws (and there are quite a few) it was a very interesting learning exercise, and it worked better than I ever really expected ;)
I don't really intend to ever do any more work on it, especially now that there are open source "real" implementations. But it's been nice to see it used in Blazor :)
If you have any questions about it, please ask.