Locator – my first Windows Mobile App

A month back, I bought a new mobile phone (HTC S710) running Windows Mobile 6.0. I specifically bought it for playing around with the Windows Mobile API, and I’ve been trying out a few things with it. I’m pretty impressed by the .NET Compact Framework, it makes it ridiculously simple to do things that require huge chunks of code in C++.

Anyways, one of the few things I wished I could do with my old phone was to use the location information broadcast by cellular networks. Almost all GSM providers (Airtel/BSNL/Vodafone) broadcast the current location to the cellphone – the phone usually displays it in the “home” screen, but that’s about it. That information could be much more useful though – it’s effectively a low resolution GPS.

Think about this scenario – you are travelling to a distant location and the route has patchy network coverage. You are supposed to reach the destination by 9:00 AM, but for some reason, you don’t get there by that time. Someone who cares about you gets anxious and wants to know where you are – he or she tries to call you, but thanks to the patchy network, the call doesn’t get through. Or maybe, you’re sleeping and you set the profile to “Silent”. Wouldn’t it be nice if that person can send a message and get to know where you are, without you having to do anything?

Locator does precisely that. Once Locator is launched, it listens for SMS messages with a particular body – once such a message arrives, it sends a reply with the current location as the message body (along with the time of the last location change). The current location, is read from the information broadcast by the cellular network.

This is how Locator looks like: 

 

Once launched, message interception is activated automatically – Locator responds to any new SMS messages with the body #where art thou#, with “<Owner> is at Home (Asdf) since <DateTime>”, where Owner is the name of the phone’s owner, and DateTime is the date and time when the location changed to Asdf.

The left button closes the application and deactivates message interception. The right button opens a menu that allows you to add the current location to an existing group (like Home) or create a new group with the current location. 

C# 3.0 compiler bug – Using object initializers, generics and value types

There is a description of the bug here. The following piece of code demonstrates the bug.


    class Program
    {
        interface I
        {
            int X { get; set; }
        }

        struct S : I
        {
            public int X { get; set; }
        }

        static void Main(string[] args)
        {
            Func<S>();
        }

        static void Func<T>() where T : I, new()
        {
            var c = new T() { X = 1 };
            Console.WriteLine(c.X);
        }
    }

The code prints 0 instead of 1. The bug goes away if object initializers are not used – changing var c = new T() { X = 1 }; to var c = new T(); c.X = 1; will print 1.

I had assumed all along that object initializers were transformed into property setters at the source code level (or somewhere above IL). This bug doesn’t help much to confirm that :)

Anyway, let’s see what’s causing the problem. Peeking into the generated IL, 


   .locals init (
        [0] !!T c,
        [1] !!T <>g__initLocal0,
        [2] !!T CS$0$0000)
        ... // Store zeroed out instance of S in locals[1]
    L_0022: ldloc.1 
    L_0023: box !!T
    L_0028: ldc.i4.1 
    L_0029: callvirt instance void CSharp3Test.Program/I::set_X(int32)
    L_002e: nop 
    L_002f: ldloc.1 
    L_0030: stloc.0 
    L_0031: ldloca.s c
    L_0033: constrained !!T
    L_0039: callvirt instance int32 CSharp3Test.Program/I::get_X()
    L_003e: call void [mscorlib]System.Console::WriteLine(int32)

 Can you spot the problem now?

You can see that at L_0023, S is boxed and the boxed instance is used to make the virtual call to set X. You can also see that the boxed instance is not stored in any of the local variables, the callvirt instruction pops it off the stack and then it’s gone. To load the value of X, the callvirt instruction is given a reference to c (locals[0]), which contains the unboxed instance of the struct. Which is why we are getting a 0 (the default value), instead of 1. Essentially, the compiler is generating the equivalent IL for something like 


   S s = new S();
   I i = s;
   i.X = 10;
   Console.WriteLine(s.X);

This again prints 0 instead of 10, because i is assigned a different (boxed) instance of S and therefore changing i.X doesn’t change s.X.

But then how does doing the initialization in two steps (var c = new T(); c.X = 1) work. The answer – Two step initialization does not use boxing when setting the value of X. Here’s how the generated IL looks.

   .locals init (
        [0] !!T c,
        [1] !!T CS$0$0000)
    L_0021: stloc.0 
    L_0022: ldloca.s c
    L_0024: ldc.i4.1 
    L_0025: constrained !!T
    L_002b: callvirt instance void CSharp3Test.Program/I::set_X(int32)
    L_0030: nop 
    L_0031: ldloca.s c
    L_0033: constrained !!T
    L_0039: callvirt instance int32 CSharp3Test.Program/I::get_X()
    L_003e: call void [mscorlib]System.Console::WriteLine(int32)

 

The box instruction is gone, instead, the compiler has generated a constrained prefix for the callvirt instruction. MSDN says that

“When a callvirt method instruction has been prefixed by constrained  thisType, the instruction is executed as follows:

  • If thisType is a reference type (as opposed to a value type) then ptr is dereferenced and passed as the ‘this’ pointer to the callvirt of method.

  • If thisType is a value type and thisType implements method then ptr is passed unmodified as the ‘this’ pointer to a call  method instruction, for the implementation of method by thisType.


 “

In other words, the address of the instance is passed as the this parameter to the call method – no boxing at all. If you’d looked carefully enough, the getter for X uses the constrained prefix, even in our buggy IL (the first listing).

That explains the bug then, but opens up another question. If virtual dispatch can be done for a value type without boxing, then why not do it that way for

   S s = new S();
I i = s;
i.X = 10;

 as well? Mind you, virtual dispatch doesn’t mean anything for value types, as they cannot derive from or derived by anything else, so any callvirt instruction on value types can be treated as a straight call instruction. The constrained prefix does exactly this, after making sure that this is a value type. So why not use it for all virtual calls? Performance (not many value types implementing interfaces)?

What do you think? 

More greasemonkeying with IRCTC

I’m glad that a lot of people found AJAXAvailability useful. For people who haven’t heard about it, AJAXAvailability is a Greasemonkey script for IRCTC’s website that loads availability information asynchronously and shows it in the availability table, right alongside the list of trains (more information here).

Mani suggested that the ability to sort the availability table based on departure time would be useful. That seemed like a nice idea, so here it is – SortItOut, a Greasemonkey script that modifies the availability table and makes the header texts clickable. Clicking on one of the headers, say “Departure time”, sorts the table by the values in that column, in ascending order.Greasemonkey script to do that.

 Ascending sort screenshot

Clicking on the same header again will sort the table in descending order. 


You can sort by any column, except the one with radio buttons (“Select”). This script also works nicely with AJAXAvailability, in that it allows you to sort the table even when availability information is loading (unless you are sorting the table by availability information, of course). 

To install the script, install Greasemonkey first (if you haven’t already), navigate to SortItOut and click Install. The next time you visit IRCTC’s website and go to the “Plan My Travel” page, the script gets loaded and runs automatically.

That’s all, folks – the rest of the post is about the technical details of how the script works, feel free to skip it if you’re not interested.



The script works by getting the availability table’s DOM object through an XPath expression and replacing the cells of the first row with dynamically created anchor elements. The click event of those elements are hooked up to a function that then sorts the table, based on the column’s values. The sort function is pretty simple – it creates an array of objects, one object per row. Each object holds a reference to it’s row and a reference to the value of the column in that row, on which the sort must be done.

The script then uses the Array.sort library function to do the sorting and then rearranges the rows in the table based on the sorted result. There are quite a few ways of rearranging the table -

1. Replace the existing HTML in each row with the HTML of the row to-be

2. Remove all rows in the table and create new rows and cells, based on the sorted output.

3. Use Greasemonkey’s insertBefore to switch around “TR” DOM objects.

The first approach wouldn’t work with AJAXAvailability. That script stores references to “TD” DOM elements, for updating availability information in the AJAX callback. Replacing the innerHTML of the table’s rows would create new TD objects, breaking that script. There was another subtle problem when I tried doing this – my sorted array and the actual table hold references to the same TR DOM objects, so replacing the HTML in the table would also affect the sorted output.

The second approach will not work for the same reason – new TD elements will be created, and the AJAXAvailability script will update the now obsolete TD elements.

The third approach works because no new objects are created, existing TR objects are shunted around, based on the sorted output. This was also the simplest to code as well. Doesn’t it feel great, when the best solution is the simplest and cleanest one as well?

Mucking around with instance field initializers – Part 2

We saw in Part 1 that C# doesn’t allow an instance field initializer to refer another field in the class. Before trying to figure out why, let’s first see if this is a restriction imposed by C#, rather than by the CLR. 

Some disassembling and reassembling later, this is what the new IL code looks like.

    IL_0000:  ldarg.0
IL_0001: ldc.i4.1
IL_0002: stfld int32 ConsoleApplication1.Program::x
IL_0007: ldarg.0
IL_0008: ldarg.0
IL_000b: ldfld int32 ConsoleApplication1.Program::x
IL_0009: ldc.i4.1
IL_000a: add
IL_000c: stfld int32 ConsoleApplication1.Program::y
IL_000d: ldarg.0
IL_000e: ldfld int32 ConsoleApplication1.Program::y
IL_000f: call void [mscorlib]System.Console::WriteLine(int32)

 It’s basically the same code in Part 1, except for the initialization of y. Instead of initializing y to 2, the code tries to load this.x, add 1 to it, store the result in y (y = x + 1) and then print out the result. The call to the constructor of System.Object comes next, but I’ve left that out for clarity. 

Guess what, it works! The code assembles, checks out with peverify and runs fine, printing the value 2.

So, it looks like the CLR does not have any problems accessing other instance fields when initializing them. Then why doesn’t the C# compiler like them?

How about fields inherited from a base class? If C# doesn’t have the instance field initializer restriction, then the following piece of code should compile . What do you expect the value of y to be?

    class A
{
protected int x = 1;
}

class B : A
{
int y = x + 1;
B() { Console.WriteLine(y); }
}

 1? 2? It depends on where the C# compiler puts the instance field initialization code. According to the current spec, it’s placed before the call to the base class constructor, which means that y will be initialized to 1. Suddenly, the derived class now gets to access uninitialized base class state. Not good at all.

You could argue that the compiler knows about inherited fields and therefore can apply the restriction only to those fields – but that would add a nasty special case to the “you-cannot-reference-during-instance-field-initialization” list. I don’t think it will be intuitive either – a typical programmer will be surprised if a “Move to base class” refactor suddenly breaks working code.

Static fields don’t have this problem – they aren’t really “inherited”. Which could be why the compiler allows static field initializers to reference other fields.

What do you think?

Mucking around with instance field initializers – Part 1

What do you think of the following piece of code?


    class Program
{
int x = 1;
int y = x + 1;
}

Looks simple, except that it doesn’t compile (error CS0236: A field initializer cannot reference the non-static field, method, or property ‘Program.x’)

Try making x and y static – the code will compile fine now. I have been trying to find out why – so far, I haven’t got a clue. Just in case it’s not obvious, I do know that moving y = x + 1 into the body of Program’s constructor will get me what I want, but I was (and am) curious to know why field initializers, and only instance field initializers, aren’t allowed to access non-static fields.

The C# spec says that field initializers “correspond to a sequence of assignments that are executed immediately upon entry to any one of the instance constructors”, just before the call to the base class constructor. When I generated IL for Program’s constructor after replacing y = x + 1 with y = 2, it looked like this


    L_0000: ldarg.0 
L_0001: ldc.i4.1
L_0002: stfld int32 ConsoleApplication1.Program::x
L_0007: ldarg.0
L_0008: ldc.i4.2
L_0009: stfld int32 ConsoleApplication1.Program::y
L_000e: ldarg.0
L_000f: call instance void [mscorlib]System.Object::.ctor()
L_0014: nop
L_0015: ret


The generated IL matches with the spec – 1 and 2 are stfld’ed into x and y before calling the base class constructor (System.Object::.ctor()).

The C# spec also says that a field initializer is not allowed to reference the this pointer – “ variable initializer for an instance field cannot reference the instance being created.” It doesn’t say why though.

The IL shown above clearly indicates that this (ldarg.0) is valid when storing 1 and 2 into x and y. So why doesn’t C# allow y = x + 1?

I initially wondered if that rule is to prevent code like this 


    class Program
{
int x = y + 1;
int y = x + 1;
}

but then, the C# spec clearly says that the variable initializers will be run in “textual” order. If you combine that with the fact that x and y will be assigned their default values even before their variable initializers run, you’ll see that the above code should run fine, resulting in x = 1 (because y is zero) and y = 2. You can make x and y static and run the code, you will see the same result.

So again, why? Can you figure out why? We’ll do some more digging into this in the next post.