internal void OptimizeSetter() { using (PerformanceStatistics.StartGlobalStopwatch(PerformanceCounter.AdaptersCompilation)) { if (m_Setter != null && !(PropertyInfo.DeclaringType.IsValueType)) { MethodInfo setterMethod = PropertyInfo.GetSetMethod(true); if (IsStatic) { var paramExp = Expression.Parameter(typeof(object), "dummy"); var paramValExp = Expression.Parameter(typeof(object), "val"); var castParamValExp = Expression.Convert(paramValExp, this.PropertyInfo.PropertyType); var callExpression = Expression.Call(setterMethod, castParamValExp); var lambda = Expression.Lambda <Action <object, object> >(callExpression, paramExp, paramValExp); Interlocked.Exchange(ref m_OptimizedSetter, lambda.Compile()); } else { var paramExp = Expression.Parameter(typeof(object), "obj"); var paramValExp = Expression.Parameter(typeof(object), "val"); var castParamExp = Expression.Convert(paramExp, this.PropertyInfo.DeclaringType); var castParamValExp = Expression.Convert(paramValExp, this.PropertyInfo.PropertyType); var callExpression = Expression.Call(castParamExp, setterMethod, castParamValExp); var lambda = Expression.Lambda <Action <object, object> >(callExpression, paramExp, paramValExp); Interlocked.Exchange(ref m_OptimizedSetter, lambda.Compile()); } } } }
internal void OptimizeGetter() { using (PerformanceStatistics.StartGlobalStopwatch(PerformanceCounter.AdaptersCompilation)) { if (m_Getter != null) { if (IsStatic) { var paramExp = Expression.Parameter(typeof(object), "dummy"); var propAccess = Expression.Property(null, PropertyInfo); var castPropAccess = Expression.Convert(propAccess, typeof(object)); var lambda = Expression.Lambda <Func <object, object> >(castPropAccess, paramExp); Interlocked.Exchange(ref m_OptimizedGetter, lambda.Compile()); } else { var paramExp = Expression.Parameter(typeof(object), "obj"); var castParamExp = Expression.Convert(paramExp, this.PropertyInfo.DeclaringType); var propAccess = Expression.Property(castParamExp, PropertyInfo); var castPropAccess = Expression.Convert(propAccess, typeof(object)); var lambda = Expression.Lambda <Func <object, object> >(castPropAccess, paramExp); Interlocked.Exchange(ref m_OptimizedGetter, lambda.Compile()); } } } }
internal void Optimize() { if (AccessMode == InteropAccessMode.Reflection) { return; } MethodInfo methodInfo = this.MethodInfo as MethodInfo; if (methodInfo == null) { return; } using (PerformanceStatistics.StartGlobalStopwatch(PerformanceCounter.AdaptersCompilation)) { var ep = Expression.Parameter(typeof(object[]), "pars"); var objinst = Expression.Parameter(typeof(object), "instance"); var inst = Expression.Convert(objinst, MethodInfo.DeclaringType); Expression[] args = new Expression[Parameters.Length]; for (int i = 0; i < Parameters.Length; i++) { if (Parameters[i].ParameterType.IsByRef) { throw new InternalErrorException("Out/Ref params cannot be precompiled."); } else { var x = Expression.ArrayIndex(ep, Expression.Constant(i)); args[i] = Expression.Convert(x, Parameters[i].ParameterType); } } Expression fn; if (IsStatic) { fn = Expression.Call(methodInfo, args); } else { fn = Expression.Call(inst, methodInfo, args); } if (this.m_IsAction) { var lambda = Expression.Lambda <Action <object, object[]> >(fn, objinst, ep); Interlocked.Exchange(ref m_OptimizedAction, lambda.Compile()); } else { var fnc = Expression.Convert(fn, typeof(object)); var lambda = Expression.Lambda <Func <object, object[], object> >(fnc, objinst, ep); Interlocked.Exchange(ref m_OptimizedFunc, lambda.Compile()); } } }
internal override void OptimizeGetter(FieldInfo fi) { #if !ONLY_AOT using (PerformanceStatistics.StartGlobalStopwatch(PerformanceCounter.AdaptersCompilation)) { // We want something that behaves like this: //lambda = (Script sc, TObj obj) => ClrToScriptConversions.ObjectToDynValue(sc, fi.GetValue(obj)); Expression <Func <Script, TObj, DynValue> > lambda; if (IsStatic) { var param1 = Expression.Parameter(typeof(Script), "script"); var param2 = Expression.Parameter(typeof(object), "container"); var fiGetValue = Expression.Field(null, fi); var objToDynValueCall = Expression.Call(typeof(ClrToScriptConversions).GetMethod("GenericToDynValue", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(fi.FieldType), param1, fiGetValue); lambda = Expression.Lambda <Func <Script, TObj, DynValue> >(objToDynValueCall, param1, param2); } else { if (fi.DeclaringType.IsValueType) { var param1 = Expression.Parameter(typeof(Script), "script"); var param2 = Expression.Parameter(fi.DeclaringType, "container"); var fiGetValue = Expression.Field(param2, fi); var objToDynValueCall = Expression.Call(typeof(ClrToScriptConversions).GetMethod("GenericToDynValue", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(fi.FieldType), param1, fiGetValue); lambda = Expression.Lambda <Func <Script, TObj, DynValue> >(objToDynValueCall, param1, param2); } else { var param1 = Expression.Parameter(typeof(Script), "script"); var param2 = Expression.Parameter(fi.DeclaringType, "container"); var fiGetValue = Expression.Field(param2, fi); var nullCheck = Expression.NotEqual(param2, Expression.Constant(null, typeof(object))); var objToDynValueCall = Expression.Call(typeof(ClrToScriptConversions).GetMethod("GenericToDynValue", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(fi.FieldType), param1, fiGetValue); var nilDynValueCall = Expression.Invoke((Expression <Func <DynValue> >)(() => DynValue.Nil)); var ifNotNull = Expression.Condition(nullCheck, objToDynValueCall, nilDynValueCall); lambda = Expression.Lambda <Func <Script, TObj, DynValue> >(ifNotNull, param1, param2); } } Interlocked.Exchange(ref m_OptimizedGetter, lambda.Compile()); } #endif }
internal void Optimize() { using (PerformanceStatistics.StartGlobalStopwatch(PerformanceCounter.AdaptersCompilation)) { var ep = Expression.Parameter(typeof(object[]), "pars"); var objinst = Expression.Parameter(typeof(object), "instance"); var inst = Expression.Convert(objinst, MethodInfo.DeclaringType); Expression[] args = new Expression[m_Arguments.Length]; for (int i = 0; i < m_Arguments.Length; i++) { var x = Expression.ArrayIndex(ep, Expression.Constant(i)); args[i] = Expression.Convert(x, m_Arguments[i]); } Expression fn; if (IsStatic) { fn = Expression.Call(MethodInfo, args); } else { fn = Expression.Call(inst, MethodInfo, args); } if (MethodInfo.ReturnType == typeof(void)) { var lambda = Expression.Lambda <Action <object, object[]> >(fn, objinst, ep); Interlocked.Exchange(ref m_OptimizedAction, lambda.Compile()); } else { var fnc = Expression.Convert(fn, typeof(object)); var lambda = Expression.Lambda <Func <object, object[], object> >(fnc, objinst, ep); Interlocked.Exchange(ref m_OptimizedFunc, lambda.Compile()); } } }