MCPcopy Create free account
hub / github.com/bloomberg/pystack / LongObject

Method LongObject

src/pystack/_pystack/pytypes.cpp:148–217  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

146}
147
148LongObject::LongObject(
149 const std::shared_ptr<const AbstractProcessManager>& manager,
150 remote_addr_t addr,
151 bool is_bool)
152: d_is_bool(is_bool)
153{
154#ifdef ENVIRONMENT64
155 constexpr unsigned int shift = 30;
156#else
157 constexpr unsigned int shift = 15;
158#endif
159
160 Structure<py_long_v> longobj(manager, addr);
161 ssize_t size;
162 bool negative;
163
164 Py_ssize_t ob_size = longobj.getField(&py_long_v::o_ob_size);
165 if (manager->versionIsAtLeast(3, 12)) {
166 auto lv_tag = *reinterpret_cast<uintptr_t*>(&ob_size);
167 negative = (lv_tag & 3) == 2;
168 size = lv_tag >> 3;
169 } else {
170 negative = ob_size < 0;
171 size = std::abs(ob_size);
172 }
173
174 if (size == 0) {
175 d_value = 0;
176 return;
177 }
178
179 /* Python's Include/longobjrep.h has this declaration:
180 * struct _longobject {
181 * PyObject_VAR_HEAD
182 * digit ob_digit[1];
183 * };
184 *
185 * with this description:
186 * The absolute value of a number is equal to
187 * SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
188 * Negative numbers are represented with ob_size < 0;
189 * zero is represented by ob_size == 0.
190 *
191 * where SHIFT can be either:
192 * #define PyLong_SHIFT 30
193 * #define PyLong_SHIFT 15
194 */
195
196 std::vector<digit> digits;
197 digits.resize(size);
198 manager->copyMemoryFromProcess(
199 longobj.getFieldRemoteAddress(&py_long_v::o_ob_digit),
200 sizeof(digit) * size,
201 digits.data());
202 for (ssize_t i = 0; i < size; ++i) {
203 long long factor;
204 if (__builtin_mul_overflow(digits[i], (1Lu << (ssize_t)(shift * i)), &factor)) {
205 d_overflowed = true;

Callers

nothing calls this directly

Calls 3

versionIsAtLeastMethod · 0.80
getFieldRemoteAddressMethod · 0.80
copyMemoryFromProcessMethod · 0.45

Tested by

no test coverage detected