Created
December 13, 2015 22:21
-
-
Save kornman00/535d77fc303dc1ae7411 to your computer and use it in GitHub Desktop.
Code Listings for Seeing Sharp C++: Behind the IL2CPP magic of Metadata and Statics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace SharpCpp | |
{ | |
public struct ValueTypeWithCctor | |
{ | |
public int Value; | |
// Comment this out and the CPP code for operator+ won't have a prologue nor invoke IL2CPP_RUNTIME_CLASS_INIT. | |
// This causes a hidden cctor to be generated by the compiler. | |
// Defined after the X, Y fields as their lexical order impacts their order in metadata, thus impacting codegen, making diff'ing less friendly | |
public static readonly ValueTypeWithCctor One = new ValueTypeWithCctor(1); | |
public ValueTypeWithCctor(int value) | |
{ | |
Value = value; | |
} | |
// This will result in class initialization glue | |
public static ValueTypeWithCctor operator +(ValueTypeWithCctor v1, ValueTypeWithCctor v2) | |
{ | |
return Add(v1, v2); | |
} | |
// This WON'T result in class initialization glue | |
public static ValueTypeWithCctor Add(ValueTypeWithCctor v1, ValueTypeWithCctor v2) | |
{ | |
return new ValueTypeWithCctor(v1.Value + v2.Value); | |
} | |
public override string ToString() | |
{ | |
return Value.ToString("X8"); | |
} | |
}; | |
public struct ValueTypeWithoutCctor | |
{ | |
public int Value; | |
public static ValueTypeWithoutCctor One { get { return new ValueTypeWithoutCctor(1); } } | |
public ValueTypeWithoutCctor(int value) | |
{ | |
Value = value; | |
} | |
public static ValueTypeWithoutCctor operator +(ValueTypeWithoutCctor v1, ValueTypeWithoutCctor v2) | |
{ | |
return Add(v1, v2); | |
} | |
public static ValueTypeWithoutCctor Add(ValueTypeWithoutCctor v1, ValueTypeWithoutCctor v2) | |
{ | |
return new ValueTypeWithoutCctor(v1.Value + v2.Value); | |
} | |
public override string ToString() | |
{ | |
return Value.ToString("X8"); | |
} | |
}; | |
public static partial class SharpCode | |
{ | |
public static void Il2Cpp_ValueTypeWithCctor() | |
{ | |
var v0 = new ValueTypeWithCctor(0); | |
var v1 = ValueTypeWithCctor.One; | |
var a = v0 + v1; | |
/*var b = */ValueTypeWithCctor.Add(v0, a); | |
} | |
public static void Il2Cpp_ValueTypeWithoutCctor() | |
{ | |
var v0 = new ValueTypeWithoutCctor(0); | |
var v1 = ValueTypeWithoutCctor.One; | |
var a = v0 + v1; | |
/*var b = */ValueTypeWithoutCctor.Add(v0, a); | |
} | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define IL2CPP_RUNTIME_CLASS_INIT(klass) do { if((klass)->has_cctor && !(klass)->cctor_finished) il2cpp::vm::Runtime::ClassInit ((klass)); } while (0) | |
// System.Void SharpCpp.ValueTypeWithCctor::.ctor(System.Int32) | |
extern "C" void ValueTypeWithCctor__ctor_m6_12 (ValueTypeWithCctor_t6_11 * __this, int32_t ___value, const MethodInfo* method) | |
{ | |
{ | |
int32_t L_0 = ___value; | |
__this->___Value_0 = L_0; | |
return; | |
} | |
} | |
// System.Void SharpCpp.ValueTypeWithCctor::.cctor() | |
extern TypeInfo* ValueTypeWithCctor_t6_11_il2cpp_TypeInfo_var; | |
extern "C" void ValueTypeWithCctor__cctor_m6_13 (Object_t * __this /* static, unused */, const MethodInfo* method) | |
{ | |
static bool s_Il2CppMethodIntialized; | |
if (!s_Il2CppMethodIntialized) | |
{ | |
ValueTypeWithCctor_t6_11_il2cpp_TypeInfo_var = il2cpp_codegen_type_info_from_index(912); | |
s_Il2CppMethodIntialized = true; | |
} | |
{ | |
ValueTypeWithCctor_t6_11 L_0 = {0}; | |
ValueTypeWithCctor__ctor_m6_12(&L_0, 1, /*hidden argument*/NULL); | |
((ValueTypeWithCctor_t6_11_StaticFields*)ValueTypeWithCctor_t6_11_il2cpp_TypeInfo_var->static_fields)->___One_1 = L_0; | |
return; | |
} | |
} | |
// SharpCpp.ValueTypeWithCctor SharpCpp.ValueTypeWithCctor::Add(SharpCpp.ValueTypeWithCctor,SharpCpp.ValueTypeWithCctor) | |
extern "C" ValueTypeWithCctor_t6_11 ValueTypeWithCctor_Add_m6_14 (Object_t * __this /* static, unused */, ValueTypeWithCctor_t6_11 ___v1, ValueTypeWithCctor_t6_11 ___v2, const MethodInfo* method) | |
{ | |
{ | |
int32_t L_0 = ((&___v1)->___Value_0); | |
int32_t L_1 = ((&___v2)->___Value_0); | |
ValueTypeWithCctor_t6_11 L_2 = {0}; | |
ValueTypeWithCctor__ctor_m6_12(&L_2, ((int32_t)((int32_t)L_0+(int32_t)L_1)), /*hidden argument*/NULL); | |
return L_2; | |
} | |
} | |
// System.String SharpCpp.ValueTypeWithCctor::ToString() | |
extern Il2CppCodeGenString* _stringLiteral135; | |
extern "C" String_t* ValueTypeWithCctor_ToString_m6_15 (ValueTypeWithCctor_t6_11 * __this, const MethodInfo* method) | |
{ | |
static bool s_Il2CppMethodIntialized; | |
if (!s_Il2CppMethodIntialized) | |
{ | |
_stringLiteral135 = il2cpp_codegen_string_literal_from_index(135); | |
s_Il2CppMethodIntialized = true; | |
} | |
{ | |
int32_t* L_0 = &(__this->___Value_0); | |
String_t* L_1 = Int32_ToString_m1_65(L_0, _stringLiteral135, /*hidden argument*/NULL); | |
return L_1; | |
} | |
} | |
// SharpCpp.ValueTypeWithCctor SharpCpp.ValueTypeWithCctor::op_Addition(SharpCpp.ValueTypeWithCctor,SharpCpp.ValueTypeWithCctor) | |
extern TypeInfo* ValueTypeWithCctor_t6_11_il2cpp_TypeInfo_var; | |
extern "C" ValueTypeWithCctor_t6_11 ValueTypeWithCctor_op_Addition_m6_16 (Object_t * __this /* static, unused */, ValueTypeWithCctor_t6_11 ___v1, ValueTypeWithCctor_t6_11 ___v2, const MethodInfo* method) | |
{ | |
static bool s_Il2CppMethodIntialized; | |
if (!s_Il2CppMethodIntialized) | |
{ | |
ValueTypeWithCctor_t6_11_il2cpp_TypeInfo_var = il2cpp_codegen_type_info_from_index(912); | |
s_Il2CppMethodIntialized = true; | |
} | |
{ | |
ValueTypeWithCctor_t6_11 L_0 = ___v1; | |
ValueTypeWithCctor_t6_11 L_1 = ___v2; | |
IL2CPP_RUNTIME_CLASS_INIT(ValueTypeWithCctor_t6_11_il2cpp_TypeInfo_var); | |
ValueTypeWithCctor_t6_11 L_2 = ValueTypeWithCctor_Add_m6_14(NULL /*static, unused*/, L_0, L_1, /*hidden argument*/NULL); | |
return L_2; | |
} | |
} | |
// System.Void SharpCpp.SharpCode::Il2Cpp_ValueTypeWithCctor() | |
extern TypeInfo* ValueTypeWithCctor_t6_11_il2cpp_TypeInfo_var; | |
extern "C" void SharpCode_Il2Cpp_ValueTypeWithCctor_m6_22 (Object_t * __this /* static, unused */, const MethodInfo* method) | |
{ | |
static bool s_Il2CppMethodIntialized; | |
if (!s_Il2CppMethodIntialized) | |
{ | |
ValueTypeWithCctor_t6_11_il2cpp_TypeInfo_var = il2cpp_codegen_type_info_from_index(912); | |
s_Il2CppMethodIntialized = true; | |
} | |
ValueTypeWithCctor_t6_11 V_0 = {0}; | |
ValueTypeWithCctor_t6_11 V_1 = {0}; | |
ValueTypeWithCctor_t6_11 V_2 = {0}; | |
{ | |
ValueTypeWithCctor__ctor_m6_12((&V_0), 0, /*hidden argument*/NULL); | |
IL2CPP_RUNTIME_CLASS_INIT(ValueTypeWithCctor_t6_11_il2cpp_TypeInfo_var); | |
ValueTypeWithCctor_t6_11 L_0 = ((ValueTypeWithCctor_t6_11_StaticFields*)ValueTypeWithCctor_t6_11_il2cpp_TypeInfo_var->static_fields)->___One_1; | |
V_1 = L_0; | |
ValueTypeWithCctor_t6_11 L_1 = V_0; | |
ValueTypeWithCctor_t6_11 L_2 = V_1; | |
ValueTypeWithCctor_t6_11 L_3 = ValueTypeWithCctor_op_Addition_m6_16(NULL /*static, unused*/, L_1, L_2, /*hidden argument*/NULL); | |
V_2 = L_3; | |
ValueTypeWithCctor_t6_11 L_4 = V_0; | |
ValueTypeWithCctor_t6_11 L_5 = V_2; | |
ValueTypeWithCctor_Add_m6_14(NULL /*static, unused*/, L_4, L_5, /*hidden argument*/NULL); | |
return; | |
} | |
} | |
// From vm/Runtime.cpp: | |
// We currently call Runtime::ClassInit in 4 places: | |
// 1. Just after we allocate storage for a new object (Object::NewAllocSpecific) | |
// 2. Just before reading any static field | |
// 3. Just before calling any static method | |
// 4. Just before calling class instance constructor from a derived class instance constructor | |
void Runtime::ClassInit (TypeInfo *klass); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// System.Void SharpCpp.ValueTypeWithoutCctor::.ctor(System.Int32) | |
extern "C" void ValueTypeWithoutCctor__ctor_m6_17 (ValueTypeWithoutCctor_t6_12 * __this, int32_t ___value, const MethodInfo* method) | |
{ | |
{ | |
int32_t L_0 = ___value; | |
__this->___Value_0 = L_0; | |
return; | |
} | |
} | |
// SharpCpp.ValueTypeWithoutCctor SharpCpp.ValueTypeWithoutCctor::get_One() | |
extern "C" ValueTypeWithoutCctor_t6_12 ValueTypeWithoutCctor_get_One_m6_18 (Object_t * __this /* static, unused */, const MethodInfo* method) | |
{ | |
{ | |
ValueTypeWithoutCctor_t6_12 L_0 = {0}; | |
ValueTypeWithoutCctor__ctor_m6_17(&L_0, 1, /*hidden argument*/NULL); | |
return L_0; | |
} | |
} | |
// SharpCpp.ValueTypeWithoutCctor SharpCpp.ValueTypeWithoutCctor::Add(SharpCpp.ValueTypeWithoutCctor,SharpCpp.ValueTypeWithoutCctor) | |
extern "C" ValueTypeWithoutCctor_t6_12 ValueTypeWithoutCctor_Add_m6_19 (Object_t * __this /* static, unused */, ValueTypeWithoutCctor_t6_12 ___v1, ValueTypeWithoutCctor_t6_12 ___v2, const MethodInfo* method) | |
{ | |
{ | |
int32_t L_0 = ((&___v1)->___Value_0); | |
int32_t L_1 = ((&___v2)->___Value_0); | |
ValueTypeWithoutCctor_t6_12 L_2 = {0}; | |
ValueTypeWithoutCctor__ctor_m6_17(&L_2, ((int32_t)((int32_t)L_0+(int32_t)L_1)), /*hidden argument*/NULL); | |
return L_2; | |
} | |
} | |
// System.String SharpCpp.ValueTypeWithoutCctor::ToString() | |
extern Il2CppCodeGenString* _stringLiteral135; | |
extern "C" String_t* ValueTypeWithoutCctor_ToString_m6_20 (ValueTypeWithoutCctor_t6_12 * __this, const MethodInfo* method) | |
{ | |
static bool s_Il2CppMethodIntialized; | |
if (!s_Il2CppMethodIntialized) | |
{ | |
_stringLiteral135 = il2cpp_codegen_string_literal_from_index(135); | |
s_Il2CppMethodIntialized = true; | |
} | |
{ | |
int32_t* L_0 = &(__this->___Value_0); | |
String_t* L_1 = Int32_ToString_m1_65(L_0, _stringLiteral135, /*hidden argument*/NULL); | |
return L_1; | |
} | |
} | |
// SharpCpp.ValueTypeWithoutCctor SharpCpp.ValueTypeWithoutCctor::op_Addition(SharpCpp.ValueTypeWithoutCctor,SharpCpp.ValueTypeWithoutCctor) | |
extern "C" ValueTypeWithoutCctor_t6_12 ValueTypeWithoutCctor_op_Addition_m6_21 (Object_t * __this /* static, unused */, ValueTypeWithoutCctor_t6_12 ___v1, ValueTypeWithoutCctor_t6_12 ___v2, const MethodInfo* method) | |
{ | |
{ | |
ValueTypeWithoutCctor_t6_12 L_0 = ___v1; | |
ValueTypeWithoutCctor_t6_12 L_1 = ___v2; | |
ValueTypeWithoutCctor_t6_12 L_2 = ValueTypeWithoutCctor_Add_m6_19(NULL /*static, unused*/, L_0, L_1, /*hidden argument*/NULL); | |
return L_2; | |
} | |
} | |
// System.Void SharpCpp.SharpCode::Il2Cpp_ValueTypeWithoutCctor() | |
extern "C" void SharpCode_Il2Cpp_ValueTypeWithoutCctor_m6_23 (Object_t * __this /* static, unused */, const MethodInfo* method) | |
{ | |
ValueTypeWithoutCctor_t6_12 V_0 = {0}; | |
ValueTypeWithoutCctor_t6_12 V_1 = {0}; | |
ValueTypeWithoutCctor_t6_12 V_2 = {0}; | |
{ | |
ValueTypeWithoutCctor__ctor_m6_17((&V_0), 0, /*hidden argument*/NULL); | |
ValueTypeWithoutCctor_t6_12 L_0 = ValueTypeWithoutCctor_get_One_m6_18(NULL /*static, unused*/, /*hidden argument*/NULL); | |
V_1 = L_0; | |
ValueTypeWithoutCctor_t6_12 L_1 = V_0; | |
ValueTypeWithoutCctor_t6_12 L_2 = V_1; | |
ValueTypeWithoutCctor_t6_12 L_3 = ValueTypeWithoutCctor_op_Addition_m6_21(NULL /*static, unused*/, L_1, L_2, /*hidden argument*/NULL); | |
V_2 = L_3; | |
ValueTypeWithoutCctor_t6_12 L_4 = V_0; | |
ValueTypeWithoutCctor_t6_12 L_5 = V_2; | |
ValueTypeWithoutCctor_Add_m6_19(NULL /*static, unused*/, L_4, L_5, /*hidden argument*/NULL); | |
return; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment