private void LoadClassesMethods(BaseSymbol root, AssemblyGen ag) { root.Symbols.ForEach(s => { if (s.GrammarMember == GrammarMemberType.NonTerm) { NonTerm nonTerm = s as NonTerm; switch (nonTerm.TypeNonTerm) { case NonTermType.Class: Token termClassId; List <BaseSymbol> declarations; NonTermFactory.GetClassDecl(nonTerm, out termClassId, out declarations); string classId = termClassId.Value; TypeGen cl = _classesTable[classId]; Dictionary <string, MethodGen> methodsDictionary = new Dictionary <string, MethodGen>(); foreach (var declaration in declarations) { if ((declaration as NonTerm).TypeNonTerm == NonTermType.Method) { KeyValuePair <string, MethodGen> method = GenerateMethodSignature(cl, declaration, ag); methodsDictionary.Add(method.Key, method.Value); } } _methodsTables.Add(cl.Name, methodsDictionary); break; } } }); }
public void TestLeaked() { var prev = RunSharpDebug.LeakingDetection; // exception in a finalizer may terminate runtime // we don't want this RunSharpDebug.LeakingDetection = LeakingDetectionMode.StoreAndContinue; try { RunSharpDebug.RetrieveLeaks(); Assert.IsEmpty(RunSharpDebug.RetrieveLeaks()); TestingFacade.RunTest( ag => { Assert.IsEmpty(RunSharpDebug.RetrieveLeaks()); TypeGen DeclareArraysSample = ag.Class("DecalreArraysSample"); { CodeGen g = DeclareArraysSample.Public.Static.Method(typeof(void), "Main"); { var asStream = ag.ExpressionFactory.New(typeof(MemoryStream)).Cast(typeof(Stream)); asStream.GetType().GetHashCode(); } } }); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); Assert.IsNotEmpty(RunSharpDebug.RetrieveLeaks()); } finally { RunSharpDebug.LeakingDetection = prev; } }
private void CompileWithStaticGlobals(out DlrMainCallTarget target, out IAttributesCollection globals) { // Create typegen TypeGen typeGen = Snippets.Shared.DefineType(MakeDebugName(), typeof(CustomSymbolDictionary), false, SourceUnit.EmitDebugSymbols); typeGen.TypeBuilder.DefineDefaultConstructor(MethodAttributes.Public); // Create rewriter GlobalStaticFieldRewriter rewriter = new GlobalStaticFieldRewriter(typeGen); // Compile lambda LambdaExpression lambda = rewriter.RewriteLambda(Code, "Initialize"); lambda.CompileToMethod(typeGen.TypeBuilder, CompilerHelpers.PublicStatic, SourceUnit.EmitDebugSymbols); // Create globals dictionary, finish type rewriter.EmitDictionary(); Type type = typeGen.FinishType(); globals = (IAttributesCollection)Activator.CreateInstance(type); // Create target target = (DlrMainCallTarget)Delegate.CreateDelegate(typeof(DlrMainCallTarget), type.GetMethod("Initialize")); // TODO: clean this up after clarifying dynamic site initialization logic InitializeFields(type); }
private Expression RewriteCallSite(CallSite site, TypeGen tg) { IExpressionSerializable serializer = site.Binder as IExpressionSerializable; if (serializer == null) { throw new ArgumentException("Generating code from non-serializable CallSiteBinder."); } Type siteType = site.GetType(); FieldBuilder fb = tg.AddStaticField(siteType, "sf" + (_id++).ToString()); Expression init = Expression.Call(siteType.GetMethod("Create"), serializer.CreateExpression()); _fieldBuilders.Add(fb); _fieldInits.Add(init); //Type t = init.Type; //if (t.IsGenericType) //{ // Type[] args = t.GetGenericArguments()[0].GetGenericArguments(); ; // // skip the first one, it is the site. // for (int k = 1; k < args.Length; k++) // { // Type p = args[k]; // //if (!p.Assembly.GetName().Name.Equals("mscorlib") && !p.Assembly.GetName().Name.Equals("Clojure")) // // Console.WriteLine("Found {0}", p.ToString()); // } //} // rewrite the node... return(Expression.Field(null, fb)); }
// example based on the MSDN Arrays Sample (arrays.cs) public static void GenArrays(AssemblyGen ag) { TypeGen DeclareArraysSample = ag.Class("DecalreArraysSample"); { CodeGen g = DeclareArraysSample.Public.Static.Void("Main"); { // Single-dimensional array Operand numbers = g.Local(Exp.NewArray <int>(5)); // Multidimensional array Operand names = g.Local(Exp.NewArray <string>(5, 4)); // Array-of-arrays (jagged array) Operand scores = g.Local(Exp.NewArray <byte[]>(5)); // Create the jagged array Operand i = g.Local(); g.For(i.Assign(0), i < scores.ArrayLength(), i.Increment()); { g.Assign(scores[i], Exp.NewArray <byte>(i + 3)); } g.End(); // Print length of each row g.For(i.Assign(0), i < scores.ArrayLength(), i.Increment()); { g.WriteLine("Length of row {0} is {1}", i, scores[i].ArrayLength()); } g.End(); } } }
public static void GenTypeAttributeTest(AssemblyGen ag) { TypeGen MyAttribute = ag.Public.Class("MyAttribute", typeof(Attribute)) .BeginAttribute <AttributeUsageAttribute>(AttributeTargets.Class).Set("AllowMultiple", true).End(); FieldGen testField = MyAttribute.Field <object>("testField") .Attribute <DescriptionAttribute>("Test field"); PropertyGen testProperty = MyAttribute.Public.SimpleProperty(testField, "TestProperty") .Attribute <ObsoleteAttribute>("Do not use this"); testProperty.Getter().Attribute <DescriptionAttribute>("Getter method"); testProperty.Getter().ReturnParameter.Attribute <DescriptionAttribute>("Getter return value"); testProperty.Setter().Attribute <DescriptionAttribute>("Setter method"); TypeGen tg = ag.Class("Test") .BeginAttribute(MyAttribute).Set("TestProperty", 3).End() .Attribute <DescriptionAttribute>("Test class"); tg.Static.Void("Main") .BeginAttribute(MyAttribute).Set("TestProperty", 3).End(); TypeGen SimpleDelegate = ag.DelegateVoid("SimpleDelegate") .Attribute <DescriptionAttribute>("Test delegate"); EventGen TestEvent = tg.Static.Event(SimpleDelegate, "TestEvent") .Attribute <DescriptionAttribute>("Test event"); TestEvent.AddMethod().Attribute <DescriptionAttribute>("Event add method"); TestEvent.RemoveMethod().Attribute <DescriptionAttribute>("Event remove method"); }
// example based on the MSDN Arrays Sample (arrays.cs) public static void GenArrays(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; TypeGen DeclareArraysSample = ag.Class("DecalreArraysSample"); { CodeGen g = DeclareArraysSample.Public.Static.Method(typeof(void), "Main"); { // Single-dimensional array var numbers = g.Local(exp.NewArray(typeof(int), 5)); // Multidimensional array var names = g.Local(exp.NewArray(typeof(string), 5, 4)); // Array-of-arrays (jagged array) var scores = g.Local(exp.NewArray(typeof(byte[]), 5)); // Create the jagged array var i = g.Local(); g.For(i.Assign(0), i < scores.ArrayLength(), i.Increment()); { g.Assign(scores[i], exp.NewArray(typeof(byte), i + 3)); } g.End(); // Print length of each row from 3 g.For(i.Assign(2), i < scores.ArrayLength(), i.Increment()); { g.WriteLine("Length of row {0} is {1}", i, scores[i].ArrayLength()); } g.End(); } } }
public static void GenIsNull(AssemblyGen ag) { TypeGen Test = ag.Class("Test"); { CodeGen g = Test.Static.Method(typeof(void), "Main"); { Operand a = g.Local(typeof(object), "notnull"); Operand b = g.Local(typeof(object), null); g.If(a == null); { g.WriteLine("a is null"); } g.Else(); { g.WriteLine("a is not null"); } g.End(); g.If(b == null); { g.WriteLine("b is null"); } g.Else(); { g.WriteLine("b is not null"); } g.End(); } } }
public void GenerateAssembly(string path) { _assemblyGen = new AssemblyGen("output", new CompilerOptions { OutputPath = path, SymbolInfo = true, TargetFrameworkName = "4.5", TargetFrameworkDisplayName = "4.5" }); using (_assemblyGen.Namespace("Language")) { _currentProgram = _assemblyGen.Public.Class("Program"); { Visit(_program); } var type = _currentProgram.GetCompletedType(true); _currentProgram = _assemblyGen.Public.Class("Runner"); { CodeGen method = _currentProgram.Public.Static.Method(typeof(void), "Main"); { Operand obj = method.Local(_currentProgram.ExpressionFactory.New(type)); method.Invoke(obj, "main"); method.WriteLine("Press any key..."); method.Invoke(typeof(Console), "ReadKey"); } } } _assemblyGen.Save(); }
public static void ClassImpl(AssemblyGen ag, bool impl) { ITypeMapper m = ag.TypeMapper; TypeGen Test = ag.Class("Test"); { CodeGen g = Test.Public.Static.Method(typeof(void), "Main"); { // test calling virtual member directly on a literal // g.Local(Operand.FromObject(3).Invoke("GetHashCode")); // test special case where the value type target doesn't implement the virtual function var value = g.Local(Test); g.Assign(value, ag.ExpressionFactory.New(Test)); g.WriteLine("Hash code of {0} is {1}", value, value.Invoke("GetHashCode")); } if (impl) { g = Test.Public.Override.Method(typeof(int), "GetHashCode"); { g.Return(-1); } } } }
/// <summary> /// Загрузка всех классов (наследование учитывается). /// Допущение - классы-наследники должны располагаться после базовых классов /// и иерархий наследования должно быть не более 1. /// </summary> /// <param name="root">Базовый символ</param> /// <param name="ag">Сборка</param> private void LoadClassesExtends(BaseSymbol root, AssemblyGen ag) { root.Symbols.ForEach(s => { if (s.GrammarMember == GrammarMemberType.NonTerm) { NonTerm nonTerm = s as NonTerm; switch (nonTerm.TypeNonTerm) { case NonTermType.Class: Token termClassId; NonTerm extends; NonTermFactory.GetClassDecl(nonTerm, out termClassId, out extends); string classId = termClassId.Value; if (extends == null) { TypeGen cl = ag.Class(classId); _classesTable.Add(cl.Name, cl); } else { Token baseClassId; NonTermFactory.GetClassId(extends, out baseClassId); TypeGen cl = _classesTable[baseClassId.Value]; cl = ag.Class(classId, cl); _classesTable.Add(cl.Name, cl); } break; } } }); }
internal PropertyGen(TypeGen owner, MethodAttributes attrs, Type type, string name) { this.owner = owner; this.attrs = attrs; this.type = type; this.name = name; }
private void AddPythonModuleAttribute(TypeGen tg, string moduleName) { assemblyGen.myAssembly.SetCustomAttribute(new CustomAttributeBuilder( typeof(PythonModuleAttribute).GetConstructor( new Type[] { typeof(string), typeof(Type) }), new Object[] { moduleName, tg.myType })); }
internal EventGen(TypeGen owner, string name, Type type, MethodAttributes mthAttr) { _owner = owner; Name = name; _type = type; _attrs = mthAttr; }
// we need to get the right execution context #if OBSOLETE private static void EmitOverrideEquals(TypeGen typeGen) { Type baseType = typeGen.TypeBuilder.BaseType; MethodInfo baseMethod = baseType.GetMethod("Equals", new Type[] { typeof(object) }); Compiler cg = typeGen.DefineMethodOverride(baseMethod); // Check if an "eql?" method exists on this class cg.EmitType(typeGen.TypeBuilder); cg.EmitString("eql?"); cg.EmitCall(typeof(RubyOps).GetMethod("ResolveDeclaredInstanceMethod")); Label callBase = cg.DefineLabel(); cg.Emit(OpCodes.Brfalse_S, callBase); // If so, call it cg.EmitThis(); cg.EmitArgGet(0); cg.EmitCall(typeof(RubyOps).GetMethod("CallEql")); cg.EmitReturn(); // Otherwise, call base class cg.MarkLabel(callBase); cg.EmitThis(); cg.EmitArgGet(0); cg.Emit(OpCodes.Call, baseMethod); // base call must be non-virtual cg.EmitReturn(); cg.Finish(); }
private static void EmitOverrideGetHashCode(TypeGen typeGen) { Type baseType = typeGen.TypeBuilder.BaseType; MethodInfo baseMethod = baseType.GetMethod("GetHashCode", Type.EmptyTypes); Compiler cg = typeGen.DefineMethodOverride(baseMethod); // Check if a "hash" method exists on this class cg.EmitType(typeGen.TypeBuilder); cg.EmitString("hash"); cg.EmitCall(typeof(RubyOps).GetMethod("ResolveDeclaredInstanceMethod")); Label callBase = cg.DefineLabel(); cg.Emit(OpCodes.Brfalse_S, callBase); // If so, call it cg.EmitThis(); cg.EmitCall(typeof(RubyOps).GetMethod("CallHash")); cg.EmitReturn(); // Otherwise, call base class cg.MarkLabel(callBase); cg.EmitThis(); cg.Emit(OpCodes.Call, baseMethod); // base call must be non-virtual cg.EmitReturn(); cg.Finish(); }
protected virtual MethodBuilder CompileForSave(TypeGen typeGen, Dictionary <SymbolId, FieldBuilder> symbolDict) { var diskRewriter = new ToDiskRewriter(typeGen); var lambda = diskRewriter.RewriteLambda(_code); return(lambda.CompileToMethod(typeGen.TypeBuilder, CompilerHelpers.PublicStatic | MethodAttributes.SpecialName, false)); }
public RunSharpBasedPropertyValuesBuilder(string propertyName, TypeGen typeGen, CreatedPropertySetObjectContainer container) { _propertyName = propertyName; _typeGen = typeGen; _container = container; _type = typeof(T); _fieldName = propertyName.ToLowerInvariant(); }
internal PropertyGen(TypeGen owner, MethodAttributes attrs, Type type, string name) { _owner = owner; _attrs = attrs; _type = type; Name = name; _indexParameters = new ParameterGenCollection(owner.TypeMapper); }
public FrameLocal(string name, TypeGen type, FrameScope frameScope) { Type = TypeGen = type; Name = name; Scope = frameScope; MangledName = "l" + MangleCounter++; //Console.WriteLine("Added " + name + " as " + MangledName + " of type " + type + " to " + Scope.Typegen); } // (name.Contains("*") ? "_ctxl_" : "") +
private void MaybeInit() { if (_typeBuilder == null) { _typeBuilder = _assemblyGen.DefinePublicType(_typeName, typeof(object), true); _typeGen = new TypeGen(_assemblyGen, _typeBuilder); _siteInfos = new List <SiteInfo>(); } }
protected override KeyValuePair <MethodBuilder, Type> CompileForSave(TypeGen typeGen) { var lambda = RewriteForSave(typeGen, _code); MethodBuilder mb = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName); lambda.CompileToMethod(mb, false); return(new KeyValuePair <MethodBuilder, Type>(mb, typeof(DlrMainCallTarget))); }
internal FieldGen(TypeGen owner, string name, Type type, FieldAttributes attrs) { _owner = owner; _attrs = attrs; Name = name; _type = type; _fb = owner.TypeBuilder.DefineField(name, type, attrs); owner.RegisterForCompletion(this); }
private void MaybeInit() { if (_typeBuilder == null) { _typeBuilder = _assemblyGen.DefinePublicType(_typeName, typeof(object), true); _typeGen = new TypeGen(_assemblyGen, _typeBuilder); _fieldBuilders = new List <FieldBuilder>(); _fieldInits = new List <Expression>(); } }
// example based on the MSDN Hello World Sample (Hello1.cs) public static void GenHello1(AssemblyGen ag) { TypeGen Hello1 = ag.Public.Class("Hello1"); { CodeGen g = Hello1.Public.Static.Method(typeof(void), "Main"); { g.WriteLine("Hello, World!"); } } }
internal EventGen(TypeGen owner, string name, Type type, MethodAttributes mthAttr) { this.owner = owner; this.name = name; this.type = type; this.attrs = mthAttr; eb = owner.TypeBuilder.DefineEvent(name, EventAttributes.None, type); owner.RegisterForCompletion(this); }
private void EmitClass(NonTerm nonTerm) { Token termClassId; List <BaseSymbol> declarations; NonTermFactory.GetClassDecl(nonTerm, out termClassId, out declarations); _currentClass = _classesTable[termClassId.Value]; declarations.ForEach(symbol => Generate(symbol)); }
public static void GenOriginalTest(AssemblyGen ag) { TypeGen Test = ag.Class("Test"); { CodeGen g = Test.Static.Method(typeof(void), "Main"); { Operand value = g.Local(typeof(int), 3); g.WriteLine("Hash code of {0} is {1}", value, value.Invoke("GetHashCode")); } } }
internal MethodBuilder CompileToDisk(TypeGen typeGen, Dictionary <SymbolId, FieldBuilder> symbolDict) { if (_code == null) { throw Error.NoCodeToCompile(); } MethodBuilder mb = CompileForSave(typeGen, symbolDict); return(mb); }
// example based on the MSDN Operator Overloading Sample (complex.cs) public static void GenComplex(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; ITypeMapper m = ag.TypeMapper; TypeGen Complex = ag.Public.Struct("Complex"); { FieldGen real = Complex.Public.Field(typeof(int), "real"); FieldGen imaginary = Complex.Public.Field(typeof(int), "imaginary"); CodeGen g = Complex.Public.Constructor() .Parameter(typeof(int), "real") .Parameter(typeof(int), "imaginary") ; { g.Assign(real, g.Arg("real")); g.Assign(imaginary, g.Arg("imaginary")); } // Declare which operator to overload (+), the types // that can be added (two Complex objects), and the // return type (Complex): g = Complex.Operator(Operator.Add, Complex, Complex, "c1", Complex, "c2"); { var c1 = g.Arg("c1"); var c2 = g.Arg("c2"); g.Return(exp.New(Complex, c1.Field("real") + c2.Field("real"), c1.Field("imaginary") + c2.Field("imaginary"))); } // Override the ToString method to display an complex number in the suitable format: g = Complex.Public.Override.Method(typeof(string), "ToString"); { g.Return(st.Invoke(typeof(string), "Format", "{0} + {1}i", real, imaginary)); } g = Complex.Public.Static.Method(typeof(void), "Main"); { var num1 = g.Local(exp.New(Complex, 2, 3)); var num2 = g.Local(exp.New(Complex, 3, 4)); // Add two Complex objects (num1 and num2) through the // overloaded plus operator: var sum = g.Local(num1 + num2); // Print the numbers and the sum using the overriden ToString method: g.WriteLine("First complex number: {0}", num1); g.WriteLine("Second complex number: {0}", num2); g.WriteLine("The sum of the two numbers: {0}", sum); } } }
private void CompilePythonModule(string fileName, PythonCompilerSink sink, bool createMain) { assemblyGen.SetPythonSourceFile(fileName); CompilerContext context = new CompilerContext(fileName, sink); Parser p = Parser.FromFile(state, context); Stmt body = p.ParseFileInput(); if (sink.Errors > 0) { return; } GlobalSuite gs = IronPython.Compiler.Binder.Bind(body, context); string moduleName = Path.GetFileNameWithoutExtension(fileName); TypeGen tg = OutputGenerator.GenerateModuleType(moduleName, assemblyGen); CodeGen init; if (!AutoImportAll) { init = OutputGenerator.GenerateModuleInitialize(context, gs, tg); } else { // auto-import all compiled modules, useful for CodeDom scenarios. init = OutputGenerator.GenerateModuleInitialize(context, gs, tg, delegate(CodeGen cg) { for (int i = 0; i < sourceFiles.Count; i++) { string otherModName = Path.GetFileNameWithoutExtension(sourceFiles[i]); if (otherModName == moduleName) { continue; } FromImportStmt stmt = new FromImportStmt( new DottedName(new Name[] { Name.Make(otherModName) }), FromImportStmt.Star, null); stmt.start = new Location(1, 1); stmt.end = new Location(1, 1); stmt.Emit(cg); } }); } if (createMain) { CodeGen main = OutputGenerator.GenerateModuleEntryPoint(tg, init, Path.GetFileNameWithoutExtension(mainFile), referencedAssemblies); assemblyGen.SetEntryPoint(main.MethodInfo, targetKind); } AddPythonModuleAttribute(tg, moduleName); tg.FinishType(); }
// example based on the MSDN Structs Sample (struct2.cs) public static void GenStruct2(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; TypeGen TheClass = ag.Class("TheClass"); { TheClass.Public.Field(typeof(int), "x"); } TypeGen TheStruct = ag.Struct("TheStruct"); { TheStruct.Public.Field(typeof(int), "x"); } TypeGen TestClass = ag.Class("TestClass"); { CodeGen g = TestClass.Public.Static.Method(typeof(void), "structtaker").Parameter(TheStruct, "s"); { ITypeMapper typeMapper = ag.TypeMapper; g.Assign(g.Arg("s").Field("x"), 5); } g = TestClass.Public.Static.Method(typeof(void), "classtaker").Parameter(TheClass, "c"); { ITypeMapper typeMapper = ag.TypeMapper; g.Assign(g.Arg("c").Field("x"), 5); } g = TestClass.Public.Static.Method(typeof(void), "Main"); { var a = g.Local(TheStruct); g.InitObj(a); ITypeMapper typeMapper4 = ag.TypeMapper; var b = g.Local(exp.New(TheClass)); ITypeMapper typeMapper = ag.TypeMapper; g.Assign(a.Field("x"), 1); ITypeMapper typeMapper2 = ag.TypeMapper; g.Assign(b.Field("x"), 1); g.Invoke(TestClass, "structtaker", a); g.Invoke(TestClass, "classtaker", b); ITypeMapper typeMapper3 = ag.TypeMapper; g.WriteLine("a.x = {0}", a.Field("x")); ITypeMapper typeMapper1 = ag.TypeMapper; g.WriteLine("b.x = {0}", b.Field("x")); } } }
// example based on the MSDN Delegates Sample (compose.cs) public static void GenCompose(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; TypeGen myDelegate = ag.Delegate(typeof(void), "MyDelegate").Parameter(typeof(string), "string"); TypeGen myClass = ag.Class("MyClass"); { CodeGen g = myClass.Public.Static.Method(typeof(void), "Hello").Parameter(typeof(string), "s"); { g.WriteLine(" Hello, {0}!", g.Arg("s")); } g = myClass.Public.Static.Method(typeof(void), "Goodbye").Parameter(typeof(string), "s"); { g.WriteLine(" Goodbye, {0}!", g.Arg("s")); } g = myClass.Public.Static.Method(typeof(void), "Main"); { ContextualOperand a = g.Local(), b = g.Local(), c = g.Local(), d = g.Local(); // Create the delegate object a that references // the method Hello: ITypeMapper typeMapper = ag.TypeMapper; g.Assign(a, exp.NewDelegate(myDelegate, myClass, "Hello")); // Create the delegate object b that references // the method Goodbye: ITypeMapper typeMapper1 = ag.TypeMapper; g.Assign(b, exp.NewDelegate(myDelegate, myClass, "Goodbye")); // The two delegates, a and b, are composed to form c, // which calls both methods in order: g.Assign(c, a + b); // Remove a from the composed delegate, leaving d, // which calls only the method Goodbye: g.Assign(d, c - a); g.WriteLine("Invoking delegate a:"); g.InvokeDelegate(a, "A"); g.WriteLine("Invoking delegate b:"); g.InvokeDelegate(b, "B"); g.WriteLine("Invoking delegate c:"); g.InvokeDelegate(c, "C"); g.WriteLine("Invoking delegate d:"); g.InvokeDelegate(d, "D"); } } }
public void TestNotLeaked() { TestingFacade.RunTest( ag => { TypeGen DeclareArraysSample = ag.Class("DecalreArraysSample"); { CodeGen g = DeclareArraysSample.Public.Static.Method(typeof(void), "Main"); { var asStream = ag.ExpressionFactory.New(typeof(MemoryStream)).Cast(typeof(Stream)).SetNotLeaked(); asStream.GetType().GetHashCode(); } } }); }
public static void GenCmdLine2(AssemblyGen ag) { ITypeMapper m = ag.TypeMapper; var st = ag.StaticFactory; var exp = ag.ExpressionFactory; ContextualOperand x; TypeGen commandLine3 = ag.Public.Class("CommandLine3"); { CodeGen g = commandLine3.Public.Method(typeof(void), "Main3").Parameter(typeof(string[]), "args"); { var args = g.Arg("args"); g.WriteLine("Number of command line 3 parameters = {0}", args.Property("Length")); var s = g.ForEach(typeof(string), args); { g.WriteLine(s); } g.End(); g.WriteLine(g.This().Invoke("GetType").Property("BaseType").Property("Name")); var inst = st.Field(typeof(CmdLineTestClass), "Default"); g.WriteLine(inst.Invoke("GetValue")); } commandLine3.Public.CommonConstructor(); } TypeGen commandLine2 = ag.Public.Class("CommandLine2"); { CodeGen g = commandLine2.Public.Static.Method(typeof(void), "Main").Parameter(typeof(string[]), "args"); { //g.Invoke(CommandLine3, "Main3", g.Arg("args")); var cl = g.Local(exp.New(commandLine3)); g.WriteLine(0); g.Invoke(cl, "Main3", g.Arg("args")); var args = g.Arg("args"); g.WriteLine("Number of command line parameters = {0}", args.Property("Length")); var s = g.ForEach(typeof(string), args); { g.WriteLine(s); } g.End(); } } }
public void Generate(ParseTree parseTree) { if (parseTree == null) return; GeneratedOK = true; defaultClass = ag.Public.Class("Default"); typeTable.Add("Default", defaultClass); mainMethod = defaultClass.Public.Static.Method(typeof(void), "Main"); //generator stack typeStack.Push(defaultClass); funcStack.Push(mainMethod); //InitIO(); InitRequiredType(); PushScope(); var ioOperand = mainMethod.Local(exp.New(typeTable["IO"])); ParseNode(parseTree.Root); if (GeneratedOK) { ag.Save(); AppDomain.CurrentDomain.ExecuteAssembly(name + ".exe"); } }
static void GenerateConstructor(RecordTypeDescriptor rtd, TypeGen tg, Type parenttype) { // constructor logic { List<Type> paramtypes = new List<Type>(); List<FieldDescriptor> allfields = new List<FieldDescriptor>(rtd.GetAllFields()); int diff = allfields.Count - rtd.Fields.Length; foreach (FieldDescriptor var in allfields) { paramtypes.Add(var.Type); } List<Type> parenttypes = new List<Type>(); for (int i = 0; i < diff; i++) { parenttypes.Add(typeof(object)); //TODO: fix this, it looks broken } if (paramtypes.Count < 9) { CodeGen cg = tg.DefineConstructor(paramtypes.ToArray()); CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make", tg.TypeBuilder, paramtypes.ToArray(), allfields.ConvertAll(x => x.Name).ToArray()); for (int i = 0; i < allfields.Count; i++) { cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name); } int fi = 0; cg.EmitThis(); for (fi = 0; fi < diff; fi++) { cg.EmitArgGet(fi); mk.EmitArgGet(fi); } // improve get constructor to look for protected constructors too cg.Emit(OpCodes.Call, (rtd.Parent == null ? parenttype.GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor)); foreach (FieldDescriptor fd in rtd.Fields) { cg.EmitThis(); cg.EmitArgGet(fi); cg.EmitFieldSet(fd.field); mk.EmitArgGet(fi); fi++; } mk.EmitNew(cg.MethodBase as ConstructorInfo); mk.EmitReturn(); cg.EmitReturn(); rtd.cg = cg; } else { CodeGen cg = tg.DefineConstructor(paramtypes.ToArray()); CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make", tg.TypeBuilder, new Type[] { typeof(object[]) }, new string[] { "args" }); for (int i = 0; i < allfields.Count; i++) { cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name); } int fi = 0; cg.EmitThis(); for (fi = 0; fi < diff; fi++) { cg.EmitArgGet(fi); mk.EmitArgGet(0); mk.EmitConstant(fi); mk.Emit(OpCodes.Ldelem, typeof(object)); } cg.Emit(OpCodes.Call, (rtd.Parent == null ? typeof(object).GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor)); foreach (FieldDescriptor fd in rtd.Fields) { cg.EmitThis(); cg.EmitArgGet(fi); cg.EmitFieldSet(fd.field); mk.EmitArgGet(0); mk.EmitConstant(fi); mk.Emit(OpCodes.Ldelem, typeof(object)); fi++; } mk.EmitNew(cg.MethodBase as ConstructorInfo); mk.EmitReturn(); cg.EmitReturn(); rtd.cg = cg; } } }
public TypeGen Struct(string name, params Type[] interfaces) { TypeGen tg = new TypeGen(this, Qualify(name), (attrs | TypeAttributes.Sealed | TypeAttributes.SequentialLayout) ^ TypeAttributes.BeforeFieldInit, typeof(ValueType), interfaces); attrs = 0; return tg; }
public TypeGen Interface(string name, params Type[] interfaces) { TypeGen tg = new TypeGen(this, Qualify(name), (attrs | TypeAttributes.Interface | TypeAttributes.Abstract) & ~(TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit), null, interfaces); attrs = 0; return tg; }
internal void AddType(TypeGen tg) { types.Add(tg); }
static void GeneratePredicate(string n, RecordTypeDescriptor rtd, TypeGen tg) { // predicate MethodBuilder pb = tg.TypeBuilder.DefineMethod(n + "?", MethodAttributes.Public | MethodAttributes.Static, typeof(object), new Type[] { typeof(object) }); pb.DefineParameter(1, ParameterAttributes.None, "obj"); ILGenerator pgen = pb.GetILGenerator(); pgen.Emit(OpCodes.Ldarg_0); pgen.Emit(OpCodes.Isinst, tg.TypeBuilder); pgen.Emit(OpCodes.Ldnull); pgen.Emit(OpCodes.Cgt_Un); pgen.Emit(OpCodes.Call, typeof(RuntimeHelpers).GetMethod("BooleanToObject")); pgen.Emit(OpCodes.Ret); rtd.predicate = pb; }
static void GenerateFields(object fields, string n, RecordTypeDescriptor rtd, TypeGen tg, object fieldtypes) { object[] f = RequiresNotNull<object[]>(fields); object[] ftypes = RequiresNotNull<object[]>(fieldtypes); List<FieldDescriptor> rtd_fields = new List<FieldDescriptor>(); for (int i = 0; i < f.Length; i++) { Cons c = (Cons) f[i]; // check for recursive definition Type t = rtd.Name == SymbolTable.IdToString((SymbolId)ftypes[i]) ? rtd.tg.TypeBuilder : ClrGenerator.ExtractTypeInfo(List(SymbolTable.StringToObject("quote"), ftypes[i])); // can this ever be null given ExtractTypeInfo throws? if (t == null) { ClrGenerator.ClrSyntaxError("GenerateFields", "type not found", ftypes[i]); } string fname = SymbolTable.IdToString(RequiresNotNull<SymbolId>(Second(c))); // we use standard names here, they will be mapped to the given names string aname = n + "-" + fname; string mname = n + "-" + fname + "-set!"; var fd = new FieldDescriptor { Name = fname }; FieldAttributes fattrs = FieldAttributes.Public | FieldAttributes.InitOnly; if (c.car == SymbolTable.StringToObject("mutable")) { fd.mutable = true; fattrs &= ~FieldAttributes.InitOnly; } FieldSlot s = tg.AddField(t, fname, fattrs) as FieldSlot; fd.field = s.Field; PropertyBuilder pi = tg.TypeBuilder.DefineProperty(fname, PropertyAttributes.None, t, new Type[0]); // accesor MethodBuilder ab = tg.TypeBuilder.DefineMethod(aname, MethodAttributes.Public | MethodAttributes.Static, t, new Type[] { tg.TypeBuilder }); ab.DefineParameter(1, ParameterAttributes.None, n); ILGenerator agen = ab.GetILGenerator(); agen.Emit(OpCodes.Ldarg_0); //agen.Emit(OpCodes.Castclass, tg.TypeBuilder); agen.Emit(OpCodes.Ldfld, fd.field); agen.Emit(OpCodes.Ret); fd.accessor = ab; pi.SetGetMethod(ab); // mutator if (fd.mutable) { MethodBuilder mb = tg.TypeBuilder.DefineMethod(mname, MethodAttributes.Public | MethodAttributes.Static, typeof(object), new Type[] { tg.TypeBuilder, t }); mb.DefineParameter(1, ParameterAttributes.None, n); ILGenerator mgen = mb.GetILGenerator(); mgen.Emit(OpCodes.Ldarg_0); //mgen.Emit(OpCodes.Castclass, tg.TypeBuilder); mgen.Emit(OpCodes.Ldarg_1); mgen.Emit(OpCodes.Stfld, fd.field); mgen.Emit(OpCodes.Ldsfld, Compiler.Generator.Unspecified); mgen.Emit(OpCodes.Ret); fd.mutator = mb; pi.SetSetMethod(mb); } rtd_fields.Add(fd); } rtd.fields = rtd_fields.ToArray(); }
public TypeGen Class(string name, Type baseType, params Type[] interfaces) { TypeGen tg = new TypeGen(this, Qualify(name), (attrs | TypeAttributes.Class) ^ TypeAttributes.BeforeFieldInit, baseType, interfaces); attrs = 0; return tg; }