Beispiel #1
0
        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();
            }
        }
Beispiel #7
0
        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();
            }
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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);
        }
Beispiel #16
0
 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");
        }
Beispiel #18
0
 internal override void GenCode0(CodeGenContext context)
 {
     context.newLine(location);
     context.ldstr(lhs.ToString());
     context.ldstr(rhs.ToString());
     context.call(Runtime.Variables.alias_variable);
 }
Beispiel #19
0
        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;
        }