public override void CallToString() { var variable = Il.DeclareLocal(_handleType); Il.SetLocal(variable); Il.LoadLocalAddress(variable); Il.Call(_tostr); }
public void EmitValueAccess(Type type) { Type memberType; if (SkipVisibility) { EmitMemberAccess(type, type.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance), ResultType.Value, out memberType); } else { Il.Call(type.GetMethod("GetValueOrDefault", Type.EmptyTypes)); } }
public void EmitMemberAssign(Type type, MemberInfo member) { switch (member.MemberType) { case MemberTypes.Property: var setter = ((PropertyInfo)member).GetSetMethod(SkipVisibility); if (setter == null) { throw new MissingMemberException(member.DeclaringType.Name, member.Name + "_set"); } Il.Call(setter, type); break; case MemberTypes.Field: Il.Stfld((FieldInfo)member); break; } }
/// <summary> /// Checks TypeCode and throws Exception if it is invalid /// </summary> public void CheckTypeCode() { LoadField(Context.Lengths); Il.Ldloc(TypeCode); // stack: [lengths, typeCode] Il.Ldelem(typeof(int)); // stack: [lengths[typeCode]] var okLabel = Il.DefineLabel("ok"); Il.Brtrue(okLabel); // if(lengths[typeCode] != 0) goto ok; Il.Ldstr("Unknown type code: "); Il.Ldloca(TypeCode); Il.Call(HackHelpers.GetMethodDefinition <int>(x => x.ToString()), typeof(int)); Il.Call(HackHelpers.GetMethodDefinition <string>(s => s + "zzz")); var constructor = typeof(DataCorruptedException).GetConstructor(new[] { typeof(string) }); if (constructor == null) { throw new MissingConstructorException(typeof(DataCorruptedException), typeof(string)); } Il.Newobj(constructor); Il.Throw(); Il.MarkLabel(okLabel); }
public void StoreObject(Type type) { if (Index == null) { return; } if (type.IsValueType) { throw new InvalidOperationException("A reference type expected"); } // Store in array of all references LoadContext(); // stack: [context] Il.Ldfld(ReaderContext.ObjectsField); // stack: [context.objects] var doneLabel = Il.DefineLabel("done"); Il.Brfalse(doneLabel); // if(context.objects == null) goto done; stack: [] LoadContext(); // stack: [context] Il.Ldfld(ReaderContext.ObjectsField); // stack: [context.objects] Il.Ldloc(Index); // stack: [context.objects, index] LoadResult(type); // stack: [context.objects, index, result] Il.Call(HackHelpers.GetMethodDefinition <Dictionary <int, object> >(dict => dict.Add(0, null))); // context.objects.Add(index, result) Il.MarkLabel(doneLabel); }
public void EmitMemberAccess(Type type, MemberInfo member, ResultType whatReturn, out Type memberType) { switch (member.MemberType) { case MemberTypes.Property: var property = (PropertyInfo)member; var getter = property.GetGetMethod(SkipVisibility); if (getter == null) { throw new MissingMemberException(member.DeclaringType.Name, member.Name + "_get"); } Il.Call(getter, type); Type propertyType = property.PropertyType; switch (whatReturn) { case ResultType.ByRefValueTypesOnly: if (!propertyType.IsValueType) { memberType = propertyType; } else { using (var temp = DeclareLocal(propertyType)) { Il.Stloc(temp); Il.Ldloca(temp); memberType = propertyType.MakeByRefType(); } } break; case ResultType.ByRefAll: throw new InvalidOperationException("It's wierd to load a property by ref for a reference type"); default: memberType = propertyType; break; } break; case MemberTypes.Field: var field = (FieldInfo)member; switch (whatReturn) { case ResultType.ByRefAll: Il.Ldflda(field); memberType = field.FieldType.MakeByRefType(); break; case ResultType.ByRefValueTypesOnly: if (field.FieldType.IsValueType) { Il.Ldflda(field); memberType = field.FieldType.MakeByRefType(); } else { Il.Ldfld(field); memberType = field.FieldType; } break; default: Il.Ldfld(field); memberType = field.FieldType; break; } break; default: throw new NotSupportedException("Member type '" + member.MemberType + "' is not supported"); } }
public override void LoadNum(string num) { Il.LoadString(num); Il.Call(_parse); }
protected override void DoNeg() { Il.Call(_neg); }
protected override void CheckEq() { Il.Call(_eq); }
protected override void DoSub() { Il.Call(_sub); }
protected override void DoAdd() { Il.Call(_add); }
protected override void CheckLte() { Il.Call(_lte); }
protected override void CheckLt() { Il.Call(_lt); }
protected override void CheckGte() { Il.Call(_gte); }
protected override void CheckGt() { Il.Call(_gt); }
protected override void CheckNeq() { Il.Call(_neq); }
public void EmitArithmeticOperation(ExpressionType nodeType, Type resultType, Type leftType, Type rightType, MethodInfo method) { if (!leftType.IsNullable() && !rightType.IsNullable()) { if (method != null) { Il.Call(method); } else { if (leftType.IsStruct()) { throw new InvalidOperationException("Unable to perfrom operation '" + nodeType + "' to a struct of type '" + leftType + "'"); } if (rightType.IsStruct()) { throw new InvalidOperationException("Unable to perfrom operation '" + nodeType + "' to a struct of type '" + rightType + "'"); } EmitOp(Il, nodeType, resultType); } } else { using (var localLeft = DeclareLocal(leftType)) using (var localRight = DeclareLocal(rightType)) { Il.Stloc(localRight); Il.Stloc(localLeft); var returnNullLabel = Il.DefineLabel("returnNull"); if (leftType.IsNullable()) { Il.Ldloca(localLeft); EmitHasValueAccess(leftType); Il.Brfalse(returnNullLabel); } if (rightType.IsNullable()) { Il.Ldloca(localRight); EmitHasValueAccess(rightType); Il.Brfalse(returnNullLabel); } if (!leftType.IsNullable()) { Il.Ldloc(localLeft); } else { Il.Ldloca(localLeft); EmitValueAccess(leftType); } if (!rightType.IsNullable()) { Il.Ldloc(localRight); } else { Il.Ldloca(localRight); EmitValueAccess(rightType); } Type argumentType = resultType.GetGenericArguments()[0]; if (method != null) { Il.Call(method); } else { EmitOp(Il, nodeType, argumentType); } Il.Newobj(resultType.GetConstructor(new[] { argumentType })); var doneLabel = Il.DefineLabel("done"); Il.Br(doneLabel); MarkLabelAndSurroundWithSP(returnNullLabel); EmitLoadDefaultValue(resultType); MarkLabelAndSurroundWithSP(doneLabel); } } }
protected override void DoMul() { Il.Call(_mul); }
protected override void DoDiv() { Il.Call(_div); }
protected override void DoAdd() { Il.Call(_concat); }