Пример #1
0
        /// <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);
            }
        }
Пример #2
0
            /// <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);
            }
Пример #3
0
        /// <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);
        }