Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What
"Method unstripping failed"
(I.e. there are a few methods that now fail to unstrip, but they crashed the CLR anyway due to faulty IL)
Why
I'm creating a Il2Cpp plugin for Dave the Diver and wanted to use IMGUI, and came across a few
"Method unstripping failed"
.So I set out to find the reason why those methods I needed didn't work and this is the result.
Translation logging
"Method unstripping failed"
is a very opaque error.This PR adds logging (to disk only) to the translation process describing why a method couldn't be translated:
The logging is saved as a
.json.gz
in theoutput
's parent folder.(I.e. it is saved in the same folder that BepInEx saves
LogOutput.log
)I choose json because it is very easy to use tools such as
jq
to query the rather large amount of methods that can't be translated currently.Examples
Excerpt
Logs from my development
The entire log file before I made any fixes/changes: unstrip_original.json.gz
Summary of error categories:
The entire log file with all commits in this PR: unstrip.json.gz
Summary of error categories:
These logs are of course very specific to the game and Unity version I've been using, but they document the progress that I've made.
Results
Il2CppInterop now correctly translates the IMGUI methods I need in Dave The Diver v1.0.0.1055.steam!
That were the metrics I went by atleast, but there's a whole slew of methods that now work correctly, including:
string
was used for aSystem.Object
parameter.(E.g. any method calling
Debug.Log
and associates)System.Object
is (and was) translated intoIl2CppSystem.Object
, butstring
is obviously not such an object.A
Il2CppSystem.String::op_Implicit(string)
is injected after the instruction responsible for thestring
stack object.Very common, as string concatenation using
+
is compiled into this.E.g.
"test" + 1 + "array"
becomes:string.Concat(new string[] {[0] = "test", [1] = 1.ToString(), [2] = "array"})
The
setelem
instruction family only works an actual arrays (e.g.string[]
), but all arrays are translated into one ofIl2CppReferenceArray<T>
Il2CppStructArray<T>
Il2CppStringArray
Thus
setelem
should be translated intocallvirt instance Il2CppBaseArray<T>::set_Item(int, T)
Even if we correctly construct an
Il2CppStringArray
and correctly fill it with items,string.Concat(string[])
still takes astring[]
.Fixed by translating method calls on primitive and string types to redirect them to the Il2Cpp equivalent, e.g:
Il2CppSystem.String.Concat(Il2CppStringArray)
Additionally, I've added some
box
/unbox
support,ld(s)flda
support, and branch retargeting tracking.The branch retargeting was mostly working before, but it was mostly coincidental.
This PR allows branch targets to be a completely different instruction (which is very common due to the processes being a translation), and it allows us to emit/insert more that one instruction in the new method and still keep the branches intact.
I more than welcome any comments, as I have many assumptions on how the library is supposed to work!