/// <summary> /// Get the value of a property on a type /// </summary> /// <typeparam name="TEmit"></typeparam> /// <typeparam name="TType"></typeparam> /// <param name="emitter"></param> /// <param name="propertyName"></param> public static void GetRuntimePropertyValue <TEmit, TType>(this OptimisingEmitter <TEmit> emitter, string propertyName) { // ReSharper disable once PossibleNullReferenceException var method = typeof(TType).GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static) !.GetMethod !; using (var local = emitter.DeclareLocal(typeof(TType), "GetRuntimePropertyValue_Callee", false)) { emitter.StoreLocal(local); emitter.LoadLocalAddress(local, true); emitter.Call(method); } }
/// <summary> /// Emit code to dynamically check for errors. If an error would occur clear out the stack and jump away to the given label /// </summary> /// <typeparam name="TEmit"></typeparam> /// <param name="emitter"></param> /// <param name="errorLabel"></param> /// <param name="parameters"></param> public void EmitDynamicWillThrow <TEmit>(OptimisingEmitter <TEmit> emitter, Compiler.Emitter.Instructions.ExceptionBlock errorLabel, IReadOnlyList <Local> parameters) { // Load parameters back onto stack for (var i = parameters.Count - 1; i >= 0; i--) { emitter.LoadLocal(parameters[i]); } // Invoke the `will throw` method to discover if this invocation would trigger a runtime error emitter.Call(WillThrow); // Create a label to jump past the error handling for the normal case var noThrowLabel = emitter.DefineLabel(); // Jump past error handling if this is ok emitter.BranchIfFalse(noThrowLabel); // If execution reaches here it means an error would occur in this operation emitter.Leave(errorLabel); emitter.MarkLabel(noThrowLabel); }
/// <summary> /// Call a method on the `Runtime` class, taking a given set of arguments /// </summary> /// <typeparam name="TEmit"></typeparam> /// <param name="emitter"></param> /// <param name="methodName"></param> /// <param name="args"></param> public static void CallRuntimeN <TEmit>(this OptimisingEmitter <TEmit> emitter, string methodName, params Type[] args) { var method = typeof(Runtime).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static, null, args, null) !; emitter.Call(method); }