internal void GenCode(CodeGenContext context) { for (Node stmt = this; stmt != null; stmt = stmt.nd_next) { stmt.GenCode0(context); if (stmt.nd_next != null && context.Reachable()) context.pop(); } }
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 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(); }
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 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); }
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; }