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);
        }
Beispiel #2
0
        internal override void GenCode0(CodeGenContext context)
        {
            // String.Concat(String.Concat(arg1, arg2), args, ...);

            head.GenCode0(context);

            if (head.nd_next != null)
            {
                int first = context.StoreInTemp("head", Runtime.StringRef, head.location);

                for (Node n = head.nd_next; n != null; n = n.nd_next)
                {
                    n.GenCode0(context);
                    int second = context.StoreInTemp("tail", Runtime.StringRef, n.location);

                    context.ldloc(first);
                    context.ldloc(second);
                    context.callvirt(Runtime.String.Concat);
                    context.stloc(first);

                    context.ReleaseLocal(second, true);
                }

                context.ldloc(first);

                context.ReleaseLocal(first, true);
            }
        }
Beispiel #3
0
        internal void GenCall(CodeGenContext context)
        {
            int result = context.CreateLocal("result", PrimitiveType.Object);

            PERWAPI.CILLabel endLabel = context.NewLabel();
            PERWAPI.CILLabel retryLabel = context.NewLabel();

            context.CodeLabel(retryLabel);

            context.StartBlock(Clause.Try);
            {
                // object result = Call(...)
                GenCall0(context);
                context.stloc(result);

                context.Goto(endLabel);
            }
            PERWAPI.TryBlock tryBlock = context.EndTryBlock();
            context.StartBlock(Clause.Catch);
            {
                CatchBreakException(context, result, endLabel);
            }
            context.EndCatchBlock(Runtime.BreakExceptionRef, tryBlock);
            context.StartBlock(Clause.Catch);
            {
                CatchRetryException(context, retryLabel);
            }
            context.EndCatchBlock(Runtime.RetryExceptionRef, tryBlock);

            context.CodeLabel(endLabel);
            context.ldloc(result);

            context.ReleaseLocal(result, true);
        }
Beispiel #4
0
        internal override void GenCode0(CodeGenContext context)
        {
            bool created;
            ISimple list = GenArgList(context, out created);
            list.GenSimple(context);
            context.callvirt(Runtime.ArgList.ToRubyObject);

            context.ReleaseLocal(list, created);
        }
        internal override void GenCode0(CodeGenContext context)
        {
            bool created;
            ISimple left = context.PreCompute(lhs, "lhs", out created);

            new COND((Node)left, rhs, (Node)left, location).GenCode(context);

            context.ReleaseLocal(left, created);
        }
Beispiel #6
0
        internal override void GenCode0(CodeGenContext context)
        {
            if (args != null)
            {
                bool created;
                ISimple list = args.GenArgList(context, out created);
                list.GenSimple(context);
                context.callvirt(Runtime.ArgList.ToRubyArray);

                context.ReleaseLocal(list, created);
            }
            else
                context.newobj(Runtime.Array.ctor);
        }
        internal override void GenCode0(CodeGenContext context)
        {
            PERWAPI.CILLabel finalLabel = context.NewLabel();

            int RescueTemp = context.CreateLocal("rescueTemp", PERWAPI.PrimitiveType.Object);
            context.ldnull();
            context.stloc(RescueTemp);

            if (ensure != null)
            {
                context.StartBlock(Clause.Try); // outer try block with finally

                context.StartBlock(Clause.Try); // inner try block with catch
            }

            GenInnerBlock(context, RescueTemp);

            if (ensure != null)
            {
                context.Goto(finalLabel);

                PERWAPI.TryBlock innerTry = context.EndTryBlock();

                context.StartBlock(Clause.Catch);
                GenRescue(context, null, 0, null);
                context.EndCatchBlock(Runtime.SystemExceptionRef, innerTry);

                PERWAPI.TryBlock outerTry = context.EndTryBlock();
                
                // Fixme: reset labels to prevent branches out of finally block.    
                context.StartBlock(Clause.Finally);
                ensure.GenCode(context);
                if (context.Reachable())
                    context.pop();
                context.endfinally();
                context.EndFinallyBlock(outerTry);

                context.CodeLabel(finalLabel);
                context.newEndPoint(location);
            }

            context.ldloc(RescueTemp);

            context.ReleaseLocal(RescueTemp, true);
        }
        internal override void Assign(CodeGenContext context, Node rhs)
        {
            bool created;
            ISimple value = context.PreCompute(rhs, "rhs", out created);

            //Ruby.Variables.gvar_set(vid, rhs, caller);
            context.ldstr(vid.ToString());
            value.GenSimple(context);
            context.ldloc(0);
            context.call(Runtime.Variables.gvar_set);

            context.ReleaseLocal(value, created);
        }
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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));
            }
        }
Beispiel #12
0
        internal override ISimple GenArgList(CodeGenContext context, out bool created)
        {
            bool single = true;

            // ArgList arglist = new ArgList();
            context.newobj(Runtime.ArgList.ctor);
            int arglist = context.StoreInTemp("arglist", Runtime.ArgListRef, location);

            int added = 0;
            for (Node arg = parameters; arg != null; arg = arg.nd_next)
            {
                //object argument = arg;
                bool argument_created;
                ISimple argument = context.PreCompute0(arg, "arg", out argument_created);

                // arglist.Add(argument);
                context.ldloc(arglist);
                argument.GenSimple(context);
                context.callvirt(Runtime.ArgList.Add);
                added++;

                context.ReleaseLocal(argument, argument_created);
            }

            if (added != 1)
                single = false;

            if (hashlist != null)
            {
                // object hash = hashlist;
                bool hash_created;
                ISimple hash = context.PreCompute(new HASH(hashlist, hashlist.location), "hashlist", out hash_created);

                // arglist.Add(hash);
                context.ldloc(arglist);
                hash.GenSimple(context);
                context.callvirt(Runtime.ArgList.Add);
                single = false;

                context.ReleaseLocal(hash, hash_created);
            }

            if (array != null)
            {
                // object list = array;
                bool list_created;
                ISimple list = context.PreCompute(array, "array", out list_created);

                // arglist.AddArray(list, caller);
                context.ldloc(arglist);
                list.GenSimple(context);
                context.ldloc(0);
                context.callvirt(Runtime.ArgList.AddArray);
                single = false;

                context.ReleaseLocal(list, list_created);
            }

            if (block != null)
            {
                // object b = block;
                bool b_created;
                ISimple b = context.PreCompute(block, "block", Runtime.ProcRef, out b_created);

                // arglist.block = b;
                context.ldloc(arglist);
                b.GenSimple(context);
                context.stfld(Runtime.ArgList.block);

                context.ReleaseLocal(b, b_created);
            }

            if (single)
            {
                context.ldloc(arglist);
                context.PushTrue();
                context.stfld(Runtime.ArgList.single_arg);
            }

            created = true;
            return new LOCAL(arglist, location);
        }
Beispiel #13
0
        internal override void Assign(CodeGenContext context, Node rhs)
        {
            // object value = rhs;
            bool created;
            ISimple value = context.PreCompute(rhs, "rhs", out created);

            // locals.field = value
            context.ldloc(0);
            value.GenSimple(context);
            context.stfld(field);

            GenCode0(context);

            context.ReleaseLocal(value, created);
        }
Beispiel #14
0
        internal void AddScopeBody(CodeGenContext context)
        {
            returnTemp = context.CreateLocal("returnTemp", PrimitiveType.Object);

            context.labels = new Labels();
            context.labels.Redo = context.NewLabel();
            context.labels.Return = context.NewLabel();

            // try { ... }
            context.StartBlock(Clause.Try);
            {
                if (BEGIN != null)
                    BEGIN.GenCode(context);

                context.CodeLabel(context.labels.Redo);

                if (body != null)
                {
                    body.GenCode(context);

                    if (context.Reachable())
                        context.stloc(returnTemp);
                }

                context.Goto(context.labels.Return);
            }
            PERWAPI.TryBlock tryBlock = context.EndTryBlock();        

            CatchReturnException(context, tryBlock);

            // ReturnLabel:
            //    return returnTemp;
            context.CodeLabel(context.labels.Return);
            context.newEndPoint(location);
            if (context.Method.GetRetType() != PERWAPI.PrimitiveType.Void)
                context.ldloc(returnTemp);
            context.ret();

            context.ReleaseLocal(returnTemp, true);
        }
        internal override void Assign(CodeGenContext context, Node rhs)
        {
            // Gen right hand sides
            ListGen mrhs;
            if (rhs is ListGen && !(rhs is MultipleRHS))
                mrhs = (ListGen)rhs;
            else
                mrhs = new ARGS(null, null, rhs, null, location, true);

            bool created;
            ISimple list = mrhs.GenArgList(context, out created);
            list.GenSimple(context);
            context.callvirt(Runtime.ArgList.CheckSingleRHS);
            int array = context.StoreInTemp("mrhs", Runtime.ArgListRef, location);

            context.ReleaseLocal(list, created);

            // Gen assignments to left hand sides
            for (LVALUE l = elements; l != null; l = (LVALUE)l.nd_next)
            {
                l.Assign(context, new MultipleRHS(array, l.location));
                context.pop();
            }

            context.ldloc(array);
            context.callvirt(Runtime.ArgList.ToRubyArray);

            context.ReleaseLocal(array, true);
        }
Beispiel #16
0
        internal override void Assign(CodeGenContext context, Node rhs)
        {
            // Fixme: make sure CurrentRubyClass is not a singleton (see cvar_cbase)

            // object value = rhs;
            bool created;
            ISimple value = context.PreCompute(rhs, "rhs", out created);

            // Ruby.Variables.cvar_set(caller, ruby_cref, "vid", value);
            context.ldloc(0);
            context.ruby_cbase(parent_scope);
            context.ldstr(vid.ToString());
            value.GenSimple(context);
            context.call(Runtime.Variables.cvar_set);

            context.ReleaseLocal(value, created);
        }
Beispiel #17
0
        // append rhs to args array
        private ISimple ArgsPlusRHS(CodeGenContext context, out bool created)
        {
            // ArgList temp = args;
            ISimple temp = args.GenArgList(context, out created);

            // object value = rhs;
            bool value_created;
            ISimple value = context.PreCompute(rhs, "rhs", out value_created);

            // temp.Add(value);
            temp.GenSimple(context);
            value.GenSimple(context);
            context.callvirt(Runtime.ArgList.Add);

            context.ReleaseLocal(value, value_created);

            return temp;
        }
        internal override void GenCode0(CodeGenContext context)
        {
            int RescueTemp = context.CreateLocal("rescueTemp", PERWAPI.PrimitiveType.Object);
            int ExceptionTemp = context.CreateLocal("exceptionTemp", PERWAPI.PrimitiveType.Object);

            PERWAPI.CILLabel endLabel = context.NewLabel();

            context.StartBlock(Clause.Try);
            {
                expr.GenCode(context);
                if (context.Reachable())
                {
                    context.stloc(RescueTemp);
                    context.Goto(endLabel);
                }
            }
            PERWAPI.TryBlock tryBlock = context.EndTryBlock();

            context.StartBlock(Clause.Catch);
            {
                PERWAPI.CILLabel stdErrLabel = context.NewLabel();
                context.stloc(ExceptionTemp);
                context.ldloc(ExceptionTemp);
                context.ldfld(Runtime.RubyException.parent);
                context.isinst(Runtime.StandardErrorRef);
                context.brtrue(stdErrLabel);
                context.ldloc(ExceptionTemp);
                context.throwOp();
                context.CodeLabel(stdErrLabel);
                rescue.GenCode(context);
                if (context.Reachable())
                {
                    context.stloc(RescueTemp);
                    context.Goto(endLabel);
                }
            }

            context.EndCatchBlock(Runtime.RubyExceptionRef, tryBlock);

            context.CodeLabel(endLabel);

            context.ldloc(RescueTemp);

            context.ReleaseLocal(RescueTemp, true);
            context.ReleaseLocal(ExceptionTemp, true);
        }
        internal void GenCode(CodeGenContext context, PERWAPI.CILLabel endLabel, int RescueTemp, int exception)
        {
            for (RESCUE_CLAUSE clause = this; clause != null; clause = clause.next)
            {
                PERWAPI.CILLabel nextClause = context.NewLabel();
                PERWAPI.CILLabel thisClause = context.NewLabel();

                context.ldc_i4(0);
                LOCAL exceptionCaught = context.StoreInLocal("caught", PERWAPI.PrimitiveType.Boolean, this.location);

                for (Node type = clause.types; type != null; type = type.nd_next)
                {
                    PERWAPI.CILLabel label1 = context.NewLabel();

                    // Precompute each separately to avoid computing a list of types
                    type.GenCode0(context);
                    LOCAL tt = context.StoreInLocal("type", PERWAPI.PrimitiveType.Object, type.location);

                    new METHOD_CALL(tt, ID.intern(Tokens.tEQQ), new AST.LOCAL(exception, type.location), type.location).GenCode(context);

                    context.ReleaseLocal(tt.local, true);

                    context.call(Runtime.Eval.Test);
                    context.brfalse(label1);
                    context.PushTrue();
                    context.stloc(exceptionCaught.local);
                    context.CodeLabel(label1);                  
                }

                context.ldloc(exceptionCaught.local);
                context.brtrue(thisClause);
                context.ReleaseLocal(exceptionCaught.local, true);

                context.br(nextClause);

                context.CodeLabel(thisClause);

                if (clause.var != null)
                {
                    clause.var.Assign(context, new AST.LOCAL(exception, clause.var.location));
                    context.pop();
                }

                if (clause.body != null)
                    clause.body.GenCode(context);
                else
                    context.ldnull();

                if (context.Reachable())
                    context.stloc(RescueTemp);

                // reset $!
                //Eval.ruby_errinfo.value = null;
                context.ldsfld(Runtime.Eval.ruby_errinfo);
                context.ldnull();
                context.stfld(Runtime.global_variable.value);

                context.Goto(endLabel);

                context.CodeLabel(nextClause);
            }
        }
        internal void GenRescue(CodeGenContext context, PERWAPI.CILLabel endLabel, int RescueTemp, RESCUE_CLAUSE clauses)
        {
            // catch (System.Exception e) {

            int e = context.StoreInTemp("e", Runtime.SystemExceptionRef, location);

            //if (e is Ruby.ControlException)
            PERWAPI.CILLabel else1 = context.NewLabel();
            context.ldloc(e);
            context.isinst(Runtime.ControlExceptionRef);
            context.brfalse(else1);
            //    throw e;
            context.rethrow();
            context.CodeLabel(else1);

            // Ruby.Exception exception;
            int exception = context.CreateLocal("exception", Runtime.ExceptionRef);

            //if (!(e is Ruby.RubyException))
            PERWAPI.CILLabel else2 = context.NewLabel();
            PERWAPI.CILLabel end = context.NewLabel();
            context.ldloc(e);
            context.isinst(Runtime.RubyExceptionRef);
            context.brtrue(else2);
            //    exception = new Ruby.CLRException(frame, e);
            context.ldloc(0);
            context.ldloc(e);
            context.newobj(Runtime.CLRException.ctor);
            context.stloc(exception);
            context.br(end);

            //else
            context.CodeLabel(else2);
            //     exception = (Ruby.RubyException)e.parent;
            context.ldloc(e);
            context.cast(Runtime.RubyExceptionRef);
            context.ldfld(Runtime.RubyException.parent);
            context.stloc(exception);

            context.CodeLabel(end);

            //Eval.ruby_errinfo.value = exception;
            context.ldsfld(Runtime.Eval.ruby_errinfo);
            context.ldloc(exception);
            context.stfld(Runtime.global_variable.value);

            if (clauses != null)
                clauses.GenCode(context, endLabel, RescueTemp, exception);

            context.rethrow();

            context.ReleaseLocal(e, true);
            context.ReleaseLocal(exception, true);
        }
Beispiel #21
0
         internal override void Defined(CodeGenContext context)
        {
            if (qualified)
                if (scope != null)
                {
                    // object result;
                    int result = context.CreateLocal("result", PrimitiveType.Object);
                    PERWAPI.CILLabel endLabel = context.NewLabel();
                    // try {
                    context.StartBlock(Clause.Try);
                    {
                        // result = Eval.const_defined(scope, vid, caller);
                        scope.GenCode(context);
                        context.ldstr(vid.ToString());
                        context.ldloc(0);
                        context.call(Runtime.Eval.const_defined);
                        context.stloc(result);
                        context.leave(endLabel);
                    }
                    TryBlock block = context.EndTryBlock();
                    // catch (System.Exception) {
                    context.StartBlock(Clause.Catch);
                    {
                        // result = null;
                        context.ldnull();
                        context.stloc(result);
                        context.leave(endLabel);
                    }
                    context.EndCatchBlock(Runtime.SystemExceptionRef, block);

                    context.CodeLabel(endLabel);
                    context.ldloc(result);
                    context.ReleaseLocal(result, true);
                }
                else
                {
                    context.ldsfld(Ruby.Compiler.Runtime.Init.rb_cObject);
                    context.ldstr(vid.ToString());
                    context.ldloc(0);
                    context.call(Runtime.Eval.const_defined);
                }
            else
            {
                context.ruby_cbase(parent_scope);
                context.ldstr(vid.ToString());
                context.ldloc(0);
                context.call(Runtime.Eval.const_defined);
            }
        }
        private void GetRestRHS(CodeGenContext context)
        {
            // rhs.GetRest();
            bool created;
            ISimple list = ((ListGen)rhs).GenArgList(context, out created);
            list.GenSimple(context);
            context.callvirt(Runtime.ArgList.GetRest);

            context.ReleaseLocal(list, created);
        }
Beispiel #23
0
        internal override void Assign(CodeGenContext context, Node rhs)
        {
            bool value_created;
            ISimple value;

            if (qualified) // Fixme: scope == null???
            {
                // object where = scope;
                bool where_created;
                ISimple where = context.PreCompute(scope, "scope", out where_created);
            
                // object value = rhs;
                value = context.PreCompute(rhs, "rhs", out value_created);

                context.ldloc(0);
                where.GenSimple(context);

                context.ReleaseLocal(where, where_created);
            }
            else
            {
                // object value = rhs;
                value = context.PreCompute(rhs, "rhs", out value_created);

                context.ldloc(0);
                context.ruby_cbase(parent_scope);
            }

            context.ldstr(vid.ToString());
            value.GenSimple(context);
            context.call(Runtime.Eval.set_const);

            context.ReleaseLocal(value, value_created);
        }
        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);
        }
Beispiel #25
0
        internal void AssignOp(CodeGenContext context, string op, Node rhs)
        {
            // object a = array;
            bool a_created;
            ISimple a = context.PreCompute(array, "array", out a_created);

            // ArgList index = args;
            bool index_created;
            index = args.GenArgList(context, out index_created);

            // access <=> a[index];
            ARRAY_ACCESS access = new ARRAY_ACCESS((Node)a, new ProxyList(Index, location), location);

            // access1 = (access2 op rhs);
            access.Assign(context, METHOD_CALL.Create(access, op, rhs, location));

            context.ReleaseLocal(a, a_created);
            context.ReleaseLocal(index, index_created);
        }
        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;
        }
Beispiel #27
0
        internal override void GenCode0(CodeGenContext context)
        {
            int receiverLocal = 0;
            // singleton_class(caller, receiver).define_method(...);
            context.newStartPoint(location);
            if (!(receiver is AST.CALL))
            {
                context.ldloc(0);
                receiver.GenCode(context);
            }
            else
            {
                receiver.GenCode(context);
                receiverLocal = context.CreateLocal("receiverLocal", PrimitiveType.Object);
                context.stloc(receiverLocal);
                context.ldloc(0);
                context.ldloc(receiverLocal);
            }
            context.call(Runtime.Class.singleton_class);
            DefineMethod(context);

            if (receiver is AST.CALL)
                context.ReleaseLocal(receiverLocal, true);
        }
        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);
        }
Beispiel #29
0
        internal void CatchReturnException(CodeGenContext context, PERWAPI.TryBlock tryBlock)
        {
            // catch (Ruby.ReturnException exception) { ... }
            context.StartBlock(Clause.Catch);
            {
                PERWAPI.CILLabel falseLabel = context.NewLabel();

                int exception = context.StoreInTemp("exception", Runtime.ReturnExceptionRef, location);

                // if (exception.scope == thisframe)
                context.ldloc(exception);
                context.ldfld(Runtime.ReturnException.scope);
                context.ldloc(0);
                context.bne(falseLabel);

                //     returnTemp = exception.return_value;
                context.ldloc(exception);
                context.ldfld(Runtime.ReturnException.return_value);
                context.stloc(returnTemp);
                context.Goto(context.labels.Return);

                // falseLabel:
                context.CodeLabel(falseLabel);
                // throw exception
                context.rethrow();

                context.ReleaseLocal(exception, true);
            }
            context.EndCatchBlock(Runtime.ReturnExceptionRef, tryBlock);
        }
Beispiel #30
0
        internal override void GenCode0(CodeGenContext context)
        {
            bool start_created, finish_created;
            ISimple start = context.PreCompute(beg, "beg", out start_created);
            ISimple finish = context.PreCompute(end, "end", out finish_created);

            start.GenSimple(context);
            finish.GenSimple(context);
            context.PushTrue();
            context.newobj(Runtime.Range.ctor);

            context.ReleaseLocal(start, start_created);
            context.ReleaseLocal(finish, finish_created);
        }