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; // } }
internal void AddScopeLocals(CodeGenContext context) { // ------------------ Start new Context ---------------------------- // [InteropMethod("MyClass")] // private class ActivationFrame: Ruby.Frame { ... } frame_def = context.CreateGlobalClass("_Internal", "Frame" + (N++), Runtime.FrameRef); Scope parentClass; for (parentClass = this; parentClass != null && !(parentClass is CLASS_OR_MODULE); parentClass = parentClass.parent_scope) ; string className = ""; if (parentClass != null) className = ((CLASS_OR_MODULE)parentClass).internal_name; ClassDef fileClass = FileClass(); string src = ""; if (fileClass != null && fileClass.Name().StartsWith("SourceFile_")) { src = fileClass.Name().Substring(11); frame_def.AddCustomAttribute(Runtime.FrameAttribute.ctor, new Constant[] { new StringConst(src), new StringConst(className) }); } foreach (string local in locals_list) CodeGenContext.AddField(frame_def, PERWAPI.FieldAttr.Public, ID.ToDotNetName(local), PrimitiveType.Object); // internal ActivationFrame(Frame caller): base(caller) { } CodeGenContext frame_ctor = context.CreateConstructor(frame_def, new Param(ParamAttr.Default, "caller", Runtime.FrameRef)); frame_ctor.ldarg(0); frame_ctor.ldarg("caller"); frame_ctor.call(Runtime.Frame.ctor); frame_ctor.ret(); frame_ctor.Close(); // internal string file() { CodeGenContext file = context.CreateMethod(frame_def, PERWAPI.MethAttr.PublicVirtual, "file", PrimitiveType.String); file.startMethod(this.location); // return "thisfile.rb" file.ldstr(this.location.file); file.ret(); file.Close(); // internal override string methodName() { CodeGenContext methodName = context.CreateMethod(frame_def, PERWAPI.MethAttr.PublicVirtual, "methodName", PrimitiveType.String); methodName.startMethod(this.location); // return "CurrentMethodName" methodName.ldstr(CurrentMethodName()); methodName.ret(); methodName.Close(); CreateNestingMethod(frame_def, context); CreateLastClassMethod(frame_def, context); // ------------------ Return to Old Context ---------------------- // ActivationFrame frame = new ActivationFrame(caller); context.ldarg("caller"); context.newobj(frame_ctor.Method); int frame = context.StoreInTemp("frame", FrameClass, location); Debug.Assert(frame == 0); // frame.block_arg = block; context.ldloc(frame); LoadBlock0(context); context.stfld(Runtime.Frame.block_arg); if (this is BLOCK) { // frame.current_block = this; context.ldloc(frame); context.ldarg(0); context.stfld(Runtime.Frame.current_block); } }
protected MethodDef GenerateClassForMethod(CodeGenContext context) { // private class Block_N: Ruby.Block { ClassDef blockClass = context.CreateGlobalClass("_Internal", "Block", Runtime.BlockRef); System.Diagnostics.Debug.Assert(frameFields.Count == 0); // create locals for outer scopes int depth = 0; for (Scope scope = block_parent; scope != null; scope = scope.block_parent) { FieldDef fieldDef = CodeGenContext.AddField(blockClass, FieldAttr.Public, "locals" + (depth++), scope.FrameClass); frameFields.Add(fieldDef); } MethodDef constructor = GenConstructor(blockClass, context); // internal static object Call(...) { body } GenCallMethod(blockClass, context); // } // -------------------------- Return to original 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 void CreateClassForFile(CodeGenContext context, string file_name) { // public class file_name: System.Object { // rifraf fileClass = context.CreateGlobalClass("_Internal", "SourceFile_" + file_name.Replace(@"\", "_").Replace(".", "_"), Runtime.SystemObjectRef); }