Thank you very much for your time, here are some answers
Lvt
[quoted text, click to view] > 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
[quoted text, click to view] > 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
[quoted text, click to view] > 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
[quoted text, click to view] > 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
[quoted text, click to view] > 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
> ....
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
[quoted text, click to view] > (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
[quoted text, click to view] > 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
[quoted text, click to view] "Holger Grund" wrote:
> "Luc Vaillant" <LucVaillant@discussions.microsoft.com> wrote
>
> > I'm trying to write a method for my PocketPC that will write a Double
> > value
> > to an Array buffer at the specified offset.
> >
> > The constraints are :
> > - Must be safe managed code
> Do you mean verifiable code? Or just valid CIL?
>
> > - Array buffer can be of any integral type (byte, short, int, long, etc.)
> > - offset can be unaligned
> >
> > I already wrote this method for Win32, and it works fine.
>
> > My Compact Framework version of SetDouble works fine on the Pocket PC 2002
> > emulator, but throws a 0x80000002 exception on my Pocket PC device (QTEK
> > 9090)
> >
> > Here is the method code I wrote (I know that I'm accessing the Array like
> > a
> > Byte array, but only for the first element in order to retreive the
> > array's
> > starting address. This works fine in my Windows.Forms version):
> >
> Did you write that in MSIL assembler? Can you share the source?
>
> BTW: There's also unaligned
> > .method public hidebysig static void
> > SetDouble(class [mscorlib]System.Array buffer,
> > int32 offset,
> > float64 'value') cil managed
> > {
> > .locals (unsigned int8* pBuffer, int32 nIndex, unsigned int8* pValue)
>
> 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.
>
> >
> > ldarg.0
> > ldc.i4.0
> > ldelema [mscorlib]System.Byte
> 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
> ....
>
> > ldarg.1
> > add
> (Managed) pointer arithmetic is not verifiable.
>
> > stloc.0
> 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.
>
> You might want to use unaligned.1 cpblk
>
> -hg
>
>
>
[quoted text, click to view] "Luc Vaillant" <LucVaillant@discussions.microsoft.com> wrote
>> 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]
[quoted text, click to view] >> 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.
[quoted text, click to view] > 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 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)
[quoted text, click to view] >> 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
}
[quoted text, click to view] >> 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
>> ....
> 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
>
You can't do much with an array whose element type is unknown (in
a verifiable way).
[quoted text, click to view] >> 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
>
Looks perfectly valid to me. Did you get the calling function
correct? What does peverify say?