-# define RETVAL_LONG_U64(V) \
- if (V > ZEND_LONG_MAX) { \
- char d[24] = {0}; \
- RETVAL_STRING(zend_print_ulong_to_buf(&d[22], V)); \
+#if HAVE_INT128
+static inline char *psi_u128_to_buf(char *buf, unsigned __int128 u128)
+{
+ for (*buf = 0; u128 > 0; u128 /= 10) {
+ *--buf = ((u128 % 10) + '0') & 0xff;
+ }
+ return buf;
+}
+
+static inline char *psi_i128_to_buf(char *buf, __int128 i128)
+{
+ if (i128 < 0) {
+ char *res = psi_u128_to_buf(buf, ~((unsigned __int128) i128) + 1);
+
+ *--res = '-';
+ return res;
+ }
+ return psi_u128_to_buf(buf, i128);
+}
+
+# define RETVAL_LONG_STR(V, s) do {\
+ char buf[0x30] = {0}; \
+ if (s && V >= ZEND_LONG_MIN && V <= ZEND_LONG_MAX) { \
+ RETVAL_LONG(V); \
+ } else if (!s && V <= ZEND_LONG_MAX) { \
+ RETVAL_LONG(V); \
+ } else if (!s && V <= ZEND_ULONG_MAX) { \
+ RETVAL_STRING(zend_print_ulong_to_buf(&buf[sizeof(buf) - 1], V)); \
+ } else if (s && V >= INT128_MIN && V <= INT128_MAX) { \
+ RETVAL_STRING(psi_i128_to_buf(&buf[sizeof(buf) - 1], V)); \