Skip to content

Commit aa79009

Browse files
committed
Use 32bit limbs for BigInt implementation
It's simpler and compatible with all platforms.
1 parent f6c5767 commit aa79009

File tree

2 files changed

+7
-127
lines changed

2 files changed

+7
-127
lines changed

quickjs.c

Lines changed: 7 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -376,27 +376,20 @@ typedef struct JSRefCountHeader {
376376
} JSRefCountHeader;
377377

378378
/* bigint */
379-
#if JS_LIMB_BITS == 32
380-
381379
typedef int32_t js_slimb_t;
382380
typedef uint32_t js_limb_t;
383381
typedef int64_t js_sdlimb_t;
384382
typedef uint64_t js_dlimb_t;
385383

386384
#define JS_LIMB_DIGITS 9
387385

388-
#else
389-
390-
typedef __int128 int128_t;
391-
typedef unsigned __int128 uint128_t;
392-
typedef int64_t js_slimb_t;
393-
typedef uint64_t js_limb_t;
394-
typedef int128_t js_sdlimb_t;
395-
typedef uint128_t js_dlimb_t;
386+
/* Must match the size of short_big_int in JSValueUnion */
387+
#define JS_LIMB_BITS 32
388+
#define JS_SHORT_BIG_INT_BITS JS_LIMB_BITS
389+
#define JS_BIGINT_MAX_SIZE ((1024 * 1024) / JS_LIMB_BITS) /* in limbs */
390+
#define JS_SHORT_BIG_INT_MIN INT32_MIN
391+
#define JS_SHORT_BIG_INT_MAX INT32_MAX
396392

397-
#define JS_LIMB_DIGITS 19
398-
399-
#endif
400393

401394
typedef struct JSBigInt {
402395
JSRefCountHeader header; /* must come first, 32-bit */
@@ -10473,19 +10466,6 @@ static inline int to_digit(int c)
1047310466

1047410467
/* bigint support */
1047510468

10476-
#define JS_BIGINT_MAX_SIZE ((1024 * 1024) / JS_LIMB_BITS) /* in limbs */
10477-
10478-
/* it is currently assumed that JS_SHORT_BIG_INT_BITS = JS_LIMB_BITS */
10479-
#if JS_SHORT_BIG_INT_BITS == 32
10480-
#define JS_SHORT_BIG_INT_MIN INT32_MIN
10481-
#define JS_SHORT_BIG_INT_MAX INT32_MAX
10482-
#elif JS_SHORT_BIG_INT_BITS == 64
10483-
#define JS_SHORT_BIG_INT_MIN INT64_MIN
10484-
#define JS_SHORT_BIG_INT_MAX INT64_MAX
10485-
#else
10486-
#error unsupported
10487-
#endif
10488-
1048910469
#define ADDC(res, carry_out, op1, op2, carry_in) \
1049010470
do { \
1049110471
js_limb_t __v, __a, __k, __k1; \
@@ -10498,18 +10478,11 @@ do { \
1049810478
res = __a; \
1049910479
} while (0)
1050010480

10501-
#if JS_LIMB_BITS == 32
1050210481
/* a != 0 */
1050310482
static inline js_limb_t js_limb_clz(js_limb_t a)
1050410483
{
1050510484
return clz32(a);
1050610485
}
10507-
#else
10508-
static inline js_limb_t js_limb_clz(js_limb_t a)
10509-
{
10510-
return clz64(a);
10511-
}
10512-
#endif
1051310486

1051410487
static js_limb_t mp_add(js_limb_t *res, const js_limb_t *op1, const js_limb_t *op2,
1051510488
js_limb_t n, js_limb_t carry)
@@ -10815,9 +10788,6 @@ static JSBigInt *js_bigint_set_si(JSBigIntBuf *buf, js_slimb_t a)
1081510788

1081610789
static JSBigInt *js_bigint_set_si64(JSBigIntBuf *buf, int64_t a)
1081710790
{
10818-
#if JS_LIMB_BITS == 64
10819-
return js_bigint_set_si(buf, a);
10820-
#else
1082110791
JSBigInt *r = (JSBigInt *)buf->big_int_buf;
1082210792
r->header.ref_count = 0; /* fail safe */
1082310793
if (a >= INT32_MIN && a <= INT32_MAX) {
@@ -10829,7 +10799,6 @@ static JSBigInt *js_bigint_set_si64(JSBigIntBuf *buf, int64_t a)
1082910799
r->tab[1] = a >> JS_LIMB_BITS;
1083010800
}
1083110801
return r;
10832-
#endif
1083310802
}
1083410803

1083510804
/* val must be a short big int */
@@ -10844,11 +10813,7 @@ static __maybe_unused void js_bigint_dump1(JSContext *ctx, const char *str,
1084410813
int i;
1084510814
printf("%s: ", str);
1084610815
for(i = len - 1; i >= 0; i--) {
10847-
#if JS_LIMB_BITS == 32
1084810816
printf(" %08x", tab[i]);
10849-
#else
10850-
printf(" %016" PRIx64, tab[i]);
10851-
#endif
1085210817
}
1085310818
printf("\n");
1085410819
}
@@ -10871,9 +10836,6 @@ static JSBigInt *js_bigint_new_si(JSContext *ctx, js_slimb_t a)
1087110836

1087210837
static JSBigInt *js_bigint_new_si64(JSContext *ctx, int64_t a)
1087310838
{
10874-
#if JS_LIMB_BITS == 64
10875-
return js_bigint_new_si(ctx, a);
10876-
#else
1087710839
if (a >= INT32_MIN && a <= INT32_MAX) {
1087810840
return js_bigint_new_si(ctx, a);
1087910841
} else {
@@ -10885,7 +10847,6 @@ static JSBigInt *js_bigint_new_si64(JSContext *ctx, int64_t a)
1088510847
r->tab[1] = a >> 32;
1088610848
return r;
1088710849
}
10888-
#endif
1088910850
}
1089010851

1089110852
static JSBigInt *js_bigint_new_ui64(JSContext *ctx, uint64_t a)
@@ -10897,14 +10858,9 @@ static JSBigInt *js_bigint_new_ui64(JSContext *ctx, uint64_t a)
1089710858
r = js_bigint_new(ctx, (65 + JS_LIMB_BITS - 1) / JS_LIMB_BITS);
1089810859
if (!r)
1089910860
return NULL;
10900-
#if JS_LIMB_BITS == 64
10901-
r->tab[0] = a;
10902-
r->tab[1] = 0;
10903-
#else
1090410861
r->tab[0] = a;
1090510862
r->tab[1] = a >> 32;
1090610863
r->tab[2] = 0;
10907-
#endif
1090810864
return r;
1090910865
}
1091010866
}
@@ -10970,17 +10926,10 @@ static js_slimb_t js_bigint_get_si_sat(const JSBigInt *a)
1097010926
if (a->len == 1) {
1097110927
return a->tab[0];
1097210928
} else {
10973-
#if JS_LIMB_BITS == 32
1097410929
if (js_bigint_sign(a))
1097510930
return INT32_MIN;
1097610931
else
1097710932
return INT32_MAX;
10978-
#else
10979-
if (js_bigint_sign(a))
10980-
return INT64_MIN;
10981-
else
10982-
return INT64_MAX;
10983-
#endif
1098410933
}
1098510934
}
1098610935

@@ -11421,21 +11370,11 @@ static uint64_t js_bigint_get_mant_exp(JSContext *ctx,
1142111370
t[j] = v;
1142211371
}
1142311372

11424-
#if JS_LIMB_BITS == 32
1142511373
a1 = ((uint64_t)t[2] << 32) | t[1];
1142611374
a0 = (uint64_t)t[0] << 32;
11427-
#else
11428-
a1 = t[1];
11429-
a0 = t[0];
11430-
#endif
1143111375
a0 |= (low_bits != 0);
1143211376
/* normalize */
11433-
if (a1 == 0) {
11434-
/* JS_LIMB_BITS = 64 bit only */
11435-
shift = 64;
11436-
a1 = a0;
11437-
a0 = 0;
11438-
} else {
11377+
{
1143911378
shift = clz64(a1);
1144011379
if (shift != 0) {
1144111380
a1 = (a1 << shift) | (a0 >> (64 - shift));
@@ -11636,18 +11575,6 @@ static const js_limb_t js_pow_dec[JS_LIMB_DIGITS + 1] = {
1163611575
10000000U,
1163711576
100000000U,
1163811577
1000000000U,
11639-
#if JS_LIMB_BITS == 64
11640-
10000000000U,
11641-
100000000000U,
11642-
1000000000000U,
11643-
10000000000000U,
11644-
100000000000000U,
11645-
1000000000000000U,
11646-
10000000000000000U,
11647-
100000000000000000U,
11648-
1000000000000000000U,
11649-
10000000000000000000U,
11650-
#endif
1165111578
};
1165211579

1165311580
/* syntax: [-]digits in base radix. Return NULL if memory error. radix
@@ -11792,15 +11719,10 @@ static char *limb_to_a(char *q, js_limb_t n, unsigned int radix, int len)
1179211719
#define JS_RADIX_MAX 36
1179311720

1179411721
static const uint8_t digits_per_limb_table[JS_RADIX_MAX - 1] = {
11795-
#if JS_LIMB_BITS == 32
1179611722
32,20,16,13,12,11,10,10, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
11797-
#else
11798-
64,40,32,27,24,22,21,20,19,18,17,17,16,16,16,15,15,15,14,14,14,14,13,13,13,13,13,13,13,12,12,12,12,12,12,
11799-
#endif
1180011723
};
1180111724

1180211725
static const js_limb_t radix_base_table[JS_RADIX_MAX - 1] = {
11803-
#if JS_LIMB_BITS == 32
1180411726
0x00000000, 0xcfd41b91, 0x00000000, 0x48c27395,
1180511727
0x81bf1000, 0x75db9c97, 0x40000000, 0xcfd41b91,
1180611728
0x3b9aca00, 0x8c8b6d2b, 0x19a10000, 0x309f1021,
@@ -11810,17 +11732,6 @@ static const js_limb_t radix_base_table[JS_RADIX_MAX - 1] = {
1181011732
0x1269ae40, 0x17179149, 0x1cb91000, 0x23744899,
1181111733
0x2b73a840, 0x34e63b41, 0x40000000, 0x4cfa3cc1,
1181211734
0x5c13d840, 0x6d91b519, 0x81bf1000,
11813-
#else
11814-
0x0000000000000000, 0xa8b8b452291fe821, 0x0000000000000000, 0x6765c793fa10079d,
11815-
0x41c21cb8e1000000, 0x3642798750226111, 0x8000000000000000, 0xa8b8b452291fe821,
11816-
0x8ac7230489e80000, 0x4d28cb56c33fa539, 0x1eca170c00000000, 0x780c7372621bd74d,
11817-
0x1e39a5057d810000, 0x5b27ac993df97701, 0x0000000000000000, 0x27b95e997e21d9f1,
11818-
0x5da0e1e53c5c8000, 0xd2ae3299c1c4aedb, 0x16bcc41e90000000, 0x2d04b7fdd9c0ef49,
11819-
0x5658597bcaa24000, 0xa0e2073737609371, 0x0c29e98000000000, 0x14adf4b7320334b9,
11820-
0x226ed36478bfa000, 0x383d9170b85ff80b, 0x5a3c23e39c000000, 0x8e65137388122bcd,
11821-
0xdd41bb36d259e000, 0x0aee5720ee830681, 0x1000000000000000, 0x172588ad4f5f0981,
11822-
0x211e44f7d02c1000, 0x2ee56725f06e5c71, 0x41c21cb8e1000000,
11823-
#endif
1182411735
};
1182511736

1182611737
static JSValue js_bigint_to_string1(JSContext *ctx, JSValueConst val, int radix)
@@ -13540,11 +13451,7 @@ static __maybe_unused void JS_DumpValue(JSRuntime *rt, JSValueConst val)
1354013451
for(i = p->len - 1; i >= 0; i--) {
1354113452
if (i != p->len - 1)
1354213453
printf("_");
13543-
#if JS_LIMB_BITS == 32
1354413454
printf("%08x", p->tab[i]);
13545-
#else
13546-
printf("%016" PRIx64, p->tab[i]);
13547-
#endif
1354813455
}
1354913456
printf("n");
1355013457
if (sgn)
@@ -13631,9 +13538,6 @@ static double js_math_pow(double a, double b)
1363113538

1363213539
JSValue JS_NewBigInt64(JSContext *ctx, int64_t v)
1363313540
{
13634-
#if JS_SHORT_BIG_INT_BITS == 64
13635-
return __JS_NewShortBigInt(ctx, v);
13636-
#else
1363713541
if (v >= JS_SHORT_BIG_INT_MIN && v <= JS_SHORT_BIG_INT_MAX) {
1363813542
return __JS_NewShortBigInt(ctx, v);
1363913543
} else {
@@ -13643,7 +13547,6 @@ JSValue JS_NewBigInt64(JSContext *ctx, int64_t v)
1364313547
return JS_EXCEPTION;
1364413548
return JS_MKPTR(JS_TAG_BIG_INT, p);
1364513549
}
13646-
#endif
1364713550
}
1364813551

1364913552
JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v)
@@ -13746,10 +13649,8 @@ static int JS_ToBigInt64Free(JSContext *ctx, int64_t *pres, JSValue val)
1374613649
JSBigInt *p = JS_VALUE_GET_PTR(val);
1374713650
/* return the value mod 2^64 */
1374813651
res = p->tab[0];
13749-
#if JS_LIMB_BITS == 32
1375013652
if (p->len >= 2)
1375113653
res |= (uint64_t)p->tab[1] << 32;
13752-
#endif
1375313654
JS_FreeValue(ctx, val);
1375413655
}
1375513656
*pres = res;
@@ -35519,11 +35420,7 @@ static int JS_WriteBigInt(BCWriterState *s, JSValueConst obj)
3551935420
bc_put_leb128(s, len);
3552035421
if (len > 0) {
3552135422
for(i = 0; i < (len / (JS_LIMB_BITS / 8)); i++) {
35522-
#if JS_LIMB_BITS == 32
3552335423
bc_put_u32(s, p->tab[i]);
35524-
#else
35525-
bc_put_u64(s, p->tab[i]);
35526-
#endif
3552735424
}
3552835425
for(i = 0; i < len % (JS_LIMB_BITS / 8); i++) {
3552935426
bc_put_u8(s, (p->tab[p->len - 1] >> (i * 8)) & 0xff);
@@ -36411,13 +36308,8 @@ static JSValue JS_ReadBigInt(BCReaderState *s)
3641136308
if (!p)
3641236309
goto fail;
3641336310
for(i = 0; i < len / (JS_LIMB_BITS / 8); i++) {
36414-
#if JS_LIMB_BITS == 32
3641536311
if (bc_get_u32(s, &v))
3641636312
goto fail;
36417-
#else
36418-
if (bc_get_u64(s, &v))
36419-
goto fail;
36420-
#endif
3642136313
p->tab[i] = v;
3642236314
}
3642336315
n = len % (JS_LIMB_BITS / 8);

quickjs.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,6 @@ typedef uint32_t JSAtom;
8585
#endif
8686
#endif
8787

88-
#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX) && !defined(_WIN32) && !defined(__TINYC__)
89-
#define JS_LIMB_BITS 64
90-
#else
91-
#define JS_LIMB_BITS 32
92-
#endif
93-
94-
#define JS_SHORT_BIG_INT_BITS JS_LIMB_BITS
95-
9688
enum {
9789
/* all tags with a reference count are negative */
9890
JS_TAG_FIRST = -9, /* first negative tag */
@@ -246,11 +238,7 @@ typedef union JSValueUnion {
246238
int32_t int32;
247239
double float64;
248240
void *ptr;
249-
#if JS_SHORT_BIG_INT_BITS == 32
250241
int32_t short_big_int;
251-
#else
252-
int64_t short_big_int;
253-
#endif
254242
} JSValueUnion;
255243

256244
typedef struct JSValue {

0 commit comments

Comments
 (0)