コード例 #1
0
        private JitAction<int> GenerateCode()
        {
            //Action<bool> sample =
            //    throwException =>
            //    {
            //        try
            //        {
            //            Console.WriteLine(0);
            //            if (throwException)
            //                throw new Exception("1");
            //        }
            //        catch (Exception e)
            //        {
            //            Console.WriteLine(e.Message);
            //        }
            //        finally
            //        {
            //            Console.WriteLine(2);
            //        }
            //    };

            JitFunction<IntPtr> getInstructionPointer = new JitFunction<IntPtr>(hints: FunctionHints.Naked);
            {
                Assembler assembler = getInstructionPointer.GetAssembler();
                assembler.Mov(Register.nax, Register.nbp);
                assembler.Ret();
                getInstructionPointer.Compile();
            }

            JitAction<int> testMethod = new JitAction<int>();

            unsafe
            {
                _threadData = (ThreadData*)Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ThreadData)));
                Marshal.StructureToPtr(new ThreadData(), (IntPtr)_threadData, false);

                Compiler c = testMethod.GetCompiler();
                c.Logger = new FileLogger(Console.Error);

                // arguments
                GPVar argThrowException = c.ArgGP(0);

                // special variables
                GPVar currentException = c.NewGP();
                GPVar nextException = c.NewGP();
                GPVar position = c.NewGP();

                // special prolog
                GPVar varMethodData = c.NewGP();
                GPVar varThreadData = c.NewGP();
                c.Mov(varThreadData, (IntPtr)_threadData);

                // labels
                Label leaveTry = c.DefineLabel();
                Label enterCatch = c.DefineLabel();
                Label leaveCatch = c.DefineLabel();
                Label enterFinally = c.DefineLabel();
                Label leaveFinally = c.DefineLabel();
                Label enterThrowHandler = c.DefineLabel();
                Label enterRethrowHandler = c.DefineLabel();
                Label enterLeaveHandler = c.DefineLabel();
                Label enterEndFinallyHandler = c.DefineLabel();
                Label retLabel = c.DefineLabel();

                // try
                c.Comment("Enter try");
                GenerateWriteLine(c, (Imm)0);
                c.Test(argThrowException, argThrowException);
                c.Jz(leaveTry, Hint.Taken);
                GenerateNewException(c, nextException, (Imm)1);
                c.Call(getInstructionPointer, position);
                c.Jmp(enterThrowHandler);
                c.MarkLabel(leaveTry);
                c.Jmp(enterLeaveHandler);

                // catch
                c.Comment("Enter catch");
                c.MarkLabel(enterCatch);
                GPVar varErrorCode = c.NewGP();
                GenerateLoadCurrentException(c, varErrorCode, varThreadData);
                GenerateLoadExceptionMessage(c, varErrorCode, varErrorCode);
                GenerateWriteLine(c, varErrorCode);
                c.Xor(varErrorCode, varErrorCode);
                c.Mov(Mem.sysint_ptr(varThreadData, ThreadData_ExceptionDataOffset), varErrorCode);
                c.MarkLabel(leaveCatch);
                c.Jmp(enterLeaveHandler);

                // finally
                c.Comment("Enter finally");
                c.MarkLabel(enterFinally);
                GenerateWriteLine(c, (Imm)2);
                c.MarkLabel(leaveFinally);
                c.Jmp(enterEndFinallyHandler);

                //// special epilog (throw and leave implementations)
                //c.Jmp(retLabel);

                c.Comment("Handler for 'throw' instructions");
                c.MarkLabel(enterThrowHandler);
                c.Mov(Mem.sysint_ptr(varThreadData, ThreadData_ExceptionDataOffset), nextException);
                c.Jmp(enterCatch);

                c.Comment("Handler for 'rethrow' instructions");
                c.MarkLabel(enterRethrowHandler);
                // rethrow is not implemented and not currently used
                c.Int3();

                c.Comment("Handler for 'leave' instructions");
                c.MarkLabel(enterLeaveHandler);
                c.Jmp(enterFinally);
                //c.Mov(Mem.sysint_ptr(varThreadData, ThreadData_ExceptionDataOffset), 0);
                //throw new NotImplementedException("TODO: check for a finally block");
                //c.Jmp(leaveTarget);

                c.Comment("Handler for 'endfinally' instructions");
                c.MarkLabel(enterEndFinallyHandler);
                GenerateLoadCurrentException(c, currentException, varThreadData);
                c.Test(currentException, currentException);
                c.Jnz(enterRethrowHandler, Hint.NotTaken);
                c.Jmp(retLabel);

                // return
                c.Comment("Return");
                c.MarkLabel(retLabel);
                c.Ret();

                testMethod.Compile();
            }

            return testMethod;
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: modulexcite/nasmjit
 private static IntPtr CreateMethod(IntPtr stubAddress)
 {
     JitFunction<int> jitFunction = new JitFunction<int>();
     Compiler compiler = jitFunction.GetCompiler();
     GPVar x = compiler.NewGP(VariableType.INT32);
     compiler.Mov(x, 2);
     compiler.Ret(x);
     jitFunction.Compile();
     return jitFunction.CompiledAddress;
 }
コード例 #3
0
        public void TestJitFunctionCall1()
        {
            JitFunction<int, int> caller = new JitFunction<int, int>();
            JitFunction<int, int> called = new JitFunction<int, int>(CallingConvention.MsFastCall);

            {
                Compiler compiler = called.GetCompiler();
                compiler.Logger = new FileLogger(Console.Error);
                GPVar arg = compiler.ArgGP(0);
                GPVar var = compiler.NewGP();
                compiler.Mov(var, arg);
                compiler.Imul(var, 2);
                compiler.Ret(var);
                called.Compile();
            }

            {
                Compiler compiler = caller.GetCompiler();
                compiler.Logger = new FileLogger(Console.Error);
                GPVar arg = compiler.ArgGP(0);
                GPVar var = compiler.NewGP();
                compiler.Call(called, arg, var);
                compiler.Ret(var);
            }

            var f = caller.GetDelegate<TestJitFunction2Fn>();
            int result = f(1);
            Assert.AreEqual(2, result);

            called.Dispose();
            caller.Dispose();
        }