ikvmnet / ikvm

A Java Virtual Machine and Bytecode-to-IL Converter for .NET
Other
1.22k stars 111 forks source link

ikvmc: fix -D flags unbalanced stack height crash #339

Closed Kojoley closed 1 year ago

Kojoley commented 1 year ago

This was working in 8.1.

I'm not familiar with testing system. a test could be simple ikvmc.exe -Da=b a.class call.

CLAassistant commented 1 year ago

CLA assistant check
All committers have signed the CLA.

wasabii commented 1 year ago

Hmm. Yeah, so that's a problem. This code was meant to be replaced when we moved to the new IKVM.Runtime.Launcher class, but only got slightly edited in that period. And ended up broken (which you've seen here).

I'm getting ready to resolve a few other Launcher-related bugs on the hotfix/8.5.1 branch. Namely that in 8.5.0, with the introduction of JVM.EnsureInitialize, and the removal of a number of IKVM-forked things (VMSystemProperties, etc), a bug was introduced that allowed access to Java classes without first going through JVM.EnsureInitialize when invoked as a library. So some i18n libraries could have been accessed without first having System properties populated.

I'm fixing this on the 8.5.1 branch by changing how JVM.EnsureInitialize is called. Instead of calling it through the static ctor of System, I'm moving the logic to a new static ctor of java.lang.Object, which will ensure that the JVM runs through it's initialize logic before the static ctor of any other class that inherits from java.lang.Object has a chance to run.

So, I haven't finished this work yet. But I realize now that you've submitted this PR, that it'll cause another problem: ikvm.runtime.Launcher extends java.lang.Object, and as such would cause JVM.EnsureInitialized to be invoked before the arguments are passed from ikvm.runtime.Launcher to IKVM.Runtime.Launcher. So VM.initializeSystemClass will end up being setup without the properties.

So this PR is going to have to be adjusted to account for the hotfix changes. Namely, it's going to need to directly invoke the new IKVM.Runtime.Launcher.Run method, which accepts a plain .NET dictionary, and not a java.util.Properties.

wasabii commented 1 year ago

@Kojoley By the way, if you're interested in having more in-depth conversations about what's ongoing, you should join the Discord. That tends to be where ad-hoc conversations and thinking happens.

Kojoley commented 1 year ago

Thanks for an invite but I don't think I have much interest in IKVM. It looks like Roslyn is vastly inferior to HotSpot, I see 6x performance difference which doesn't seem like it could be easily recovered.

wasabii commented 1 year ago

Ok.

Not sure I really understand. Roslyn is a C# compiler.

Kojoley commented 1 year ago

Not sure I really understand. Roslyn is a C# compiler.

It is the only good distinct name I know. It seems that the VM name is CLR, that's what I meant.

wasabii commented 1 year ago

Ahh. Well, .Net isn't 6 times slower then hotspot. It's faster at some stuff. Slower at other things.

Kojoley commented 1 year ago

Hmm, netcore3.1 build isn't using up-to-date VM too? I think I saw net461 build using VM from net6.

wasabii commented 1 year ago

IKVM is built targeting .NET Core 3.1. And the Java compatibility executables we distribute (java.exe, javac, etc) embed the .NET Core 3.1 runtime.

But IKVM itself can be used with any later framework version, all the way up to 8.

It's not unlike building a Java library targeting 8, but running it on some later JVM.

.NET 4.6.1 is for Framework. Last version of which was .NET 4.8.

Kojoley commented 1 year ago

I guess it will not be as easy as clicking retarget and selecting net8? (I'm asking about java.exe)

wasabii commented 1 year ago

I guess it will not be as easy as clicking retarget and selecting net8? (I'm asking about java.exe)

Might work fine for java.exe as that is a pure .NET application. Won't work for any of the other tools generated by IKVM.Net.SDK, as that can only produce executables targeting netcoreapp3.1. Until that is resolved, we can't release drops for later TFMs.

You can of course also just write your own .NET executable in C# that invokes Java code directly, and compile that targeting whatever TFM you want. That's as simple as creating a new C# project, installing the IKVM package, and adding a reference to some Java library, or calling classes in java.*, etc.

I'm going to go ahead and close this PR, since this approach isn't going to work with the code on the hotfix branch.