unsafe internal void Set(int fieldIndex, object obj, Type type, VirtualMachine virtualMachine) { fixed(Value *b = &unmanagedFields[0]) { //VirtualMachine._Info("AnonymousStorey.Set, field=" + fieldIndex + ", val=" + obj); EvaluationStackOperation.PushObject(b, b + fieldIndex, managedFields, obj, type); } }
unsafe internal object Get(int fieldIndex, Type type, VirtualMachine virtualMachine, bool valueTypeClone) { fixed(Value *b = &unmanagedFields[0]) { var ret = EvaluationStackOperation.ToObject(b, b + fieldIndex, managedFields, type, virtualMachine, valueTypeClone); //VirtualMachine._Info("AnonymousStorey.Get, field=" + fieldIndex + ", val=" + ret); return(ret); } }
public void UpdateReference(int offset, object obj, VirtualMachine virtualMachine, Type type) //反射专用 { EvaluationStackOperation.UpdateReference(ThreadStackInfo.Stack.UnmanagedStack->Base, argumentBase + offset, managedStack, obj, virtualMachine, type); }
public void PushObjectAsResult(object obj, Type type) //反射专用 { EvaluationStackOperation.PushObject(evaluationStackBase, argumentBase, managedStack, obj, type); currentTop = argumentBase + 1; }
// #lizard forgives public unsafe void Invoke(VirtualMachine virtualMachine, ref Call call, bool isInstantiate) { var managedStack = call.managedStack; var pushResult = false; var args = new object[paramCount]; try { //virtualMachine._Info("method: " + method); Value *pArg = call.argumentBase; int paramStart = 0; if (hasThis && !isInstantiate) { paramStart = 1; pArg++; } for (int i = 0; i < paramCount; i++) { if (!outFlags[i]) { args[i] = EvaluationStackOperation.ToObject(call.evaluationStackBase, pArg, managedStack, rawTypes[i], virtualMachine); } //if (pArg->Type >= ValueType.Object) //{ // managedStack[pArg->Value1] = null; //} //if (method.Name == "Invoke" && method.DeclaringType.Name == "MethodBase") //{ // VirtualMachine._Info(i + " pArg->Type:" + pArg->Type); // VirtualMachine._Info(i + " args[i]:" + args[i]); // if (args[i] != null) // { // VirtualMachine._Info(i + " args[i]:" + args[i].GetHashCode()); // } // VirtualMachine._Info(i + " args[i].GetType:" + (args[i] == null ? // "null" : args[i].GetType().ToString())); // if (i == 1 && args[i] is object[]) // { // var objs = args[i] as object[]; // for (int j = 0; j < objs.Length;j++) // { // VirtualMachine._Info("obj " + j + ": " + (objs[j] == null ? // "null" : objs[j].GetType().ToString())); // } // } //} pArg++; } object ret; if (isInstantiate || (method.IsConstructor && method.DeclaringType.IsValueType)) { ret = ctor.Invoke(args);//TODO: Delegate创建用Delegate.CreateDelegate } else { object instance = null; if (hasThis) { instance = EvaluationStackOperation.ToObject(call.evaluationStackBase, call.argumentBase, managedStack, method.DeclaringType, virtualMachine, false); } //Nullable仍然是值类型,只是新增了是否为null的标志位,仍然通过传地址的方式进行方法调用, //但这在反射调用行不通,参数是object类型,boxing到object就是null,所以会触发 //“Non-static method requires a target”异常 //所以这只能特殊处理一下 if (isNullableHasValue) { ret = (instance != null); } else if (isNullableValue) { ret = instance; } else { if (method.IsStatic == false && instance == null) { throw new TargetException(string.Format("can not invoke method [{0}.{1}], Non-static method require instance but got null.", method.DeclaringType, method.Name)); } else { ret = method.Invoke(instance, args); } } } for (int i = 0; i < paramCount; i++) { if (refFlags[i]) { call.UpdateReference(i + paramStart, args[i], virtualMachine, rawTypes[i]); } } if (hasReturn || isInstantiate) { if (method.IsConstructor && method.DeclaringType.IsValueType && !isInstantiate) { call.UpdateReference(0, ret, virtualMachine, method.DeclaringType); } else { call.PushObjectAsResult(ret, returnType); pushResult = true; } } } catch (TargetInvocationException e) { throw e.InnerException; } //catch (TargetException e) //{ // //VirtualMachine._Info("exception method: " + method + ", in " + method.DeclaringType + ", msg:" // + e.InnerException); // //for (int i = 0; i < paramCount; i++) // //{ // // VirtualMachine._Info("arg " + i + " type: " + (args[i] == null ? "null" : args[i].GetType() // // .ToString()) + " value: " + args[i]); // //} // if (e.InnerException is System.ArgumentException && args.Length == 2 && args[1] is object[]) // { // //VirtualMachine._Info("exception method: " + method + ", in " + method.DeclaringType // // + ", msg:" + e.InnerException); // if (instance is MethodBase) // { // MethodBase mb = instance as MethodBase; // VirtualMachine._Info("exception method: " + mb + ", in " + mb.DeclaringType); // } // args = args[1] as object[]; // for (int i = 0; i < args.Length; i++) // { // VirtualMachine._Info("arg " + i + " type: " + (args[i] == null ? // "null" : args[i].GetType().ToString()) + " value: " + args[i]); // } // } // throw e; //} finally { //for (int i = 0; i < paramCount; i++) //{ // args[i] = null; //} Value *pArg = call.argumentBase; if (pushResult) { pArg++; } for (int i = (pushResult ? 1 : 0); i < paramCount + ((hasThis && !isInstantiate) ? 1 : 0); i++) { managedStack[pArg - call.evaluationStackBase] = null; pArg++; } } }