/*-------------------- Constructors ---------------------------------*/ protected CodeBlock(CILLabel start, CILLabel end) { Contract.Requires(start != null); Contract.Requires(end != null); this.start = start; this.end = end; }
internal TryBlock MakeTryBlock(List <CILLabel> labels) { Contract.Requires(labels != null); Contract.Ensures(Contract.Result <TryBlock>() != null); TryBlock tBlock = new TryBlock(CILInstructions.GetLabel(labels, tryOffset), CILInstructions.GetLabel(labels, tryOffset + tryLength)); CILLabel hStart = CILInstructions.GetLabel(labels, handlerOffset); CILLabel hEnd = CILInstructions.GetLabel(labels, handlerOffset + handlerLength); HandlerBlock handler = null; switch (clauseType) { case (EHClauseType.Exception): handler = new Catch((Class)classToken, hStart, hEnd); break; case (EHClauseType.Filter): handler = new Filter(CILInstructions.GetLabel(labels, filterOffset), hStart, hEnd); break; case (EHClauseType.Finally): handler = new Finally(hStart, hEnd); break; case (EHClauseType.Fault): handler = new Fault(hStart, hEnd); break; } tBlock.AddHandler(handler); return(tBlock); }
////////////////////////////////////////////////////////////////////////// // Switch ////////////////////////////////////////////////////////////////////////// private void tableswitch() { int count = u2(); CILLabel[] labels = new CILLabel[count]; for (int i = 0; i < count; ++i) { labels[i] = jumps.add(u2()); } code.Switch(labels); }
/*-------------------- Constructors ---------------------------------*/ /// <summary> /// Create a new fault clause /// </summary> /// <param name="faultStart">start of the fault code</param> /// <param name="faultEnd">end of the fault code</param> public Fault(CILLabel faultStart, CILLabel faultEnd) : base(faultStart, faultEnd) { }
/*-------------------- Constructors ---------------------------------*/ /// <summary> /// Create a new finally clause /// </summary> /// <param name="finallyStart">start of finally code</param> /// <param name="finallyEnd">end of finally code</param> public Finally(CILLabel finallyStart, CILLabel finallyEnd) : base(finallyStart, finallyEnd) { }
/*-------------------- Constructors ---------------------------------*/ /// <summary> /// Create a new filter clause /// </summary> /// <param name="filterLabel">the label where the filter code starts</param> /// <param name="handlerStart">the start of the handler code</param> /// <param name="handlerEnd">the end of the handler code</param> public Filter(CILLabel filterLabel, CILLabel handlerStart, CILLabel handlerEnd) : base(handlerStart, handlerEnd) { this.filterLabel = filterLabel; }
/*-------------------- Constructors ---------------------------------*/ /// <summary> /// Create a new catch clause /// </summary> /// <param name="except">the exception to be caught</param> /// <param name="handlerStart">start of the handler code</param> /// <param name="handlerEnd">end of the handler code</param> public Catch(Class except, CILLabel handlerStart, CILLabel handlerEnd) : base(handlerStart, handlerEnd) { exceptType = except; }
/*-------------------- Constructors ---------------------------------*/ protected HandlerBlock(CILLabel start, CILLabel end) : base(start, end) { }
/*-------------------- Constructors ---------------------------------*/ /// <summary> /// Create a new try block /// </summary> /// <param name="start">start label for the try block</param> /// <param name="end">end label for the try block</param> public TryBlock(CILLabel start, CILLabel end) : base(start, end) { }
private void coerce() { FTypeRef from = pod.typeRef(u2()); FTypeRef to = pod.typeRef(u2()); // Bool boxing/unboxing if (from.isBoolPrimitive()) { if (to.isRef()) { boolBox(); return; } throw new Exception("Coerce " + from + " => " + to); } if (to.isBoolPrimitive()) { if (from.isRef()) { boolUnbox(!from.isBool()); return; } throw new Exception("Coerce " + from + " => " + to); } // Int boxing/unboxing if (from.isIntPrimitive()) { if (to.isRef()) { intBox(); return; } throw new Exception("Coerce " + from + " => " + to); } if (to.isIntPrimitive()) { if (from.isRef()) { intUnbox(!from.isInt()); return; } throw new Exception("Coerce " + from + " => " + to); } // Float boxing/unboxing if (from.isFloatPrimitive()) { if (to.isRef()) { floatBox(); return; } throw new Exception("Coerce " + from + " => " + to); } if (to.isFloatPrimitive()) { if (from.isRef()) { floatUnbox(!from.isFloat()); return; } throw new Exception("Coerce " + from + " => " + to); } // check nullable => non-nullable if (from.isNullable() && !to.isNullable()) { CILLabel nonnull = code.NewLabel(); code.Inst(Op.dup); code.Inst(Op.ldnull); code.Branch(BranchOp.bne_un_s, nonnull); if (parent.NullErrMakeCoerce == null) { parent.NullErrMakeCoerce = emitter.findMethod("Fan.Sys.NullErr", "makeCoerce", new string[0], "Fan.Sys.Err/Val"); } code.MethInst(MethodOp.call, parent.NullErrMakeCoerce); code.Inst(Op.throwOp); code.CodeLabel(nonnull); } // don't bother casting to obj if (to.isObj()) { return; } code.TypeInst(TypeOp.castclass, emitter.findType(to.nname())); }
private void catchErrStart() { exType = "System.Exception"; for (int i = 0; i < tryJump.Length; i++) { if (startPos == tryJump[i]) { FTypeRef typeRef = pod.typeRef(tryErr[i]); dotnetErr = Fan.Sys.Err.fanToDotnet(typeRef.nname()); if (!typeRef.isErr()) { exType = typeRef.nname() + "/Val"; } break; } } // close try block errBlocks.Push(getLastTryBlock()); // use a filter if we need to "dual-check" for native exception if (dotnetErr != null) { code.CodeLabel(filterStart = code.NewLabel()); CILLabel match = code.NewLabel(); CILLabel endfilter = code.NewLabel(); // check native type first code.Inst(Op.dup); code.TypeInst(TypeOp.isinst, emitter.findType(dotnetErr)); code.Inst(Op.ldnull); code.Branch(BranchOp.bne_un_s, match); // then check Fantom type code.Inst(Op.dup); code.TypeInst(TypeOp.isinst, emitter.findType(exType)); code.Inst(Op.ldnull); code.Branch(BranchOp.bne_un_s, match); // no match code.Inst(Op.pop); // pop exception off stack code.IntInst(IntOp.ldc_i4, 0); code.Branch(BranchOp.br_s, endfilter); // match code.CodeLabel(match); code.Inst(Op.pop); // pop exception off stack code.IntInst(IntOp.ldc_i4, 1); // endfilter code.CodeLabel(endfilter); code.Inst(Op.endfilter); } // start handler block code.StartBlock(); // there is already a System.Exception on the stack, but // we need to map into a sys::Err type if (parent.ErrMake == null) { parent.ErrMake = emitter.findMethod("Fan.Sys.Err", "make", new string[] { "System.Exception" }, "Fan.Sys.Err"); } code.MethInst(MethodOp.call, parent.ErrMake); cast(); }
internal static void ILSpyMtNoRt(ClassDef classDef, MethodDef methodDef, Method startLogMethod, Method endLogMethod) { string classNameString = MethodLoggerUtil.GetQualifiedClassName(classDef); string methodNameString = methodDef.Name(); string paramsString = MethodLoggerUtil.GetParamsAsString(methodDef.GetParams()); List <Local> CLRLocals = new List <Local>(); CLRLocals.Clear(); Param[] parms = methodDef.GetParams(); if (methodDef.GetMaxStack() < 3) { methodDef.SetMaxStack(3); } string strGuid = Guid.NewGuid().ToString(); CILInstructions instructions = methodDef.GetCodeBuffer(); if (instructions == null) { return; } instructions.StartInsert(); instructions.Inst(Op.nop); instructions.StartBlock(); // Try #1 instructions.StartBlock(); // Try #2 instructions.Inst(Op.nop); instructions.ldstr(strGuid); instructions.ldstr(classNameString); instructions.ldstr(methodNameString); instructions.ldstr(paramsString); instructions.MethInst(MethodOp.call, startLogMethod); instructions.EndInsert(); while (instructions.GetNextInstruction().GetPos() < instructions.NumInstructions() - 2) { ; } instructions.StartInsert(); instructions.Inst(Op.nop); CILLabel cel0 = instructions.NewLabel(); CILLabel cel9 = instructions.NewLabel(); instructions.Branch(BranchOp.leave_s, cel9); TryBlock tBlk2 = instructions.EndTryBlock(); // #2 instructions.StartBlock(); int istloc = 0; if (methodDef.GetLocals() != null) { istloc = methodDef.GetLocals().Length; } instructions.IntInst(IntOp.stloc_s, istloc); instructions.Inst(Op.nop); //instructions.Inst(Op.rethrow); CILLabel cel = instructions.NewLabel(); instructions.CodeLabel(cel0); instructions.OpenScope(); //start---add exceptiong to stocks variables Local loc = new Local("SpyMtNoRt", Runtime.SystemExceptionRef); if (methodDef.GetLocals() != null) { foreach (Local lab in methodDef.GetLocals()) { CLRLocals.Add(lab); } } CLRLocals.Add(loc); methodDef.AddLocals(CLRLocals.ToArray(), false); foreach (Local la in methodDef.GetLocals()) { instructions.BindLocal(la); } //start---add exceptiong to stocks variables instructions.CloseScope(); instructions.IntInst(IntOp.ldloc_s, istloc); Method LogException = null; MethodLoggerUtil.GetMethodsFromClass("LogException", out LogException); instructions.MethInst(MethodOp.call, LogException); instructions.Inst(Op.nop); instructions.Inst(Op.nop); instructions.Branch(BranchOp.leave_s, cel9); instructions.EndCatchBlock(Runtime.SystemExceptionRef, tBlk2); instructions.CodeLabel(cel9); instructions.Branch(BranchOp.leave_s, cel); TryBlock tBlk1 = instructions.EndTryBlock(); // #1 instructions.StartBlock(); // Finally instructions.Inst(Op.nop); instructions.ldstr(strGuid); instructions.ldstr(classNameString); instructions.ldstr(methodNameString); instructions.ldstr(paramsString); instructions.MethInst(MethodOp.call, endLogMethod); instructions.Inst(Op.nop); instructions.Inst(Op.nop); instructions.Inst(Op.endfinally); instructions.EndFinallyBlock(tBlk1); instructions.CodeLabel(cel); instructions.EndInsert(); }