(replicated from:
http://www.codeproject.com/KB/dotnet/runsharp.aspx?msg=2378379#xx2378379xx)
Hi, first of all - great work on this!
I had a problem trying to call GetHashCode() on an int, here's an example:
public delegate int Int32Delegate();
static void Main(string[] args)
{
DynamicMethodGen dmg =
DynamicMethodGen.Static(typeof(Program)).Method(typeof(int));
CodeGen g = dmg.Code;
{
Operand value = g.Local(typeof(int), 0);
g.Return(value.Invoke("GetHashCode"));
}
DynamicMethod dm = dmg.GetCompletedDynamicMethod(true);
Int32Delegate myfunc =
(Int32Delegate)dm.CreateDelegate(typeof(Int32Delegate));
Console.WriteLine(myfunc()); // causes NullReferenceException
}
Unfortunately, when the delegate gets called the generated code throws and
exception. If I output the same function to a dll and run it through
peverify.exe I get the following:
[IL]: Error: [hello.dll : MyClass::DoIt][offset 0x00000004][found address
of Int32][expected ref 'System.Object'] Unexpected type on the stack.
[IL]: Error: [hello.dll : MyClass::DoIt][offset 0x00000004] Call to base
type of valuetype.
Ok, the IL looks unhappy for some reason. Here's the line in question:
IL_0004: callvirt instance int32 [mscorlib]System.Object::GetHashCode()
After some digging around I find the following IL is ok:
IL_0004: call instance int32 [mscorlib]System.Int32::GetHashCode()
Ok, looks like the IL being generated via Invoke() doesn't seem to like
calling virtual functions (like GetHashCode()) that are defined on value
types. callvirt is expecting to see a System.Object but barfs as it's
getting a System.Int32 instead.
If you need a workaround, you can cast the value type to an object (at
least in this instance.) I've come up with a patch that generates IL that
passes peverify, but I've no idea if it breaks anything else. Here it is:
--- dist/RunSharp/Operand.cs Mon Nov 05 22:00:36 2007
+++ dist/RunSharp/Operand.cs Fri Jan 04 15:12:50 2008
@@ -70,7 +70,7 @@
internal virtual bool TrivialAccess { get { return false; } }
internal virtual bool IsStaticTarget { get { return false; } }
- internal virtual bool SuppressVirtual { get { return false; } }
+ internal virtual bool SuppressVirtual { get { return Type != null &&
Type.IsValueType; } }
internal virtual object ConstantValue { get { return null; } }
internal virtual void AssignmentHint(Operand op) { }
#endregion
--- dist/RunSharp/TypeInfo.cs Mon Nov 05 22:00:36 2007
+++ dist/RunSharp/TypeInfo.cs Fri Jan 04 15:15:37 2008
@@ -345,7 +345,7 @@
{
for (; t != null; t = t.BaseType)
{
- ApplicableFunction af = OverloadResolver.Resolve(Filter(GetMethods(t),
name, false, @static, false), args);
+ ApplicableFunction af = OverloadResolver.Resolve(Filter(GetMethods(t),
name, false, @static, !@static), args);
if (af != null)
return af;
This can be applied the the 0.1.1 pre-alpha version that sits on
SourceForge at the moment.
cheers,
ninj
Nobody/Anonymous ( nobody ) - 2008-01-04 17:38
5
Closed
Fixed
Stefan Simek
None
None
Public
|
Date: 2009-08-07 22:29 the bug is fixed in the hg repository, fix will be included in next release |
|
Date: 2008-01-07 16:27 Logged In: NO |
|
Date: 2008-01-06 22:15
|
| Filename | Description | Download |
|---|---|---|
| runsharp-0.1.1-pre-alpha-patch-sw.patch | unified diff patch file | Download |
| runsharp-0.1.1-pre-alpha-value-virt.patch | patch proposal (unified diff) | Download |
| Field | Old Value | Date | By |
|---|---|---|---|
| status_id | Open | 2009-08-07 22:29 | pista |
| close_date | - | 2009-08-07 22:29 | pista |
| allow_comments | 1 | 2009-08-07 22:29 | pista |
| resolution_id | None | 2009-08-07 22:29 | pista |
| status_id | Pending | 2008-01-06 22:23 | pista |
| resolution_id | Accepted | 2008-01-06 22:23 | pista |
| close_date | 2008-01-06 22:16 | 2008-01-06 22:23 | pista |
| status_id | Open | 2008-01-06 22:16 | pista |
| assigned_to | nobody | 2008-01-06 22:16 | pista |
| resolution_id | None | 2008-01-06 22:16 | pista |
| close_date | - | 2008-01-06 22:16 | pista |
| File Added | 261099: runsharp-0.1.1-pre-alpha-value-virt.patch | 2008-01-06 22:15 | pista |
| File Added | 260790: runsharp-0.1.1-pre-alpha-patch-sw.patch | 2008-01-04 17:38 | nobody |
Copyright © 2010 Geeknet, Inc. All rights reserved. Terms of Use