libTriton version 1.0 build 1592
Loading...
Searching...
No Matches
utils.cpp
Go to the documentation of this file.
1
2/*
3** Copyright (C) - Triton
4**
5** This program is under the terms of the Apache License 2.0.
6*/
7
8
11#include <triton/exceptions.hpp>
13
14#include <limits>
15
16
17#if PY_VERSION_HEX >= 0x030C0000
18
19 #define tt_GET_OB_DIGIT(obj) obj->long_value.ob_digit
20 #define tt_SET_OB_DIGIT(obj, n) obj->long_value.lv_tag = (n << 3) | (obj->long_value.lv_tag & 3)
21 #define tt_PyLong_IsNegative(obj) ((obj->long_value.lv_tag & 3) == 2)
22 #define tt_PyLong_DigitCount(obj) (obj->long_value.lv_tag >> 3)
23
24#elif PY_VERSION_HEX >= 0X030A00F0
25
26 #define tt_GET_OB_DIGIT(obj) obj->ob_digit
27 #define tt_SET_OB_DIGIT(obj, n) Py_SET_SIZE(obj, n)
28 #define tt_PyLong_IsNegative(obj) (Py_SIZE(obj) < 0)
29 #define tt_PyLong_DigitCount(obj) (tt_PyLong_IsNegative(obj) ? -Py_SIZE(obj) : Py_SIZE(obj))
30
31#else
32
33 #define tt_GET_OB_DIGIT(obj) obj->ob_digit
34 #define tt_SET_OB_DIGIT(obj, n) Py_SIZE(obj) = n
35 #define tt_PyLong_IsNegative(obj) (Py_SIZE(obj) < 0)
36 #define tt_PyLong_DigitCount(obj) (tt_PyLong_IsNegative(obj) ? -Py_SIZE(obj) : Py_SIZE(obj))
37
38#endif
39
40
41namespace triton {
42 namespace bindings {
43 namespace python {
44
45 bool PyLong_AsBool(PyObject* obj) {
46 return (PyObject_IsTrue(obj) != 0);
47 }
48
49
51 triton::__uint x = 0, prev = 0;
52 PyLongObject* v = nullptr;
53 Py_ssize_t i = 0;
54 bool n = false;
55
56 if (vv == NULL || !PyLong_Check(vv)) {
57 if (vv != NULL && PyInt_Check(vv)) {
58 return PyInt_AsLong(vv);
59 }
60 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint(): Bad internal call.");
61 }
62
63 v = reinterpret_cast<PyLongObject*>(vv);
64 n = tt_PyLong_IsNegative(v);
65 i = tt_PyLong_DigitCount(v);
66 x = 0;
67
68 while (--i >= 0) {
69 prev = x;
70 x = (x << PyLong_SHIFT) | tt_GET_OB_DIGIT(v)[i];
71 if ((x >> PyLong_SHIFT) != prev)
72 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint(): long int too large to convert.");
73 }
74
75 return (n ? ((~x)+1) : x);
76 }
77
78
80 triton::usize x = 0, prev = 0;
81 PyLongObject* v = nullptr;
82 Py_ssize_t i = 0;
83 bool n = false;
84
85 if (vv == NULL || !PyLong_Check(vv)) {
86 if (vv != NULL && PyInt_Check(vv)) {
87 return PyInt_AsLong(vv);
88 }
89 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUsize(): Bad internal call.");
90 }
91
92 v = reinterpret_cast<PyLongObject*>(vv);
93 n = tt_PyLong_IsNegative(v);
94 i = tt_PyLong_DigitCount(v);
95 x = 0;
96
97 while (--i >= 0) {
98 prev = x;
99 x = (x << PyLong_SHIFT) | tt_GET_OB_DIGIT(v)[i];
100 if ((x >> PyLong_SHIFT) != prev)
101 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUsize(): long int too large to convert.");
102 }
103
104 return (n ? ((~x)+1) : x);
105 }
106
107
109 triton::uint32 x = 0, prev = 0;
110 PyLongObject* v = nullptr;
111 Py_ssize_t i = 0;
112 bool n = false;
113
114 if (vv == NULL || !PyLong_Check(vv)) {
115 if (vv != NULL && PyInt_Check(vv)) {
116 return PyInt_AsLong(vv);
117 }
118 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint32(): Bad internal call.");
119 }
120
121 v = reinterpret_cast<PyLongObject*>(vv);
122 n = tt_PyLong_IsNegative(v);
123 i = tt_PyLong_DigitCount(v);
124 x = 0;
125
126 while (--i >= 0) {
127 prev = x;
128 x = (x << PyLong_SHIFT) | tt_GET_OB_DIGIT(v)[i];
129 if ((x >> PyLong_SHIFT) != prev)
130 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint32(): long int too large to convert.");
131 }
132
133 return (n ? ((~x)+1) : x);
134 }
135
136
138 triton::uint64 x = 0, prev = 0;
139 PyLongObject* v = nullptr;
140 Py_ssize_t i = 0;
141 bool n = false;
142
143 if (vv == NULL || !PyLong_Check(vv)) {
144 if (vv != NULL && PyInt_Check(vv)) {
145 return PyInt_AsLong(vv);
146 }
147 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint64(): Bad internal call.");
148 }
149
150 v = reinterpret_cast<PyLongObject*>(vv);
151 n = tt_PyLong_IsNegative(v);
152 i = tt_PyLong_DigitCount(v);
153 x = 0;
154
155 while (--i >= 0) {
156 prev = x;
157 x = (x << PyLong_SHIFT) | tt_GET_OB_DIGIT(v)[i];
158 if ((x >> PyLong_SHIFT) != prev)
159 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint64(): long int too large to convert.");
160 }
161
162 return (n ? ((~x)+1) : x);
163 }
164
165
167 triton::uint128 x = 0, prev = 0;
168 PyLongObject* v = nullptr;
169 Py_ssize_t i = 0;
170 bool n = false;
171
172 if (vv == NULL || !PyLong_Check(vv)) {
173 if (vv != NULL && PyInt_Check(vv)) {
174 return PyInt_AsLong(vv);
175 }
176 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint128(): Bad internal call.");
177 }
178
179 v = reinterpret_cast<PyLongObject*>(vv);
180 n = tt_PyLong_IsNegative(v);
181 i = tt_PyLong_DigitCount(v);
182 x = 0;
183
184 while (--i >= 0) {
185 prev = x;
186 x = (x << PyLong_SHIFT) | tt_GET_OB_DIGIT(v)[i];
187 if ((x >> PyLong_SHIFT) != prev)
188 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint128(): long int too large to convert.");
189 }
190
191 return (n ? ((~x)+1) : x);
192 }
193
194
196 triton::uint256 x = 0, prev = 0;
197 PyLongObject* v = nullptr;
198 Py_ssize_t i = 0;
199 bool n = false;
200
201 if (vv == NULL || !PyLong_Check(vv)) {
202 if (vv != NULL && PyInt_Check(vv)) {
203 return PyInt_AsLong(vv);
204 }
205 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint256(): Bad internal call.");
206 }
207
208 v = reinterpret_cast<PyLongObject*>(vv);
209 n = tt_PyLong_IsNegative(v);
210 i = tt_PyLong_DigitCount(v);
211 x = 0;
212
213 while (--i >= 0) {
214 prev = x;
215 x = (x << PyLong_SHIFT) | tt_GET_OB_DIGIT(v)[i];
216 if ((x >> PyLong_SHIFT) != prev)
217 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint256(): long int too large to convert.");
218 }
219
220 return (n ? ((~x)+1) : x);
221 }
222
223
225 triton::uint512 x = 0, prev = 0;
226 PyLongObject* v = nullptr;
227 Py_ssize_t i = 0;
228 bool n = false;
229
230 if (vv == NULL || !PyLong_Check(vv)) {
231 if (vv != NULL && PyInt_Check(vv)) {
232 return PyInt_AsLong(vv);
233 }
234 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint512(): Bad internal call.");
235 }
236
237 v = reinterpret_cast<PyLongObject*>(vv);
238 n = tt_PyLong_IsNegative(v);
239 i = tt_PyLong_DigitCount(v);
240 x = 0;
241
242 while (--i >= 0) {
243 prev = x;
244 x = (x << PyLong_SHIFT) | tt_GET_OB_DIGIT(v)[i];
245 if ((x >> PyLong_SHIFT) != prev)
246 throw triton::exceptions::Bindings("triton::bindings::python::PyLong_AsUint512(): long int too large to convert.");
247 }
248
249 return (n ? ((~x)+1) : x);
250 }
251
252
253 /* Returns a PyObject from a {32,64}-bits integer */
255 #if defined(__i386) || defined(_M_IX86)
256 return PyInt_FromLong(static_cast<long>(value));
257 #else
258 PyLongObject* v;
260 int ndigits = 0;
261
262 // it is mandatory to let Python deal with small numbers (static objects)
263 if (value <= std::numeric_limits<long>::max())
264 return PyInt_FromLong(static_cast<long>(value));
265
266 /* Count the number of Python digits. */
267 t = value;
268 while (t) {
269 ++ndigits;
270 t >>= PyLong_SHIFT;
271 }
272
273 v = _PyLong_New(ndigits);
274 digit* p = tt_GET_OB_DIGIT(v);
275 tt_SET_OB_DIGIT(v, ndigits);
276
277 while (value) {
278 *p++ = static_cast<digit>(value & PyLong_MASK);
279 value >>= PyLong_SHIFT;
280 }
281
282 return (PyObject*)v;
283 #endif
284 }
285
286
287 /* Returns a PyObject from a {32,64}-bits integer */
289 #if defined(__i386) || defined(_M_IX86)
290 return PyInt_FromLong(static_cast<long>(value));
291 #else
292 PyLongObject* v;
294 int ndigits = 0;
295
296 // it is mandatory to let Python deal with small numbers (static objects)
297 if (value <= std::numeric_limits<long>::max())
298 return PyInt_FromLong(static_cast<long>(value));
299
300 /* Count the number of Python digits. */
301 t = value;
302 while (t) {
303 ++ndigits;
304 t >>= PyLong_SHIFT;
305 }
306
307 v = _PyLong_New(ndigits);
308 digit* p = tt_GET_OB_DIGIT(v);
309 tt_SET_OB_DIGIT(v, ndigits);
310
311 while (value) {
312 *p++ = static_cast<digit>(value & PyLong_MASK);
313 value >>= PyLong_SHIFT;
314 }
315
316 return (PyObject*)v;
317 #endif
318 }
319
320
321 /* Returns a PyObject from a 32-bits integer */
323 return PyInt_FromLong(static_cast<long>(value));
324 }
325
326
327 /* Returns a PyObject from a 64-bits integer */
329 PyLongObject* v;
331 int ndigits = 0;
332
333 // it is mandatory to let Python deal with small numbers (static objects)
334 if (value <= std::numeric_limits<long>::max())
335 return PyInt_FromLong(static_cast<long>(value));
336
337 /* Count the number of Python digits. */
338 t = value;
339 while (t) {
340 ++ndigits;
341 t >>= PyLong_SHIFT;
342 }
343
344 v = _PyLong_New(ndigits);
345 digit* p = tt_GET_OB_DIGIT(v);
346 tt_SET_OB_DIGIT(v, ndigits);
347
348 while (value) {
349 *p++ = static_cast<digit>(value & PyLong_MASK);
350 value >>= PyLong_SHIFT;
351 }
352
353 return (PyObject*)v;
354 }
355
356
357 /* Returns a PyObject from a 128-bits integer */
359 PyLongObject* v;
361 int ndigits = 0;
362
363 // it is mandatory to let Python deal with small numbers (static objects)
364 if (value <= std::numeric_limits<long>::max())
365 return PyInt_FromLong(static_cast<long>(value));
366
367 /* Count the number of Python digits. */
368 t = value;
369 while (t) {
370 ++ndigits;
371 t >>= PyLong_SHIFT;
372 }
373
374 v = _PyLong_New(ndigits);
375 digit* p = tt_GET_OB_DIGIT(v);
376 tt_SET_OB_DIGIT(v, ndigits);
377
378 while (value) {
379 *p++ = static_cast<digit>(value & PyLong_MASK);
380 value >>= PyLong_SHIFT;
381 }
382
383 return (PyObject*)v;
384 }
385
386
387 /* Returns a PyObject from a 256-bits integer */
389 PyLongObject* v;
391 int ndigits = 0;
392
393 // it is mandatory to let Python deal with small numbers (static objects)
394 if (value <= std::numeric_limits<long>::max())
395 return PyInt_FromLong(static_cast<long>(value));
396
397 /* Count the number of Python digits. */
398 t = value;
399 while (t) {
400 ++ndigits;
401 t >>= PyLong_SHIFT;
402 }
403
404 v = _PyLong_New(ndigits);
405 digit* p = tt_GET_OB_DIGIT(v);
406 tt_SET_OB_DIGIT(v, ndigits);
407
408 while (value) {
409 *p++ = static_cast<digit>(value & PyLong_MASK);
410 value >>= PyLong_SHIFT;
411 }
412
413 return (PyObject*)v;
414 }
415
416
417 /* Returns a PyObject from a 512-bits integer */
419 PyLongObject* v;
420 triton::uint512 t = 0;
421 int ndigits = 0;
422
423 // it is mandatory to let Python deal with small numbers (static objects)
424 if (value <= std::numeric_limits<long>::max())
425 return PyInt_FromLong(static_cast<long>(value));
426
427 /* Count the number of Python digits. */
428 t = value;
429 while (t) {
430 ++ndigits;
431 t >>= PyLong_SHIFT;
432 }
433
434 v = _PyLong_New(ndigits);
435 digit* p = tt_GET_OB_DIGIT(v);
436 tt_SET_OB_DIGIT(v, ndigits);
437
438 while (value) {
439 *p++ = static_cast<digit>(value & PyLong_MASK);
440 value >>= PyLong_SHIFT;
441 }
442
443 return (PyObject*)v;
444 }
445
446 }; /* python namespace */
447 }; /* bindings namespace */
448}; /* triton namespace */
449
450#undef tt_GET_OB_DIGIT
451#undef tt_SET_OB_DIGIT
452#undef tt_PyLong_IsNegative
453#undef tt_PyLong_DigitCount
The exception class used by bindings.
PyObject * PyLong_FromUint(triton::__uint value)
Returns a pyObject from a triton::__uint.
Definition utils.cpp:254
triton::uint64 PyLong_AsUint64(PyObject *vv)
Returns a triton::uint64 from a pyObject.
Definition utils.cpp:137
triton::uint128 PyLong_AsUint128(PyObject *vv)
Returns a triton::uint128 from a pyObject.
Definition utils.cpp:166
PyObject * PyLong_FromUsize(triton::usize value)
Returns a pyObject from a triton::usize.
Definition utils.cpp:288
triton::__uint PyLong_AsUint(PyObject *vv)
Returns a triton::__uint from a pyObject.
Definition utils.cpp:50
PyObject * PyLong_FromUint256(triton::uint256 value)
Returns a pyObject from a triton::uint256.
Definition utils.cpp:388
bool PyLong_AsBool(PyObject *obj)
Returns a bool from a pyObject.
Definition utils.cpp:45
PyObject * PyLong_FromUint512(triton::uint512 value)
Returns a pyObject from a triton::uint512.
Definition utils.cpp:418
triton::uint512 PyLong_AsUint512(PyObject *vv)
Returns a triton::uint512 from a pyObject.
Definition utils.cpp:224
triton::uint256 PyLong_AsUint256(PyObject *vv)
Returns a triton::uint256 from a pyObject.
Definition utils.cpp:195
PyObject * PyLong_FromUint64(triton::uint64 value)
Returns a pyObject from a triton::uint64.
Definition utils.cpp:328
triton::uint32 PyLong_AsUint32(PyObject *vv)
Returns a triton::uint32 from a pyObject.
Definition utils.cpp:108
triton::usize PyLong_AsUsize(PyObject *vv)
Returns a triton::usize from a pyObject.
Definition utils.cpp:79
PyObject * PyLong_FromUint128(triton::uint128 value)
Returns a pyObject from a triton::uint128.
Definition utils.cpp:358
PyObject * PyLong_FromUint32(triton::uint32 value)
Returns a pyObject from a triton::uint32.
Definition utils.cpp:322
std::size_t usize
unsigned MAX_INT 32 or 64 bits according to the CPU.
std::uint64_t uint64
unisgned 64-bits
std::uint32_t uint32
unisgned 32-bits
unsigned long long __uint
unsigned long long if the arch is 64-bits.
The Triton namespace.