internal override void GenCode0(CodeGenContext context) { PERWAPI.CILLabel elseLabel = context.NewLabel(); PERWAPI.CILLabel endLabel = context.NewLabel(); // if (Eval.Test(cond)) context.newLine(cond.location); cond.GenCode(context); context.call(Runtime.Eval.Test); context.brfalse(elseLabel); if (body != null) { context.newStartPoint(body.location); body.GenCode(context); } else context.ldnull(); if (context.Reachable()) context.br(endLabel); context.CodeLabel(elseLabel); if (_else != null) { context.newStartPoint(_else.location); _else.GenCode(context); } else context.ldnull(); context.CodeLabel(endLabel); context.newEndPoint(location); }
internal override void GenCode0(CodeGenContext context) { context.newLine(location); lhs.Assign(context, rhs); }
internal override void GenCode0(CodeGenContext context) { context.newLine(location); recv.GenCode(context); LOCAL recvLocal = context.StoreInLocal("recv", PrimitiveType.Object, recv.location); // lhs.vid=(lhs.vid() op rhs) new METHOD_CALL(recvLocal, vid + "=", new METHOD_CALL(new METHOD_CALL(recvLocal, vid, new ARGS(null, null, null, null, recv.location, true), null, recv.location), op, rhs, location), location).GenCode(context); context.ReleaseLocal(recvLocal.local, true); }
internal override void GenCode0(CodeGenContext context) { context.newLine(location); if (lhs is ARRAY_ACCESS) // for array access -> need to avoid recomputation of lhs index ((ARRAY_ACCESS)lhs).AssignOp(context, op, rhs); else if (lhs is CVAR && op == "||") { CILLabel alreadyDefined1 = new CILLabel(); CILLabel alreadyDefined2 = new CILLabel(); CILLabel alreadyDefined3 = new CILLabel(); Node lhsDefined = new DEFINED(lhs, location); lhsDefined.GenCode(context); context.brtrue(alreadyDefined1); lhs.Assign(context, rhs); context.br(alreadyDefined2); context.CodeLabel(alreadyDefined1); lhs.Assign(context, METHOD_CALL.Create(lhs, op, rhs, location)); context.CodeLabel(alreadyDefined2); } else lhs.Assign(context, METHOD_CALL.Create(lhs, op, rhs, location)); }
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) { PERWAPI.CILLabel endLabel = context.NewLabel(); Node clause; if (target != null) { context.newLine(target.location); target.GenCode(context); LOCAL t = context.StoreInLocal("target", PrimitiveType.Object, location); for (clause = body; clause != null && clause is WHEN; clause = clause.nd_next) ((WHEN)clause).GenCode(context, t, endLabel); context.ReleaseLocal(t.local, true); } else { for (clause = body; clause != null && clause is WHEN; clause = clause.nd_next) { context.newLine(clause.location); ((WHEN)clause).GenCode(context, endLabel); } } if (clause != null) /* assume else clause */ clause.GenCode(context); else context.ldnull(); context.CodeLabel(endLabel); context.newEndPoint(location); }
internal override void GenCode0(CodeGenContext context) { // Eval.alias(ruby_class, lhs, rhs, myFrame); context.newLine(location); context.ruby_class(parent_scope); context.ldstr(lhs.ToString()); context.ldstr(rhs.ToString()); context.ldloc(0); context.call(Runtime.Eval.alias); }
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 override void GenCode0(CodeGenContext context) { context.newLine(location); SetLine(context); // Ruby.ArgList arguments = args; bool created; arguments = args.GenArgList(context, out created); GenCall(context); context.ReleaseLocal(arguments, created); }
internal override void GenCode0(CodeGenContext context) { context.newLine(location); SetLine(context); if (args == null) args = ParentArgs(context); // object arguments = args; bool created; arguments = args.GenArgList(context, out created); if (parent_scope is BLOCK) { arguments.GenSimple(context); LoadBlock(context); context.stfld(Runtime.ArgList.block); } GenCall(context); context.ReleaseLocal(arguments, created); }
internal override void GenCode0(CodeGenContext context) { if (Scanner.is_identchar(method_id[0])) context.newLine(location); SetLine(context); bool self_created, arguments_created = false; if (isVarAccess) { context.ldloc(0); context.call(Runtime.Frame.SetCallStatusVCall); } else { context.ldloc(0); context.call(Runtime.Frame.SetCallStatusNone); } // object self = receiver; self = context.PreCompute(receiver, "receiver", out self_created); if (args.ShortAndSimple()) fixed_arguments = args.GenFixedArgs(context, out fixed_created); else arguments = args.GenArgList(context, out arguments_created); GenCall(context); context.ReleaseLocal(self, self_created); if (args.ShortAndSimple()) for (int i = 0; i < fixed_created.Count; i++) context.ReleaseLocal(fixed_arguments[i], fixed_created[i]); else context.ReleaseLocal(arguments, arguments_created); }
internal void GenCode(CodeGenContext context, PERWAPI.CILLabel endLabel) { PERWAPI.CILLabel elseLabel = context.NewLabel(); context.newLine(comparison.location); // if (comparision.ToRubyArray().includes(true, caller)) bool created; ISimple list = comparison.GenArgList(context, out created); list.GenSimple(context); context.ReleaseLocal(list, created); context.callvirt(Runtime.ArgList.ToRubyArray); new TRUE(comparison.location).GenCode(context); context.ldloc(0); context.callvirt(Runtime.Array.includes); context.brfalse(elseLabel); if (body != null) { context.newStartPoint(body.location); body.GenCode(context); } else context.ldnull(); context.br(endLabel); context.CodeLabel(elseLabel); }
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 override void GenCode0(CodeGenContext context) { context.newLine(location); if (return_val != null) return_val.GenCode(context); else context.ldnull(); context.stloc(parent_scope.returnTemp); if (context.labels != null && context.labels.Next != null) context.Goto(context.labels.Next); else context.Goto(context.labels.Return); }
internal override void GenCode0(CodeGenContext context) { // ruby_class.undef_method(mid); context.newLine(location); context.ruby_class(parent_scope); context.ldstr(mid.ToString()); context.callvirt(Runtime.Class.undef_method); context.ldnull(); }
internal override void GenCode0(CodeGenContext context) { context.newLine(location); if (context.labels != null && context.labels.Redo != null) context.Goto(context.labels.Redo); else throw new System.Exception("unexpected REDO not in loop or block"); }
internal override void GenCode0(CodeGenContext context) { context.newLine(location); context.ldstr(lhs.ToString()); context.ldstr(rhs.ToString()); context.call(Runtime.Variables.alias_variable); }
internal override void GenCode0(CodeGenContext context) { Labels original = context.labels; // ---------------- Create new label context for loop ---------------------- context.labels = new Labels(); context.labels.Next = context.NewLabel(); context.labels.Break = context.NewLabel(); context.labels.Redo = context.NewLabel(); context.labels.Retry = context.NewLabel(); context.labels.Return = original.Return; context.CodeLabel(context.labels.Retry); context.newStartPoint(location); context.ldnull(); context.stloc(parent_scope.returnTemp); context.CodeLabel(context.labels.Redo); if (body != null) { body.GenCode(context); if (context.Reachable()) context.pop(); } context.CodeLabel(context.labels.Next); // if (Eval.Test(cond)) context.newLine(cond.location); cond.GenCode(context); context.call(Runtime.Eval.Test); if (whileTrue) context.brtrue(context.labels.Retry); else context.brfalse(context.labels.Retry); context.CodeLabel(context.labels.Break); context.newEndPoint(location); context.ldloc(parent_scope.returnTemp); // --------------------- Restore Label context ------------------------- context.labels = original; }