yeptris 0.6.17.1 → 0.6.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e317e3324f6bd24065dec096878270922234973be2957c7c850fdb59dea214c6
4
- data.tar.gz: e98c83679d4228d3b35ee70b527f3d10f916308090f35b17585aaa9679292726
3
+ metadata.gz: 658657a4f718471797ff0c61fea6a4549a990974827b6946a1246bbd8249b4a6
4
+ data.tar.gz: 6e3b1331c96a030091ce62ddf51b7a1a001fa137c45306441d9e19bca43d3d72
5
5
  SHA512:
6
- metadata.gz: 4861baa93673811f488bdb34f33826dd9a204eabda55f8b0a2064a2eee1e021e36c49bba8ee597d0ac832c5368bcf572d42adfee257325f46e334ad4e3e7d846
7
- data.tar.gz: '08cd8dc7729a1a3eaac787d85e6fdea0bb9001e1bd449e2c31dc57ebc9c2d327ab505f62d6dc647f99dad1d356a3fab3efc6ac3e1c5429e70589581e5114d741'
6
+ metadata.gz: 9636825560b2ec8aebb29a42bccc9b25ce357d7e3800cc2f349bce9f0fa68d2934bfc7e545e8050c20d200b0d7301eda04c21d03787db86e4078948c824112cd
7
+ data.tar.gz: 56b6bc6ece08fe4dd01d4929a727527fbe4894f5d7d44aab0b35e8010b797309aef0cd375db13a59532f1e745c8afcb013bc9f1cd82869c6d1d98ccf36963d8e
data/lib/yeptris.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Yeptris
4
4
  # The gem's version lives in the parent namespace's file — the last
5
5
  # internal require (yeptris/version) retired with it.
6
- VERSION = "0.6.17.1".freeze
6
+ VERSION = "0.6.18.1".freeze
7
7
  # The error hierarchy lives in THIS file (the parent namespace's
8
8
  # own file): nested constants do not trigger a parent-constant
9
9
  # autoload, and the law forbids internal requires — defining the
@@ -3,7 +3,7 @@
3
3
  cmake_minimum_required(VERSION 3.20)
4
4
 
5
5
  project(yeptris
6
- VERSION 0.6.17
6
+ VERSION 0.6.18
7
7
  DESCRIPTION "Ultra-fast YAML 1.2 parser, emitter and streamer in C"
8
8
  LANGUAGES C CXX
9
9
  )
@@ -23,10 +23,13 @@
23
23
 
24
24
  #include "emit/float/api.h"
25
25
 
26
- #if defined(__SIZEOF_INT128__)
26
+ /* YEP_FLOAT_FORCE_LIMBS: test hook — exercises the portable lo/hi
27
+ * tier on hosts that also have __int128 (the limbs math is otherwise
28
+ * only compiled on 32-bit targets). */
29
+ #if defined(__SIZEOF_INT128__) && !defined(YEP_FLOAT_FORCE_LIMBS) && !defined(YEP_FLOAT_FORCE_LIMBS)
27
30
  typedef unsigned __int128 yep_u128;
28
31
  #define YEP_MUL64(a, b) ((yep_u128)(uint64_t)(a) * (uint64_t)(b))
29
- #elif defined(_MSC_VER)
32
+ #elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
30
33
  #include <intrin.h>
31
34
  /* MSVC has no __int128: the lo/hi pair behind the SAME helper surface
32
35
  * (print.c's interval loop rides only these — no operator arithmetic
@@ -35,10 +38,17 @@ typedef struct {
35
38
  uint64_t lo, hi;
36
39
  } yep_u128;
37
40
  #define YEP_MUL64(a, b) yep_u128_mul64(a, b)
41
+ #else
42
+ /* Any compiler without __int128 (32-bit GCC/Clang, MSVC x86-32): the
43
+ * same lo/hi pair; multiplication via 32-bit limbs (below). */
44
+ typedef struct {
45
+ uint64_t lo, hi;
46
+ } yep_u128;
47
+ #define YEP_MUL64(a, b) yep_u128_mul64(a, b)
38
48
  #endif
39
49
 
40
50
  static inline yep_u128 yep_u128_of(uint64_t v) {
41
- #if defined(__SIZEOF_INT128__)
51
+ #if defined(__SIZEOF_INT128__) && !defined(YEP_FLOAT_FORCE_LIMBS)
42
52
  return (yep_u128)v;
43
53
  #else
44
54
  yep_u128 r = {v, 0};
@@ -47,7 +57,7 @@ static inline yep_u128 yep_u128_of(uint64_t v) {
47
57
  }
48
58
 
49
59
  static inline yep_u128 yep_u128_max(void) {
50
- #if defined(__SIZEOF_INT128__)
60
+ #if defined(__SIZEOF_INT128__) && !defined(YEP_FLOAT_FORCE_LIMBS)
51
61
  return ~(yep_u128)0;
52
62
  #else
53
63
  yep_u128 r = {~(uint64_t)0, ~(uint64_t)0};
@@ -56,7 +66,7 @@ static inline yep_u128 yep_u128_max(void) {
56
66
  }
57
67
 
58
68
  static inline yep_u128 yep_u128_add(yep_u128 a, yep_u128 b) {
59
- #if defined(__SIZEOF_INT128__)
69
+ #if defined(__SIZEOF_INT128__) && !defined(YEP_FLOAT_FORCE_LIMBS)
60
70
  return a + b;
61
71
  #else
62
72
  yep_u128 r;
@@ -67,7 +77,7 @@ static inline yep_u128 yep_u128_add(yep_u128 a, yep_u128 b) {
67
77
  }
68
78
 
69
79
  static inline yep_u128 yep_u128_sub(yep_u128 a, yep_u128 b) {
70
- #if defined(__SIZEOF_INT128__)
80
+ #if defined(__SIZEOF_INT128__) && !defined(YEP_FLOAT_FORCE_LIMBS)
71
81
  return a - b;
72
82
  #else
73
83
  yep_u128 r;
@@ -79,7 +89,7 @@ static inline yep_u128 yep_u128_sub(yep_u128 a, yep_u128 b) {
79
89
 
80
90
  /* n < 128 */
81
91
  static inline yep_u128 yep_u128_shl(yep_u128 a, unsigned n) {
82
- #if defined(__SIZEOF_INT128__)
92
+ #if defined(__SIZEOF_INT128__) && !defined(YEP_FLOAT_FORCE_LIMBS)
83
93
  return a << n;
84
94
  #else
85
95
  yep_u128 r = {0, 0};
@@ -98,7 +108,7 @@ static inline yep_u128 yep_u128_shl(yep_u128 a, unsigned n) {
98
108
 
99
109
  /* n < 128 */
100
110
  static inline yep_u128 yep_u128_shr(yep_u128 a, unsigned n) {
101
- #if defined(__SIZEOF_INT128__)
111
+ #if defined(__SIZEOF_INT128__) && !defined(YEP_FLOAT_FORCE_LIMBS)
102
112
  return a >> n;
103
113
  #else
104
114
  yep_u128 r = {0, 0};
@@ -116,7 +126,7 @@ static inline yep_u128 yep_u128_shr(yep_u128 a, unsigned n) {
116
126
  }
117
127
 
118
128
  static inline int yep_u128_cmp(yep_u128 a, yep_u128 b) {
119
- #if defined(__SIZEOF_INT128__)
129
+ #if defined(__SIZEOF_INT128__) && !defined(YEP_FLOAT_FORCE_LIMBS)
120
130
  return a < b ? -1 : (a > b ? 1 : 0);
121
131
  #else
122
132
  if (a.hi != b.hi) {
@@ -142,29 +152,47 @@ static inline yep_u128 yep_u128_mul64(uint64_t a, uint64_t b) {
142
152
  r.lo = a * b;
143
153
  return r;
144
154
  }
155
+ #elif !defined(__SIZEOF_INT128__) || defined(YEP_FLOAT_FORCE_LIMBS)
156
+ /* portable: 32-bit limbs, exact (the struct tier only) */
157
+ static inline yep_u128 yep_u128_mul64(uint64_t a, uint64_t b) {
158
+ uint64_t a0 = (uint32_t)a, a1 = a >> 32;
159
+ uint64_t b0 = (uint32_t)b, b1 = b >> 32;
160
+ uint64_t ll = a0 * b0;
161
+ uint64_t lh = a0 * b1;
162
+ uint64_t hl = a1 * b0;
163
+ uint64_t mid = (ll >> 32) + (uint32_t)lh + (uint32_t)hl;
164
+ yep_u128 r;
165
+ r.lo = (mid << 32) | (uint32_t)ll;
166
+ r.hi = (a1 * b1) + (lh >> 32) + (hl >> 32) + (mid >> 32);
167
+ return r;
168
+ }
145
169
  #endif
146
170
 
147
171
  /* x * 10 stays in range */
148
172
  static inline int yep_u128_fits10(yep_u128 x) {
149
- #if defined(__SIZEOF_INT128__)
173
+ #if defined(__SIZEOF_INT128__) && !defined(YEP_FLOAT_FORCE_LIMBS)
150
174
  return x <= (~(yep_u128)0) / 10;
151
175
  #else
152
- /* exact: hi*10 must not overflow 64 bits (with the lo carry) */
153
- uint64_t hi_prod_hi = __umulh(x.hi, 10u);
154
- uint64_t hi_prod_lo = x.hi * 10u;
155
- uint64_t lo_carry = __umulh(x.lo, 10u);
156
- return hi_prod_hi == 0 && hi_prod_lo + lo_carry >= hi_prod_lo;
176
+ /* exact: x*10 = (hi*10 << 64) + lo*10 overflow iff hi*10
177
+ * escapes 64 bits or the lo-carry wraps the sum */
178
+ yep_u128 hp = YEP_MUL64(x.hi, 10u);
179
+ if (hp.hi != 0) {
180
+ return 0;
181
+ }
182
+ yep_u128 lp = YEP_MUL64(x.lo, 10u);
183
+ return hp.lo + lp.hi >= hp.lo;
157
184
  #endif
158
185
  }
159
186
 
160
187
  /* m small (< 2^32); caller guarantees no overflow (fits10 guarded) */
161
188
  static inline yep_u128 yep_u128_mul_small(yep_u128 a, uint32_t m) {
162
- #if defined(__SIZEOF_INT128__)
189
+ #if defined(__SIZEOF_INT128__) && !defined(YEP_FLOAT_FORCE_LIMBS)
163
190
  return a * m;
164
191
  #else
165
192
  yep_u128 r;
166
- r.lo = a.lo * m;
167
- r.hi = a.hi * m + __umulh(a.lo, m);
193
+ yep_u128 lp = YEP_MUL64(a.lo, m);
194
+ r.lo = lp.lo;
195
+ r.hi = a.hi * m + lp.hi;
168
196
  return r;
169
197
  #endif
170
198
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yeptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.17.1
4
+ version: 0.6.18.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.