예제 #1
0
 protected void PushObject(object obj)
 {
     MethodContext.PushObject(obj);
 }
예제 #2
0
        public override void Wykonaj()
        {
            var method = Instruction.Operand as System.Reflection.MethodBase;
            //var methodDef = methodRef.Resolve();
            var    parameters  = new List <object>();
            object instance    = null;
            object instancePop = null;

            foreach (var paramDef in method.GetParameters())
            {
                parameters.Add(MethodContext.PopObject());
            }
            if (method.IsStatic == false)
            {
                instancePop = MethodContext.Pop();
                if (instancePop is ObjectWraperBase wraper)
                {
                    instance = wraper.GetValue();
                }
                else
                {
                    instance = instancePop;
                }
            }

            parameters.Reverse();

            MethodContext.WirtualnaMaszyna.EventCall(method, parameters);

            if (method.Name.Equals("Hibernate") && method.DeclaringType == typeof(VirtualMachine))
            {
                //wywołał metodę do hibernacji wirtualnej maszyny
                if (parameters.Count > 0)
                {
                    var p = (object[])parameters[0];
                    this.MethodContext.WirtualnaMaszyna.HibernateVirtualMachine(p);
                }
                else
                {
                    this.MethodContext.WirtualnaMaszyna.HibernateVirtualMachine(null);
                }

                return;
            }

            if (method.Name.Equals("EndProcess") && method.DeclaringType == typeof(VirtualMachine))
            {
                //wywołał metodę do hibernacji wirtualnej maszyny
                this.MethodContext.WirtualnaMaszyna.EndProcessVirtualMachine();
                return;
            }

            //if (method.IsSetter)
            //{
            //    setter(methodDef, instance, parameters);
            //}
            //else if (methodDef.IsGetter)
            //{
            //    getter(methodRef, instance, parameters);
            //}
            //else
            {
                //Wykonywanie
                if (CzyWykonacCzyInterpretowac(method, instance) == true)
                {
                    //wykonywanie



                    //var methodInfo = type.GetMethod(methodRef);
                    var dopasowaneParametry = new List <object>();

                    int i = 0;
                    foreach (var parameter in parameters)
                    {
                        var methodParam = method.GetParameters()[i];
                        i++;

                        if (methodParam.ParameterType == typeof(bool) && parameter is int)
                        {
                            dopasowaneParametry.Add(Convert.ToBoolean((int)parameter));
                        }
                        else
                        {
                            dopasowaneParametry.Add(parameter);
                        }
                    }

                    object ret = null;
                    try
                    {
                        if (method.IsConstructor == true)
                        {
                            var constructor = method as ConstructorInfo;
                            ret = constructor.Invoke(dopasowaneParametry.ToArray());
                            //po wykonaniu odznaczam że był powrót z funkcji (bo już nie będzie instrukcji ret)
                            MethodContext.WirtualnaMaszyna.EventRet(ret);

                            if (instancePop is ObjectWraperBase wraperBase)
                            {
                                wraperBase.SetValue(ret);
                            }
                            else
                            {
                                MethodContext.PushObject(ret);
                            }
                        }
                        else if (instance == null && method.IsStatic == false)
                        {
                            //wykonywanie metody nie statycznej dla instance==null np. null.Equals(..)

                            var expressionParameters = new List <UnaryExpression>();
                            i = 0;
                            foreach (var item in dopasowaneParametry)
                            {
                                var methodParam = method.GetParameters()[i];
                                i++;
                                expressionParameters
                                .Add(Expression.Convert(Expression.Constant(item), methodParam.ParameterType));
                            }

                            var call = Expression.Call(Expression.Constant(instance,
                                                                                                           //typeof(int?)),
                                                                                                           //method.DeclaringType),
                                                                           MethodContext.ConstrainedType), //ConstrainedType set by Constrained instruction
                                                       (MethodInfo)method,
                                                       expressionParameters);

                            MethodContext.ConstrainedType = null;
                            var lambda = Expression.Lambda(call).Compile();
                            ret = lambda.DynamicInvoke();

                            //po wykonaniu odznaczam że był powrót z funkcji (bo już nie będzie instrukcji ret)
                            MethodContext.WirtualnaMaszyna.EventRet(ret);
                        }
                        else
                        {
                            //standardowe wykonywanie metod
                            ret = method.Invoke(instance, dopasowaneParametry.ToArray());

                            //po wykonaniu odznaczam że był powrót z funkcji (bo już nie będzie instrukcji ret)
                            MethodContext.WirtualnaMaszyna.EventRet(ret);
                        }
                    } catch (Exception exception)
                    {
                        //wyjątek z zewnętrznej funkcji
                        HardwareContext.Status = VirtualMachineState.Exception;
                        Throw.ObslugaRzuconegoWyjatku(MethodContext.WirtualnaMaszyna, exception);
                        return;
                    }

                    if (method is MethodInfo methodInfo)
                    {
                        if (methodInfo.ReturnType == typeof(void))
                        {
                            //nie zwracam wyniku
                        }
                        else
                        {
                            MethodContext.PushObject(ret);
                        }
                    }
                    MethodContext.WykonajNastepnaInstrukcje();
                }
                else
                {
                    //interpretowanie

                    //tworzę nową metodę i wrzucam ją na stos wykonania

                    var m = new MethodState(method, MethodContext.WirtualnaMaszyna, instance);
                    m.WczytajInstrukcje();
                    MethodContext = m;
                    var iloscArgumentow = method.GetParameters().Count();

                    if (method.IsStatic == false)
                    {
                        MethodContext.PushObject(instance);
                        iloscArgumentow += 1;
                    }

                    foreach (var parameter in parameters)
                    {
                        MethodContext.PushObject(parameter);
                    }

                    MethodContext.WczytajLokalneArgumenty(iloscArgumentow);


                    //wrzucam na stos wykonania nową metodę
                    HardwareContext.PushAktualnaMetode(MethodContext);
                }
            }
        }