示例#1
0
        public virtual void Emit(OpCode opcode, Label label)
        {
            int tlen = target_len(opcode);

            make_room(6);
            ll_emit(opcode);
            if (cur_stack > labels [label.label].maxStack)
            {
                labels [label.label].maxStack = cur_stack;
            }

            if (fixups == null)
            {
                fixups = new LabelFixup [defaultFixupSize];
            }
            else if (num_fixups >= fixups.Length)
            {
                LabelFixup[] newf = new LabelFixup [fixups.Length * 2];
                System.Array.Copy(fixups, newf, fixups.Length);
                fixups = newf;
            }
            fixups [num_fixups].offset    = tlen;
            fixups [num_fixups].pos       = code_len;
            fixups [num_fixups].label_idx = label.label;
            num_fixups++;
            code_len += tlen;
        }
示例#2
0
        public void Emit(OpCode opc, Label[] labels)
        {
            Emit(opc);
            LabelFixup fix = new LabelFixup();

            fix.label  = -1;
            fix.offset = code.Position;
            labelFixups.Add(fix);
            code.Write(labels.Length);
            foreach (Label label in labels)
            {
                code.Write(label.Index);
                if (this.labels[label.Index] != -1)
                {
                    if (labelStackHeight[label.Index] != stackHeight)
                    {
                        // the "backward branch constraint" prohibits this, so we don't need to support it
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    Debug.Assert(labelStackHeight[label.Index] == -1 || labelStackHeight[label.Index] == stackHeight);
                    labelStackHeight[label.Index] = stackHeight;
                }
            }
        }
示例#3
0
        public virtual void Emit(OpCode opcode, Label[] labels)
        {
            if (labels == null)
            {
                throw new ArgumentNullException("labels");
            }

            /* opcode needs to be switch. */
            int count = labels.Length;

            make_room(6 + count * 4);
            ll_emit(opcode);

            for (int i = 0; i < count; ++i)
            {
                if (cur_stack > this.labels [labels [i].label].maxStack)
                {
                    this.labels [labels [i].label].maxStack = cur_stack;
                }
            }

            emit_int(count);
            if (fixups == null)
            {
                fixups = new LabelFixup [defaultFixupSize + count];
            }
            else if (num_fixups + count >= fixups.Length)
            {
                LabelFixup[] newf = new LabelFixup [count + fixups.Length * 2];
                System.Array.Copy(fixups, newf, fixups.Length);
                fixups = newf;
            }

            // ECMA 335, Partition III, p94 (7-10)
            //
            // The switch instruction implements a jump table. The format of
            // the instruction is an unsigned int32 representing the number of targets N,
            // followed by N int32 values specifying jump targets: these targets are
            // represented as offsets (positive or negative) from the beginning of the
            // instruction following this switch instruction.
            //
            // We must make sure it gets an offset from the *end* of the last label
            // (eg, the beginning of the instruction following this).
            //
            // remaining is the number of bytes from the current instruction to the
            // instruction that will be emitted.

            for (int i = 0, remaining = count * 4; i < count; ++i, remaining -= 4)
            {
                fixups [num_fixups].offset    = remaining;
                fixups [num_fixups].pos       = code_len;
                fixups [num_fixups].label_idx = labels [i].label;
                num_fixups++;
                code_len += 4;
            }
        }
示例#4
0
        public void Emit(OpCode opc, Label label)
        {
            // We need special stackHeight handling for unconditional branches,
            // because the branch and next flows have differing stack heights.
            // Note that this assumes that unconditional branches do not push/pop.
            int flowStackHeight = this.stackHeight;

            Emit(opc);
            if (opc == OpCodes.Leave || opc == OpCodes.Leave_S)
            {
                flowStackHeight = 0;
            }
            else if (opc.FlowControl != FlowControl.Branch)
            {
                flowStackHeight = this.stackHeight;
            }
            // if the label has already been marked, we can emit the branch offset directly
            if (labels[label.Index] != -1)
            {
                if (labelStackHeight[label.Index] != flowStackHeight && (labelStackHeight[label.Index] != 0 || flowStackHeight != -1))
                {
                    // the "backward branch constraint" prohibits this, so we don't need to support it
                    throw new NotSupportedException("'Backward branch constraints' violated");
                }
                if (opc.OperandType == OperandType.ShortInlineBrTarget)
                {
                    WriteByteBranchOffset(labels[label.Index] - (code.Position + 1));
                }
                else
                {
                    code.Write(labels[label.Index] - (code.Position + 4));
                }
            }
            else
            {
                Debug.Assert(labelStackHeight[label.Index] == -1 || labelStackHeight[label.Index] == flowStackHeight || (flowStackHeight == -1 && labelStackHeight[label.Index] == 0));
                labelStackHeight[label.Index] = flowStackHeight;
                LabelFixup fix = new LabelFixup();
                fix.label  = label.Index;
                fix.offset = code.Position;
                labelFixups.Add(fix);
                if (opc.OperandType == OperandType.ShortInlineBrTarget)
                {
                    code.Write((byte)1);
                }
                else
                {
                    code.Write(4);
                }
            }
        }
示例#5
0
		public virtual void Emit (OpCode opcode, Label[] labels)
		{
			if (labels == null)
				throw new ArgumentNullException ("labels");

			/* opcode needs to be switch. */
			int count = labels.Length;
			make_room (6 + count * 4);
			ll_emit (opcode);

			for (int i = 0; i < count; ++i)
				if (cur_stack > this.labels [labels [i].label].maxStack)
					this.labels [labels [i].label].maxStack = cur_stack;

			emit_int (count);
			if (fixups == null)
				fixups = new LabelFixup [defaultFixupSize + count]; 
			else if (num_fixups + count >= fixups.Length) {
				LabelFixup[] newf = new LabelFixup [count + fixups.Length * 2];
				System.Array.Copy (fixups, newf, fixups.Length);
				fixups = newf;
			}
			
			// ECMA 335, Partition III, p94 (7-10)
			//
			// The switch instruction implements a jump table. The format of 
			// the instruction is an unsigned int32 representing the number of targets N,
			// followed by N int32 values specifying jump targets: these targets are
			// represented as offsets (positive or negative) from the beginning of the 
			// instruction following this switch instruction.
			//
			// We must make sure it gets an offset from the *end* of the last label
			// (eg, the beginning of the instruction following this).
			//
			// remaining is the number of bytes from the current instruction to the
			// instruction that will be emitted.
			
			for (int i = 0, remaining = count * 4; i < count; ++i, remaining -= 4) {
				fixups [num_fixups].offset = remaining;
				fixups [num_fixups].pos = code_len;
				fixups [num_fixups].label_idx = labels [i].label;
				num_fixups++;
				code_len += 4;
			}
		}
示例#6
0
		public virtual void Emit (OpCode opcode, Label label)
		{
			int tlen = target_len (opcode);
			make_room (6);
			ll_emit (opcode);
			if (cur_stack > labels [label.label].maxStack)
				labels [label.label].maxStack = cur_stack;
			
			if (fixups == null)
				fixups = new LabelFixup [defaultFixupSize]; 
			else if (num_fixups >= fixups.Length) {
				LabelFixup[] newf = new LabelFixup [fixups.Length * 2];
				System.Array.Copy (fixups, newf, fixups.Length);
				fixups = newf;
			}
			fixups [num_fixups].offset = tlen;
			fixups [num_fixups].pos = code_len;
			fixups [num_fixups].label_idx = label.label;
			num_fixups++;
			code_len += tlen;

		}