public void Visit(ASTNode_Application node)
            {
                var delegateType = JITInterpreter_DS2.Instance().GetDelegateType(node.actualNodes.Count);

                mTaillCallFlags.Push(false);
                node.procedureNode.AcceptVisitor(this);
                mTaillCallFlags.Pop();

                mILGenerator.Emit(OpCodes.Castclass, delegateType);
                foreach (var n in node.actualNodes)
                {
                    mTaillCallFlags.Push(false);
                    n.AcceptVisitor(this);
                    mTaillCallFlags.Pop();
                }

                if (mTaillCallFlags.All(b => b))
                {
                    mILGenerator.Emit(OpCodes.Tailcall);
                    mILGenerator.Emit(OpCodes.Callvirt, delegateType.GetMethod("Invoke"));
                    mILGenerator.Emit(OpCodes.Ret);
                }
                else
                {
                    mILGenerator.Emit(OpCodes.Callvirt, delegateType.GetMethod("Invoke"));
                }
            }
            public void Visit(ASTNode_SetVar node)
            {
                if (node.address is GlobalAddress)
                {
                    JITInterpreter_DS2.Instance().BeginEmitPopGlobal(mILGenerator, (GlobalAddress)node.address);

                    mTaillCallFlags.Push(false);
                    node.rightNode.AcceptVisitor(this);
                    mTaillCallFlags.Pop();

                    JITInterpreter_DS2.Instance().EndEmitPopGlobal(mILGenerator, (GlobalAddress)node.address);
                }
                else if (node.address is LocalAddress)
                {
                    BeginEmitPopLocal((LocalAddress)node.address);

                    mTaillCallFlags.Push(false);
                    node.rightNode.AcceptVisitor(this);
                    mTaillCallFlags.Pop();

                    EndEmitPopLocal((LocalAddress)node.address);
                }
                else
                {
                    BeginEmitPopFree((FreeAddress)node.address);

                    mTaillCallFlags.Push(false);
                    node.rightNode.AcceptVisitor(this);
                    mTaillCallFlags.Pop();

                    EndEmitPopFree((FreeAddress)node.address);
                }
                mILGenerator.Emit(OpCodes.Ldnull);
            }
 public static JITInterpreter_DS2 Instance()
 {
     if (sInstance == null)
     {
         sInstance = new JITInterpreter_DS2();
     }
     return(sInstance);
 }
            private void DeclareLocals()
            {
                var formalBuilders = new List <ParameterBuilder>();

                for (int i = 0; i < mLambdaNode.formalCount; ++i)
                {
                    formalBuilders.Add(MethodBuilder.DefineParameter(i + 1, ParameterAttributes.In, mLambdaNode.locals[i]));
                }

                var heapLocals = mLambdaNode.childrenFreeAddresses.Where(a => a.envIndex == 0).Select(a => a.index).OrderBy(a => a).ToList();

                for (int i = 0; i < mLambdaNode.formalCount; ++i)
                {
                    if (heapLocals.IndexOf(i) == -1)
                    {
                        mLocalBuilders.Add(formalBuilders[i]);
                    }
                    else
                    {
                        var localBuilder = mILGenerator.DeclareLocal(typeof(SharedValue));
                        if (JITInterpreter_DS2.Instance().HasSymbolInfo())
                        {
                            localBuilder.SetLocalSymInfo("_" + mLambdaNode.locals[i]);
                        }
                        mLocalBuilders.Add(localBuilder);

                        JITInterpreter_DS2.EmitLoadArg(mILGenerator, HasThisArgument(), formalBuilders[i]);
                        mILGenerator.Emit(OpCodes.Newobj, typeof(SharedValue).GetConstructor(new Type[] { typeof(object) }));
                        JITInterpreter_DS2.EmitStoreLocal(mILGenerator, localBuilder);
                    }
                }

                for (int i = mLambdaNode.formalCount; i < mLambdaNode.locals.Count; ++i)
                {
                    if (heapLocals.IndexOf(i) == -1)
                    {
                        var localBuilder = mILGenerator.DeclareLocal(typeof(object));
                        if (JITInterpreter_DS2.Instance().HasSymbolInfo())
                        {
                            localBuilder.SetLocalSymInfo("_" + mLambdaNode.locals[i]);
                        }
                        mLocalBuilders.Add(localBuilder);
                    }
                    else
                    {
                        var localBuilder = mILGenerator.DeclareLocal(typeof(SharedValue));
                        if (JITInterpreter_DS2.Instance().HasSymbolInfo())
                        {
                            localBuilder.SetLocalSymInfo("_" + mLambdaNode.locals[i]);
                        }
                        mLocalBuilders.Add(localBuilder);

                        mILGenerator.Emit(OpCodes.Ldnull);
                        mILGenerator.Emit(OpCodes.Newobj, typeof(SharedValue).GetConstructor(new Type[] { typeof(object) }));
                        JITInterpreter_DS2.EmitStoreLocal(mILGenerator, localBuilder);
                    }
                }
            }
 public void Visit(ASTNode_GetVar node)
 {
     if (node.address is GlobalAddress)
     {
         JITInterpreter_DS2.Instance().EmitLoadGlobal(mILGenerator, (GlobalAddress)node.address);
     }
     else if (node.address is LocalAddress)
     {
         EmitLoadLocal((LocalAddress)node.address);
     }
     else
     {
         EmitLoadFree((FreeAddress)node.address);
     }
 }
            public ASTNodeVisitor_JITCompiler(TypeBuilder parentTypeBuilder, ASTNode_Lambda node)
            {
                mLambdaNode = node;
                TypeBuilder = parentTypeBuilder.DefineNestedType(JITInterpreter_DS2.Instance().GenernateUniqueString("closure"), TypeAttributes.NestedPublic);

                ConstructorBuilder = TypeBuilder.DefineDefaultConstructor(MethodAttributes.Public);

                FieldBuilders = new Dictionary <FreeAddress, FieldBuilder>();
                foreach (var address in mLambdaNode.GetFreeAddresses())
                {
                    FieldBuilders[address] = TypeBuilder.DefineField(address.ToString(), typeof(SharedValue), FieldAttributes.Public);
                }

                if (HasThisArgument())
                {
                    MethodBuilder = TypeBuilder.DefineMethod(
                        "Invoke",
                        MethodAttributes.Public,
                        CallingConventions.HasThis,
                        typeof(object),
                        Enumerable.Repeat(typeof(object), mLambdaNode.formalCount).ToArray());
                }
                else
                {
                    MethodBuilder = TypeBuilder.DefineMethod(
                        "Invoke",
                        MethodAttributes.Static | MethodAttributes.Public,
                        CallingConventions.Standard,
                        typeof(object),
                        Enumerable.Repeat(typeof(object), mLambdaNode.formalCount).ToArray());
                }


                mILGenerator = MethodBuilder.GetILGenerator();

                DeclareLocals();

                mTaillCallFlags.Push(true);
                mLambdaNode.bodyNode.AcceptVisitor(this);
                mTaillCallFlags.Pop();

                mILGenerator.Emit(OpCodes.Ret);

                TypeBuilder.CreateType();
            }
Exemple #7
0
        static void Main(string[] args)
        {
            var tokens = Parser.Tokenize(new System.IO.StreamReader("../../test.rkt").ReadToEnd());

            while (true)
            {
                object s = Parser.Parse(tokens);
                if (s == null)
                {
                    break;
                }
                object v = JITInterpreter_DS2.Instance().Interpret(s);
                // object v = JITInterpreter_DS.Instance().Interpret(s);
                // object v = ASTInterpreter.Instance().Interpret(s);
                if (v != null)
                {
                    ListProcess.PrintPairExp(v);
                }
            }
        }
            private void EndEmitPopLocal(LocalAddress address)
            {
                var builder = mLocalBuilders[address.index];

                if (builder is ParameterBuilder)
                {
                    JITInterpreter_DS2.EmitStoreArg(mILGenerator, HasThisArgument(), builder as ParameterBuilder);
                }
                else
                {
                    LocalBuilder localBuilder = builder as LocalBuilder;
                    if (localBuilder.LocalType == typeof(object))
                    {
                        JITInterpreter_DS2.EmitStoreLocal(mILGenerator, localBuilder);
                    }
                    else
                    {
                        mILGenerator.Emit(OpCodes.Stfld, typeof(SharedValue).GetField("value"));
                    }
                }
            }
            private void BeginEmitPopLocal(LocalAddress address)
            {
                var builder = mLocalBuilders[address.index];

                if (builder is ParameterBuilder)
                {
                    //
                }
                else
                {
                    LocalBuilder localBuilder = builder as LocalBuilder;
                    if (localBuilder.LocalType == typeof(object))
                    {
                        //
                    }
                    else
                    {
                        JITInterpreter_DS2.EmitLoadLocal(mILGenerator, localBuilder);
                    }
                }
            }
            public void Visit(ASTNode_Lambda node)
            {
                var childCompiler = new ASTNodeVisitor_JITCompiler(TypeBuilder, node);

                if (childCompiler.MethodBuilder.IsStatic)
                {
                    mILGenerator.Emit(OpCodes.Ldnull);
                    mILGenerator.Emit(OpCodes.Ldftn, childCompiler.MethodBuilder);
                    mILGenerator.Emit(OpCodes.Newobj,
                                      JITInterpreter_DS2.Instance().GetDelegateType(node.formalCount).
                                      GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }));
                }
                else
                {
                    mILGenerator.Emit(OpCodes.Newobj, childCompiler.ConstructorBuilder);

                    foreach (var address in node.GetFreeAddresses())
                    {
                        mILGenerator.Emit(OpCodes.Dup);
                        if (address.envIndex == 1)
                        {
                            JITInterpreter_DS2.EmitLoadLocal(mILGenerator, (LocalBuilder)mLocalBuilders[address.index]);
                        }
                        else
                        {
                            JITInterpreter_DS2.EmitLoadThis(mILGenerator);
                            mILGenerator.Emit(OpCodes.Ldfld, FieldBuilders[address.GetOuterAddress()]);
                        }
                        mILGenerator.Emit(OpCodes.Stfld, childCompiler.FieldBuilders[address]);
                    }

                    mILGenerator.Emit(OpCodes.Ldftn, childCompiler.MethodBuilder);
                    mILGenerator.Emit(OpCodes.Newobj,
                                      JITInterpreter_DS2.Instance().GetDelegateType(node.formalCount)
                                      .GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }));
                }
            }
 public static JITInterpreter_DS2 Instance()
 {
     if (sInstance == null) sInstance = new JITInterpreter_DS2();
     return sInstance;
 }
 public void Visit(ASTNode_Literal node)
 {
     JITInterpreter_DS2.Instance().EmitLoadLiteral(mILGenerator, node.value);
 }
 private void BeginEmitPopFree(FreeAddress address)
 {
     JITInterpreter_DS2.EmitLoadThis(mILGenerator);
     mILGenerator.Emit(OpCodes.Ldfld, FieldBuilders[address]);
 }
 private void EmitLoadFree(FreeAddress address)
 {
     JITInterpreter_DS2.EmitLoadThis(mILGenerator);
     mILGenerator.Emit(OpCodes.Ldfld, FieldBuilders[address]);
     mILGenerator.Emit(OpCodes.Ldfld, typeof(SharedValue).GetField("value"));
 }