/* Performs indirect loading of value * (corresponds to CILPE.CFG.LoadIndirect class) */ public void Perform_LoadIndirect(Type type, out Exception exc) { exc = null; Value val = Pop(); if (val is NullValue) { exc = new NullReferenceException(); } else { if (!(val is PointerValue)) { throw new InvalidOperandException(); } object obj = (val as PointerValue).GetReferencedObject(); if (type == typeof(object)) { Push(new ObjectReferenceValue(obj)); } else { StructValue.TypeIndex typeIndex = StructValue.getTypeIndex(type); if (typeIndex != StructValue.TypeIndex.INVALID) { StructValue.TypeIndex objTypeIndex = StructValue.getTypeIndex(obj.GetType()); if (!compareTypes(objTypeIndex, typeIndex)) { throw new InvalidOperandException(); } Push(new StructValue(obj as ValueType)); } else if (type.IsValueType) { if (type != obj.GetType()) { throw new InvalidOperandException(); } Push(new StructValue(obj as ValueType)); } else { throw new InvalidLoadIndirectException(); } } } }
/* Performs loading of array element * (corresponds to CILPE.CFG.LoadElement class) */ public void Perform_LoadElement(Type type, out Exception exc) { int index = popArrayIndex(); Array array = popArray(out exc); if (exc == null) { if (type != typeof(object)) { StructValue.TypeIndex typeIndex = StructValue.getTypeIndex(type); StructValue.TypeIndex arrTypeIndex = StructValue.getTypeIndex(array.GetType().GetElementType()); if (!compareTypes(arrTypeIndex, typeIndex)) { exc = new ArrayTypeMismatchException(); } } if (exc == null) { object elem = null; try { elem = array.GetValue(index); } catch (IndexOutOfRangeException e) { exc = e; } if (exc == null) { if (StructValue.getTypeIndex(type) != StructValue.TypeIndex.INVALID) { Push(new StructValue(elem as ValueType)); } else { if (elem != null) { Push(new ObjectReferenceValue(elem)); } else { Push(new NullValue()); } } } } } }
public override void SetReferencedValue(Value val) { Type t = obj.GetType(); StructValue structVal = val.FromStack(t) as StructValue; if (structVal.IsPrimitive) { DataModelUtils.StoreToBox(obj, (int)(StructValue.getTypeIndex(t)), structVal.Obj); } else { FieldInfo[] fields = obj.GetType().GetFields((BindingFlags) (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ); foreach (FieldInfo field in fields) { field.SetValue(obj, field.GetValue(structVal.Obj)); } } }
/* Performs conversion of primitive value on top of the stack * (corresponds to CILPE.CFG.ConvertValue class) */ public void Perform_ConvertValue(Type type, bool overflow, bool unsigned, out Exception exc) { exc = null; Value val = Pop(); if (!(val is StructValue && (val as StructValue).IsPrimitive)) { throw new InvalidOperandException(); } StructValue primVal = val as StructValue; StructValue.TypeIndex typeIndex = StructValue.getTypeIndex(type), valTypeIndex = primVal.getTypeIndex(); if (!overflow && unsigned && typeIndex != StructValue.TypeIndex.FLOAT64 || overflow && typeIndex == StructValue.TypeIndex.FLOAT32 || overflow && typeIndex == StructValue.TypeIndex.FLOAT64) { throw new InvalidConvertOpException(); } object res; bool success = DataModelUtils.Convert( (int)typeIndex, overflow, unsigned, primVal.Obj, (int)valTypeIndex, out res ); if (!success) { exc = res as Exception; } else { push(new StructValue(res as ValueType)); } }
/* Performs unary operation on the value on top of the stack * (corresponds to CILPE.CFG.UnaryOp class) */ public void Perform_UnaryOp(UnaryOp.ArithOp op) { Value val = Pop(); ValueType res = null; if (val is StructValue && (val as StructValue).IsPrimitive) { StructValue strVal = val as StructValue; ValueType obj = strVal.Obj; StructValue.TypeIndex typeIndex = strVal.getTypeIndex(); if (!DataModelUtils.Unary((int)op, obj, (int)typeIndex, out res)) { throw new InvalidOperandException(); } } else { throw new InvalidOperandException(); } push(new StructValue(res)); }