/// <summary> /// Starts a locking-block scope using the given <paramref cref="lockObject"/> parameter. /// </summary> /// <param name="lockObject">The object to do the locking on.</param> /// <exception cref="NotSupportedException">Nested locks currently not supported.</exception> public void BeginLock(FieldDefinition lockObject) { var body = _method.Body; _method.Body.InitLocals = true; _lockLocal = body.Variables.Count; if (_tryBegin != null) { throw new NotSupportedException("nested locks currently not supported"); } _tryBegin = _processor.CreateLdloc(_lockLocal); body.Variables.Add(new VariableDefinition(_module.TypeSystem.Object)); _lockCheckLocal = body.Variables.Count; var checkLocalVariable = new VariableDefinition(_module.TypeSystem.Boolean); body.Variables.Add(checkLocalVariable); _processor.Emit(OpCodes.Ldsfld, lockObject); _processor.EmitStloc(_lockLocal); _processor.Emit(OpCodes.Ldc_I4_0); _processor.EmitStloc(_lockCheckLocal); _processor.Append(_tryBegin); _processor.Emit(OpCodes.Ldloca_S, checkLocalVariable); MethodReference monitorEnter = _module.ImportReference(GetMonitorEnter(_module)); _processor.Emit(OpCodes.Call, monitorEnter); }
private void CreateLibraryLoadSymbol(MethodDefinition m, string mangledName, ILProcessor processor) { int fnPtrLocalIndex = m.Body.Variables.Count; m.Body.Variables.Add(new VariableDefinition(Module.TypeSystem.IntPtr)); var importLoaderAttribute = GetImportLoaderAttribute(); if (importLoaderAttribute.LoaderCookie == null) { processor.Emit(OpCodes.Ldnull); } else { processor.Emit(OpCodes.Ldstr, importLoaderAttribute.LoaderCookie); } processor.Emit(OpCodes.Call, Module.ImportReference(importLoaderAttribute.GetInstanceMethod)); processor.Emit(OpCodes.Call, CreateOrGetLibraryLoadLib(importLoaderAttribute)); var libLoaderGetProc = new MethodReference(nameof(ICustomLibraryLoader.GetProcAddress), Module.TypeSystem.IntPtr, Module.ImportReference(importLoaderAttribute.GetInstanceMethod.ReturnType)); libLoaderGetProc.HasThis = true; libLoaderGetProc.Parameters.Add(new ParameterDefinition(Module.TypeSystem.IntPtr)); libLoaderGetProc.Parameters.Add(new ParameterDefinition(Module.TypeSystem.String)); processor.Emit(OpCodes.Ldstr, _mangledName); processor.Emit(OpCodes.Callvirt, libLoaderGetProc); processor.Emit(OpCodes.Dup); processor.EmitStloc(fnPtrLocalIndex); var reloadFnPtr = processor.CreateLdloc(fnPtrLocalIndex); processor.Emit(OpCodes.Brtrue_S, reloadFnPtr); //TODO: perhaps special error handling processor.Append(reloadFnPtr); processor.Emit(OpCodes.Stsfld, FunctionPointer); }
/// <summary> /// Emits optimal <see cref="OpCodes.Ldloc"/> instructions by a given <paramref name="variable"/>. /// </summary> /// <remarks> /// <see cref="EmitLdloc(ILProcessor, int)"/> /// </remarks> /// <param name="processor">The <see cref="ILProcessor"/>.</param> /// <param name="variable">The variable to load.</param> public static void EmitLdloc(this ILProcessor processor, VariableDefinition variable) { processor.Append(processor.CreateLdloc(variable)); }
/// <summary> /// Emits optimal <see cref="OpCodes.Ldloc"/> instructions by a given <paramref name="index"/>. /// </summary> /// <remarks> /// Optimal meaning Creating the special OpCodes(e.g. <see cref="OpCodes.Ldloc_0"/>...) /// if <paramref name="index"/> is smaller than 4. /// </remarks> /// <param name="processor">The <see cref="ILProcessor"/>.</param> /// <param name="index">The index of the variable to load.</param> public static void EmitLdloc(this ILProcessor processor, int index) { processor.Append(processor.CreateLdloc(index)); }
/// <summary> /// Creates optimal <see cref="OpCodes.Ldloc"/> instructions by a given <paramref name="variable"/>. /// </summary> /// <remarks> /// <see cref="CreateLdloc(ILProcessor, int)"/> /// </remarks> /// <param name="processor">The <see cref="ILProcessor"/>.</param> /// <param name="variable">The variable to load.</param> /// <returns>The created <see cref="Instruction"/>.</returns> public static Instruction CreateLdloc(this ILProcessor processor, VariableDefinition variable) { return(processor.CreateLdloc(variable.Index)); }