xref: /freebsd/contrib/bearssl/T0/TValue.cs (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1 /*
2  * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 using System;
26 using System.Collections.Generic;
27 
28 /*
29  * Each value is represented with a TValue structure. Integers use the 'x'
30  * field, and 'ptr' is null; for pointers, the 'ptr' field is used, and the
31  * 'x' is then an offset in the object represented by 'ptr'.
32  */
33 
34 struct TValue {
35 
36 	internal int x;
37 	internal TPointerBase ptr;
38 
39 	internal TValue(int x)
40 	{
41 		this.x = x;
42 		this.ptr = null;
43 	}
44 
45 	internal TValue(uint x)
46 	{
47 		this.x = (int)x;
48 		this.ptr = null;
49 	}
50 
51 	internal TValue(bool b)
52 	{
53 		this.x = b ? -1 : 0;
54 		this.ptr = null;
55 	}
56 
57 	internal TValue(int x, TPointerBase ptr)
58 	{
59 		this.x = x;
60 		this.ptr = ptr;
61 	}
62 
63 	/*
64 	 * Convert this value to a boolean; integer 0 and null pointer are
65 	 * 'false', other values are 'true'.
66 	 */
67 	internal bool Bool {
68 		get {
69 			if (ptr == null) {
70 				return x != 0;
71 			} else {
72 				return ptr.ToBool(this);
73 			}
74 		}
75 	}
76 
77 	/*
78 	 * Get this value as an integer. Pointers cannot be converted to
79 	 * integers.
80 	 */
81 	internal int Int {
82 		get {
83 			if (ptr == null) {
84 				return x;
85 			}
86 			throw new Exception("not an integer: " + ToString());
87 		}
88 	}
89 
90 	/*
91 	 * Get this value as an unsigned integer. This is the integer
92 	 * value, reduced modulo 2^32 in the 0..2^32-1 range.
93 	 */
94 	internal uint UInt {
95 		get {
96 			return (uint)Int;
97 		}
98 	}
99 
100 	/*
101 	 * String format of integers uses decimal representation. For
102 	 * pointers, this depends on the pointed-to value.
103 	 */
104 	public override string ToString()
105 	{
106 		if (ptr == null) {
107 			return String.Format("{0}", x);
108 		} else {
109 			return ptr.ToString(this);
110 		}
111 	}
112 
113 	/*
114 	 * If this value is an XT, then execute it. Otherwise, an exception
115 	 * is thrown.
116 	 */
117 	internal void Execute(T0Comp ctx, CPU cpu)
118 	{
119 		ToXT().Execute(ctx, cpu);
120 	}
121 
122 	/*
123 	 * Convert this value to an XT. On failure, an exception is thrown.
124 	 */
125 	internal TPointerXT ToXT()
126 	{
127 		TPointerXT xt = ptr as TPointerXT;
128 		if (xt == null) {
129 			throw new Exception(
130 				"value is not an xt: " + ToString());
131 		}
132 		return xt;
133 	}
134 
135 	/*
136 	 * Compare this value to another.
137 	 */
138 	internal bool Equals(TValue v)
139 	{
140 		if (x != v.x) {
141 			return false;
142 		}
143 		if (ptr == v.ptr) {
144 			return true;
145 		}
146 		if (ptr == null || v.ptr == null) {
147 			return false;
148 		}
149 		return ptr.Equals(v.ptr);
150 	}
151 
152 	public static implicit operator TValue(bool val)
153 	{
154 		return new TValue(val);
155 	}
156 
157 	public static implicit operator TValue(sbyte val)
158 	{
159 		return new TValue((int)val);
160 	}
161 
162 	public static implicit operator TValue(byte val)
163 	{
164 		return new TValue((int)val);
165 	}
166 
167 	public static implicit operator TValue(short val)
168 	{
169 		return new TValue((int)val);
170 	}
171 
172 	public static implicit operator TValue(ushort val)
173 	{
174 		return new TValue((int)val);
175 	}
176 
177 	public static implicit operator TValue(char val)
178 	{
179 		return new TValue((int)val);
180 	}
181 
182 	public static implicit operator TValue(int val)
183 	{
184 		return new TValue((int)val);
185 	}
186 
187 	public static implicit operator TValue(uint val)
188 	{
189 		return new TValue((int)val);
190 	}
191 
192 	public static implicit operator bool(TValue v)
193 	{
194 		return v.Bool;
195 	}
196 
197 	public static implicit operator sbyte(TValue v)
198 	{
199 		return (sbyte)v.Int;
200 	}
201 
202 	public static implicit operator byte(TValue v)
203 	{
204 		return (byte)v.Int;
205 	}
206 
207 	public static implicit operator short(TValue v)
208 	{
209 		return (short)v.Int;
210 	}
211 
212 	public static implicit operator ushort(TValue v)
213 	{
214 		return (ushort)v.Int;
215 	}
216 
217 	public static implicit operator char(TValue v)
218 	{
219 		return (char)v.Int;
220 	}
221 
222 	public static implicit operator int(TValue v)
223 	{
224 		return (int)v.Int;
225 	}
226 
227 	public static implicit operator uint(TValue v)
228 	{
229 		return (uint)v.Int;
230 	}
231 }
232