public void Execute(MethodContext context, MethodState state, object operand = null) { if (context.EvalStack.Count < 1) { throw new InvalidStackSizeException("Evaluation stack should contain an element"); } ESSlot refSlot = context.EvalStack.Pop(); if (refSlot.SType != ESSlotType.HORef || ((Int32)refSlot.Val) == GCHeapObj.NullObj.Addr) { throw new InvalidOperationException("Stack contains an invalid data"); } //Get heap object by address GCHeapObj hObj = context.GCHeap.GetObj((Int32)refSlot.Val); var typeObject = context.TypesHeap.GetTypeObject(hObj.TypeToken); if (typeObject == null) { throw new InvalidOperationException("UnboxEngine: Type was not loaded"); } else if (!typeObject.TypeDesc.IsValueType) { throw new InvalidOperationException("Reference type cannot be unboxed"); } ESSlot valSlot = new ESSlot() { SType = ESSlotType.Val, TypeToken = hObj.TypeToken }; if (hObj.TypeToken.IsPrimitive) { valSlot.Val = GetUnaryOperation(hObj.TypeToken.PrimitiveType, UnaryPrimitiveOpType.GetStackRep)(hObj.Val); } else { valSlot.Val = hObj.Val; } context.EvalStack.Push(valSlot); }
public void Execute(MethodContext context, MethodState state, object operand = null) { if (context.EvalStack.Count < 1) { throw new InvalidStackSizeException("Evaluation stack should contain an element to be boxed"); } ESSlot valueSlot = context.EvalStack.Pop(); if (valueSlot.SType != ESSlotType.Val) { throw new InvalidOperationException("Stack contains an invalid data that cannot be boxed"); } //Check if type is loaded if (!context.TypeLoader.TypeIsLoaded(valueSlot.TypeToken)) { throw new InvalidOperationException("Type is not loaded into the domain"); } if (valueSlot.TypeToken.IsPrimitive) { if (!IsPrimaryType(valueSlot.TypeToken.PrimitiveType)) { valueSlot.Val = GetUnaryOperation(valueSlot.TypeToken.PrimitiveType, UnaryPrimitiveOpType.GetStoreRep)(valueSlot.Val); } } TypeObject typeObj = context.TypesHeap.GetTypeObject(valueSlot.TypeToken); GCHeapObj hObj = context.GCHeap.AllocObj(typeObj); hObj.Val = valueSlot.Val; ESSlot refSlot = new ESSlot() { TypeToken = valueSlot.TypeToken, SType = ESSlotType.HORef, Val = hObj.Addr }; context.EvalStack.Push(refSlot); }
public void Execute(MethodContext context, MethodState state, object operand = null) { //Pop "this" from stack and check to null ESSlot objThisSlot = context.EvalStack.Peek(); Int32 thisRefAddr = (Int32)objThisSlot.Val; if (thisRefAddr == GCHeapObj.NullObj.Addr) { throw new NullReferenceException("Object is null"); } //Get right method var methodDef = (operand as MethodToken); if (methodDef == null) { throw new ArgumentException("Incorrect or null method definition"); } GCHeapObj thisObject = context.GCHeap.GetObj((Int32)objThisSlot.Val); //if (typeObjHeap == GCHeapObj.NullObj) // throw new NullReferenceException("Type object is null"); TypeObject typeObj = context.TypesHeap.GetTypeObject(thisObject.TypeToken); MethodDesc method = typeObj.VTable.GetMethod(methodDef); if (method == null) { throw new InvalidOperationException("Method described by the provided metadata was not found in type's vtable"); } state.CallMethod = method; state.ExecutionInterruption = ExecutionInterruption.Call; }