protected void PushObject(object obj) { MethodContext.PushObject(obj); }
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); } } }