Skip to content

Commit

Permalink
Improved CLR Binding for Field Access
Browse files Browse the repository at this point in the history
  • Loading branch information
liiir1985 committed Apr 3, 2020
1 parent e5f45ad commit 0f34c7f
Show file tree
Hide file tree
Showing 11 changed files with 295 additions and 40 deletions.
16 changes: 16 additions & 0 deletions ILRuntime/CLR/TypeSystem/CLRType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,22 @@ public bool CopyFieldToStack(int hash, object target, Runtime.Intepreter.ILIntep
return false;
}

public bool AssignFieldFromStack(int hash, ref object target, Runtime.Intepreter.ILIntepreter intp, StackObject* esp, IList<object> mStack)
{
if (fieldMapping == null)
InitializeFields();
if (fieldBindingCache == null)
return false;
var binding = GetFieldBinding(hash);
if (binding.Value != null)
{
esp = binding.Value(ref target, intp, esp, mStack);
return true;
}
else
return false;
}

public void SetStaticFieldValue(int hash, object value)
{
if (fieldMapping == null)
Expand Down
5 changes: 2 additions & 3 deletions ILRuntime/Runtime/CLRBinding/BindingCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -437,16 +437,15 @@ internal static void CrawlAppdomain(ILRuntime.Runtime.Enviorment.AppDomain domai
info = CreateNewBindingInfo(t.TypeForCLR);
infos[t.TypeForCLR] = info;
}
if(ins.Code == Intepreter.OpCodes.OpCodeEnum.Stfld || ins.Code == Intepreter.OpCodes.OpCodeEnum.Stsfld)
if (ins.Code == Intepreter.OpCodes.OpCodeEnum.Stfld || ins.Code == Intepreter.OpCodes.OpCodeEnum.Stsfld)
{
if (t.IsValueType)
{
info.ValueTypeNeeded = true;
info.DefaultInstanceNeeded = true;
}
}
if (t.TypeForCLR.CheckCanPinn() || !t.IsValueType)
info.Fields.Add(fi);
info.Fields.Add(fi);
}
}
}
Expand Down
24 changes: 18 additions & 6 deletions ILRuntime/Runtime/CLRBinding/FieldBindingGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,14 @@ internal static string GenerateFieldWraperCode(this Type type, FieldInfo[] field
}
else
{
sb.AppendLine(string.Format(" {0} ins =({0})o;", typeClsName));
sb.AppendLine(string.Format(" ins.{0} = ({1})v;", i.Name, realClsName));
sb.AppendLine(" o = ins;");
if (type.IsValueType)
{
sb.AppendLine(string.Format(" {0} ins =({0})o;", typeClsName));
sb.AppendLine(string.Format(" ins.{0} = ({1})v;", i.Name, realClsName));
sb.AppendLine(" o = ins;");
}
else
sb.AppendLine(string.Format(" (({0})o).{1} = ({2})v;", typeClsName, i.Name, realClsName));
}
sb.AppendLine(" }");
sb.AppendLine();
Expand All @@ -123,9 +128,16 @@ internal static string GenerateFieldWraperCode(this Type type, FieldInfo[] field
}
else
{
sb.AppendLine(string.Format(" {0} ins =({0})o;", typeClsName));
sb.AppendLine(string.Format(" ins.{0} = @{0};", i.Name));
sb.AppendLine(" o = ins;");
if (type.IsValueType)
{
sb.AppendLine(string.Format(" {0} ins =({0})o;", typeClsName));
sb.AppendLine(string.Format(" ins.{0} = @{0};", i.Name));
sb.AppendLine(" o = ins;");
}
else
{
sb.AppendLine(string.Format(" (({0})o).{1} = @{1};", typeClsName, i.Name));
}
}
sb.AppendLine(" return ptr_of_this_method;");
sb.AppendLine(" }");
Expand Down
23 changes: 16 additions & 7 deletions ILRuntime/Runtime/Intepreter/ILIntepreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public object Run(ILMethod method, object instance, object[] p)
}
unhandledException = false;
StackObject* objRef, objRef2, dst, val, a, b, arrRef;
object obj = null;
object obj = null, objVal = null;
IType type;
Type clrType;
int intVal;
Expand Down Expand Up @@ -526,7 +526,8 @@ public object Run(ILMethod method, object instance, object[] p)
else
{
var t = AppDomain.GetType(ip->TokenInteger);
((CLRType)t).SetFieldValue(idx, ref obj, t.TypeForCLR.CheckCLRTypes(StackObject.ToObject(val, AppDomain, mStack)));
if (!((CLRType)t).AssignFieldFromStack(idx, ref obj, this, val, mStack))
((CLRType)t).SetFieldValue(idx, ref obj, t.TypeForCLR.CheckCLRTypes(StackObject.ToObject(val, AppDomain, mStack)));
}
}
break;
Expand All @@ -539,7 +540,9 @@ public object Run(ILMethod method, object instance, object[] p)
}
else
{
((CLRType)t).SetStaticFieldValue(objRef->ValueLow, t.TypeForCLR.CheckCLRTypes(StackObject.ToObject(val, AppDomain, mStack)));
obj = null;
if (!((CLRType)t).AssignFieldFromStack(objRef->ValueLow, ref obj, this, val, mStack))
((CLRType)t).SetStaticFieldValue(objRef->ValueLow, t.TypeForCLR.CheckCLRTypes(StackObject.ToObject(val, AppDomain, mStack)));
}
}
break;
Expand Down Expand Up @@ -1882,7 +1885,8 @@ public object Run(ILMethod method, object instance, object[] p)
val = esp - 1;
var fieldToken = (int)ip->TokenLong;
var f = ((CLRType)type).GetField(fieldToken);
((CLRType)type).SetFieldValue(fieldToken, ref obj, f.FieldType.CheckCLRTypes(CheckAndCloneValueType(StackObject.ToObject(val, domain, mStack), domain)));
if (!((CLRType)type).AssignFieldFromStack(fieldToken, ref obj, this, val, mStack))
((CLRType)type).SetFieldValue(fieldToken, ref obj, f.FieldType.CheckCLRTypes(CheckAndCloneValueType(StackObject.ToObject(val, domain, mStack), domain)));
//Writeback
if (t.IsValueType)
{
Expand Down Expand Up @@ -2091,7 +2095,9 @@ public object Run(ILMethod method, object instance, object[] p)
int idx = (int)ip->TokenLong;
var f = t.GetField(idx);
val = esp - 1;
t.SetStaticFieldValue(idx, f.FieldType.CheckCLRTypes(CheckAndCloneValueType(StackObject.ToObject(val, domain, mStack), domain)));
obj = null;
if (!((CLRType)t).AssignFieldFromStack(idx, ref obj, this, val, mStack))
t.SetStaticFieldValue(idx, f.FieldType.CheckCLRTypes(CheckAndCloneValueType(StackObject.ToObject(val, domain, mStack), domain)));
}
}
else
Expand Down Expand Up @@ -4885,8 +4891,11 @@ void StoreValueToFieldReference(ref object obj, int idx, StackObject* val, IList
else
{
CLRType t = AppDomain.GetType(obj.GetType()) as CLRType;
var v = obj.GetType().CheckCLRTypes(CheckAndCloneValueType(StackObject.ToObject(val, AppDomain, mStack), AppDomain));
t.SetFieldValue(idx, ref obj, v);
if (!t.AssignFieldFromStack(idx, ref obj, this, val, mStack))
{
var v = obj.GetType().CheckCLRTypes(CheckAndCloneValueType(StackObject.ToObject(val, AppDomain, mStack), AppDomain));
t.SetFieldValue(idx, ref obj, v);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,14 @@ static object get_testField_0(ref object o)

static void set_testField_0(ref object o, object v)
{
ILRuntimeTest.TestFramework.BaseClassTest ins =(ILRuntimeTest.TestFramework.BaseClassTest)o;
ins.testField = (System.Boolean)v;
o = ins;
((ILRuntimeTest.TestFramework.BaseClassTest)o).testField = (System.Boolean)v;
}

static StackObject* AssignFromStack_testField_0(ref object o, ILIntepreter __intp, StackObject* ptr_of_this_method, IList<object> __mStack)
{
ILRuntime.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
System.Boolean @testField = ptr_of_this_method->Value == 1;
ILRuntimeTest.TestFramework.BaseClassTest ins =(ILRuntimeTest.TestFramework.BaseClassTest)o;
ins.testField = @testField;
o = ins;
((ILRuntimeTest.TestFramework.BaseClassTest)o).testField = @testField;
return ptr_of_this_method;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,18 +190,14 @@ static object get_TestVal2_0(ref object o)

static void set_TestVal2_0(ref object o, object v)
{
ILRuntimeTest.TestFramework.ClassInheritanceTest ins =(ILRuntimeTest.TestFramework.ClassInheritanceTest)o;
ins.TestVal2 = (System.Int32)v;
o = ins;
((ILRuntimeTest.TestFramework.ClassInheritanceTest)o).TestVal2 = (System.Int32)v;
}

static StackObject* AssignFromStack_TestVal2_0(ref object o, ILIntepreter __intp, StackObject* ptr_of_this_method, IList<object> __mStack)
{
ILRuntime.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
System.Int32 @TestVal2 = ptr_of_this_method->Value;
ILRuntimeTest.TestFramework.ClassInheritanceTest ins =(ILRuntimeTest.TestFramework.ClassInheritanceTest)o;
ins.TestVal2 = @TestVal2;
o = ins;
((ILRuntimeTest.TestFramework.ClassInheritanceTest)o).TestVal2 = @TestVal2;
return ptr_of_this_method;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,14 @@ static object get_Struct_0(ref object o)

static void set_Struct_0(ref object o, object v)
{
ILRuntimeTest.TestFramework.TestClass3 ins =(ILRuntimeTest.TestFramework.TestClass3)o;
ins.Struct = (ILRuntimeTest.TestFramework.TestStruct)v;
o = ins;
((ILRuntimeTest.TestFramework.TestClass3)o).Struct = (ILRuntimeTest.TestFramework.TestStruct)v;
}

static StackObject* AssignFromStack_Struct_0(ref object o, ILIntepreter __intp, StackObject* ptr_of_this_method, IList<object> __mStack)
{
ILRuntime.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
ILRuntimeTest.TestFramework.TestStruct @Struct = (ILRuntimeTest.TestFramework.TestStruct)typeof(ILRuntimeTest.TestFramework.TestStruct).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
ILRuntimeTest.TestFramework.TestClass3 ins =(ILRuntimeTest.TestFramework.TestClass3)o;
ins.Struct = @Struct;
o = ins;
((ILRuntimeTest.TestFramework.TestClass3)o).Struct = @Struct;
return ptr_of_this_method;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public static void Register(ILRuntime.Runtime.Enviorment.AppDomain app)
{
BindingFlags flag = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
MethodBase method;
FieldInfo field;
Type[] args;
Type type = typeof(ILRuntimeTest.TestFramework.TestStruct);
args = new Type[]{typeof(ILRuntimeTest.TestFramework.TestStruct).MakeByRefType()};
Expand All @@ -32,6 +33,15 @@ public static void Register(ILRuntime.Runtime.Enviorment.AppDomain app)
method = type.GetMethod("DoTest2", flag, null, args, null);
app.RegisterCLRMethodRedirection(method, DoTest2_2);

field = type.GetField("value", flag);
app.RegisterCLRFieldGetter(field, get_value_0);
app.RegisterCLRFieldSetter(field, set_value_0);
app.RegisterCLRFieldBinding(field, CopyToStack_value_0, AssignFromStack_value_0);
field = type.GetField("instance", flag);
app.RegisterCLRFieldGetter(field, get_instance_1);
app.RegisterCLRFieldSetter(field, set_instance_1);
app.RegisterCLRFieldBinding(field, CopyToStack_instance_1, AssignFromStack_instance_1);

app.RegisterCLRMemberwiseClone(type, PerformMemberwiseClone);

app.RegisterCLRCreateDefaultInstance(type, () => new ILRuntimeTest.TestFramework.TestStruct());
Expand Down Expand Up @@ -233,6 +243,61 @@ static void WriteBackInstance(ILRuntime.Runtime.Enviorment.AppDomain __domain, S
}


static object get_value_0(ref object o)
{
return ((ILRuntimeTest.TestFramework.TestStruct)o).value;
}

static StackObject* CopyToStack_value_0(ref object o, ILIntepreter __intp, StackObject* __ret, IList<object> __mStack)
{
var result_of_this_method = ((ILRuntimeTest.TestFramework.TestStruct)o).value;
__ret->ObjectType = ObjectTypes.Integer;
__ret->Value = result_of_this_method;
return __ret + 1;
}

static void set_value_0(ref object o, object v)
{
ILRuntimeTest.TestFramework.TestStruct ins =(ILRuntimeTest.TestFramework.TestStruct)o;
ins.value = (System.Int32)v;
o = ins;
}

static StackObject* AssignFromStack_value_0(ref object o, ILIntepreter __intp, StackObject* ptr_of_this_method, IList<object> __mStack)
{
ILRuntime.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
System.Int32 @value = ptr_of_this_method->Value;
ILRuntimeTest.TestFramework.TestStruct ins =(ILRuntimeTest.TestFramework.TestStruct)o;
ins.value = @value;
o = ins;
return ptr_of_this_method;
}

static object get_instance_1(ref object o)
{
return ILRuntimeTest.TestFramework.TestStruct.instance;
}

static StackObject* CopyToStack_instance_1(ref object o, ILIntepreter __intp, StackObject* __ret, IList<object> __mStack)
{
var result_of_this_method = ILRuntimeTest.TestFramework.TestStruct.instance;
return ILIntepreter.PushObject(__ret, __mStack, result_of_this_method);
}

static void set_instance_1(ref object o, object v)
{
ILRuntimeTest.TestFramework.TestStruct.instance = (ILRuntimeTest.TestFramework.TestStruct)v;
}

static StackObject* AssignFromStack_instance_1(ref object o, ILIntepreter __intp, StackObject* ptr_of_this_method, IList<object> __mStack)
{
ILRuntime.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
ILRuntimeTest.TestFramework.TestStruct @instance = (ILRuntimeTest.TestFramework.TestStruct)typeof(ILRuntimeTest.TestFramework.TestStruct).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
ILRuntimeTest.TestFramework.TestStruct.instance = @instance;
return ptr_of_this_method;
}


static object PerformMemberwiseClone(ref object o)
{
var ins = new ILRuntimeTest.TestFramework.TestStruct();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,7 @@ static object get_vector_0(ref object o)

static void set_vector_0(ref object o, object v)
{
ILRuntimeTest.TestFramework.TestVectorClass ins =(ILRuntimeTest.TestFramework.TestVectorClass)o;
ins.vector = (ILRuntimeTest.TestFramework.TestVector3)v;
o = ins;
((ILRuntimeTest.TestFramework.TestVectorClass)o).vector = (ILRuntimeTest.TestFramework.TestVector3)v;
}

static StackObject* AssignFromStack_vector_0(ref object o, ILIntepreter __intp, StackObject* ptr_of_this_method, IList<object> __mStack)
Expand All @@ -119,9 +117,7 @@ static void set_vector_0(ref object o, object v)
} else {
@vector = (ILRuntimeTest.TestFramework.TestVector3)typeof(ILRuntimeTest.TestFramework.TestVector3).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
}
ILRuntimeTest.TestFramework.TestVectorClass ins =(ILRuntimeTest.TestFramework.TestVectorClass)o;
ins.vector = @vector;
o = ins;
((ILRuntimeTest.TestFramework.TestVectorClass)o).vector = @vector;
return ptr_of_this_method;
}

Expand Down
Loading

0 comments on commit 0f34c7f

Please sign in to comment.