Пример #1
0
        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();
        }