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