Example #1
0
        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));
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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));
        }
Example #4
0
        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);
        }
Example #5
0
        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();
            }
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        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()
                );
        }
Example #9
0
        private Type ArrayTypeUncached(Type elementType, GenericScope genericScope)
        {
            if (TypeSupport.IsRuntime(elementType))
            {
                return(elementType.MakeArrayType());
            }

            return /*new ErasedWrapperType(
                    * typeof(CilinObject).MakeArrayType(),*/
                   (NewIntepretedArrayType((NonRuntimeType)elementType, genericScope)
                    /*)*/);
        }
Example #10
0
        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);
        }
Example #11
0
        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
                       ));
        }