public static void GetStrLen(ITypeResolver typeResolver, out byte[] code, out IList <object> tokenResolutions, out IList <IType> locals, out IList <IParameter> parameters) { var codeBuilder = new IlCodeBuilder(); codeBuilder.LoadArgument(0); codeBuilder.SaveLocal(0); var initialJumpLabel = codeBuilder.Branch(Code.Br, Code.Br_S); var jumpBack = codeBuilder.CreateLabel(); codeBuilder.LoadLocal(0); codeBuilder.LoadConstant(1); codeBuilder.Add(Code.Conv_I); codeBuilder.Add(Code.Add); codeBuilder.SaveLocal(0); codeBuilder.Add(initialJumpLabel); codeBuilder.LoadLocal(0); codeBuilder.Add(Code.Ldind_I1); codeBuilder.LoadConstant(0); codeBuilder.Branch(Code.Bgt, Code.Bgt_S, jumpBack); codeBuilder.LoadLocal(0); codeBuilder.LoadArgument(0); codeBuilder.Add(Code.Sub); // and if element size is bugger 1, you need to devide it by element size // codeBuilder.LoadConstant(<size>); // codeBuilder.Add(Code.Div); codeBuilder.Add(Code.Ret); code = codeBuilder.GetCode(); locals = new List <IType>(); locals.Add(typeResolver.System.System_SByte.ToPointerType()); tokenResolutions = new List <object>(); parameters = new List <IParameter>(); parameters.Add(typeResolver.System.System_SByte.ToPointerType().ToParameter()); }
public static void GetStrLen(ITypeResolver typeResolver, out byte[] code, out IList<object> tokenResolutions, out IList<IType> locals, out IList<IParameter> parameters) { var codeBuilder = new IlCodeBuilder(); codeBuilder.LoadArgument(0); codeBuilder.SaveLocal(0); var initialJumpLabel = codeBuilder.Branch(Code.Br, Code.Br_S); var jumpBack = codeBuilder.CreateLabel(); codeBuilder.LoadLocal(0); codeBuilder.LoadConstant(1); codeBuilder.Add(Code.Conv_I); codeBuilder.Add(Code.Add); codeBuilder.SaveLocal(0); codeBuilder.Add(initialJumpLabel); codeBuilder.LoadLocal(0); codeBuilder.Add(Code.Ldind_I1); codeBuilder.LoadConstant(0); codeBuilder.Branch(Code.Bgt, Code.Bgt_S, jumpBack); codeBuilder.LoadLocal(0); codeBuilder.LoadArgument(0); codeBuilder.Add(Code.Sub); // and if element size is bugger 1, you need to devide it by element size // codeBuilder.LoadConstant(<size>); // codeBuilder.Add(Code.Div); codeBuilder.Add(Code.Ret); code = codeBuilder.GetCode(); locals = new List<IType>(); locals.Add(typeResolver.System.System_SByte.ToPointerType()); tokenResolutions = new List<object>(); parameters = new List<IParameter>(); parameters.Add(typeResolver.System.System_SByte.ToPointerType().ToParameter()); }
public static void Register(ITypeResolver typeResolver) { var codeList = new IlCodeBuilder(); // set Type of TypedReference codeList.LoadArgument(1); codeList.Add(Code.Ldflda, 2); // Load element typeCode codeList.LoadArgument(0); codeList.Add(Code.Castclass, 4); codeList.Add(Code.Ldfld, 5); // Save typeCode into TypedReference TypeCode codeList.Add(Code.Conv_I); codeList.Add(Code.Stfld, 3); // Calculate data index // check if it 1-dim array codeList.LoadArgument(2); codeList.LoadConstant(1); codeList.Add(Code.Sub); var labelGotoMultiDimArray = codeList.Branch(Code.Brtrue, Code.Brtrue_S); // set Value of TypedReference codeList.LoadArgument(1); codeList.Add(Code.Ldflda, 1); // Load reference to an array (do not load reference to field data) codeList.LoadArgument(0); codeList.Add(Code.Castclass, 4); // Load elementSize codeList.LoadArgument(0); codeList.Add(Code.Castclass, 4); codeList.Add(Code.Ldfld, 6); codeList.Add(Code.Dup); codeList.SaveLocal(0); // Load index codeList.LoadArgument(3); codeList.Add(Code.Ldind_I4); // multiply it codeList.Add(Code.Mul); // load address of an element codeList.Add(Code.Ldelema, 7); // align index codeList.LoadLocal(0); // elementSize - 1 codeList.LoadConstant(1); codeList.Add(Code.Sub); codeList.Add(Code.Dup); codeList.SaveLocal(0); // size + align - 1 codeList.Add(Code.Add); // size &= ~(align - 1) codeList.LoadLocal(0); codeList.LoadConstant(-1); codeList.Add(Code.Xor); codeList.Add(Code.And); // Save address into TypedReference Value codeList.Add(Code.Conv_I); codeList.Add(Code.Stfld, 3); codeList.Add(Code.Ret); // for multiarray codeList.Add(labelGotoMultiDimArray); // *indeces += count; codeList.LoadArgument(3); codeList.LoadArgument(2); codeList.Add(Code.Conv_I); codeList.LoadConstant(4); codeList.Add(Code.Mul); codeList.Add(Code.Add); codeList.SaveArgument(3); // init multiplier // Load elementSize codeList.LoadArgument(0); codeList.Add(Code.Castclass, 4); codeList.Add(Code.Ldfld, 6); codeList.SaveLocal(0); // calculate first index codeList.LoadArgument(3); codeList.LoadConstant(4); codeList.Add(Code.Sub); codeList.Add(Code.Dup); codeList.SaveArgument(3); codeList.Add(Code.Ldind_I4); codeList.LoadArgument(0); codeList.Add(Code.Castclass, 9); codeList.Add(Code.Ldfld, 10); codeList.LoadConstant(0); codeList.Add(Code.Ldelem_I4); codeList.Add(Code.Sub); codeList.LoadLocal(0); codeList.Add(Code.Mul); codeList.SaveLocal(1); // init 'i' (index) codeList.LoadConstant(1); codeList.SaveLocal(2); var labelLoopStart = codeList.Branch(Code.Br, Code.Br_S); // loop start var labelLoopBack = codeList.CreateLabel(); codeList.LoadLocal(0); codeList.LoadArgument(0); codeList.Add(Code.Castclass, 9); codeList.Add(Code.Ldfld, 11); codeList.LoadLocal(2); codeList.LoadConstant(1); codeList.Add(Code.Sub); codeList.Add(Code.Ldelem_I4); codeList.Add(Code.Mul); codeList.SaveLocal(0); codeList.LoadLocal(1); codeList.LoadArgument(3); codeList.LoadConstant(4); codeList.Add(Code.Sub); codeList.Add(Code.Dup); codeList.SaveArgument(3); codeList.Add(Code.Ldind_I4); codeList.LoadArgument(0); codeList.Add(Code.Castclass, 9); codeList.Add(Code.Ldfld, 10); codeList.LoadLocal(2); codeList.Add(Code.Ldelem_I4); codeList.Add(Code.Sub); codeList.LoadLocal(0); codeList.Add(Code.Mul); codeList.Add(Code.Add); codeList.SaveLocal(1); codeList.LoadLocal(2); codeList.LoadConstant(1); codeList.Add(Code.Add); codeList.SaveLocal(2); codeList.Add(labelLoopStart); codeList.LoadLocal(2); codeList.LoadArgument(2); codeList.Branch(Code.Blt, Code.Blt_S, labelLoopBack); // set Value of TypedReference codeList.LoadArgument(1); codeList.Add(Code.Ldflda, 1); // align index (array offset) (Local.0) and save it to TypedReferenece // Load reference to an array (do not load reference to field data) codeList.LoadArgument(0); codeList.Add(Code.Castclass, 9); codeList.LoadLocal(1); // load address of an element codeList.Add(Code.Ldelema, 7); // elementSize codeList.LoadArgument(0); codeList.Add(Code.Castclass, 4); codeList.Add(Code.Ldfld, 6); // elementSize - 1 codeList.LoadConstant(1); codeList.Add(Code.Sub); codeList.Add(Code.Dup); codeList.SaveLocal(2); // size + align - 1 codeList.Add(Code.Add); // size &= ~(align - 1) codeList.LoadLocal(2); codeList.LoadConstant(-1); codeList.Add(Code.Xor); codeList.Add(Code.And); // Save address into TypedReference Value codeList.Add(Code.Conv_I); codeList.Add(Code.Stfld, 3); codeList.Add(Code.Ret); var typedReferenceType = typeResolver.System.System_TypedReference; var intPtrType = typeResolver.System.System_IntPtr; var byteType = typeResolver.System.System_Byte; var arrayType = byteType.ToArrayType(1); var multiArrayType = byteType.ToArrayType(2); var tokenResolutions = new List <object>(); tokenResolutions.Add(typedReferenceType.GetFieldByName("Value", typeResolver)); tokenResolutions.Add(typedReferenceType.GetFieldByName("Type", typeResolver)); tokenResolutions.Add(intPtrType.GetFieldByName("m_value", typeResolver)); tokenResolutions.Add(arrayType); tokenResolutions.Add(arrayType.GetFieldByName("typeCode", typeResolver)); tokenResolutions.Add(arrayType.GetFieldByName("elementSize", typeResolver)); tokenResolutions.Add(byteType); tokenResolutions.Add(arrayType.GetFieldByName("rank", typeResolver)); tokenResolutions.Add(multiArrayType); tokenResolutions.Add(multiArrayType.GetFieldByName("lowerBounds", typeResolver)); tokenResolutions.Add(multiArrayType.GetFieldByName("lengths", typeResolver)); var locals = new List <IType>(); locals.Add(typeResolver.System.System_Int32); locals.Add(typeResolver.System.System_Int32); locals.Add(typeResolver.System.System_Int32); var parameters = new List <IParameter>(); parameters.Add(typeResolver.System.System_Void.ToPointerType().ToParameter()); parameters.Add(typeResolver.System.System_Int32.ToParameter()); parameters.Add(typeResolver.System.System_Int32.ToPointerType().ToParameter()); MethodBodyBank.Register(Name, codeList.GetCode(), tokenResolutions, locals, parameters); }
public static void Register(ITypeResolver typeResolver) { var codeList = new IlCodeBuilder(); // set Type of TypedReference codeList.LoadArgument(1); codeList.Add(Code.Ldflda, 2); // Load element typeCode codeList.LoadArgument(0); codeList.Add(Code.Castclass, 4); codeList.Add(Code.Ldfld, 5); // Save typeCode into TypedReference TypeCode codeList.Add(Code.Conv_I); codeList.Add(Code.Stfld, 3); // Calculate data index // check if it 1-dim array codeList.LoadArgument(2); codeList.LoadConstant(1); codeList.Add(Code.Sub); var labelGotoMultiDimArray = codeList.Branch(Code.Brtrue, Code.Brtrue_S); // set Value of TypedReference codeList.LoadArgument(1); codeList.Add(Code.Ldflda, 1); // Load reference to an array (do not load reference to field data) codeList.LoadArgument(0); codeList.Add(Code.Castclass, 4); // Load elementSize codeList.LoadArgument(0); codeList.Add(Code.Castclass, 4); codeList.Add(Code.Ldfld, 6); codeList.Add(Code.Dup); codeList.SaveLocal(0); // Load index codeList.LoadArgument(3); codeList.Add(Code.Ldind_I4); // multiply it codeList.Add(Code.Mul); // load address of an element codeList.Add(Code.Ldelema, 7); // align index codeList.LoadLocal(0); // elementSize - 1 codeList.LoadConstant(1); codeList.Add(Code.Sub); codeList.Add(Code.Dup); codeList.SaveLocal(0); // size + align - 1 codeList.Add(Code.Add); // size &= ~(align - 1) codeList.LoadLocal(0); codeList.LoadConstant(-1); codeList.Add(Code.Xor); codeList.Add(Code.And); // Save address into TypedReference Value codeList.Add(Code.Conv_I); codeList.Add(Code.Stfld, 3); codeList.Add(Code.Ret); // for multiarray codeList.Add(labelGotoMultiDimArray); // *indeces += count; codeList.LoadArgument(3); codeList.LoadArgument(2); codeList.Add(Code.Conv_I); codeList.LoadConstant(4); codeList.Add(Code.Mul); codeList.Add(Code.Add); codeList.SaveArgument(3); // init multiplier // Load elementSize codeList.LoadArgument(0); codeList.Add(Code.Castclass, 4); codeList.Add(Code.Ldfld, 6); codeList.SaveLocal(0); // calculate first index codeList.LoadArgument(3); codeList.LoadConstant(4); codeList.Add(Code.Sub); codeList.Add(Code.Dup); codeList.SaveArgument(3); codeList.Add(Code.Ldind_I4); codeList.LoadArgument(0); codeList.Add(Code.Castclass, 9); codeList.Add(Code.Ldfld, 10); codeList.LoadConstant(0); codeList.Add(Code.Ldelem_I4); codeList.Add(Code.Sub); codeList.LoadLocal(0); codeList.Add(Code.Mul); codeList.SaveLocal(1); // init 'i' (index) codeList.LoadConstant(1); codeList.SaveLocal(2); var labelLoopStart = codeList.Branch(Code.Br, Code.Br_S); // loop start var labelLoopBack = codeList.CreateLabel(); codeList.LoadLocal(0); codeList.LoadArgument(0); codeList.Add(Code.Castclass, 9); codeList.Add(Code.Ldfld, 11); codeList.LoadLocal(2); codeList.LoadConstant(1); codeList.Add(Code.Sub); codeList.Add(Code.Ldelem_I4); codeList.Add(Code.Mul); codeList.SaveLocal(0); codeList.LoadLocal(1); codeList.LoadArgument(3); codeList.LoadConstant(4); codeList.Add(Code.Sub); codeList.Add(Code.Dup); codeList.SaveArgument(3); codeList.Add(Code.Ldind_I4); codeList.LoadArgument(0); codeList.Add(Code.Castclass, 9); codeList.Add(Code.Ldfld, 10); codeList.LoadLocal(2); codeList.Add(Code.Ldelem_I4); codeList.Add(Code.Sub); codeList.LoadLocal(0); codeList.Add(Code.Mul); codeList.Add(Code.Add); codeList.SaveLocal(1); codeList.LoadLocal(2); codeList.LoadConstant(1); codeList.Add(Code.Add); codeList.SaveLocal(2); codeList.Add(labelLoopStart); codeList.LoadLocal(2); codeList.LoadArgument(2); codeList.Branch(Code.Blt, Code.Blt_S, labelLoopBack); // set Value of TypedReference codeList.LoadArgument(1); codeList.Add(Code.Ldflda, 1); // align index (array offset) (Local.0) and save it to TypedReferenece // Load reference to an array (do not load reference to field data) codeList.LoadArgument(0); codeList.Add(Code.Castclass, 9); codeList.LoadLocal(1); // load address of an element codeList.Add(Code.Ldelema, 7); // elementSize codeList.LoadArgument(0); codeList.Add(Code.Castclass, 4); codeList.Add(Code.Ldfld, 6); // elementSize - 1 codeList.LoadConstant(1); codeList.Add(Code.Sub); codeList.Add(Code.Dup); codeList.SaveLocal(2); // size + align - 1 codeList.Add(Code.Add); // size &= ~(align - 1) codeList.LoadLocal(2); codeList.LoadConstant(-1); codeList.Add(Code.Xor); codeList.Add(Code.And); // Save address into TypedReference Value codeList.Add(Code.Conv_I); codeList.Add(Code.Stfld, 3); codeList.Add(Code.Ret); var typedReferenceType = typeResolver.System.System_TypedReference; var intPtrType = typeResolver.System.System_IntPtr; var byteType = typeResolver.System.System_Byte; var arrayType = byteType.ToArrayType(1); var multiArrayType = byteType.ToArrayType(2); var tokenResolutions = new List<object>(); tokenResolutions.Add(typedReferenceType.GetFieldByName("Value", typeResolver)); tokenResolutions.Add(typedReferenceType.GetFieldByName("Type", typeResolver)); tokenResolutions.Add(intPtrType.GetFieldByName("m_value", typeResolver)); tokenResolutions.Add(arrayType); tokenResolutions.Add(arrayType.GetFieldByName("typeCode", typeResolver)); tokenResolutions.Add(arrayType.GetFieldByName("elementSize", typeResolver)); tokenResolutions.Add(byteType); tokenResolutions.Add(arrayType.GetFieldByName("rank", typeResolver)); tokenResolutions.Add(multiArrayType); tokenResolutions.Add(multiArrayType.GetFieldByName("lowerBounds", typeResolver)); tokenResolutions.Add(multiArrayType.GetFieldByName("lengths", typeResolver)); var locals = new List<IType>(); locals.Add(typeResolver.System.System_Int32); locals.Add(typeResolver.System.System_Int32); locals.Add(typeResolver.System.System_Int32); var parameters = new List<IParameter>(); parameters.Add(typeResolver.System.System_Void.ToPointerType().ToParameter()); parameters.Add(typeResolver.System.System_Int32.ToParameter()); parameters.Add(typeResolver.System.System_Int32.ToPointerType().ToParameter()); MethodBodyBank.Register(Name, codeList.GetCode(), tokenResolutions, locals, parameters); }
public static void GetMulticastDelegateInvoke( IMethod method, ITypeResolver typeResolver, out byte[] code, out IList<object> tokenResolutions, out IList<IType> locals, out IList<IParameter> parameters) { parameters = method.GetParameters().ToList(); var codeList = new IlCodeBuilder(); codeList.Add(Code.Ldarg_0); codeList.Add(Code.Ldfld, 1); #if MSCORLIB // to load value from IntPtr codeList.Add(Code.Ldind_I); #endif var jumpForBrtrue_S = codeList.Branch(Code.Brtrue, Code.Brtrue_S); codeList.Add(Code.Call, 2); codeList.Add(jumpForBrtrue_S); codeList.Add(Code.Ldc_I4_0); codeList.Add(Code.Stloc_0); var labelForFirstJump = codeList.Branch(Code.Br, Code.Br_S); // label var labelForConditionLoop = codeList.CreateLabel(); codeList.Add(Code.Ldarg_0); codeList.Add(Code.Ldfld, 3); #if MSCORLIB codeList.Add(Code.Castclass, 5); #endif codeList.Add(Code.Ldloc_0); codeList.Add(Code.Ldelem_Ref); var index = 1; foreach (var parameter in parameters) { codeList.LoadArgument(index); index++; } codeList.Add(Code.Callvirt, 4); if (!method.ReturnType.IsVoid()) { codeList.Add(Code.Stloc_1); } codeList.LoadLocal(0); codeList.LoadConstant(1); codeList.Add(Code.Add); codeList.SaveLocal(0); // label codeList.Add(labelForFirstJump); // for test codeList.LoadLocal(0); codeList.LoadArgument(0); codeList.Add(Code.Ldfld, 1); #if MSCORLIB // to load value from IntPtr codeList.Add(Code.Ldind_I); #endif codeList.Branch(Code.Blt, Code.Blt_S, labelForConditionLoop); if (!method.ReturnType.IsVoid()) { codeList.Add(Code.Ldloc_1); } codeList.Add(Code.Ret); code = codeList.GetCode(); locals = new List<IType>(); locals.Add(typeResolver.System.System_Int32); if (!method.ReturnType.IsVoid()) { locals.Add(method.ReturnType); } tokenResolutions = new List<object>(); // 1 tokenResolutions.Add(method.DeclaringType.BaseType.GetFieldByName("_invocationCount", typeResolver)); // call Delegate.Invoke // 2 tokenResolutions.Add( new SynthesizedStaticMethod( string.Empty, method.DeclaringType, typeResolver.System.System_Void, new List<IParameter>(), (llvmWriter, opCode) => { // get element size llvmWriter.WriteDelegateInvoke(method, true, true); })); // 3 tokenResolutions.Add(method.DeclaringType.BaseType.GetFieldByName("_invocationList", typeResolver)); // call Default stub for now - "ret undef"; // 4 tokenResolutions.Add(IlReader.Methods(method.DeclaringType, typeResolver).First(m => m.Name == "Invoke")); #if MSCORLIB // 5, to case Object to Object[] tokenResolutions.Add(typeResolver.System.System_Object.ToArrayType(1)); #endif }
public static void GetMulticastDelegateInvoke( IMethod method, ITypeResolver typeResolver, out byte[] code, out IList <object> tokenResolutions, out IList <IType> locals, out IList <IParameter> parameters) { parameters = method.GetParameters().ToList(); var codeList = new IlCodeBuilder(); codeList.Add(Code.Ldarg_0); codeList.Add(Code.Ldfld, 1); #if MSCORLIB // to load value from IntPtr codeList.Add(Code.Ldind_I); #endif var jumpForBrtrue_S = codeList.Branch(Code.Brtrue, Code.Brtrue_S); codeList.Add(Code.Call, 2); codeList.Add(jumpForBrtrue_S); codeList.Add(Code.Ldc_I4_0); codeList.Add(Code.Stloc_0); var labelForFirstJump = codeList.Branch(Code.Br, Code.Br_S); // label var labelForConditionLoop = codeList.CreateLabel(); codeList.Add(Code.Ldarg_0); codeList.Add(Code.Ldfld, 3); #if MSCORLIB codeList.Add(Code.Castclass, 5); #endif codeList.Add(Code.Ldloc_0); codeList.Add(Code.Ldelem_Ref); var index = 1; foreach (var parameter in parameters) { codeList.LoadArgument(index); index++; } codeList.Add(Code.Callvirt, 4); if (!method.ReturnType.IsVoid()) { codeList.Add(Code.Stloc_1); } codeList.LoadLocal(0); codeList.LoadConstant(1); codeList.Add(Code.Add); codeList.SaveLocal(0); // label codeList.Add(labelForFirstJump); // for test codeList.LoadLocal(0); codeList.LoadArgument(0); codeList.Add(Code.Ldfld, 1); #if MSCORLIB // to load value from IntPtr codeList.Add(Code.Ldind_I); #endif codeList.Branch(Code.Blt, Code.Blt_S, labelForConditionLoop); if (!method.ReturnType.IsVoid()) { codeList.Add(Code.Ldloc_1); } codeList.Add(Code.Ret); code = codeList.GetCode(); locals = new List <IType>(); locals.Add(typeResolver.System.System_Int32); if (!method.ReturnType.IsVoid()) { locals.Add(method.ReturnType); } tokenResolutions = new List <object>(); // 1 tokenResolutions.Add(method.DeclaringType.BaseType.GetFieldByName("_invocationCount", typeResolver)); // call Delegate.Invoke // 2 tokenResolutions.Add( new SynthesizedStaticMethod( string.Empty, method.DeclaringType, typeResolver.System.System_Void, new List <IParameter>(), (llvmWriter, opCode) => { // get element size llvmWriter.WriteDelegateInvoke(method, true, true); })); // 3 tokenResolutions.Add(method.DeclaringType.BaseType.GetFieldByName("_invocationList", typeResolver)); // call Default stub for now - "ret undef"; // 4 tokenResolutions.Add(IlReader.Methods(method.DeclaringType, typeResolver).First(m => m.Name == "Invoke")); #if MSCORLIB // 5, to case Object to Object[] tokenResolutions.Add(typeResolver.System.System_Object.ToArrayType(1)); #endif }