Inheritance: CILInstruction
Beispiel #1
0
 /*-------------------- 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)
 {
 }
 internal void brfalse(CILLabel label) {
     buffer.Branch(BranchOp.brfalse, label);
 }
Beispiel #3
0
 internal static CILLabel GetLabel(ArrayList labs, uint targetOffset)
 {
     CILLabel lab;
     int i=0;
     while ((i < labs.Count) && (((CILLabel)labs[i]).offset < targetOffset))  i++;
     if (i < labs.Count) {
         if (((CILLabel)labs[i]).offset == targetOffset) // existing label
             lab = (CILLabel)labs[i];
         else {
             lab = new CILLabel(targetOffset);
             labs.Insert(i,lab);
         }
     } else {
         lab = new CILLabel(targetOffset);
         labs.Add(lab);
     }
     return lab;
 }
Beispiel #4
0
 /*-------------------- 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)
 {
 }
Beispiel #5
0
 /// <summary>
 /// Add a label to the CIL instructions
 /// </summary>
 /// <param name="lab">the label to be added</param>
 public void CodeLabel(CILLabel lab)
 {
     if (lab.Buffer == null) {
         lab.Buffer = this;
     } else if (lab.Buffer != this) {
         throw new DescriptorException("Cannot add a label to two different code buffers");
     }
     AddToBuffer(lab);
 }
Beispiel #6
0
 /// <summary>
 /// Create a new label at this position in the code buffer
 /// </summary>
 /// <returns>the label at the current position</returns>
 public CILLabel NewCodedLabel()
 {
     CILLabel lab = new CILLabel();
     lab.Buffer = this;
     AddToBuffer(lab);
     return lab;
 }
 internal override void GenCode0(CodeGenContext context)
 {
     context.newLine(location);
     if (lhs is ARRAY_ACCESS) // for array access -> need to avoid recomputation of lhs index
         ((ARRAY_ACCESS)lhs).AssignOp(context, op, rhs);
     else if (lhs is CVAR && op == "||")
     {
         CILLabel alreadyDefined1 = new CILLabel();
         CILLabel alreadyDefined2 = new CILLabel();
         CILLabel alreadyDefined3 = new CILLabel();
         Node lhsDefined = new DEFINED(lhs, location);
         lhsDefined.GenCode(context);
         context.brtrue(alreadyDefined1);
         lhs.Assign(context, rhs);
         context.br(alreadyDefined2);
         context.CodeLabel(alreadyDefined1);
         lhs.Assign(context, METHOD_CALL.Create(lhs, op, rhs, location));
         context.CodeLabel(alreadyDefined2);
     }
     else
         lhs.Assign(context, METHOD_CALL.Create(lhs, op, rhs, location));
 }
Beispiel #8
0
 /*-------------------- 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;
 }
        // -----------------------------------------------------------------

        internal void CodeLabel(CILLabel label) {
            buffer.CodeLabel(label);
        }
        internal void Goto(CILLabel label) {
            Clause top = Clause.None;
            if (blocks.Count > 0)
                top = blocks.Peek();

            if (top == Clause.Try || top == Clause.Catch)
                leave(label);
            else if (top == Clause.Finally)
                endfinally();
            else
                br(label);
        }
 internal void bge(CILLabel label) {
     buffer.Branch(BranchOp.bge, label);
 }
 internal void bne(CILLabel label) {
     buffer.Branch(BranchOp.bne_un, label);
 }
 internal void brtrue(CILLabel label) {
     buffer.Branch(BranchOp.brtrue, label);
 }
Beispiel #14
0
 public void SetDests(CILLabel[] dests)
 {
     cases = dests;
 }
Beispiel #15
0
 //////////////////////////////////////////////////////////////////////////
 // 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);
 }
Beispiel #16
0
 /*-------------------- 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)
 {
 }
Beispiel #17
0
 private void catchEnd()
 {
     PERWAPI.TryBlock lastTry = (PERWAPI.TryBlock)errBlocks.Pop();
       if (dotnetErr != null)
       {
     // use a filter if we need to "dual-check" for native exception
     code.EndFilterBlock(filterStart, lastTry);
     dotnetErr = null;
     filterStart = null;
       }
       else
       {
     // this is the normal catch block
     code.EndCatchBlock(emitter.findType(exType) as PERWAPI.Class, lastTry);
       }
 }
Beispiel #18
0
 /// <summary>
 /// Add a branch instruction
 /// </summary>
 /// <param name="inst">the branch instruction</param>
 /// <param name="lab">the label that is the target of the branch</param>
 public void Branch(BranchOp inst,  CILLabel lab)
 {
     Debug.Assert(lab != null);
     AddToBuffer(new BranchInstr(inst,lab));
 }
Beispiel #19
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();
        }
Beispiel #20
0
 /// <summary>
 /// Mark this position as the end of the last started block and
 /// make it a filter block.  This filter block is associated with the
 /// specified try block.  The format is:
 /// filterLab:   ...
 ///              ...
 /// filterHandler :  ...
 ///                  ...
 /// </summary>
 /// <param name="filterLab">the label where the filter code is</param>
 /// <param name="tryBlock">the try block associated with this filter block</param>
 public void EndFilterBlock(CILLabel filterLab, TryBlock tryBlock)
 {
     Filter filBlock = new Filter(filterLab,(CILLabel)blockStack.Pop(),NewCodedLabel());
     tryBlock.AddHandler(filBlock);
 }
Beispiel #21
0
 /*-------------------- Constructors ---------------------------------*/
 public BranchInstr(BranchOp inst, CILLabel dst)
     : base((uint)inst)
 {
     dest = dst;
     shortVer = (inst < BranchOp.br) || (inst == BranchOp.leave_s);
     if (shortVer)
         size++;
     else
         size += 4;
 }
Beispiel #22
0
 /// <summary>
 /// Add a switch instruction
 /// </summary>
 /// <param name="labs">the target labels for the switch</param>
 public void Switch(CILLabel[] labs)
 {
     AddToBuffer(new SwitchInstr(labs));
 }
Beispiel #23
0
 public void SetDest(CILLabel lab)
 {
     dest = lab;
 }
Beispiel #24
0
 /*-------------------- Constructors ---------------------------------*/
 public CodeBlock(CILLabel start, CILLabel end)
 {
     this.start = start;
     this.end = end;
 }
Beispiel #25
0
 internal void MakeTargetLabel(ArrayList labs)
 {
     uint targetOffset = (uint)(offset + size + target);
     dest = CILInstructions.GetLabel(labs,targetOffset);
 }
Beispiel #26
0
 /*-------------------- 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;
 }
Beispiel #27
0
 /*-------------------- Constructors ---------------------------------*/
 public SwitchInstr(CILLabel[] dsts)
     : base(0x45)
 {
     cases = dsts;
     if (cases != null) numCases = (uint)cases.Length;
     size += 4 + (numCases * 4);
 }
Beispiel #28
0
 /*-------------------- Constructors ---------------------------------*/
 public HandlerBlock(CILLabel start, CILLabel end)
     : base(start,end)
 {
 }
 internal void leave(CILLabel label) {
     buffer.Branch(BranchOp.leave, label);
 }