# Saturday, 05 April 2003
« Sockets | Main | More on value types »
Value Types & Reference Arguments

I've added experimental support for using value types and reference arguments in Java. The challenge is to do this without having to build a new Java compiler.

Here is a value type I constructed in C# for testing purposes:

public struct ValType {

  public int foo;

 

  public ValType(int f) {

    foo = f;

  }

 

  public override string ToString() {

    return "ValType:" + foo;

  }

 

  public static void Increment(ref ValType v) {

    v.foo++;

  }

}  

Here is a Java example that uses value types and calls a method with a reference argument:

import system.DateTime;

 

class ValTest {

  static DateTime dt;

 

  public static void main(String[] args) {

    ValType v = new ValType(0);

    v.foo = 42;

    System.out.println(v);

 

    ValType[] av = new ValType[1];

    av[0] = v;

    ValType.Increment(av);

    System.out.println(av[0]);

 

    dt = DateTime.get_Now();

    DateTime d = new DateTime(0);

    d = AddDay(d);

    System.out.println(d);

    System.out.println(dt);

  }

 

  private static DateTime AddDay(DateTime dt) {

    return dt.AddDays(1);

  }

}

How is this code compiled? Whenever a value type is loaded from a field or array, instantiated or returned from a method it is boxed. Local variables are references to boxed instances of the value type. When a boxed value type instance is assigned to a field, stored in an array or passed to a method, it is unboxed. Referenced method arguments are exported by NetExp as arrays.

Let's look at a few examples:

    ValType v = new ValType(0);

Is compiled as:

ldc.i4.0

newobj     instance void ValType::.ctor(int32)

box        ValType

stloc.0

The local variable v is of type object and contains a reference to the boxed value.

    v.foo = 42;

Assigning a field in the boxed value:

ldloc.0

ldc.i4.s   42

stloc.1

unbox      ValType

ldloc.1

stfld      int32 ValType::foo

After loading the reference to the boxed value, the constant (42) gets stored in a temporary local and then reference gets unboxed, this leaves a managed pointer to the interior of the boxed value on the stack and the stfld instruction uses this pointer to set the field.

    av[0] = v;

Setting an array element:

ldloc.2

ldc.i4.0

ldloc.0

stloc.3

ldelema    ValType

ldloc.3

unbox      ValType

ldobj      ValType

stobj      ValType

The address of element 0 of the array is loaded, v is unboxed and copied into the array.

    ValType.Increment(av);

Calling a method with a reference argument:

ldloc.2

stloc.s    V_4

ldloc.s    V_4

ldc.i4.0

ldelema    ValType

call void ValType::Increment(valuetype ValType&)

The Java code passes an array and the byte code to CIL compiler takes the address of the first element of the array and passes that to the method. BTW, if the array is of length zero, ldelema throws a System.IndexOutOfRangeException.

Pros and Cons of this Approach

The advantage of enabling value type of reference arguments are that it is easier to leverage .NET framework code from within Java code (targetted at IKVM.NET) and it enables me to write more glue code in Java.

The downside is the non-intuitive behavior. Compare these two lines:

    v.foo = 42;

    av[0].foo = 42;

The first line does what you'd expect, it assigns 42 to the field foo of the boxed value type. However, the second line has no effect, because it results in a boxed copy being loaded from the array, that boxed copy's field foo is assigned the value 42, but it is not copied back into the array. This also applies to fields, only local variables contain boxed value types and can be manipulated safely.

Finally, a small problem with arrays of value types is that the Java compiler will happily compile:

    Object[] array = new ValueType[1];

Obviously this isn't legal.

I'd like to get feedback from people who either like or dislike this new functionality. Of course, any ideas for alternative approaches would be most welcome too.

Saturday, 05 April 2003 16:03:00 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1] Tracked by:
"diet pills drop ship" (diet pills drop ship) [Trackback]
"Online poker demographics" (Online poker demographics) [Trackback]