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 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 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) { 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) { 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; }