public void Visit(ASTNode_Application node) { var delegateType = JITInterpreter_DS.Instance().GetDelegateType(node.actualNodes.Count); mTailCallFlags.Push(false); node.procedureNode.AcceptVisitor(this); mTailCallFlags.Pop(); mILGenerator.Emit(OpCodes.Castclass, delegateType); foreach (var n in node.actualNodes) { mTailCallFlags.Push(false); n.AcceptVisitor(this); mTailCallFlags.Pop(); } if (mTailCallFlags.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_DS.Instance().BeginEmitPopGlobal(mILGenerator, (GlobalAddress)node.address); mTailCallFlags.Push(false); node.rightNode.AcceptVisitor(this); mTailCallFlags.Pop(); JITInterpreter_DS.Instance().EndEmitPopGlobal(mILGenerator, (GlobalAddress)node.address); } else if (node.address is LocalAddress) { BeginEmitPopLocal((LocalAddress)node.address); mTailCallFlags.Push(false); node.rightNode.AcceptVisitor(this); mTailCallFlags.Pop(); EndEmitPopLocal((LocalAddress)node.address); } else { var context = BeginEmitPopFree((FreeAddress)node.address); mTailCallFlags.Push(false); node.rightNode.AcceptVisitor(this); mTailCallFlags.Pop(); EndEmitPopFree((FreeAddress)node.address, context); } mILGenerator.Emit(OpCodes.Ldnull); }
public static JITInterpreter_DS Instance() { if (sInstance == null) { sInstance = new JITInterpreter_DS(); } return(sInstance); }
private void DeclareLocals() { for (var i = mLambdaNode.formalCount; i < mLambdaNode.locals.Count; ++i) { var localBuilder = mILGenerator.DeclareLocal(typeof(object)); if (JITInterpreter_DS.Instance().HasSymbolInfo()) { localBuilder.SetLocalSymInfo(mLambdaNode.locals[i]); } mLocalBuilders.Add(localBuilder); } }
private FieldBuilder EmitLoadFreeEnv(FreeAddress address) { JITInterpreter_DS.EmitLoadThis(mILGenerator); ASTNodeVisitor_JITCompiler visitor = mParent; for (int i = 1; i < address.envIndex; ++i) { mILGenerator.Emit(OpCodes.Ldfld, visitor.mHeapEnvFieldBuilders[PREV_ENV_FIELD_NAME]); visitor = visitor.mParent; } return(visitor.mHeapEnvFieldBuilders[visitor.mLambdaNode.locals[address.index]]); }
public void Visit(ASTNode_GetVar node) { if (node.address is GlobalAddress) { JITInterpreter_DS.Instance().EmitLoadGlobal(mILGenerator, (GlobalAddress)node.address); } else if (node.address is LocalAddress) { EmitLoadLocal((LocalAddress)node.address); } else { EmitLoadFree((FreeAddress)node.address); } }
private void EndEmitPopLocal(LocalAddress address) { string localName = mLambdaNode.locals[address.index]; if (mHeapEnvFieldBuilders.ContainsKey(localName)) { mILGenerator.Emit(OpCodes.Stfld, mHeapEnvFieldBuilders[localName]); } else if (address.index < mLambdaNode.formalCount) { JITInterpreter_DS.EmitStoreArg(mILGenerator, HasThisArgument(), mArgBuilders[address.index]); } else { JITInterpreter_DS.EmitStoreLocal(mILGenerator, mLocalBuilders[address.index - mLambdaNode.formalCount]); } }
private void BeginEmitPopLocal(LocalAddress address) { string localName = mLambdaNode.locals[address.index]; if (mHeapEnvFieldBuilders.ContainsKey(localName)) { JITInterpreter_DS.EmitLoadLocal(mILGenerator, mHeapEnvBuilder); } else if (address.index < mLambdaNode.formalCount) { // } else { // } }
private void EmitInitHeapEnv() { if (!HasHeapEnv()) { return; } mHeapEnvBuilder = mILGenerator.DeclareLocal(mHeapEnvTypeBuilder); if (JITInterpreter_DS.Instance().HasSymbolInfo()) { mHeapEnvBuilder.SetLocalSymInfo(HEAP_ENV_LOCAL_NAME); } var constructor = mHeapEnvTypeBuilder.DefineDefaultConstructor(MethodAttributes.Public); mILGenerator.Emit(OpCodes.Newobj, constructor); EmitStoreLocal(mILGenerator, mHeapEnvBuilder); if (mLambdaNode.childrenFreeAddresses.Where(v => v.envIndex > 0).GetEnumerator().MoveNext()) { var fieldBuilder = mHeapEnvTypeBuilder.DefineField(PREV_ENV_FIELD_NAME, mEnvTypeBuilder, FieldAttributes.Public); mHeapEnvFieldBuilders[PREV_ENV_FIELD_NAME] = fieldBuilder; JITInterpreter_DS.EmitLoadLocal(mILGenerator, mHeapEnvBuilder); JITInterpreter_DS.EmitLoadThis(mILGenerator); mILGenerator.Emit(OpCodes.Stfld, fieldBuilder); } var heapLocals = mLambdaNode.childrenFreeAddresses.Where(a => a.envIndex == 0).Select(a => a.index).OrderBy(a => a).ToList(); foreach (var index in heapLocals) { var fieldBuilder = mHeapEnvTypeBuilder.DefineField(mLambdaNode.locals[index], typeof(object), FieldAttributes.Public); mHeapEnvFieldBuilders[mLambdaNode.locals[index]] = fieldBuilder; if (index < mLambdaNode.formalCount) { JITInterpreter_DS.EmitLoadLocal(mILGenerator, mHeapEnvBuilder); JITInterpreter_DS.EmitLoadArg(mILGenerator, HasThisArgument(), mArgBuilders[index]); mILGenerator.Emit(OpCodes.Stfld, fieldBuilder); } } }
public ASTNodeVisitor_JITCompiler(ASTNodeVisitor_JITCompiler parent, TypeBuilder envTypeBuilder, ASTNode_Lambda node) { mParent = parent; mEnvTypeBuilder = envTypeBuilder; mLambdaNode = node; mHeapEnvTypeBuilder = envTypeBuilder.DefineNestedType(JITInterpreter_DS.Instance().GenernateUniqueString("nested_class")); if (HasThisArgument()) { MethodBuilder = envTypeBuilder.DefineMethod( JITInterpreter_DS.Instance().GenernateUniqueString("method"), MethodAttributes.Public, CallingConventions.HasThis, typeof(object), Enumerable.Repeat(typeof(object), mLambdaNode.formalCount).ToArray()); } else { MethodBuilder = envTypeBuilder.DefineMethod( JITInterpreter_DS.Instance().GenernateUniqueString("static_method"), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, typeof(object), Enumerable.Repeat(typeof(object), mLambdaNode.formalCount).ToArray()); } mILGenerator = MethodBuilder.GetILGenerator(); DeclareArguments(); DeclareLocals(); EmitInitHeapEnv(); mTailCallFlags.Push(true); mLambdaNode.bodyNode.AcceptVisitor(this); mTailCallFlags.Pop(); mILGenerator.Emit(OpCodes.Ret); mHeapEnvTypeBuilder.CreateType(); }
public void Visit(ASTNode_Lambda node) { var methodBuilder = new ASTNodeVisitor_JITCompiler(this, mHeapEnvTypeBuilder, node).MethodBuilder; if (methodBuilder.IsStatic) { mILGenerator.Emit(OpCodes.Ldnull); mILGenerator.Emit(OpCodes.Ldftn, methodBuilder); mILGenerator.Emit(OpCodes.Newobj, JITInterpreter_DS.Instance().GetDelegateType(node.formalCount). GetConstructor(new Type[] { typeof(object), typeof(IntPtr) })); } else { JITInterpreter_DS.EmitLoadLocal(mILGenerator, mHeapEnvBuilder); mILGenerator.Emit(OpCodes.Ldftn, methodBuilder); mILGenerator.Emit(OpCodes.Newobj, JITInterpreter_DS.Instance().GetDelegateType(node.formalCount) .GetConstructor(new Type[] { typeof(object), typeof(IntPtr) })); } }
public void Visit(ASTNode_Literal node) { JITInterpreter_DS.Instance().EmitLoadLiteral(mILGenerator, node.value); }
public static JITInterpreter_DS Instance() { if (sInstance == null) sInstance = new JITInterpreter_DS(); return sInstance; }