private Type GenericPathTypeUncached(Type declaringType, Type definitionType, TypeDefinition definition, Type[] arguments, bool allArgumentsAreRuntime, GenericScope genericScope) { if (!TypeSupport.IsRuntime(definitionType)) { return(NewInterpretedGenericPathType(declaringType, definitionType, definition, arguments, genericScope)); } if (arguments.Length == 0) { return(declaringType.GetNestedType(definitionType.Name)); } if (allArgumentsAreRuntime) { return(definitionType.MakeGenericType(arguments)); } return(NewInterpretedGenericPathType(declaringType, definitionType, definition, arguments, genericScope)); //var erased = new Type[arguments.Length]; //for (var i = 0; i < arguments.Length; i++) { // erased[i] = TypeSupport.IsRuntime(arguments[i]) ? arguments[i] : typeof(CilinObject); //} //var erasedFull = definitionType.MakeGenericType(erased); //return new ErasedWrapperType(erasedFull, NewInterpretedGenericPathType(declaringType, definitionType, definition, arguments, genericScope)); }
public void Handle(Instruction instruction, CilHandlerContext context) { var method = context.Resolver.Method((MethodReference)instruction.Operand, context.GenericScope); var parameters = method.GetParameters(); var arguments = new object[parameters.Length]; for (var i = parameters.Length - 1; i >= 0; i--) { arguments[i] = TypeSupport.Convert(context.Stack.Pop(), parameters[i].ParameterType); } if (instruction.OpCode == OpCodes.Newobj) { var instance = context.Invoker.Invoke(method, null, arguments, context.Method); context.Stack.Push(instance); return; } var target = (object)null; if (!method.IsStatic) { target = TypeSupport.Convert(context.Stack.Pop(), method.DeclaringType); } var result = context.Invoker.Invoke(method, target, arguments, context.Method); if (!method.IsConstructor && ((MethodInfo)method).ReturnType != typeof(void)) { context.Stack.Push(result); } }
private Type GenericPathType(Type declaringType, Type definitionType, TypeDefinition definition, TypeReference reference, GenericScope genericScope) { var generic = reference as GenericInstanceType; var arguments = generic != null ? new Type[generic.GenericArguments.Count] : System.Type.EmptyTypes; var allArgumentsAreRuntime = true; if (generic != null) { for (var i = 0; i < generic.GenericArguments.Count; i++) { var resolved = Type(generic.GenericArguments[i], genericScope); allArgumentsAreRuntime = allArgumentsAreRuntime && TypeSupport.IsRuntime(resolved); arguments[i] = resolved; } } var cacheKey = new GenericTypeKey(declaringType, definitionType, arguments); Type cached; if (_genericTypeCache.TryGetValue(cacheKey, out cached)) { return(cached); } var resultType = GenericPathTypeUncached(declaringType, definitionType, definition, arguments, allArgumentsAreRuntime, genericScope); _genericTypeCache.Add(cacheKey, resultType); return(GenericPathType(declaringType, definitionType, definition, arguments, allArgumentsAreRuntime, genericScope)); }
private Type TypeByDefinition(TypeDefinition definition) { MemberInfo cached; if (_memberDefinitionCache.TryGetValue(definition, out cached)) { return((Type)cached); } if (ShouldBeRuntime(definition)) { var fullName = TypeSupport.GetFullName(definition); try { return(System.Type.GetType(fullName + ", " + definition.Module.Assembly.Name, true)); } catch (Exception ex) { throw new Exception($"Failed to resolve type '{fullName}': {ex.Message}.", ex); } } var declaringType = definition.DeclaringType != null?TypeByDefinition(definition.DeclaringType) : null; var type = NewInterpretedDefinitionType(declaringType, definition); _memberDefinitionCache.Add(definition, type); return(type); }
private bool IsConditionTrue(Instruction instruction, CilHandlerContext context) { switch (instruction.OpCode.Code) { case Code.Br: case Code.Br_S: return(true); case Code.Brtrue: case Code.Brtrue_S: return(TypeSupport.Convert <bool>(context.Stack.Pop())); case Code.Brfalse: case Code.Brfalse_S: return(!TypeSupport.Convert <bool>(context.Stack.Pop())); case Code.Beq_S: return(IsBinaryConditionTrue(Primitives.Equal, context)); case Code.Bne_Un_S: return(IsBinaryConditionTrue(Primitives.NotEqual, context)); case Code.Blt_S: return(IsBinaryConditionTrue(Primitives.IsLessThan, context)); case Code.Ble_S: return(IsBinaryConditionTrue(Primitives.IsLessThanOrEqual, context)); default: throw new NotImplementedException(); } }
public void Handle(Instruction instruction, CilHandlerContext context) { var index = TypeSupport.Convert <IntPtr>(context.Stack.Pop()); var array = (Array)ObjectWrapper.UnwrapIfRequired(context.Stack.Pop()); var value = array.GetValue(index.ToInt64()); context.Stack.Push(value); }
private bool TryInvokeSpecialConstructor(ConstructorInfo constructor, object[] arguments, out object instance) { if (TypeSupport.IsDelegate(constructor.DeclaringType)) { instance = new CilinDelegate(arguments[0], (NonRuntimeMethodPointer)arguments[1], constructor.DeclaringType); return(true); } instance = null; return(false); }
public void Handle(Instruction instruction, CilHandlerContext context) { var value = context.Stack.Pop(); var index = TypeSupport.Convert <IntPtr>(context.Stack.Pop()); var array = (Array)ObjectWrapper.UnwrapIfRequired(context.Stack.Pop()); array.SetValue( TypeSupport.Convert(value, array.GetType().GetElementType()), index.ToInt64() ); }
private Type ArrayTypeUncached(Type elementType, GenericScope genericScope) { if (TypeSupport.IsRuntime(elementType)) { return(elementType.MakeArrayType()); } return /*new ErasedWrapperType( * typeof(CilinObject).MakeArrayType(),*/ (NewIntepretedArrayType((NonRuntimeType)elementType, genericScope) /*)*/); }
public void Handle(Instruction instruction, CilHandlerContext context) { var field = context.Resolver.Field((FieldReference)instruction.Operand, context.GenericScope); var target = (object)null; if (instruction.OpCode == OpCodes.Ldfld) { target = TypeSupport.Convert(context.Stack.Pop(), field.DeclaringType); } var value = field.GetValue(target); context.Stack.Push(value); }
public object Invoke(MethodBase method, object target, object[] arguments, MethodBase caller, BindingFlags invokeAttr = BindingFlags.Default, Binder binder = null, CultureInfo culture = null) { if (binder != null) { throw new NotSupportedException(); } if (method.DeclaringType.ContainsGenericParameters) { throw new Exception($"Attempted to call method {method} on open generic type {method.DeclaringType}."); } if ((method as MethodInfo)?.ContainsGenericParameters ?? false) { throw new Exception($"Attempted to call open generic method {method}."); } if (method.IsConstructor && !method.IsStatic && (target == null)) { return(InvokeConstructorForNewObject((ConstructorInfo)method, arguments, caller)); } object result; if (TryInvokeSpecialMethod(method, arguments, caller, out result)) { return(result); } if (!method.IsStatic) { if (target == null) { throw new NullReferenceException($"Attempted to call instance method {method.Name} on null reference."); } var custom = target as ICustomInvoker; if (custom != null) { return(custom.Invoke(method, arguments, invokeAttr, binder, culture)); } } if (!(method is IInterpretedMethodBase)) { var unwrapped = ObjectWrapper.UnwrapIfRequired(target); if (!(unwrapped is INonRuntimeObject)) { if (method.DeclaringType.IsInterface && !unwrapped.GetType().IsArray) { method = GetMatchingMethod(unwrapped.GetType(), (MethodInfo)method); } return(method.Invoke(unwrapped, invokeAttr, binder, arguments, culture)); } } if (!method.IsStatic && !method.IsConstructor) { var targetType = TypeSupport.GetTypeOf(target); if (method.DeclaringType != targetType) { method = GetMatchingMethod(targetType, (MethodInfo)method); } } var interpreted = method as IInterpretedMethodBase; if (interpreted == null) { throw new Exception($"Cannot invoke runtime method {method} on non-runtime instance {target}."); } return(_interpreter.InterpretCall( method.DeclaringType.GetGenericArguments(), (MethodBase)interpreted, (MethodDefinition)interpreted.InvokableDefinition, method.GetGenericArguments(), target, arguments )); }