protected new PERWAPI.MethodDef GenerateClassForMethod(CodeGenContext context) { // public class Eval: IEval { evalClass = context.CreateGlobalClass("_Internal", "Eval", Runtime.SystemObjectRef); evalClass.AddImplementedInterface(Runtime.IEvalRef); if (context.CurrentRubyClass == null) { context.CurrentRubyClass = CodeGenContext.AddField(evalClass, PERWAPI.FieldAttr.PublicStatic, "myRubyClass", Runtime.ClassRef); CodeGenContext cctor = context.CreateStaticConstructor(evalClass); cctor.ldsfld(Runtime.Init.rb_cObject); cctor.stsfld(context.CurrentRubyClass); cctor.ret(); cctor.Close(); } MethodDef constructor = GenConstructor(evalClass, context); GenInvokeMethod(evalClass, context); return constructor; // } }
private FieldDef GenerateClassForMethod(CodeGenContext context) { ClassRef baseClass; if (formals.ShortAndSimple()) baseClass = Runtime.MethodBodyNRef(formals.min_args); else baseClass = Runtime.MethodBodyRef; // private class MyMethod: MethodBody? { ClassDef methodClass = context.CreateGlobalClass("_Internal", "Method_" + ID.ToDotNetName(method_id), baseClass); methodClass.AddCustomAttribute(Runtime.InteropMethodAttribute.ctor, System.Text.UnicodeEncoding.UTF8.GetBytes(method_id)); // internal static Calln(Class last_class, object recv, ...) { body } GenCallMethod(methodClass, context); // internal MyMethod() {} CodeGenContext constructor = context.CreateConstructor(methodClass); constructor.ldarg(0); constructor.call(Runtime.MethodBodyCtor(baseClass)); constructor.ret(); constructor.Close(); // internal static MyMethod singleton; FieldDef singleton = CodeGenContext.AddField(methodClass, FieldAttr.PublicStatic, "myRubyMethod", methodClass); // static MyMethod() { // singleton = new MyMethod(); // } CodeGenContext staticConstructor = context.CreateStaticConstructor(methodClass); staticConstructor.newobj(constructor.Method); staticConstructor.stsfld(singleton); staticConstructor.ret(); staticConstructor.Close(); // } // ------------------- Return to original context ----------------------------- return singleton; }
internal override FieldDef DefineAllocator(CodeGenContext context, MethodDef ctor) { // Conservative - don't create allocator if we're not sure what the base class is // BBTAG: should be able to create this in all cases now, since we do a test in // define_alloc_func //if (super_class != null) // return null; ClassRef baseClass = Runtime.MethodBodyNRef(0); ClassDef allocator = context.CreateGlobalClass("_Internal", "Method_" + internal_name + "_Allocator", baseClass); context.currentSkeleton.allocator = allocator; // internal static Call0(Class last_class, object recv, ...) { body } CodeGenContext Call = context.CreateMethod(allocator, MethAttr.PublicVirtual, "Call0", PrimitiveType.Object, new Param[] { new Param(ParamAttr.Default, "last_class", Runtime.ClassRef), new Param(ParamAttr.Default, "recv", PrimitiveType.Object), new Param(ParamAttr.Default, "caller", Runtime.FrameRef), new Param(ParamAttr.Default, "block", Runtime.ProcRef)}); // return new MyClass((Class)recv)); Call.ldarg("recv"); Call.cast(Runtime.ClassRef); Call.newobj(ctor); Call.ret(); Call.Close(); // internal MyAllocator() {} CodeGenContext constructor = context.CreateConstructor(allocator); constructor.ldarg(0); constructor.call(Runtime.MethodBodyCtor(baseClass)); constructor.ret(); constructor.Close(); // internal static MyAllocator singleton; FieldDef singleton = CodeGenContext.AddField(allocator, FieldAttr.PublicStatic, "myRubyMethod", allocator); // static MyAllocator() { // singleton = new MyAllocator(); // } CodeGenContext staticConstructor = context.CreateStaticConstructor(allocator); staticConstructor.newobj(constructor.Method); staticConstructor.stsfld(singleton); staticConstructor.ret(); staticConstructor.Close(); return singleton; }
private PERWAPI.ClassDef GenerateClassForFile(CodeGenContext context, string file_name, bool autoLoad, List<SOURCEFILE> files) { if (fileClass == null) CreateClassForFile(context, file_name); // internal static object Load(object recv, Caller caller, Proc block) LoadMethod = context.CreateMethod(fileClass, MethAttr.PublicStatic, "Load", PrimitiveType.Object, new Param[] { new Param(ParamAttr.Default, "recv", PrimitiveType.Object), new Param(ParamAttr.Default, "caller", Runtime.FrameRef) }); LoadMethod.startMethod(location); AddScopeLocals(LoadMethod); AddScopeBody(LoadMethod); LoadMethod.ReleaseLocal(0, true); // } LoadMethod.Close(); if (autoLoad) { // accessing this field should trigger the .cctor to load the main source file CodeGenContext.AddField(fileClass, FieldAttr.PublicStatic, "loaded", PrimitiveType.Boolean); // public static .cctor() { CodeGenContext cctor = context.CreateStaticConstructor(fileClass); // register other ruby source files in assembly so that they can be loaded if requested foreach (SOURCEFILE f in files) { if (f.fileClass == null) f.CreateClassForFile(context, File.stripExtension(f.location.file)); // Ruby.Runtime.Program.AddProgram(filename, fileClass); cctor.ldstr(File.stripExtension(f.location.file)); cctor.ldtoken(f.fileClass); cctor.call(Runtime.SystemType.GetTypeFromHandle); cctor.call(Runtime.Program.AddProgram); } // Load(Object.ruby_top_self, null); cctor.ldsfld(Runtime.Object.ruby_top_self); cctor.ldnull(); cctor.call(LoadMethod.Method); cctor.pop(); cctor.ret(); // } cctor.Close(); } return fileClass; }