.NET Oxford Feb Meetup: Inside the CLR with Chris Bacon

18 February 2019 - .NET , dotnetoxford , Meetups

For this month's .NET Oxford, we were joined by Chris Bacon from Google for a fascinating talk about how to build a .NET runtime in C! Chris's talk was pure code all the way through (no slides whatsoever!), and even though it was quite a complicated topic, he did a fantastic job of explaining it - extremely clear - and surprisingly given the topic, very funny too!

Intro Talk

We started off as usual with a 15 minute intro talk. The first topic was about the survey we sent out a few weeks ago. I had written a blog post with the survey results, which I sent out to the Meetup.com mailing list - but I also spent a bit of time in the intro talking about both the questions and the results. I won't repeat it here though, as all the information is in that blog post.

The next thing I spoke about was my recent visit to the London.NET usergroup to see Scott Hanselman's talk. We had Ian Cooper at .NET Oxford last month, who is one of the organisers of London.NET, and he very kindly said that I could stand up on stand for a few minutes to talk about .NET Oxford. It was great being able to spread knowledge of our user group to such a large audience. It was certainly very surreal being on the same stage as Scott Hanselman! Scott's talk was recorded, and can be found here, and I'd definitely recommend having a watch!

Finally, before moving over to the news and prize draws - I mentioned that we're going to start using our Facebook group a bit more moving forwards, as I was aware that we're most active on Twitter, and not everyone uses Twitter. Out of interest though, I did ask everyone to raise their hands if they were a Twitter user, then again if they were a Facebook user. Surprisingly, most hands went up for Twitter, and not many at all for Facebook! I wasn't expecting that! Maybe we don't need to be more proactive on Facebook after all!

For information about both the news items and prize draw winners, see further down this blog post.

The published slides for the intro talk are available here, and the Reveal.js source code can be found on our Github account.


Chris Bacon - Inside the CLR

Chris started by telling us that what we'll learn in this talk is completely pointless and something we'll never need to do! Well that had me sold from the start! :) Whilst his statement may have been true - it was a really fascinating talk all the same, and extremely well delivered! It also brought back a ton of memories from my C/C++ days! Especially when he was navigating file formats using offsets!


Chris introduced himself saying that he works at Google, and spoke about an old project he created quite a few years ago called DotNetAnywhere. This is a .NET runtime written in C that he did as a hobby project. He also mentioned that unbeknown to him at the time, DotNetAnywhere was used in an initial prototype of Blazor!

Chris's talk had no slides, and was all code (which is what we like!) - and he went through creating a very basic cutdown version of DotNetAnywhere, implementing just a few opcodes to give us a basic understanding of how a runtime works.

He showed a very basic "Hello world" C# application...

using System;

namespace HelloWorld
    class Program
        static void Main(string[] args)
            Console.WriteLine("Hello World!");

The idea being that the runtime written (in C) during this talk will load and execute this hello world app. Chris then looked at the class, shook his head, then commented out the Console.WriteLine, stating that the program was too complicated (bringing chuckles from the audience :)). He then explained that the Console.WriteLine is actually more complicated than you'd initially think. It deals with a string literal; calling another method (with an argument); and also a method that exists in another assembly. He said we'd hopefully get there by the end of the talk, and we did!

He introduced the Common Language Infrastructure ECMA-335 PDF document which he used as reference throughout his talk. Or more accurately, he showed us references to the bits he was coding - as he'd obviously already read this fascinating bit of bedtime reading! This document covers everything you need to implement the .NET runtime, which surprisingly hasn't changed since this document from 2012 (up until C#8 that is). He introduced the Portable Executable (PE) file format, and showed the section in the PDF covering this (see page 303 in the PDF).

The rest of the first half of his talk was about navigating the .NET executable by navigating to offsets defined in the PE header. He jumped back and forth from the ECMA-335 PDF and his code showing this in action. Stepping through his code one line at a time as he explained it (also showing the console output showing as he stepped through). I thought this was a really nice way of doing it. We've all experienced it where we're reading someone else's code, but only scan it, and don't really understand it fully. I quite often intentionally stop myself from scanning, and make myself read one line at a time. Stepping through whilst explaining it, as well as showing the console logs, made it really clear what the code was doing. Especially with Chris's extremely clear method of explaining! I found it interesting that he works with Jon Skeet - as he really reminded me of Jon's talk with us last year in the way the talk was delivered. Both excellent speakers!

He covered quite a bit of other stuff before the break - eg. entry point tokens (to get at the main entry point (ie. Main)); sections; virtual addresses; meta-data streams; and much more. Ending before the break with starting a switch statement where he'd start to implement various op-codes. The only case he had added to the switch before the break was 0x2a, which is "return". For now, he just threw an exception, showed that his program got to this exception (which meant we had processed the return statement in the .NET program!), then we stopped for the break.

Part 2

After the break, Chris then started to focus on what he described as the more fun part - implementing these opcodes, and expanding out the switch statement. The first one being the 'return' opcode that he started before the break. For this, he literally just used the C return statement - explaining that he'll utilise the C callstack to also manage the C# callstack. He added that this isn't what he does in DotNetAnywhere, but its sufficient for this basic example of a runtime. He even showed the return method returning an integer value - explaining how return values work by pushing the value onto the stack.

Like in the first half, Chris frequency swapped over to the ECMA-335 PDF to show us which area in the documentation referencing the opcode he was trying to implement. You can see a list of all the opcode on page 296 of the PDF.

The opcodes he implemented in the talk were...

  • 0x2ea (return) - which we've already discussed
  • 0x1f (ldc.i4.s) - which pushes a 32bit int onto the stack. Chris explained how various operations require values being pushed onto the stack so that operations can take them off the stack to use them. The PDF document explains what should be on the stack for each opcode.
  • 0x28 (call) - this opcode handles calling a method.
  • 0x58 (add) - he also demoed adding two numbers together in his C# hello world app.

After implementing these, it was time to uncomment out the Console.WriteLine! Earlier when talking about metadata streams (not to be confused with what we know as a stream in C#), Chris explained about the different types of heaps - eg. #String heap for things like class names, variable names, etc - and #US heap for user strings. So now we can take that knowledge and use the #US heap to access the "Hello world" string literal. Another issue was that he couldn't use the System.Console assembly as we know it, as that assembly assumes we're using the main runtime. So Chris got around this by implementing a custom System.Console class in C# with the WriteLine defined...

namespace System {
    public static class Console {
        extern public static void WriteLine(string s);

Then handled this specifically from within the runtime, using C to write to the console.

In the remaining few minutes, Chris showed a few more changes to the C# application - eg. adding numbers together (see 'add' opcode above), and passing the 'hello world' as a variable instead of a string literal. Then running this C# application via the runtime he'd been writing during the talk.

Whilst his talk was obviously a very basic example of a C# runtime - it really demonstrated the patterns around doing this, and showed that it's not actually as complicated as you might think! Although, I'm sure a real runtime is just as complicated as one might think! :)

A massive thank you again to Chris Bacon for joining us his talk - thoroughly enjoyed by all! Below are some related links - including a video of a shorter version of his talk that he did at NDC Oslo...




As usual, a few of us headed down to the The Royal Blenheim afterwards - and was great to have Chris join us too! Plenty of geekout conversations - talking about everything from cloud providers (remember Chris works at Google ;), to Kubernetes, to financial investing!



Corriculo Recruitment

As usual, a massive thank you to our Primary sponsor - Corriculo Recruitment! An integral part of the .NET Oxford team, helping us out in so many different ways. Not only helping us out financially, but also welcoming people in on the doors, supplying and serving drinks and refreshments, helping us with marketing and promotion, and much more!

And check out the t-shirts!!!...



Our secondary sponsor is my own company, Everstack. Providing a lot of my own time for organising and managing .NET Oxford. Everstack provides software development and consultation services - specialising in .NET and the Cloud.


Whilst not technically a sponsor - I'd also like to say a massive thank you to John Parkin for his help with the photography. I work with John in one of my main contracts, and he's very kindly offered to help out with photography - which is fantastic, as decent pictures of the events were something we were really lacking previously!


.NET Core 3 Preview 2 announced

With Preview 1, they started added some of the C#8 features. Now in Preview 2, they've added additional C#8 features - eg. using declarations, switch expression, async streams - plus plenty more!

Azure Cost Management

To anyone who's had trouble managing their costs in Azure, this will come as great addition. Last year, Microsoft added Azure Cost Management to Enterprise Agreement customers as a preview. This has now gone into GA for EA customers.

For Pay As You Go customers, this has now gone into Preview, and I can now see it in my PAYG portal!

This adds things like cost analysis, budgets, alerts, exports, and APIs.

A few more mentions...

Prize Draw Winners

During the intro talk, we also had our prize-draw giveaway using my usual WPF Prize Draw app. A massive congratulation to the winners, and a massive thank you to our awesome prize draw sponsors!

The prize draw app pulls from the RSVP list, and unfortunately once again we had a large number of no-shows being drawn. It's such a shame that no matter how much we ask our members to update their RSVPs if they RSVP then find they can't make it - we still get so many no-shows. A lot of members have certainly got better, but we've a long way to go. Someone in the audience suggested that we blacklist no-shows from the prize draw app - which isn't a bad idea!


Congratulations to Annie Andrews for winning a year-long Jetbrains product licence! She decided to go with PhpStorm (no comment! ;)).

Manning Books

Congratulations to Andy Pook for winning a Manning ebook! The winner has the choice of any of the awesome Manning ebooks from their website, and Andy chose C# in Depth, Fourth Edition.

Remember that we have our special Manning coupon code (ug367) which gives all of our members a 36% discount on any of their e-books! They've also asked me to share a link to some of their new courses for their LiveVideo system.


Congratulations to Rob Amos for winning the Oz-Code licence!

For those that don't know, Oz-Code is a Visual Studio extension that puts your debugger on steroids. Take a look at their website for videos of their features. If you haven't checked it out, then definitely download the trial and have a play. All our member get a free 3 month trial licence (see below) or 50% off a full licence! To claim, you can visit this link to pick up your licence!


Upcoming Meetups

Below are our upcoming meetups. We'll be announcing more meetups for next year shortly, and if you subscribe to the meetup group, you'll get email notifications as they are announced.

12th March 2019: Functional C# - Simon Painter

Our March meetup will be with Simon Painter talking about writing Functional C#.

10th April 2019: An evening with Uncle Bob!

We're very excited to announce that in April, we'll be joined by Uncle Bob himself! He'll be talking about the three laws of TDD. This will be in our larger venue at St Aldates Conference Centre (where we had the Jon Skeet event). Also note that this is on a Wednesday rather than our usual Tuesday. The event has been announced on Meetup, but we haven't opened RSVPs yet, to try and minimise on no-shows.

May 2019: Lightning Talks

We're thinking of another lightning talk event for May. If you're interested in doing a 5, 10, 15, or 20 minute talk - then let us know!

June 2019: F#, Kubernetes, Raspberry Pis and more!

In our survey, you said you wanted a talk on F#, and also on running .NET in a Linux environment - so your wish is our command! In June, we have James World talking about F#, and all our regulars will know what a great speaker James is, as he's spoken quite a few times now! And I'll also be doing a talk on running a Kubernetes cluster on some Raspberry Pis, and running .NET with RabbitMQ on it.

Please retweet if you enjoyed this post ...


Recent Posts

Featured Posts

.NET Oxford Links