Tutorial :System.AccessViolationException storing a variable with reflectio.emit


I'm building a compiler with reflection.emit in my spare time, and i've come to a problem that i'm not understanding.

A little context, I've a runtime with a couple of types and one of them is Float2, a simpler vector struct with two float values (X and Y). I've made a couple of properties that allow me to swizzle the values (a la hlsl). For example if i have a new Float2(1.0f, 2.0f), if i make something like (new Float2(1.0f, 2.0f)).YX i'm going to get a Float2(2.0f, 1.0f) I'm using this type in my language and currently testing this case (minor details of the language omitted):

float2 a = float2(1.0, 2.0).yx;  return a;  

I'm transforming float2(1.0, 2.0) in a new call and accessing the property YX of my Float2 type in .yx.

The problem is I'm getting a "System.AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.". I don't understand why because if I make something like this:

float2 a = float2(1.0, 2.0);  return a;  

Everything goes well.

The IL code that i'm generating is the following (I think the problem occurs in "L_0014: stloc.0", I don't know why it happens though) :

    .method public virtual final instance valuetype  [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 Main() cil managed  {      .maxstack 3      .locals init (          [0] valuetype [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 num)      L_0000: ldc.r4 1      L_0005: ldc.r4 2      L_000a: newobj instance void [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2::.ctor(float32, float32)      L_000f: call instance valuetype [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2::get_XY()      L_0014: stloc.0       L_0015: ldloc.0       L_0016: ret   }  

Result of peverify:

[IL]: Error: [offset 0x0000000F] [found value 'Bifrost.Psl.Compiler.Runtime.Float2'][expected address of value 'Bifrost.Psl.Compiler.Runtime.Float2'] Unexpected type on the stack.


The IL looks OK, although I don't know what your Float2 looks like.

I found the best way to debug this is to save the assembly to disk, then run peverify. Any code that generates an AccessViolationException will cause an error in peverify.

Edit: The newobj doc on MSDN talks about pushing an object reference onto the stack, which I took to be a pointer to a value type. If you're getting this error from peverify then I think you need to

  1. newobj
  2. stloc to a temporary variable
  3. ldloca to get the address of the value type stored in the temporary variable
  4. call

Now that I think about it, this is what the C# compiler does if you do a direct call on a value type like 4.ToString();.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »