1178172Simp/*
2178172Simp * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
3178172Simp *
4178172Simp * Permission is hereby granted, free of charge, to any person obtaining
5178172Simp * a copy of this software and associated documentation files (the
6178172Simp * "Software"), to deal in the Software without restriction, including
7178172Simp * without limitation the rights to use, copy, modify, merge, publish,
8178172Simp * distribute, sublicense, and/or sell copies of the Software, and to
9178172Simp * permit persons to whom the Software is furnished to do so, subject to
10178172Simp * the following conditions:
11178172Simp *
12178172Simp * The above copyright notice and this permission notice shall be
13178172Simp * included in all copies or substantial portions of the Software.
14178172Simp *
15178172Simp * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16178172Simp * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17178172Simp * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18178172Simp * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19178172Simp * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20178172Simp * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21178172Simp * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22178172Simp * SOFTWARE.
23178172Simp */
24178172Simp
25178172Simpusing System;
26178172Simp
27178172Simpclass CodeElementJump : CodeElement {
28178172Simp
29178172Simp	uint jumpType;
30178172Simp	CodeElement target;
31178172Simp
32178172Simp	internal CodeElementJump(uint jumpType)
33178172Simp	{
34178172Simp		this.jumpType = jumpType;
35178172Simp	}
36178172Simp
37178172Simp	/* obsolete
38178172Simp	internal override int Length {
39178172Simp		get {
40178172Simp			int len = Encode7EUnsigned(jumpType, null);
41178172Simp			int joff = JumpOff;
42178172Simp			if (joff == Int32.MinValue) {
43178172Simp				len ++;
44232449Sjmallett			} else {
45178172Simp				len += Encode7ESigned(joff, null);
46178172Simp			}
47203476Sneel			return len;
48233412Sgonzo		}
49178172Simp	}
50178172Simp	*/
51178172Simp
52178172Simp	internal override int GetLength(bool oneByteCode)
53178172Simp	{
54178172Simp		int len = oneByteCode ? 1 : Encode7EUnsigned(jumpType, null);
55178172Simp		int joff = JumpOff;
56178172Simp		if (joff == Int32.MinValue) {
57178172Simp			len ++;
58178172Simp		} else {
59178172Simp			len += Encode7ESigned(joff, null);
60178172Simp		}
61178172Simp		return len;
62178172Simp	}
63178172Simp
64178172Simp	internal override void SetJumpTarget(CodeElement target)
65178172Simp	{
66178172Simp		this.target = target;
67178172Simp	}
68178172Simp
69178172Simp	int JumpOff {
70178172Simp		get {
71178172Simp			if (target == null || Address < 0 || target.Address < 0)
72178172Simp			{
73178172Simp				return Int32.MinValue;
74178172Simp			} else {
75178172Simp				return target.Address - (Address + LastLength);
76178172Simp			}
77178172Simp		}
78178172Simp	}
79178172Simp
80178172Simp	internal override int Encode(BlobWriter bw, bool oneByteCode)
81178172Simp	{
82202046Simp		if (bw == null) {
83178172Simp			return GetLength(oneByteCode);
84178172Simp		}
85178172Simp		int len;
86232577Sgonzo		if (oneByteCode) {
87178172Simp			len = EncodeOneByte(jumpType, bw);
88178172Simp		} else {
89178172Simp			len = Encode7EUnsigned(jumpType, bw);
90178172Simp		}
91178172Simp		int joff = JumpOff;
92178172Simp		if (joff == Int32.MinValue) {
93178172Simp			throw new Exception("Unresolved addresses");
94178172Simp		}
95233412Sgonzo		return len + Encode7ESigned(joff, bw);
96233412Sgonzo	}
97233412Sgonzo}
98233412Sgonzo