internal override void Assign(CodeGenContext context, Node rhs) { // object value = rhs; bool created; ISimple value = context.PreCompute(rhs, "rhs", out created); // thisblock.localsN.SetDynamic("vid", value); context.ldarg(0); context.ldfld(block.frameFields[depth - 1]); context.ldstr(Name); value.GenSimple(context); context.call(Runtime.Frame.SetDynamic); value.GenSimple(context); context.ReleaseLocal(value, created); }
public virtual void GenSimple(CodeGenContext context) { // thisblock.localsN.vid context.ldarg(0); context.ldfld(block.frameFields[depth - 1]); context.ldfld(field); }
public override void GenSimple(CodeGenContext context) { // thisblock.localsN.GetDynamic("vid"); context.ldarg(0); context.ldfld(block.frameFields[depth - 1]); context.ldstr(Name); context.call(Runtime.Frame.GetDynamic); }
internal override void Assign(CodeGenContext context, Node rhs) { // object value = rhs; bool created; ISimple value = context.PreCompute(rhs, "rhs", out created); // thisblock.localsN.vid = value; context.ldarg(0); context.ldfld(block.frameFields[depth - 1]); value.GenSimple(context); context.stfld(field); value.GenSimple(context); context.ReleaseLocal(value, created); }
private void CopyNormalFormals(CodeGenContext context, Scope scope) { PERWAPI.CILLabel OKLabel = context.NewLabel(); if (min_args > 0) { // if (args.Length < min_args) context.ldarg("args"); context.callvirt(Runtime.ArgList.get_Length); int length = context.StoreInTemp("length", PrimitiveType.Int32, location); context.ldloc(length); context.ldc_i4(min_args); context.bge(OKLabel); //context.Inst(Op.clt); //context.brfalse(OKLabel); // context.Branch(BranchOp.bge, OKLabel); // throw new ArgumentError(string.Format("wrong number of arguments ({0} for {1})", args.Length, arity).raise(caller); // FIXME: next line needs a String context.ldstr("wrong number of arguments ({0} for {1})"); context.ldloc(length); context.box(PrimitiveType.Int32); context.ldc_i4(min_args); context.box(PrimitiveType.Int32); context.call(Runtime.SystemString.Format); context.newobj(Runtime.ArgumentError.ctor); context.ldloc(0); context.callvirt(Runtime.Exception.raise); context.throwOp(); context.ReleaseLocal(length, true); // OKLabel: context.CodeLabel(OKLabel); } // Copy parameters to locals for (Node f = normal; f != null; f = f.nd_next) { string name = ID.ToDotNetName(((VAR)f).vid); // local.f = args.GetNext(); context.ldloc(0); context.ldarg("args"); context.callvirt(Runtime.ArgList.GetNext); context.stfld(scope.GetFrameField(name)); } }
internal override void GenCode0(CodeGenContext context) { CodeGenContext Begin = context.CreateMethod(FileClass(), MethAttr.PublicStatic, "Begin" + (seq++), PrimitiveType.Object, new Param(ParamAttr.Default, "recv", PrimitiveType.Object), new Param(ParamAttr.Default, "caller", Runtime.FrameRef)); Begin.startMethod(this.location); AddScopeLocals(Begin); AddScopeBody(Begin); Begin.ReleaseLocal(0, true); Begin.Close(); // Begin(recv, caller); context.ldarg("recv"); context.ldloc(0); context.call(Begin.Method); context.pop(); }
public void GenSimple(CodeGenContext context) { context.ldarg(parameter_name); }
public void GenSimple(CodeGenContext context) { // Eval.ivar_get(recv, vid) context.ldarg("recv"); context.ldstr(vid); context.call(Runtime.Eval.ivar_get); }
internal override void GenCode0(CodeGenContext context) { context.newLine(location); if (return_val != null) return_val.GenCode(context); else context.ldnull(); if (this.parent_scope is BLOCK) { //throw new Ruby.ReturnException(return_value, this.defining_scope); context.ldarg(0); // current Ruby.MethodBody context.ldfld(Runtime.Block.defining_scope); context.newobj(Runtime.ReturnException.ctor); context.throwOp(); } else if (this.parent_scope is BEGIN) { //throw new Ruby.ReturnException(return_value, caller); context.ldarg("caller"); context.newobj(Runtime.ReturnException.ctor); context.throwOp(); } else { // return context.stloc(parent_scope.returnTemp); context.Goto(context.labels.Return); } }
internal override void GenCode0(CodeGenContext context) { context.newLine(location); if (context.labels != null && context.labels.Retry != null) context.Goto(context.labels.Retry); else { System.Diagnostics.Debug.Assert(this.parent_scope is BLOCK); // throw new Ruby.RetryException(block.defining_scope); context.ldarg(0); // current Ruby.MethodBody context.ldfld(Runtime.Block.defining_scope); context.newobj(Runtime.RetryException.ctor); context.throwOp(); } }
internal override void GenCode0(CodeGenContext context) { context.newLine(location); if (return_val != null) return_val.GenCode(context); else context.ldnull(); if (context.labels != null && context.labels.Break != null) { context.stloc(parent_scope.returnTemp); context.Goto(context.labels.Break); } else { System.Diagnostics.Debug.Assert(this.parent_scope is BLOCK); //throw new Ruby.BreakException(return_value, this.defining_scope); context.ldarg(0); // current Ruby.MethodBody context.ldfld(Runtime.Block.defining_scope); context.newobj(Runtime.BreakException.ctor); context.throwOp(); } }
internal void CopySimple(CodeGenContext context, Scope scope) { if (block != null) { // locals.block = block; string bname = ID.ToDotNetName(block.vid); context.ldloc(0); LoadBlock(context); context.stfld(scope.GetFrameField(bname)); } for (Node f = normal; f != null; f = f.nd_next) { string fname = ID.ToDotNetName(((VAR)f).vid); // local.f = f; context.ldloc(0); context.ldarg(fname); context.stfld(scope.GetFrameField(fname)); } }
private void CopyRestFormals(CodeGenContext context, Scope scope) { if (rest != null) { string name = ID.ToDotNetName(rest.vid); // locals.name = args.GetRest(); context.ldloc(0); context.ldarg("args"); context.callvirt(Runtime.ArgList.GetRest); context.stfld(scope.GetFrameField(name)); } }
private void CopyOptionalFormals(CodeGenContext context, Scope scope) { for (ASSIGNMENT opt = (ASSIGNMENT)optional; opt != null; opt = (ASSIGNMENT)opt.nd_next) { PERWAPI.CILLabel runout_label = context.NewLabel(); PERWAPI.CILLabel end_label = context.NewLabel(); string name = ID.ToDotNetName(((VAR)(opt.lhs)).vid); Node defaultValue = opt.rhs; // if (args.RunOut()) goto RunOut context.ldarg("args"); context.callvirt(Runtime.ArgList.RunOut); context.brtrue(runout_label); // locals.name = args.GetNext(); context.ldloc(0); context.ldarg("args"); context.callvirt(Runtime.ArgList.GetNext); context.br(end_label); // RunOut: context.CodeLabel(runout_label); // object def = defaultValue; bool created; ISimple def = context.PreCompute(defaultValue, "default", out created); // locals.name = defaultValue context.ldloc(0); def.GenSimple(context); context.ReleaseLocal(def, created); context.CodeLabel(end_label); // locals.name = ... context.stfld(scope.GetFrameField(name)); } }
internal void LoadBlock0(CodeGenContext context) { if (context.HasArg(Runtime.ArgListRef)) { context.ldarg("args"); // args.block context.ldfld(Runtime.ArgList.block); } else if (context.HasArg(Runtime.ProcRef)) { context.ldarg("block"); } else context.ldnull(); }
internal override void Defined(CodeGenContext context) { // Eval.ivar_defined(recv, vid) context.ldarg("recv"); context.ldstr(vid); context.call(Runtime.Eval.ivar_defined); }
internal override void DefineClass(CodeGenContext context, PERWAPI.FieldDef singleton) { // Class.singleton_class(caller, super) context.ldloc(0); context.ldarg("super"); context.call(Runtime.Class.singleton_class); context.stsfld(singleton); }
internal override void Assign(CodeGenContext context, Node rhs) { // object value = rhs; bool created; ISimple value = context.PreCompute(rhs, "rhs", out created); // Eval.ivar_set(caller, recv, "vid", rhs); context.ldloc(0); context.ldarg("recv"); context.ldstr(vid); value.GenSimple(context); context.call(Runtime.Eval.ivar_set); context.ReleaseLocal(value, created); }
internal override void DefineClass(CodeGenContext context, PERWAPI.FieldDef singleton) { // Class.define_module(scope, name.vid, caller); context.ldarg("scope"); context.ldstr(name.vid.ToString()); context.ldloc(0); context.call(Runtime.Class.rb_define_module); context.stsfld(singleton); }
internal override void GenCode0(CodeGenContext context) { MethodDef BlockN_constructor = GenerateClassForMethod(context); // new Ruby.Proc(recv, block, new BlockN(locals, this.locals1, this.locals2 ...), arity); context.ldarg("recv"); // recv LoadBlock(context); context.ldloc(0); // locals if (block_parent is BLOCK) foreach (FieldDef field in ((BLOCK)block_parent).frameFields) { // this.localsN context.ldarg(0); context.ldfld(field); } context.newobj(BlockN_constructor); context.ldc_i4(arity); context.newobj(Runtime.Proc.ctor); }
internal override void GenCode0(CodeGenContext context) { bool scope_created, super_created; CodeGenContext newContext = new CodeGenContext(context); // scope and super must be evaluated in surrounding scope and passed to Init method ISimple scope = PushScope(context, out scope_created); ISimple super = PushSuper(context, out super_created); string basename = ID.ToDotNetName(name.vid); // BBTAG: try and get the superclass PERWAPI.Class superClass = Runtime.ObjectRef; bool superClassFound = false; PERWAPI.Method superClassConstructor0 = null; PERWAPI.Method superClassConstructor1 = Runtime.Object.ctor; if (this is CLASS) { superClass = ((CLASS)this).GetSuperClassRef(newContext); if (superClass != null) { superClassFound = true; superClassConstructor0 = superClass.GetMethodDesc(".ctor", new Type[0]); if (superClassConstructor0 is MethodDef) superClassConstructor0 = ((MethodDef)superClassConstructor0).MakeRefOf(); superClassConstructor1 = superClass.GetMethodDesc(".ctor", new Type[] { Runtime.ClassRef }); if (superClassConstructor1 is MethodDef) superClassConstructor1 = ((MethodDef)superClassConstructor1).MakeRefOf(); } else superClass = Runtime.ObjectRef; } //public class MyClass: Object { // check if this class has already been created in a referenced DLL // FIXME: this won't work for nested classes PERWAPI.Class classRef = ClassSkeleton.FindPERWAPIClass(null, name, context.peFiles); bool defineInteropClass = (classRef == null); // if it seems like an extension of a ruby builtin class, don't generate an interop class // FIXME: this won't work for nested classes if (Ruby.Runtime.BuiltinClasses.IsBuiltinClass(basename)) { Compiler.InteropWarning(basename + " is a Ruby built-in class, interop class not generated"); defineInteropClass = false; } //ClassDef interopClass = newContext.CreateNestedClass(CurrentInteropClass(), basename, Runtime.ObjectRef); // BBTAG ClassDef interopClass = null; if (defineInteropClass) { if (superClass is PERWAPI.ClassDef) interopClass = newContext.CreateNestedClass(CurrentInteropClass(), basename, ((PERWAPI.ClassDef)superClass).MakeRefOf()); // BBTAG else interopClass = newContext.CreateNestedClass(CurrentInteropClass(), basename, superClass); // BBTAG interopClasses.Push(interopClass); classRef = interopClass; } //context.classes[classname] = interopClass; // BBTAG: create skeleton for this class ClassSkeleton skeleton; if (context.currentSkeleton.nestedClasses.ContainsKey(basename)) skeleton = context.currentSkeleton.nestedClasses[basename]; else skeleton = new ClassSkeleton(basename, classRef); skeleton.lexicalParent = context.currentSkeleton; newContext.currentSkeleton = skeleton; skeleton.lexicalParent.nestedClasses[basename] = skeleton; if (!superClassFound && this is AST.CLASS && ((AST.CLASS)this).super_class != null && defineInteropClass) { // do not add to post pass list if supertype is a built-in Ruby class //List<string> qualifiedSuperClass = ClassSkeleton.ConstNodeToClassList(((AST.CLASS)this).super_class); //if (!(qualifiedSuperClass.Count == 1 && Ruby.Runtime.BuiltinClasses.IsBuiltinClass(qualifiedSuperClass[0]))) newContext.postPassList.Add(new ClassSkeletonPostPass(skeleton, interopClass, ((AST.CLASS)this).super_class)); } // public static Class classname; int seqNo = 0; internal_name = basename; while (FileClass().GetField(internal_name) != null) internal_name = basename + (seqNo++); // Define singleton in file class so that it gets initialized by .cctor singletonField = FileClass().AddField(PERWAPI.FieldAttr.PublicStatic, internal_name, Runtime.ClassRef); newContext.CurrentRubyClass = singletonField; // public MyClass() : base(singleton) { }; CodeGenContext class_constructor = null; if (defineInteropClass) { if (interopClass.GetMethod(".ctor", new Type[0]) == null) { CodeGenContext class_constructor0 = newContext.CreateConstructor(interopClass); class_constructor0.ldarg(0); if (superClassConstructor0 != null) class_constructor0.call(superClassConstructor0); else { class_constructor0.ldsfld(singletonField); class_constructor0.call(superClassConstructor1); } class_constructor0.ret(); class_constructor0.Close(); } // public MyClass(Class klass) : base(klass) { }; MethodDef ctor = interopClass.GetMethod(".ctor", new Type[] { Runtime.ClassRef }); //CodeGenContext class_constructor; if (ctor == null) { class_constructor = newContext.CreateConstructor(interopClass, new Param(ParamAttr.Default, "klass", Runtime.ClassRef)); class_constructor.ldarg(0); class_constructor.ldarg("klass"); class_constructor.call(superClassConstructor1); class_constructor.ret(); class_constructor.Close(); } else { class_constructor = new CodeGenContext(); class_constructor.Method = ctor; } } // internal static void Init_fullname(object scope, object super, object recv, Frame caller) { CodeGenContext Init = newContext.CreateMethod(FileClass(), MethAttr.PublicStatic, "Init_" + internal_name, PrimitiveType.Object, new Param(ParamAttr.Default, "scope", PrimitiveType.Object), new Param(ParamAttr.Default, "super", PrimitiveType.Object), new Param(ParamAttr.Default, "recv", PrimitiveType.Object), new Param(ParamAttr.Default, "caller", Runtime.FrameRef)); skeleton.initMethod = Init.Method; Init.startMethod(this.location); AddScopeLocals(Init); // singleton = scope.define_???(...) DefineClass(Init, singletonField); // recv = singleton; Init.ldsfld(singletonField); Init.starg("recv"); // Fixme: should be conditional // singleton.define_allocator(allocator); if (defineInteropClass) { FieldDef allocator = DefineAllocator(newContext, class_constructor.Method); if (allocator != null) { Init.ldsfld(singletonField); Init.ldsfld(allocator); Init.call(Runtime.Class.define_alloc_func); } } AddScopeBody(Init); Init.ReleaseLocal(0, true); Init.Close(); if (defineInteropClass) interopClasses.Pop(); // --------------------- Return to old Context ---------------------------- context.newLine(location); // Init(scope, super, recv, caller); scope.GenSimple(context); super.GenSimple(context); context.ldarg("recv"); context.ldloc(0); context.call(Init.Method); context.ReleaseLocal(super, super_created); context.ReleaseLocal(scope, scope_created); }
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); } }
public void GenSimple(CodeGenContext context) { context.ldarg("recv"); }