Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
341 commits
Select commit Hold shift + click to select a range
24d161e
SzArray register initializer
ds5678 Oct 15, 2025
823c9ed
Register initializers for multidimensional arrays
ds5678 Oct 15, 2025
d5141fc
Replace mscorlib references with System.Runtime
ds5678 Oct 15, 2025
a265484
Remove Cpp2IL projects
ds5678 Oct 15, 2025
d35a031
Method body analysis
ds5678 Oct 15, 2025
91562fd
Update global usings
ds5678 Oct 15, 2025
ab84547
Formatting
ds5678 Oct 15, 2025
72e99b2
Move extensions into their namespace
ds5678 Oct 15, 2025
53ae4c2
Rename StringExtensions
ds5678 Oct 15, 2025
a2bbd2e
Visitors namespace
ds5678 Oct 15, 2025
a886a9e
Fix compile errors
ds5678 Oct 15, 2025
bbea1e8
Move DictionaryExtensions
ds5678 Oct 15, 2025
886299f
Delete TypeBlittablility
ds5678 Oct 15, 2025
db2bc6c
Expand details about what still needs to be done
ds5678 Oct 15, 2025
14118a8
Don't emit bodies for abstract methods
ds5678 Oct 16, 2025
e89da98
Pointer constructors need runtime special name attribute
ds5678 Oct 16, 2025
2acd1a4
Initialize locals
ds5678 Oct 16, 2025
15fba91
Remove redundant runtime property
ds5678 Oct 16, 2025
bee0f5d
Implement IIl2CppType<> on IObject, IValueType, IEnum
ds5678 Oct 16, 2025
6e5dbd6
Implement Il2CppType<> on arrays
ds5678 Oct 16, 2025
54d6de3
Remove readonly from non-constant fields
ds5678 Oct 16, 2025
625eebf
Fix using callvirt on a struct method
ds5678 Oct 16, 2025
b3cc28b
Part 2 of previous commit
ds5678 Oct 16, 2025
8cd7e9c
Copy generic constraints
ds5678 Oct 16, 2025
3c0d7cb
Ignore unaligned instruction
ds5678 Oct 16, 2025
9e72e9a
Fix generic constant initialization
ds5678 Oct 16, 2025
b17473a
Resolve LocallocStackNotEmpty
ds5678 Oct 17, 2025
1a4deff
Resolve CallCtor
ds5678 Oct 17, 2025
84dfc2f
Resolve ThisMismatch
ds5678 Oct 17, 2025
70e372c
Formatting
ds5678 Oct 17, 2025
0c1d28a
Fix FallthroughException
ds5678 Oct 20, 2025
1cc9a28
Fix bad change of handler start
ds5678 Oct 20, 2025
5b99742
Remove bad type attributes
ds5678 Oct 20, 2025
1cedc46
Remove bad attributes from properties
ds5678 Oct 20, 2025
2405440
Interfaces have no base type
ds5678 Oct 21, 2025
bc43bbb
Temporary fix for interface base type not null
ds5678 Oct 21, 2025
6be642f
Add final method attribute
ds5678 Oct 21, 2025
545f049
Remove variance for generic parameters
ds5678 Oct 21, 2025
0e7615a
remove layout from non value types
ds5678 Oct 22, 2025
ead8192
Disable stable renaming
ds5678 Oct 22, 2025
2fd4dac
Implement invisible interfaces
ds5678 Oct 22, 2025
4fca91e
Move attributes to the common library
ds5678 Oct 22, 2025
56e46f9
Nullable common library
ds5678 Oct 22, 2025
25cecc8
Fix bug in ReferenceAssemblyInjectionProcessingLayer
ds5678 Oct 22, 2025
cb803eb
Treat multi dimensional arrays with rank 1 as sz arrays
ds5678 Oct 22, 2025
518cbbb
Improve ldfld unstripping
ds5678 Oct 24, 2025
0391664
Fix object overrides for generic value types
ds5678 Oct 24, 2025
93bab89
Fix generic instantiation in some methods
ds5678 Oct 24, 2025
05503b8
Fix unstripping ldflda for reference types
ds5678 Oct 24, 2025
b677a22
Add IObject as a constraint
ds5678 Oct 24, 2025
bd742b0
Fix invoke methods for object and enum
ds5678 Oct 24, 2025
56250be
Fix OutOfMemoryException for missing initializer
ds5678 Oct 24, 2025
2de9503
Add DefaultMemberAttribute to classes with indexers
ds5678 Oct 24, 2025
984dccd
Fix struct field as property in mock Il2Cppmscorlib
ds5678 Nov 2, 2025
061a77a
Remove pointless private constructor for static types
ds5678 Nov 2, 2025
1d8f076
Known type for IObject, IValueType, and IEnum
ds5678 Nov 2, 2025
d61800a
Filter out invalid constraints from initialization
ds5678 Nov 2, 2025
08accbc
Ensure no angle brackets in invoker methods
ds5678 Nov 22, 2025
b1208fa
Move MethodAnalysisContextExtensions
ds5678 Nov 22, 2025
528a65f
Use property accessors for Pointer<T> and ByReference<T> fields
ds5678 Nov 22, 2025
c31a8e6
Use an equality comparer in TypeConversionVisitor
ds5678 Nov 22, 2025
6caa891
Make clean renaming more robust
ds5678 Nov 22, 2025
8fb6736
Attempt to fix interface overrides
ds5678 Nov 23, 2025
bba18eb
Ensure injected methods are new slot
ds5678 Nov 23, 2025
7639040
Register initializers for Pointer<T> and ByReference<T>
ds5678 Nov 23, 2025
d784ea1
invalid field removal
ds5678 Nov 23, 2025
4939f8c
Ensure runtime type initialization in Il2Cpp types
ds5678 Nov 24, 2025
7576d9d
Bump to .NET 10
ds5678 Nov 24, 2025
9d305fc
Nullable annotations
ds5678 Nov 24, 2025
afb2aa5
Improve documentation
ds5678 Nov 24, 2025
6e8593a
Restructure Il2Cpp array inheritance
ds5678 Nov 24, 2025
c654c45
Output assemblies should reference .NET 10
ds5678 Nov 24, 2025
093a96c
Check for null pointers in ByReference<> and Pointer<>
ds5678 Nov 24, 2025
0a337ed
ThrowHelper class
ds5678 Nov 24, 2025
76290ec
Update Il2CppClassPointerStore
ds5678 Nov 24, 2025
eb929e5
Change DllImport to LibraryImport
ds5678 Nov 24, 2025
59a8fc3
Subtract 16 from field offsets
ds5678 Nov 24, 2025
8c2e675
Prevent duplicate initializer registration
ds5678 Nov 25, 2025
c135d09
Improve Il2CppSystem.Object finalizer
ds5678 Nov 25, 2025
7f709f8
Fix incorrect assembly names in initialization code
ds5678 Dec 4, 2025
9b61ea4
Add example for invalid field removal
ds5678 Dec 4, 2025
a5dbe01
Switch to AssetRipper.Cpp2IL.Core
ds5678 Dec 4, 2025
edde9b6
Replace method overrides
ds5678 Dec 4, 2025
10cecef
Improve interface override recovery
ds5678 Dec 4, 2025
16dd3d8
Attribute changes for HarmonySupport
ds5678 Dec 5, 2025
19063ae
Fix GetIl2CppGenericInstanceMethod
ds5678 Dec 5, 2025
d853dda
Fix ClassInjectorBase
ds5678 Dec 5, 2025
d67eb73
Initialize RuntimeType in GetIl2CppGenericInstanceType and GetIl2CppG…
ds5678 Dec 5, 2025
d19460b
Fix XrefInstanceExtensions
ds5678 Dec 5, 2025
d0fc6c8
Enforce Il2Cppmscorlib rules
ds5678 Dec 5, 2025
d85c3eb
Handle `void` type in GetNativeClassPointer method
ds5678 Dec 5, 2025
19f052e
Remove static constructors for Pointer and ByReference
ds5678 Dec 5, 2025
be57b84
Implement icalls
ds5678 Dec 6, 2025
864c512
Boolean explicit layout
ds5678 Dec 6, 2025
36b6dd1
Add helper class for rank 1 arrays
ds5678 Dec 9, 2025
1c074e0
Improve HarmonySupport (#2)
Atmudia Dec 11, 2025
8c14690
Parameter type validation in icall resolution
ds5678 Dec 11, 2025
71dd671
Fix bug in icall resolution
ds5678 Dec 11, 2025
1632f73
Fix crashing ClassInjector because wrong parameter (#6)
Atmudia Dec 11, 2025
b4498e3
Update rewrite status in Program.cs
ds5678 Dec 11, 2025
9aa9ac9
ICall improvements
ds5678 Dec 11, 2025
13976e8
Fix icall implementation
ds5678 Dec 12, 2025
2170631
Make GetFixedSizeStructType generate inline arrays of bytes
ds5678 Dec 12, 2025
656646c
Clear Culture, Version, PublicKey, and PublicKeyToken properties on a…
ds5678 Dec 12, 2025
f127f9d
Harmony support for non-blittable structs
ds5678 Dec 15, 2025
e81156f
Fix field offsets on 32 bit games
ds5678 Dec 15, 2025
a847839
Small refactor
ds5678 Dec 15, 2025
60d7469
Fix EmitConvertArgumentToManaged
ds5678 Dec 15, 2025
ebcf6ee
Fix version
ds5678 Dec 15, 2025
45bc377
Set Inherited and AllowMultiple on Il2Cpp attributes
ds5678 Dec 15, 2025
93e6471
Delete RegisterTypeOptions
ds5678 Dec 16, 2025
b1427d5
Delete ClassInjector.DerivedConstructorPointer
ds5678 Dec 16, 2025
1161e55
Move Il2CppInterfaceCollection to a new file
ds5678 Dec 16, 2025
b171dbf
Compile time check for IIl2CppType interface implementation
ds5678 Dec 16, 2025
88633ce
Delete Il2Cpp field types
ds5678 Dec 16, 2025
623de85
No hiding from Il2Cpp
ds5678 Dec 16, 2025
82ad3d8
Remove also initialize
ds5678 Dec 16, 2025
02cf6de
Remove some exception throws
ds5678 Dec 18, 2025
a4e88d6
Add documentation about unstripping
ds5678 Jan 2, 2026
34a82b1
Formatting
ds5678 Jan 5, 2026
028cde1
.NET 10 in CI
ds5678 Jan 5, 2026
2da975f
Use default calling convention for icalls instead of cdecl
ds5678 Apr 12, 2026
98e4072
Fix Finalize_ being protected not public for some types
ds5678 Apr 12, 2026
ce94d2d
Fix stackoverflow in Il2CppTypeHelper.Box<IObject>
ds5678 Apr 12, 2026
9163f2a
Unstripped abstract members should be made virtual
ds5678 Apr 12, 2026
11e28d3
Bump to latest Cpp2IL and AsmResolver
ds5678 Apr 13, 2026
5bb2b97
Simple fix for getting field offsets for unstripped constants
ds5678 Apr 13, 2026
df3a9b5
Don't unstrip types that interact with generics
ds5678 Apr 13, 2026
fa5ee4b
Remove Il2Cppmscorlib dll reference from HarmonySupport
ds5678 Apr 14, 2026
f479fd4
Remove unnecessary System.Net.Http package reference
ds5678 Apr 14, 2026
23e808a
Improve argument validation and simplify EnumInjector API
ds5678 Apr 14, 2026
9a3985f
NativeClassPtr -> NativeClassPointer
ds5678 Apr 14, 2026
7a9e019
Create a TypeInjector class to use during generation
ds5678 Apr 14, 2026
69c8646
Add GetFullyQualifiedName<T>() to Il2CppTypeHelper
ds5678 Apr 16, 2026
c4265b6
Don't unstrip any type that creates or implements an abstract generic…
ds5678 Apr 16, 2026
ab93226
Rename FieldAccessHelper and RuntimeInvokeHelper
ds5678 Apr 16, 2026
9797c13
Add default implemention to IIl2CppType.ObjectClass
ds5678 Apr 16, 2026
00b355e
Move IIl2CppValueType functionality to IValueType
ds5678 Apr 16, 2026
9ff2cfe
Move IIl2CppType to common library
ds5678 Apr 16, 2026
30a2019
Fix field offsets for reference types
ds5678 Apr 16, 2026
ed34d59
Use injected fields in Il2CppToMonoDelegateReference
ds5678 Apr 16, 2026
ee8c599
Support static methods in ClassInjector
ds5678 Apr 17, 2026
9747c43
InjectorHelpers.GetOrCreateImage
ds5678 Apr 17, 2026
9a27eb7
Update comments
ds5678 Apr 17, 2026
801a630
Fix DelegateSupport trampoline code generation
ds5678 Apr 19, 2026
3df7abd
Don't store a managed gc handle in injected classes
ds5678 Apr 19, 2026
a577528
Add il2cpp_raise_exception to IL2CPP.cs
ds5678 Apr 19, 2026
1366927
Don't generate unsafe static method helpers for abstract methods
ds5678 Apr 19, 2026
5b5f55b
Improve creation of IEnum
ds5678 Apr 20, 2026
0508c7e
Update conflict renaming to ensure a consistent result across all games
ds5678 Apr 20, 2026
29d0f78
Rename internal EnumInjector method
ds5678 Apr 20, 2026
d3bce9b
Update IIl2CppType<>:AssemblyName to use Assembly-CSharp as a default
ds5678 Apr 20, 2026
70f1c3a
Add Il2CppMethodInfo* to generated ClassInjector constructor
ds5678 Apr 20, 2026
d84c071
Simplified empty ctor creation
ds5678 Apr 20, 2026
93a40d8
Simplify String -> string conversion code
ds5678 Apr 20, 2026
1fbc1b9
Refactor some code in DelegateSupport
ds5678 Apr 21, 2026
9ef72a4
Make TrampolineHelpers.NativeType more accurate
ds5678 Apr 22, 2026
b4bcb3a
Remove attribute in DelegateSupport specifying a bad calling convention
ds5678 Apr 22, 2026
7a43bdf
Remove unused parameters in DelegateSupport
ds5678 Apr 22, 2026
43c5417
Fix native <-> managed type conversion in DelegateSupport
ds5678 Apr 22, 2026
981c2fc
Remove some bad type validation in DelegateSupport
ds5678 Apr 22, 2026
91850c9
Type injection
ds5678 Apr 22, 2026
d2c5885
Delete RuntimeReflectionHelper
ds5678 Apr 22, 2026
90d2514
Store class pointer for ByReference<> and Pointer<>
ds5678 Apr 22, 2026
fb6d682
Fix ICall generated delegate code
ds5678 Apr 22, 2026
a89ff9f
Conversions from Il2Cpp primitives to system primitives are implicit
ds5678 Apr 22, 2026
25c59b0
Check for null in Class_FromIl2CppType_Hook
ds5678 Apr 22, 2026
ed696d6
Assign tokens for injected classes and structs also
ds5678 Apr 22, 2026
dcbd8b0
Make Il2CppToMonoDelegateReference not nested
ds5678 Apr 22, 2026
abec119
Don't inject nested types
ds5678 Apr 22, 2026
838fb0f
Fix injected interfaces getting a constructor
ds5678 Apr 22, 2026
16b055b
Fix bad parameter wrapping
ds5678 Apr 22, 2026
d626588
Fix by reference types in TrampolineHelpers
ds5678 Apr 22, 2026
95d3fc5
Fix infinite loop in unstripping
ds5678 Apr 22, 2026
9933b35
Ensure structs have a large enough vtable allocated
ds5678 Apr 22, 2026
0cf4087
Il2CppTypePointerStore
ds5678 Apr 22, 2026
3de6379
Cleanup DelegateSupport
ds5678 Apr 22, 2026
f8b4e49
Refactor Class_FromIl2CppType_Hook
ds5678 Apr 22, 2026
94de139
Bump package versions
ds5678 Apr 22, 2026
dab354e
Fix method attributes for object overrides on value types
ds5678 Apr 25, 2026
9e59edd
Include parent classes when creating hash dictionaries in type injection
ds5678 Apr 25, 2026
95a2aab
Fix field injection for value types
ds5678 Apr 25, 2026
37fe2e1
Do not try to init injected classes
ds5678 Apr 25, 2026
f25723d
Actually inject fields
ds5678 Apr 25, 2026
8c8ed3d
Make generated code more robust against null pointers
ds5678 Apr 26, 2026
e58110b
Refactor Il2CppInteropUtils
ds5678 Apr 26, 2026
9af3528
Create a class for assembly injection
ds5678 Apr 26, 2026
b785ef2
Create a generation internals class
ds5678 Apr 26, 2026
c68afe9
Improve unstripping of the throw instruction
ds5678 Apr 26, 2026
f263459
Move methods to GenerationInternals
ds5678 Apr 26, 2026
d72ba86
Move MemoryUtils to injection namespace
ds5678 Apr 26, 2026
1b64683
Delete ThrowHelper
ds5678 Apr 26, 2026
d68564e
Register Il2CppToMonoDelegateReference with object pool
ds5678 Apr 26, 2026
87dceb9
Remove Il2CppType class
ds5678 Apr 26, 2026
09a1e8f
Move exceptions into their namespace
ds5678 Apr 26, 2026
a8e225e
Rename Il2CppTypeHelper to Il2CppType
ds5678 Apr 26, 2026
9307d03
Move RuntimeConfiguration to its own file
ds5678 Apr 26, 2026
5290291
Fix nullable warnings for startup classes
ds5678 Apr 26, 2026
5cdf034
Set .ValueType in TypeInjector
ds5678 Apr 26, 2026
04257ef
Make IndexerAttributeInjectionProcessingLayer more robust
ds5678 Apr 26, 2026
16c46e9
Fix exception hierarchy regression
ds5678 Apr 26, 2026
a92ff62
Fix assembly names not having dll extension
ds5678 Apr 26, 2026
98b5902
Support multiple platforms
ds5678 Apr 27, 2026
184c608
Stripped Code Registration Support
ds5678 Apr 27, 2026
288305f
Fix nullable annotations in Il2CppArrayRank1<> conversions
ds5678 Apr 27, 2026
c793c94
Delete MiniILParser
ds5678 Apr 27, 2026
98428c9
Move AssemblyExtensions to the Runtime project
ds5678 Apr 27, 2026
52bde59
Move InternalsVisibleTo from AssemblyInfo.cs to csproj
ds5678 Apr 28, 2026
669fd88
Convert struct generator from library to CLI
ds5678 Apr 28, 2026
584e31e
Update class initialization
ds5678 Apr 29, 2026
22ee721
Update TrampolineHelpers.NativeType to only use pinvoke for value types
ds5678 Apr 29, 2026
6da9c06
Add source generation attributes
ds5678 Apr 30, 2026
219401d
Use init properties for attributes
ds5678 Apr 30, 2026
c4b5c6d
Remove unnecessary RootNamespace properties
ds5678 Apr 30, 2026
6ab5fb7
Make ByReference<> and Pointer<> readonly
ds5678 Apr 30, 2026
3091782
Add more IIl2CppType<> implementations to the Il2Cppmscorlib stub
ds5678 Apr 30, 2026
0808bff
Fix bug in previous commit
ds5678 Apr 30, 2026
85384b8
Use AssetRipper.Primitives in struct generator
ds5678 Apr 30, 2026
924ee54
Remove ClangSharp from struct generator
ds5678 Apr 30, 2026
e1e2404
Fix IIl2CppType<>.AssemblyName not including the dll extension by def…
ds5678 Apr 30, 2026
ede5898
Use AssetRipper.Primitives for UnityVersion
ds5678 Apr 30, 2026
4cb3d92
Delete extra ParameterInfo methods
ds5678 May 1, 2026
fd43546
Change ParameterInfo version suffixes
ds5678 May 1, 2026
9c983c0
Block scoped namespace for ParameterInfo
ds5678 May 1, 2026
27a5195
Delete static HasNamePosToken
ds5678 May 1, 2026
c411b8b
Refactor ParameterInfo to be more like generated types
ds5678 May 1, 2026
8b60a48
Update struct generator to use headers from https://github.com/nneonn…
ds5678 May 1, 2026
6c22090
Run struct generator
ds5678 May 1, 2026
2b5f45d
Move ElementProtection
ds5678 May 1, 2026
2389ef0
Move EnumUnderlyingType and CodeGenEnumElement into their own files
ds5678 May 1, 2026
5f450a8
Struct generator performance improvements
ds5678 May 1, 2026
0c671e6
Make CodeGenEnumElement a record struct
ds5678 May 1, 2026
1bc4112
Switch struct generator from StringBuilder to IndentedTextWriter
ds5678 May 1, 2026
635230b
Cleanup comments in struct generator
ds5678 May 1, 2026
74e14ba
Cleanup Il2CppStructWrapperGenerator
ds5678 May 1, 2026
706b4ad
Move types to their own files
ds5678 May 1, 2026
e663508
Move Config and ConversionUtils
ds5678 May 1, 2026
d137406
Use collection expressions in struct generator
ds5678 May 1, 2026
1967103
Fix nullable warnings in struct generator
ds5678 May 1, 2026
31a34b1
Delete AddExtraUsing
ds5678 May 1, 2026
d28b306
Remove unused dependency resolution from struct generation
ds5678 May 1, 2026
09415ab
Remove use of Activator.CreateInstance from struct generator
ds5678 May 1, 2026
9afc01d
Formatting
ds5678 May 1, 2026
1ef0f9a
Make CodeGenParameter a record struct
ds5678 May 1, 2026
f401d5e
Move ByRefWrapper to its own file
ds5678 May 1, 2026
dabfd40
Small performance improvement
ds5678 May 1, 2026
3cef1fc
Replace IntPtr and UIntPtr with their keywords
ds5678 May 1, 2026
653e1cb
CodeGenType
ds5678 May 1, 2026
d26f706
Block-scoped namespace for interfaces
ds5678 May 1, 2026
29928df
implement source generator for Il2Cpp type definitions (#9)
Atmudia May 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
30 changes: 27 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,29 @@ insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
end_of_line = lf

# Generated code
[*{_AssemblyInfo.cs,.notsupported.cs,AsmOffsets.cs}]
generated_code = true
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
end_of_line = lf
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion

# C# files
[*.cs]
Expand Down Expand Up @@ -54,15 +73,15 @@ dotnet_style_predefined_type_for_member_access = true:suggestion
# name all constant fields using PascalCase
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_style.pascal_case_style.capitalization = pascal_case

# static fields should have s_ prefix
dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
dotnet_naming_symbols.static_fields.applicable_kinds = field
dotnet_naming_symbols.static_fields.required_modifiers = static
dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
Expand All @@ -72,7 +91,7 @@ dotnet_naming_style.static_prefix_style.capitalization = camel_case
# internal and private fields should be _camelCase
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
Expand Down Expand Up @@ -150,6 +169,11 @@ csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent
csharp_style_prefer_primary_constructors = true:suggestion
csharp_prefer_system_threading_lock = true:suggestion

# C++ Files
[*.{cpp,h,in}]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
dotnet-version: 10.0.x

- name: Extract Release Version
id: get_version
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/format_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
dotnet-version: 10.0.x

- name: Check format
run: |
Expand Down
1 change: 0 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
<LangVersion>latest</LangVersion>
<Nullable>disable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RootNamespace>Il2CppInterop</RootNamespace>
<LangVersion>latest</LangVersion>
<PackageIcon>logo_icon.png</PackageIcon>
<PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression>
Expand Down
10 changes: 10 additions & 0 deletions Documentation/Design/Arrays.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Arrays

## Array Types

Il2Cpp arrays are represented with a closed type hierarchy.

* `Il2CppArrayBase`
* `Il2CppArrayBase<T>`

`Il2CppArrayBase<T>` is the type used everywhere. `Il2CppArrayBase` is just for unstripping certain op codes.
3 changes: 3 additions & 0 deletions Documentation/Design/Attributes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Attributes

Attributes are not applied to types.
187 changes: 187 additions & 0 deletions Documentation/Design/CorLibTypes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
# Core Library Types

## Numeric Primitives, `char`, and `bool`

These are blittable and should be directly reused, kind of. Signatures will use the Il2Cpp types, but implicit conversions will be used inside unstripped method bodies.

```cs
public static Il2CppSystem.Int32 Add(Il2CppSystem.Int32 x, Il2CppSystem.Int32 y)
{
// Conversions to Managed are applied on function entry
ref
int x2 = (int)x;
int y2 = (int)y;

// All operations are done with managed types
int z = x2 + y2;

// If an Il2Cpp primitive must be returned, conversion back is applied right before the return instruction.
return (Il2CppSystem.Int32)z;
}
```

This ensures that CIL opcodes function as expected. However, it can cause some complexities with instance methods on the corlib types. For that, unsafe helpers are used.

```cs
public static Il2CppSystem.String Sum(Il2CppSystem.Int32 x, Il2CppSystem.Int32 y)
{
int z = (int)x + (int)y;
return Unsafe.As<int, Il2CppSystem.Int32>(ref z).ToString();
}
```

## `string`

Strings should not be implicitly marshalled. In other words, `Il2CppSystem.String` should be used.

## `object`

For compatibility with interfaces and value types, this should be emitted as-is, despite the more complicated marshalling involved.

## `Attribute`

## `ValueType` and `Enum`

Boxing to these types is invalid.

## `Exception`

## Counterargument to all of the above

```cs
// Original code
public static void DoSomething<T>(T value) where T : System.IConvertible
{
}
public static void DoSomethingElse()
{
DoSomething<System.Enum>(System.StringComparison.Ordinal);
DoSomething<System.StringComparison>(default);
DoSomething<int>(default);
}

// Unstripped code
public static void DoSomething<T>() where T : Il2CppSystem.IConvertible
{
}
public static void DoSomethingElse()
{
// Which is correct?
// System.Enum fails the constraint check.
// Il2CppSystem.Enum makes the method unusable because boxed enums inherit from `System.Enum` not `Il2CppSystem.Enum`.
DoSomething<System.Enum>(Il2CppSystem.StringComparison.Ordinal);
DoSomething<Il2CppSystem.Enum>(Il2CppSystem.StringComparison.Ordinal);
DoSomething<Il2CppSystem.Enum>(Cast(Il2CppSystem.StringComparison.Ordinal)); // Maybe this is the way it should be emitted?

// If the type is a real enum, it fails the constraint check.
DoSomething<Il2CppSystem.StringComparison>(default);

// Which is correct?
// int fails the constraint check, but is what we currently do.
DoSomething<int>(default);
DoSomething<Il2CppSystem.Int32>(default);
}
private static Il2CppSystem.Enum Cast(object value)
{
if (value is Il2CppSystem.Enum il2cppEnum)
{
return il2cppEnum;
}
if (value is System.Enum sysEnum)
{
throw new NotImplementedException("Cannot cast System.Enum to Il2CppSystem.Enum");
}
throw new InvalidCastException("Cannot cast to Il2CppSystem.Enum");
}

// Proposal
public static void DoSomething<T>() where T : Il2CppSystem.IConvertible
{
}
public static void DoSomethingElse()
{
DoSomething<Il2CppSystem.IEnum>(Il2CppSystem.StringComparison.Ordinal);
DoSomething<Il2CppSystem.StringComparison>(default);
DoSomething<Il2CppSystem.Int32>(default);
}
namespace Il2CppSystem
{
public interface IObject
{
// Instance members of Il2CppSystem.Object
}
public interface IValueType : IObject
{
// No members
}
public interface IEnum : IValueType, Il2CppSystem.IComparable, Il2CppSystem.IFormattable, Il2CppSystem.IConvertible
{
// Instance members of Il2CppSystem.Enum, except for interface implementations
}
public class Object : IObject
{
// A static method should be generated for each instance method
}
public abstract class ValueType : Object, IValueType
{
// A static method should be generated for each instance method
}
public abstract class Enum : ValueType, IEnum
{
// A static method should be generated for each instance method
}
public readonly struct StringComparison : IEnum // Maybe inject other interfaces like System.IEquatable<> for user convenience
{
// [System.Flags] // Only if the Il2Cpp enum has the Flags attribute
private enum __Internal
{
CurrentCulture = 0,
CurrentCultureIgnoreCase = 1,
InvariantCulture = 2,
InvariantCultureIgnoreCase = 3,
Ordinal = 4,
OrdinalIgnoreCase = 5
}

// Might make this `int` instead. The only reason to use `__Internal` is to have a more efficient ToString implementation.
private readonly __Internal value__;

// Sacrifice the ability to use Il2Cpp enums in constants.
public static readonly StringComparison CurrentCulture = new StringComparison(__Internal.CurrentCulture);
public static readonly StringComparison CurrentCultureIgnoreCase = new StringComparison(__Internal.CurrentCultureIgnoreCase);
public static readonly StringComparison InvariantCulture = new StringComparison(__Internal.InvariantCulture);
public static readonly StringComparison InvariantCultureIgnoreCase = new StringComparison(__Internal.InvariantCultureIgnoreCase);
public static readonly StringComparison Ordinal = new StringComparison(__Internal.Ordinal);
public static readonly StringComparison OrdinalIgnoreCase = new StringComparison(__Internal.OrdinalIgnoreCase);

private StringComparison(__Internal value) => value__ = value;
public StringComparison(int value) => value__ = unchecked((__Internal)value);
public static explicit operator int(StringComparison value) => unchecked((int)value.value__);
public static explicit operator StringComparison(int value) => new StringComparison(value);

// Numerical operators like shift

// Override ToString, GetHashCode, Equals, etc.
public override int GetHashCode()
{
// Use the static method from Il2CppSystem.Enum
// We need to ensure that behavior is consistent with the native method.
return Il2CppSystem.Enum.GetHashCode(this);
}

static StringComparison()
{
// OriginalNameAttribute no longer needed.
}
}
public interface ICloneable : IObject, System.ICloneable
{
IObject Clone();

object System.ICloneable.Clone()
{
return Clone();
}
}
}
```
3 changes: 3 additions & 0 deletions Documentation/Design/Delegates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Delegates

All Il2Cpp delegates have a generated conversion to a system delegate, which might be generated if necessary.
29 changes: 29 additions & 0 deletions Documentation/Design/Enums.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Enums

Enums are converted to readonly structs.

```cs
// Original
public enum ElectricityType
{
Off = 0,
On = 1
}

// Converted
public struct ElectricityType : IObject, IValueType, IEnum, IComparable, IFormattable, IConvertible
{
private readonly Int32 value__;

public static readonly ElectricityType Off = (ElectricityType)0;
public static readonly ElectricityType On = (ElectricityType)1;
}
```

## Generic constraint

`Il2CppSystem.Enum` should be replaced with `Il2CppSystem.IEnum` in generic constraints.

## Interfaces

Additional interfaces like `IEquatable<>`, `IEqualityOperators<,,>`, and `IBitwiseOperators<,,>` could be introduced for user convenience.
7 changes: 7 additions & 0 deletions Documentation/Design/Exceptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Exceptions

Il2Cpp exceptions each have a cooresponding system exception generated, making up a full hierarchy and enabling try catch support in unstripped code.

## Runtime exceptions

Unstripped code currently allows exceptions (such as `NullReferenceException`) to be thrown by the .NET runtime. Ideally, all such exceptions would be handled.
19 changes: 19 additions & 0 deletions Documentation/Design/Fields.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Fields

## Generated code

```cs
// Reference type
public FieldType fieldName
{
get => throw null;
set => throw null;
}
public static ByReference<FieldType> UnsafeField_fieldName(Class obj) => throw null;
private static readonly IntPtr FieldInfoPtr_fieldIndex;

// Value type
public FieldType fieldName;
public static ByReference<FieldType> UnsafeField_fieldName(ByRerefence<Struct> obj) => throw null;
private static readonly IntPtr FieldInfoPtr_fieldIndex;
```
22 changes: 22 additions & 0 deletions Documentation/Design/GenericMethods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generic Methods

## Pointers

Pointers are resolved as needed using Il2Cpp reflection. It's fine to do this initialization lazily because all generic type instances are known in advance.

```cs
private static class MethodInfoStoreGeneric_Aggregate<TSource, TAccumulate>
{
internal static System.IntPtr Pointer = IL2CPP.il2cpp_method_get_from_reflection(IL2CPP.Il2CppObjectBaseToPtrNotNull(new MethodInfo(IL2CPP.il2cpp_method_get_object(NativeMethodInfoPtr_Aggregate, Il2CppClassPointerStore<Enumerable>.NativeClassPtr))
.MakeGenericMethod(new Il2CppReferenceArray<Type>(new Type[2]
{
Type.internal_from_handle(IL2CPP.il2cpp_class_get_type(Il2CppClassPointerStore<TSource>.NativeClassPtr)),
Type.internal_from_handle(IL2CPP.il2cpp_class_get_type(Il2CppClassPointerStore<TAccumulate>.NativeClassPtr))
}))));
}
```

If a modder tries to use a generic method instantiation that doesn't exist, an exception is thrown.

* <https://github.com/dreamanlan/il2cpp_ref/blob/09316fe508773b8ced098dae6147b44ee1f6516c/libil2cpp/icalls/mscorlib/System.Reflection/MonoMethod.cpp#L253>
* <https://github.com/dreamanlan/il2cpp_ref/blob/09316fe508773b8ced098dae6147b44ee1f6516c/libil2cpp/icalls/mscorlib/System.Reflection/MonoMethod.cpp#L305>
10 changes: 10 additions & 0 deletions Documentation/Design/GenericTypes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Generic Types

```cs
Il2CppClassPointerStore<Dictionary<TKey, TValue>>.NativeClassPtr = IL2CPP.il2cpp_class_from_type(Type.internal_from_handle(IL2CPP.il2cpp_class_get_type(IL2CPP.GetIl2CppClass("mscorlib.dll", "System.Collections.Generic", "Dictionary`2"))).MakeGenericType(new Il2CppReferenceArray<Type>(new Type[2]
{
Type.internal_from_handle(IL2CPP.il2cpp_class_get_type(Il2CppClassPointerStore<TKey>.NativeClassPtr)),
Type.internal_from_handle(IL2CPP.il2cpp_class_get_type(Il2CppClassPointerStore<TValue>.NativeClassPtr))
})).TypeHandle.value);
IL2CPP.il2cpp_runtime_class_init(Il2CppClassPointerStore<Dictionary<TKey, TValue>>.NativeClassPtr);
```
Loading
Loading