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