private static void EmitOverrideGetHashCode(TypeGen typeGen) { Type baseType = typeGen.TypeBuilder.BaseType; MethodInfo baseMethod = baseType.GetMethod("GetHashCode", Type.EmptyTypes); Compiler cg = typeGen.DefineMethodOverride(baseMethod); // Check if a "hash" method exists on this class cg.EmitType(typeGen.TypeBuilder); cg.EmitString("hash"); cg.EmitCall(typeof(RubyOps).GetMethod("ResolveDeclaredInstanceMethod")); Label callBase = cg.DefineLabel(); cg.Emit(OpCodes.Brfalse_S, callBase); // If so, call it cg.EmitThis(); cg.EmitCall(typeof(RubyOps).GetMethod("CallHash")); cg.EmitReturn(); // Otherwise, call base class cg.MarkLabel(callBase); cg.EmitThis(); cg.Emit(OpCodes.Call, baseMethod); // base call must be non-virtual cg.EmitReturn(); cg.Finish(); }
// we need to get the right execution context #if OBSOLETE private static void EmitOverrideEquals(TypeGen typeGen) { Type baseType = typeGen.TypeBuilder.BaseType; MethodInfo baseMethod = baseType.GetMethod("Equals", new Type[] { typeof(object) }); Compiler cg = typeGen.DefineMethodOverride(baseMethod); // Check if an "eql?" method exists on this class cg.EmitType(typeGen.TypeBuilder); cg.EmitString("eql?"); cg.EmitCall(typeof(RubyOps).GetMethod("ResolveDeclaredInstanceMethod")); Label callBase = cg.DefineLabel(); cg.Emit(OpCodes.Brfalse_S, callBase); // If so, call it cg.EmitThis(); cg.EmitArgGet(0); cg.EmitCall(typeof(RubyOps).GetMethod("CallEql")); cg.EmitReturn(); // Otherwise, call base class cg.MarkLabel(callBase); cg.EmitThis(); cg.EmitArgGet(0); cg.Emit(OpCodes.Call, baseMethod); // base call must be non-virtual cg.EmitReturn(); cg.Finish(); }