Vulcan.NET: System.InvalidProgramException

Public support forum for peer to peer support with related to the Visual Objects and Vulcan.NET products
User avatar
robert
Posts: 4520
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Vulcan.NET: System.InvalidProgramException

Post by robert »

Matthias,

Do you really have to use the Vulcan compiler ?
Have you tried to convert the Vulcan projects to X# and compile with the X# compiler?
You can still use the Vulcan runtime, but by switching to the X# compiler it will much easier for us to help you.
The X# compiler is also much faster and the language has been enhanced with new features.

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
Kromi
Posts: 45
Joined: Wed Jan 13, 2016 8:31 am

Vulcan.NET: System.InvalidProgramException

Post by Kromi »

Hi Robert,

we would love to switch to the X# compiler. We are working on the switch, but we still have some show stoppers. This is one of them: https://www.xsharp.eu/forum/private-product/1190-macrocompiler-issue-with-alltrim-rc1-bandol-2-0-1-0-fox-x-runtime-vulcan#10193

Mathias
User avatar
robert
Posts: 4520
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Vulcan.NET: System.InvalidProgramException

Post by robert »

Mathias,
Two things:
1) You can use the X# compiler and still use the Vulcan runtime. In that case the Vulcan Macro compiler will be used which does not have this issue afaik.
2) That issue is fixed in the release from today.

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
Chris
Posts: 4910
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Vulcan.NET: System.InvalidProgramException

Post by Chris »

Hi Matthias,

I agree with Robert, better try compiling with X# instead. Just use the vulcan runtime in the beginning, and after you make sure the app is working fine and any issue with the X# runtime is solved, then you also move to the X# runtime.

But, out of curiosity, can you please post the actual full (vulcan) code of this method? Maybe it will ring some bell.

I would also try to zip the solution from a PC that produces a good exe and unzip it in your PC, load it and build from this source, to make sure there really are zero differences to project or code files.
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Kromi
Posts: 45
Joined: Wed Jan 13, 2016 8:31 am

Vulcan.NET: System.InvalidProgramException

Post by Kromi »

Robert,
robert wrote: 1) You can use the X# compiler and still use the Vulcan runtime. In that case the Vulcan Macro compiler will be used which does not have this issue afaik.
Since we have a huge piece of old software here that is hard to test, we have decided to make only one transition and get rid of Vulcan completely.
robert wrote:2) That issue is fixed in the release from today.
That is great news, thank you!

Mathias
Kromi
Posts: 45
Joined: Wed Jan 13, 2016 8:31 am

Vulcan.NET: System.InvalidProgramException

Post by Kromi »

Chris,

here's the complete method. Note that I have found many methods that have the same difference to the working code, namely the unsafe modifier and these strange additions in the Monitor.Enter line.

Mathias

Code: Select all

[ClipperCallingConvention(new string[]
{

})]
public unsafe GapProcessInfo(params __Usual[] _0024args)
{
    //Error decoding local variables: Signature type sequence must have at least one element.
    Monitor.Enter(lockTaken: ref *(bool*)VnLibGUITool.Functions._0024_0024StaticLocal_InitFlag__0024iSOFT_002ELSC_002EKernel_002EGapProcessInfo_0024_002Ector_0024_003A558_003A15_0024lIsNewProc, obj: (object)/*Error near IL_00b1: Stack underflow*/);
    try
    {
        if (VnLibGUITool.Functions._0024_0024StaticLocal_InitFlag__0024iSOFT_002ELSC_002EKernel_002EGapProcessInfo_0024_002Ector_0024_003A558_003A15_0024lIsNewProc.State == 0)
        {
            VnLibGUITool.Functions._0024_0024StaticLocal_InitFlag__0024iSOFT_002ELSC_002EKernel_002EGapProcessInfo_0024_002Ector_0024_003A558_003A15_0024lIsNewProc.State = 2;
            VnLibGUITool.Functions._StaticLocal_iSOFT_LSC_Kernel_GapProcessInfo__ctor_558_15_lIsNewProc = true;
        }
        else if (VnLibGUITool.Functions._0024_0024StaticLocal_InitFlag__0024iSOFT_002ELSC_002EKernel_002EGapProcessInfo_0024_002Ector_0024_003A558_003A15_0024lIsNewProc.State == 2)
        {
            throw new StaticLocalInitException();
        }
    }
    finally
    {
        StaticLocalInitFlag _0024_0024StaticLocal_InitFlag__0024iSOFT_002ELSC_002EKernel_002EGapProcessInfo_0024_002Ector_0024_003A558_003A15_0024lIsNewProc = VnLibGUITool.Functions._0024_0024StaticLocal_InitFlag__0024iSOFT_002ELSC_002EKernel_002EGapProcessInfo_0024_002Ector_0024_003A558_003A15_0024lIsNewProc;
        _0024_0024StaticLocal_InitFlag__0024iSOFT_002ELSC_002EKernel_002EGapProcessInfo_0024_002Ector_0024_003A558_003A15_0024lIsNewProc.State = 1;
        Monitor.Exit(_0024_0024StaticLocal_InitFlag__0024iSOFT_002ELSC_002EKernel_002EGapProcessInfo_0024_002Ector_0024_003A558_003A15_0024lIsNewProc);
    }
    base._002Ector();
    nIsDevelopment = (short)(-1);
    getInfo();
    oMemInfo = null;
}
User avatar
Chris
Posts: 4910
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Vulcan.NET: System.InvalidProgramException

Post by Chris »

Sorry, I meant please post the original vulcan code!
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Kromi
Posts: 45
Joined: Wed Jan 13, 2016 8:31 am

Vulcan.NET: System.InvalidProgramException

Post by Kromi »

Chris,

sure, here it is:

Code: Select all

CONSTRUCTOR() 
	STATIC LOCAL lIsNewProc	:= TRUE AS LOGIC
	SUPER()
	SELF:nIsDevelopment := -1
	SELF:getInfo()
	SELF:oMemInfo := NULL_OBJECT
If I comment out the STATIC LOCAL declaration in that constructor, the error message lists another method (getInfo() which is called by the constructor) in the call stack, and this method also has STATIC LOCAL declarations. If I comment out this method call, the exception is risen by yet another method with static locals.
User avatar
robert
Posts: 4520
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Vulcan.NET: System.InvalidProgramException

Post by robert »

Mathias,
Vulcan is overdoing this imho.
Take the example

Code: Select all

CLASS Foo
   protect nIsDevelopment as LONG
   protect  oMemInfo as OBJECT
CONSTRUCTOR() 
   STATIC LOCAL lIsNewProc	:= TRUE AS LOGIC
   SUPER()
   SELF:nIsDevelopment := -1
   SELF:getInfo()
   SELF:oMemInfo := NULL_OBJECT	
METHOD GetInfo() as VOID
   RETURN	
END CLASS	

X# generates the following constructor code (the local is a so called REF local which points to the static field in the class)

Code: Select all

.method public hidebysig specialname rtspecialname 
	instance void .ctor () cil managed 
{
	// Method begins at RVA 0x20cc
	// Code size 36 (0x24)
	.maxstack 2
	.locals init (
		[0] bool&
	)

	IL_0000: nop
	IL_0001: ldsflda bool Foo::Xs$StaticLocal$ctor$lIsNewProc$0
	IL_0006: stloc.0
	IL_0007: ldarg.0
	IL_0008: call instance void [mscorlib]System.Object::.ctor()
	IL_000d: nop
	IL_000e: ldarg.0
	IL_000f: ldc.i4.m1
	IL_0010: stfld int32 Foo::nIsDevelopment
	IL_0015: ldarg.0
	IL_0016: callvirt instance void Foo::GetInfo()
	IL_001b: nop
	IL_001c: ldarg.0
	IL_001d: ldnull
	IL_001e: stfld object Foo::oMemInfo
	IL_0023: ret

and declares a field for the static local inside the same class which is initialized in the class constructor

Code: Select all

.field assembly static bool Xs$StaticLocal$ctor$lIsNewProc$0
.method private hidebysig specialname rtspecialname static 
	void .cctor () cil managed 
{
	// Method begins at RVA 0x2101
	// Code size 7 (0x7)
	.maxstack 8

	IL_0000: ldc.i4.1
	IL_0001: stsfld bool Foo::Xs$StaticLocal$ctor$lIsNewProc$0
	IL_0006: ret
} // end of method Foo::.cctor
Vulcan declares 2 fields (in the Functions class):

Code: Select all

.field assembly static specialname bool _StaticLocal_Foo__ctor_16_15_lIsNewProc
.field assembly static specialname class [VulcanRT]Vulcan.Internal.StaticLocalInitFlag '$$StaticLocal_InitFlag_$Foo$.ctor$:16:15$lIsNewProc'
and inside the constructor it then tries to check if the field has already been initialized and uses locking (Monitor:Enter) to prevent 2 threads from initializing the local at the same time:

Code: Select all

.method public hidebysig specialname rtspecialname 
	instance void .ctor () cil managed 
{
	// Method begins at RVA 0x20a4
	// Code size 139 (0x8b)
	.maxstack 13

	IL_0000: nop
	IL_0001: ldarg.0
	IL_0002: call instance void [mscorlib]System.Object::.ctor()
	IL_0007: nop
	IL_0008: nop
	IL_0009: ldsfld class [VulcanRT]Vulcan.Internal.StaticLocalInitFlag Application1.Exe.Functions::'$$StaticLocal_InitFlag_$Foo$.ctor$:16:15$lIsNewProc'
	IL_000e: call void [mscorlib]System.Threading.Monitor::Enter(object, bool&)
	.try
	{
		IL_0013: ldsfld class [VulcanRT]Vulcan.Internal.StaticLocalInitFlag Application1.Exe.Functions::'$$StaticLocal_InitFlag_$Foo$.ctor$:16:15$lIsNewProc'
		IL_0018: ldfld int16 [VulcanRT]Vulcan.Internal.StaticLocalInitFlag::State
		IL_001d: ldc.i4.0
		IL_001e: ceq
		IL_0020: brfalse IL_003b

		IL_0025: ldsfld class [VulcanRT]Vulcan.Internal.StaticLocalInitFlag Application1.Exe.Functions::'$$StaticLocal_InitFlag_$Foo$.ctor$:16:15$lIsNewProc'
		IL_002a: ldc.i4.2
		IL_002b: stfld int16 [VulcanRT]Vulcan.Internal.StaticLocalInitFlag::State
		IL_0030: ldc.i4.1
		IL_0031: stsfld bool Application1.Exe.Functions::_StaticLocal_Foo__ctor_16_15_lIsNewProc
		IL_0036: br IL_0053

		IL_003b: ldsfld class [VulcanRT]Vulcan.Internal.StaticLocalInitFlag Application1.Exe.Functions::'$$StaticLocal_InitFlag_$Foo$.ctor$:16:15$lIsNewProc'
		IL_0040: ldfld int16 [VulcanRT]Vulcan.Internal.StaticLocalInitFlag::State
		IL_0045: ldc.i4.2
		IL_0046: ceq
		IL_0048: brfalse IL_0053

		IL_004d: newobj instance void [VulcanRT]Vulcan.Internal.StaticLocalInitException::.ctor()
		IL_0052: throw

		IL_0053: leave IL_006a
	} // end .try
	finally
	{
		IL_0058: ldsfld class [VulcanRT]Vulcan.Internal.StaticLocalInitFlag Application1.Exe.Functions::'$$StaticLocal_InitFlag_$Foo$.ctor$:16:15$lIsNewProc'
		IL_005d: dup
		IL_005e: ldc.i4.1
		IL_005f: stfld int16 [VulcanRT]Vulcan.Internal.StaticLocalInitFlag::State
		IL_0064: call void [mscorlib]System.Threading.Monitor::Exit(object)
		IL_0069: endfinally
	} // end handler

	IL_006a: nop
	IL_006b: ldarg.0
	IL_006c: call instance void [mscorlib]System.Object::.ctor()
	IL_0071: nop
	IL_0072: nop
	IL_0073: ldarg.0
	IL_0074: ldc.i4.m1
	IL_0075: stfld int32 Foo::nIsDevelopment
	IL_007a: nop
	IL_007b: ldarg.0
	IL_007c: callvirt instance void Foo::GetInfo()
	IL_0081: nop
	IL_0082: nop
	IL_0083: ldarg.0
	IL_0084: ldnull
	IL_0085: stfld object Foo::oMemInfo
	IL_008a: ret
} // end of method Foo::.ctor
We only produce something that complicated when the default value of the static local is not a compile time constant.
That is why I suggested to first switch the compiler and then the runtime. Our compiler simply produces better code.

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
Kromi
Posts: 45
Joined: Wed Jan 13, 2016 8:31 am

Vulcan.NET: System.InvalidProgramException

Post by Kromi »

Robert,

thank you for this detailed clarification. I'll take it and discuss with the team if using the Vulcan runtime could be a intermediate step we want to go.

But even if we actually do that, it will be a process that takes months, and in the meantime I can't run the code.

Do you have any idea why code produced by the Vulcan compiler on my machine differs from that on other machines? It's the same version of Vulcan (4.0.401.0), it's the same code and the same project settings. Is it possible that for example a Windows update influences how the Vulcan compiler works? Or could the installation of Visual Studio 2019 have such an influence?

Mathias
Post Reply