Issues creating a call to Nullable<Boolean>.Value

224 views
Skip to first unread message

Austin Brkich

unread,
Nov 7, 2015, 1:09:36 PM11/7/15
to mono-cecil
I am having issues trying to create a instruction to call Nullable<Boolean>.Value

The closest I have come is by using the following code as it will generate ILCode that appears to be almost identical to what it was originally. I have also included the Test.exe that I am modifying, In this example I am replacing a call to Nullable<Boolean>.Value that was generated from the compiler with one generated by Mono.Cecil, but I am getting the following error when trying to run the modified executable.

https://gist.github.com/7H3LaughingMan/311662c07b8bf8f8d2c6
https://dl.dropboxusercontent.com/u/7231478/Test.exe

Unhandled Exception: System.TypeLoadException: Could not load type 'System.Nullable`1' from assembly 'Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' due to value type mismatch.
   at Test.Program.Main(String[] args)

Jb Evain

unread,
Nov 8, 2015, 12:59:50 PM11/8/15
to mono-...@googlegroups.com
Hi Austin,

Yeah dealing with generics is not always a pleasant experience right now.

Here's code that works:

http://paste2.org/YeD09NEI

Always work with definitions until you need to create references in
your module, it's much easier. In this case, retrieve the definition
from get_Value, up until the point where you create a reference.

And then there's the MakeGeneric method that should be in
Mono.Cecil.Rocks but isn't.

Jb
> --
> --
> --
> mono-cecil
> ---
> You received this message because you are subscribed to the Google Groups
> "mono-cecil" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mono-cecil+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Austin Brkich

unread,
Nov 13, 2015, 9:15:20 AM11/13/15
to mono-cecil
Somewhat related to this issue is that I am having issued making a call now to Nullable<Boolean>.HasValue but I am only able to replicate this in my actual program. The program is an attempt to add a Modding API to a game and it does this by parsing an XML file to figure out what needs to be inserted and where.

This file represents how Call OpCodes are handled.
https://github.com/7H3LaughingMan/PhiScript/blob/master/PhiPatcher/Instructions/Call.cs


This is the actual XML file with all the modifications. I will include the part that I am having issues with.

<Instruction OpCode="Call" Assembly="CoreLibrary" Type="System.Nullable`1" Method="get_HasValue">
<GenericParameter Assembly="CoreLibrary" Type="System.Boolean" />
</Instruction>

This is the exception I am getting.
InvalidProgramException: Invalid IL code in Planetbase.ConstructionComponent:canProduce (): IL_000a: call      0x0a0001bc

And using ILSpy this is the resulting IL code.
IL_000a: call instance bool valuetype [mscorlib]System.Nullable`1<bool>::get_HasValue()

Jb Evain

unread,
Nov 13, 2015, 1:26:12 PM11/13/15
to mono-...@googlegroups.com
Hi,

I'm not going to be able to debug your entire program I'm afraid.

What happens if you run peverify on your modified binary?

Thanks,
Jb

Austin Brkich

unread,
Nov 13, 2015, 1:43:13 PM11/13/15
to mono-cecil
This is what I get when running peverify

[IL]: Error: [C:\Program Files (x86)\Steam\SteamApps\common\Planetbase\Planetbase_Data\Managed\Assembly-CSharp.dll : Planetbase.ConstructionComponent::canProduce][offset 0x0000000A][found value 'System.Nullable`1[System.Boolean]'][expected address of value 'System.Nullable`1[System.Boolean]'] Unexpected type on the stack.

[IL]: Error: [C:\Program Files (x86)\Steam\SteamApps\common\Planetbase\Planetbase_Data\Managed\Assembly-CSharp.dll : Planetbase.ConstructionComponent::canProduce][offset 0x00000013][found value 'System.Nullable`1[System.Boolean]'][expected address of value 'System.Nullable`1[System.Boolean]'] Unexpected type on the stack.

2 Error(s) Verifying Assembly-CSharp.dll

Jb Evain

unread,
Nov 13, 2015, 1:51:28 PM11/13/15
to mono-...@googlegroups.com
Hi Austin,

Peverify is telling you that the semantic of the code is wrong.

Can you pastebin the entire IL of the method?

Jb

Austin Brkich

unread,
Nov 13, 2015, 2:34:16 PM11/13/15
to mono-cecil

IL_0000: ldarg.0
IL_0001: call valuetype [mscorlib]System.Nullable`1<bool> [PhiScript]PhiScript.Manager.ConstructionComponentManager::OnCanProduce(class ['Assembly-CSharp']Planetbase.ConstructionComponent)
IL_0006: stloc.s 8
IL_0008: ldloc.s 8


IL_000a: call instance bool valuetype [mscorlib]System.Nullable`1<bool>::get_HasValue()

IL_000f: brfalse.s IL_0019

IL_0011: ldloc.s 8
IL_0013: call instance !0 valuetype [mscorlib]System.Nullable`1<bool>::get_Value()
IL_0018: ret


This is my section of code that I am inserting. The rest of the Method is code that doesn't really matter, but if you need that let me know.

Jb Evain

unread,
Nov 13, 2015, 8:08:42 PM11/13/15
to mono-...@googlegroups.com
You need to:

ldloca
call get_HasValue

Nullable are value types.

Jb

Austin Brkich

unread,
Nov 14, 2015, 12:05:23 PM11/14/15
to mono-...@googlegroups.com
Thanks for the help, that fixed the issue. Didn't realize there was a
difference between ldloc and ldloca.
> You received this message because you are subscribed to a topic in the Google Groups "mono-cecil" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/mono-cecil/1LtKdqVww8c/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to mono-cecil+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages