Details
Description
a = matrix(int, (2,3))
print a[0,0].ToString() // outputs 11152508
Boo does not directly read values from arrays, but uses Array.GetValue() instead, which returns a boxed int.
When calling a member method directly on the value, it is not correctly unboxed; so a wrong memory address is accessed and the wrong value is displayed.
Disassembly of Boo code above:
//000001: a = matrix(int, (2,3))
IL_0000: ldtoken [mscorlib]System.Int32
IL_0005: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000a: ldc.i4 0x2
IL_000f: newarr [mscorlib]System.Int32
IL_0014: dup
IL_0015: ldc.i4 0x0
IL_001a: ldc.i4 0x2
IL_001f: stelem.i4
IL_0020: dup
IL_0021: ldc.i4 0x1
IL_0026: ldc.i4 0x3
IL_002b: stelem.i4
IL_002c: call class [mscorlib]System.Array [Boo]Boo.Lang.Builtins::matrix(class [mscorlib]System.Type,
int32[])
IL_0031: castclass int32[,]
IL_0036: stloc.0
//000002: print a[0,0].ToString()
IL_0037: ldloc.0
IL_0038: ldc.i4 0x2
IL_003d: newarr [mscorlib]System.Int32
IL_0042: dup
IL_0043: ldc.i4 0x0
IL_0048: ldc.i4.0
IL_0049: stelem.i4
IL_004a: dup
IL_004b: ldc.i4 0x1
IL_0050: ldc.i4.0
IL_0051: stelem.i4
IL_0052: callvirt instance object [mscorlib]System.Array::GetValue(int32[])
IL_0057: stloc.1
IL_0058: ldloca.s V_1
IL_005a: call instance string [mscorlib]System.Int32::ToString()
IL_005f: call void [mscorlib]System.Console::WriteLine(string)
Notice that the equivalent C# code does not use any boxing at all and does not need to create an array to access a position in the array:
//000009: int[,] a = new int[2, 3];
IL_0000: ldc.i4.2
IL_0001: ldc.i4.3
IL_0002: newobj instance void int32[0...,0...]::.ctor(int32,
int32)
IL_0007: stloc.0
//000010: Console.WriteLine(a[0,0].ToString());
IL_0008: ldloc.0
IL_0009: ldc.i4.0
IL_000a: ldc.i4.0
IL_000b: call instance int32& int32[0...,0...]::Address(int32,
int32)
IL_0010: call instance string [mscorlib]System.Int32::ToString()
IL_0015: call void [mscorlib]System.Console::WriteLine(string)