That's probably not verifiable. You should cast to the array
type before via
ldarg.0
castclass unsigned int8[]
ldc.i4.0
ldelema unsigned int8
...
(Managed) pointer arithmetic is not verifiable.
Thank you very much for your time, here are some answers
Lvt
> Do you mean verifiable code? Or just valid CIL?
LVT : I just want not to be bored if security constraints (like only managed
code is allowed to run on this computer) are ON in .Net Framework
> Did you write that in MSIL assembler? Can you share the source?
LVT : Yes, I wrote this code in MSIL : First I wrote a small class with
empty methods, then I used ILDASM to get the MSIL of my class with methods
doing nothing, and then I wrote the missing MSIL code in my methods
Here is the code of the C# class :
using System;
namespace Memory
{
public class Buffer
{
private Buffer() {}
public static void SetDouble(Array buffer, Int32 offset, Double value)
{}
}
}
Here is the SetDouble generated code with my MSIL:
.method public hidebysig static void
SetDouble(class [mscorlib]System.Array buffer,
int32 offset,
float64 'value') cil managed
{
.locals (int32 nIndex, unsigned int8* pValue, unsigned int8* pBuffer)
ldc.i4.0 // 0
stloc.0 // nIndex = 0
ldarga.s 2 // &value
stloc.1 // pValue = &value;
ldarg.0 // buffer
ldarg.1 // offset
ldelema [mscorlib]System.Byte // &buffer[offset]
stloc.2 // pBuffer = &buffer[offset]
LOOP:
ldloc.2 // pBuffer
ldloc.0 // nIndex
add // pBuffer + nIndex
ldloc.1 // pValue
ldloc.0 // nIndex
add // &pValue[nIndex]
ldind.i1 // pValue[nIndex]
stind.i1 // pBuffer[nIndex] = pValue[nIndex]
ldloc.0 // nIndex
ldc.i4.1 // 1
add // nIndex++
stloc.0 // ->nIndex
ldloc.0 // nIndex
ldc.i4.8 // 8
blt.s LOOP // if (nIndex < 8) goto LOOP
ret
} // end of method Buffer::SetDouble
> BTW: There's also unaligned
LVT: Yes, alignment is a big issue on ARM, that's why I used a loop
The first version I wrote in MSIL for SetDouble was:
IL_0000: ldarg.0
IL_0001: ldc.i4.0
IL_0002: ldelema [mscorlib]System.Byte
IL_0007: ldarg.1
IL_0008: add
IL_0009: ldarg.2
IL_000a: unaligned. 1
IL_000d: stind.r8
IL_000e: ret
but this code throws an exception on my Pocket PC
> I don't think you can do anything verifiable with native pointers. And
> if you really want to use them, make sure the pointee is pinned.
LVT: I don't know how to pin memory
> That's probably not verifiable. You should cast to the array
> type before via
[quoted text clipped - 3 lines]
> ldelema unsigned int8
> ....
LVT : Unfortunately, I couldn't cast the Array because I don't know its type
My first Idea was to provide a method that works on any integral type array,
but I realize that drive me to a lot of problems for 'nothing'.
I Think I will simply allow bytes array and then used Byte[] parameter type
instead of Array type.
This way I can use the ldelem.u1 just like BitConverter.ToDouble is doing in
its CF version
> (Managed) pointer arithmetic is not verifiable.
> You store a managed pointer into a variable of native pointer
> type. You should only do so if you know the memory pointed
> to can't be moved by the GC.
LVT: You're right and I will avoid pointer arithmetic with ldelem.u1
> You might want to use unaligned.1 cpblk
LVT: Idealy YES but the following code throws an InvalidProgramException:
.method public hidebysig static void
SetDouble(unsigned int8[] buffer,
int32 offset,
float64 'value') cil managed
{
ldarg.0 // buffer
ldarg.1 // offset
ldelema [mscorlib]System.Byte // &buffer[offset]
ldarga.s 2 // &value
ldc.i4.8 // 8
unaligned. 1 cpblk // CopyMemory
ret
} // end of method Buffer::SetDouble
> > I'm trying to write a method for my PocketPC that will write a Double
> > value
[quoted text clipped - 55 lines]
>
> -hg
Holger Grund - 17 Nov 2005 13:22 GMT
>> Do you mean verifiable code? Or just valid CIL?
> LVT : I just want not to be bored if security constraints (like only
> managed
> code is allowed to run on this computer) are ON in .Net Framework
You probably want your code to verifiable then. Almost none of the things
suggested in here will work then. Maybe there are some base library
helpers which are statically known to be safe, but I'm afraid you'll have
to stick with a less efficient method.
[snip]
>> BTW: There's also unaligned
> LVT: Yes, alignment is a big issue on ARM, that's why I used a loop
Alignment is important on almost all platforms.
> The first version I wrote in MSIL for SetDouble was:
>
[quoted text clipped - 9 lines]
>
> but this code throws an exception on my Pocket PC
I don't see anything wrong here. What's the exception?
Can you locate where it happens in the CIL stream? (You may
want to ilasm with debug information /DEBUG)
>> I don't think you can do anything verifiable with native pointers. And
>> if you really want to use them, make sure the pointee is pinned.
> LVT: I don't know how to pin memory
You need a managed pointer with the pinned attribute to
point to the object (or any subobject of the complete object).
This can safely be converted to a native pointer. However,
native pointers are never verifiable.
.class X { // .ctor
.field int32 f; }
.method public static void main() {
.entrypoint
.locals ( int32& pinned p )
newobj instance void class X::.ctor() // x
ldflda int32 X::f
stloc p
// x.f is now pinned => x is pinned
ldloc p
conv.u
// top of the stack can be used as a native pointer
ret
}
>> That's probably not verifiable. You should cast to the array
>> type before via
[quoted text clipped - 14 lines]
> in
> its CF version
You can't do much with an array whose element type is unknown (in
a verifiable way).
>> You might want to use unaligned.1 cpblk
> LVT: Idealy YES but the following code throws an InvalidProgramException:
[quoted text clipped - 12 lines]
> ret
> } // end of method Buffer::SetDouble
Looks perfectly valid to me. Did you get the calling function
correct? What does peverify say?
Luc Vaillant - 17 Nov 2005 13:57 GMT
Unfortunately, I do not have time to spend on this issue right now (my
clients are waiting for me...), I will investigate this later.
For now, I just change Array type to Byte[] and use a 8 bytes loop just like
BitConverter.ToDouble does.
As you certainely guess, I'm new in MSIL coding, and I found your remarks
very helpfull.
Thank you very much
Lvt
> >> Do you mean verifiable code? Or just valid CIL?
> > LVT : I just want not to be bored if security constraints (like only
[quoted text clipped - 96 lines]
> Looks perfectly valid to me. Did you get the calling function
> correct? What does peverify say?