Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/VM/src/lintlib.cpp
2725 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
#include "lualib.h"
3
4
#include "lcommon.h"
5
#include "lnumutils.h"
6
#include "lobject.h"
7
8
#include <climits>
9
#include <cmath>
10
11
#ifdef _MSC_VER
12
#include <intrin.h>
13
#endif
14
15
LUAU_FASTFLAGVARIABLE(LuauIntegerLibrary)
16
17
#define mask64(w) (0xFFFFFFFFFFFFFFFFULL >> (64 - (w)))
18
19
static int int64_create(lua_State* L)
20
{
21
double x = luaL_checknumber(L, 1);
22
if (x >= -9223372036854775808.0 && x < 9223372036854775808.0)
23
{
24
int64_t l = (int64_t)x;
25
if (((double)l) == x)
26
{
27
lua_pushinteger64(L, l);
28
return 1;
29
}
30
}
31
32
lua_pushnil(L);
33
34
return 1;
35
}
36
37
static int int64_fromstring(lua_State* L)
38
{
39
const char* s = luaL_checkstring(L, 1);
40
int base = luaL_optinteger(L, 2, 10);
41
luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
42
43
int64_t result;
44
if (luaO_str2l(s, &result, base))
45
lua_pushinteger64(L, result);
46
else
47
lua_pushnil(L);
48
49
return 1;
50
}
51
52
static int int64_tonumber(lua_State* L)
53
{
54
int64_t x = luaL_checkinteger64(L, 1);
55
56
lua_pushnumber(L, (double)x);
57
58
return 1;
59
}
60
61
static int int64_neg(lua_State* L)
62
{
63
int64_t x = luaL_checkinteger64(L, 1);
64
65
lua_pushinteger64(L, (int64_t)(~(uint64_t)x + 1));
66
67
return 1;
68
}
69
70
static int int64_add(lua_State* L)
71
{
72
int64_t x = luaL_checkinteger64(L, 1);
73
int64_t y = luaL_checkinteger64(L, 2);
74
75
lua_pushinteger64(L, (int64_t)((uint64_t)x + (uint64_t)y));
76
77
return 1;
78
}
79
80
static int int64_sub(lua_State* L)
81
{
82
int64_t x = luaL_checkinteger64(L, 1);
83
int64_t y = luaL_checkinteger64(L, 2);
84
85
lua_pushinteger64(L, (int64_t)((uint64_t)x - (uint64_t)y));
86
87
return 1;
88
}
89
90
static int int64_mul(lua_State* L)
91
{
92
int64_t x = luaL_checkinteger64(L, 1);
93
int64_t y = luaL_checkinteger64(L, 2);
94
95
lua_pushinteger64(L, (int64_t)((uint64_t)x * (uint64_t)y));
96
97
return 1;
98
}
99
100
static int int64_div(lua_State* L)
101
{
102
int64_t a = luaL_checkinteger64(L, 1);
103
int64_t b = luaL_checkinteger64(L, 2);
104
105
if (b == 0)
106
luaL_error(L, "division by zero");
107
if ((a == LLONG_MIN) && (b == -1))
108
luaL_error(L, "integer overflow");
109
110
lua_pushinteger64(L, a / b);
111
112
return 1;
113
}
114
115
static int int64_idiv(lua_State* L)
116
{
117
int64_t a = luaL_checkinteger64(L, 1);
118
int64_t b = luaL_checkinteger64(L, 2);
119
120
if (b == 0)
121
luaL_error(L, "division by zero");
122
if ((a == LLONG_MIN) && (b == -1))
123
luaL_error(L, "integer overflow");
124
125
int64_t result = a / b;
126
if ((result < 0) && (a % b))
127
lua_pushinteger64(L, result - 1);
128
else
129
lua_pushinteger64(L, result);
130
131
return 1;
132
}
133
134
static int int64_rem(lua_State* L)
135
{
136
int64_t a = luaL_checkinteger64(L, 1);
137
int64_t b = luaL_checkinteger64(L, 2);
138
139
if (b == 0)
140
luaL_error(L, "division by zero");
141
142
if ((a == LLONG_MIN) && (b == -1))
143
{
144
lua_pushinteger64(L, 0);
145
return 1;
146
}
147
148
lua_pushinteger64(L, a % b);
149
150
return 1;
151
}
152
153
static int int64_mod(lua_State* L)
154
{
155
int64_t a = luaL_checkinteger64(L, 1);
156
int64_t b = luaL_checkinteger64(L, 2);
157
158
if (b == 0)
159
luaL_error(L, "division by zero");
160
161
int64_t remainder = 0;
162
if ((a != LLONG_MIN) || (b != -1))
163
{
164
remainder = a % b;
165
if (remainder && ((a < 0) != (b < 0)))
166
remainder += b;
167
}
168
169
lua_pushinteger64(L, remainder);
170
171
return 1;
172
}
173
174
static int int64_udiv(lua_State* L)
175
{
176
uint64_t a = luaL_checkinteger64(L, 1);
177
uint64_t b = luaL_checkinteger64(L, 2);
178
179
if (b == 0)
180
luaL_error(L, "division by zero");
181
182
lua_pushinteger64(L, a / b);
183
184
return 1;
185
}
186
187
static int int64_urem(lua_State* L)
188
{
189
uint64_t a = luaL_checkinteger64(L, 1);
190
uint64_t b = luaL_checkinteger64(L, 2);
191
192
if (b == 0)
193
luaL_error(L, "division by zero");
194
195
lua_pushinteger64(L, a % b);
196
197
return 1;
198
}
199
200
static int int64_min(lua_State* L)
201
{
202
int64_t tmin = luaL_checkinteger64(L, 1);
203
int n = lua_gettop(L);
204
for (int i = 2; i <= n; i++)
205
{
206
int64_t x = luaL_checkinteger64(L, i);
207
if (x < tmin)
208
tmin = x;
209
}
210
211
lua_pushinteger64(L, tmin);
212
213
return 1;
214
}
215
216
static int int64_max(lua_State* L)
217
{
218
int64_t tmax = luaL_checkinteger64(L, 1);
219
int n = lua_gettop(L);
220
for (int i = 2; i <= n; i++)
221
{
222
int64_t x = luaL_checkinteger64(L, i);
223
if (x > tmax)
224
tmax = x;
225
}
226
227
lua_pushinteger64(L, tmax);
228
229
return 1;
230
}
231
232
static int int64_band(lua_State* L)
233
{
234
uint64_t tres = ULLONG_MAX;
235
int n = lua_gettop(L);
236
237
for (int i = 1; i <= n; i++)
238
{
239
uint64_t x = (uint64_t)luaL_checkinteger64(L, i);
240
tres &= x;
241
}
242
243
lua_pushinteger64(L, tres);
244
245
return 1;
246
}
247
248
static int int64_bor(lua_State* L)
249
{
250
uint64_t tres = 0;
251
int n = lua_gettop(L);
252
253
for (int i = 1; i <= n; i++)
254
{
255
uint64_t x = (uint64_t)luaL_checkinteger64(L, i);
256
tres |= x;
257
}
258
259
lua_pushinteger64(L, tres);
260
261
return 1;
262
}
263
264
static int int64_bnot(lua_State* L)
265
{
266
uint64_t a = luaL_checkinteger64(L, 1);
267
268
lua_pushinteger64(L, ~a);
269
270
return 1;
271
}
272
273
static int int64_bxor(lua_State* L)
274
{
275
uint64_t tres = 0;
276
int n = lua_gettop(L);
277
278
for (int i = 1; i <= n; i++)
279
{
280
uint64_t x = (uint64_t)luaL_checkinteger64(L, i);
281
tres ^= x;
282
}
283
284
lua_pushinteger64(L, tres);
285
286
return 1;
287
}
288
289
static int int64_lt(lua_State* L)
290
{
291
int64_t a = luaL_checkinteger64(L, 1);
292
int64_t b = luaL_checkinteger64(L, 2);
293
294
lua_pushboolean(L, a < b);
295
296
return 1;
297
}
298
299
static int int64_le(lua_State* L)
300
{
301
int64_t a = luaL_checkinteger64(L, 1);
302
int64_t b = luaL_checkinteger64(L, 2);
303
304
lua_pushboolean(L, a <= b);
305
306
return 1;
307
}
308
309
static int int64_ult(lua_State* L)
310
{
311
uint64_t a = luaL_checkinteger64(L, 1);
312
uint64_t b = luaL_checkinteger64(L, 2);
313
314
lua_pushboolean(L, a < b);
315
316
return 1;
317
}
318
319
static int int64_ule(lua_State* L)
320
{
321
uint64_t a = luaL_checkinteger64(L, 1);
322
uint64_t b = luaL_checkinteger64(L, 2);
323
324
lua_pushboolean(L, a <= b);
325
326
return 1;
327
}
328
329
static int int64_gt(lua_State* L)
330
{
331
int64_t a = luaL_checkinteger64(L, 1);
332
int64_t b = luaL_checkinteger64(L, 2);
333
334
lua_pushboolean(L, a > b);
335
336
return 1;
337
}
338
339
static int int64_ge(lua_State* L)
340
{
341
int64_t a = luaL_checkinteger64(L, 1);
342
int64_t b = luaL_checkinteger64(L, 2);
343
344
lua_pushboolean(L, a >= b);
345
346
return 1;
347
}
348
349
static int int64_ugt(lua_State* L)
350
{
351
uint64_t a = luaL_checkinteger64(L, 1);
352
uint64_t b = luaL_checkinteger64(L, 2);
353
354
lua_pushboolean(L, a > b);
355
356
return 1;
357
}
358
359
static int int64_uge(lua_State* L)
360
{
361
uint64_t a = luaL_checkinteger64(L, 1);
362
uint64_t b = luaL_checkinteger64(L, 2);
363
364
lua_pushboolean(L, a >= b);
365
366
return 1;
367
}
368
369
static int int64_lshift(lua_State* L)
370
{
371
uint64_t n = luaL_checkinteger64(L, 1);
372
int64_t i = luaL_checkinteger64(L, 2);
373
374
if ((i >= -63) && (i <= 63))
375
lua_pushinteger64(L, (i < 0) ? (n >> (-i)) : (n << i));
376
else
377
lua_pushinteger64(L, 0);
378
379
return 1;
380
}
381
382
static int int64_rshift(lua_State* L)
383
{
384
uint64_t n = luaL_checkinteger64(L, 1);
385
int64_t i = luaL_checkinteger64(L, 2);
386
387
if ((i >= -63) && (i <= 63))
388
lua_pushinteger64(L, (i < 0) ? (n << (-i)) : (n >> i));
389
else
390
lua_pushinteger64(L, 0);
391
392
return 1;
393
}
394
395
static int int64_arshift(lua_State* L)
396
{
397
int64_t n = luaL_checkinteger64(L, 1);
398
int64_t i = luaL_checkinteger64(L, 2);
399
400
if ((i >= -63) && (i <= 63))
401
lua_pushinteger64(L, (i < 0) ? (int64_t)((uint64_t)n << (-i)) : (n >> i));
402
else if (i < -63)
403
lua_pushinteger64(L, 0);
404
else
405
lua_pushinteger64(L, (n < 0) ? -1 : 0);
406
407
return 1;
408
}
409
410
static int int64_lrotate(lua_State* L)
411
{
412
uint64_t n = (uint64_t)luaL_checkinteger64(L, 1);
413
unsigned s = (unsigned)((uint64_t)luaL_checkinteger64(L, 2) % 64);
414
415
lua_pushinteger64(L, (int64_t)(s != 0 ? (n << s) | (n >> (64 - s)) : n));
416
417
return 1;
418
}
419
420
static int int64_rrotate(lua_State* L)
421
{
422
uint64_t n = (uint64_t)luaL_checkinteger64(L, 1);
423
unsigned s = (unsigned)((uint64_t)luaL_checkinteger64(L, 2) % 64);
424
425
lua_pushinteger64(L, (int64_t)(s != 0 ? (n >> s) | (n << (64 - s)) : n));
426
427
return 1;
428
}
429
430
static int int64_extract(lua_State* L)
431
{
432
int64_t n = luaL_checkinteger64(L, 1);
433
int64_t f = luaL_checkinteger64(L, 2);
434
int64_t w = luaL_optinteger64(L, 3, 1);
435
436
luaL_argcheck(L, 0 <= f && f <= 63, 2, "field cannot be negative");
437
luaL_argcheck(L, 0 < w, 3, "width must be positive");
438
if (f + w > 64)
439
luaL_error(L, "trying to access non-existent bits");
440
441
lua_pushinteger64(L, ((uint64_t)n >> f) & mask64(w));
442
443
return 1;
444
}
445
446
static int int64_replace(lua_State* L)
447
{
448
int64_t n = luaL_checkinteger64(L, 1);
449
int64_t r = luaL_checkinteger64(L, 2);
450
int64_t f = luaL_checkinteger64(L, 3);
451
int64_t w = luaL_optinteger64(L, 4, 1);
452
453
luaL_argcheck(L, 0 <= f && f <= 63, 3, "field cannot be negative");
454
luaL_argcheck(L, 0 < w, 4, "width must be positive");
455
if (f + w > 64)
456
luaL_error(L, "trying to access non-existent bits");
457
458
uint64_t baseMask = ((0xFFFFFFFFFFFFFFFFULL) >> (64 - w));
459
uint64_t replacement = (((uint64_t)r) & baseMask) << f;
460
uint64_t mask = 0xFFFFFFFFFFFFFFFFULL ^ (baseMask << f);
461
lua_pushinteger64(L, (((uint64_t)n) & mask) | replacement);
462
463
return 1;
464
}
465
466
static int int64_clamp(lua_State* L)
467
{
468
int64_t a = luaL_checkinteger64(L, 1);
469
int64_t mi = luaL_checkinteger64(L, 2);
470
int64_t mx = luaL_checkinteger64(L, 3);
471
472
luaL_argcheck(L, mi <= mx, 3, "max must be greater than or equal to min");
473
474
if (a < mi)
475
lua_pushinteger64(L, mi);
476
else if (a > mx)
477
lua_pushinteger64(L, mx);
478
else
479
lua_pushinteger64(L, a);
480
481
return 1;
482
}
483
484
static int int64_btest(lua_State* L)
485
{
486
uint64_t tres = ULLONG_MAX;
487
int n = lua_gettop(L);
488
489
for (int i = 1; i <= n; i++)
490
{
491
uint64_t x = (uint64_t)luaL_checkinteger64(L, i);
492
tres &= x;
493
}
494
495
lua_pushboolean(L, (tres != 0));
496
497
return 1;
498
}
499
500
static int int64_countrz(lua_State* L)
501
{
502
uint64_t n = luaL_checkinteger64(L, 1);
503
int result;
504
#ifdef _MSC_VER
505
#ifdef _WIN64
506
unsigned long rl;
507
result = _BitScanForward64(&rl, n) ? int(rl) : 64;
508
#else
509
unsigned long rl;
510
if (_BitScanForward(&rl, uint32_t(n)))
511
result = int(rl);
512
else
513
result = _BitScanForward(&rl, uint32_t(n >> 32)) ? int(rl) + 32 : 64;
514
#endif
515
#else
516
result = (n == 0) ? 64 : __builtin_ctzll(n);
517
#endif
518
519
lua_pushinteger64(L, result);
520
521
return 1;
522
}
523
524
static int int64_countlz(lua_State* L)
525
{
526
uint64_t n = luaL_checkinteger64(L, 1);
527
int result;
528
#ifdef _MSC_VER
529
#ifdef _WIN64
530
unsigned long rl;
531
result = _BitScanReverse64(&rl, n) ? 63 - int(rl) : 64;
532
#else
533
unsigned long rl;
534
if (_BitScanReverse(&rl, uint32_t(n >> 32)))
535
result = 31 - int(rl);
536
else
537
result = _BitScanReverse(&rl, uint32_t(n)) ? 63 - int(rl) : 64;
538
#endif
539
#else
540
result = (n == 0) ? 64 : __builtin_clzll(n);
541
#endif
542
lua_pushinteger64(L, result);
543
544
return 1;
545
}
546
547
static int int64_bswap(lua_State* L)
548
{
549
uint64_t a = luaL_checkinteger64(L, 1);
550
551
lua_pushinteger64(
552
L,
553
(a >> 56) | ((a & 0xFF000000000000) >> 40) | ((a & 0xFF0000000000) >> 24) | ((a & 0xFF00000000) >> 8) | ((a & 0xFF000000) << 8) |
554
((a & 0xFF0000) << 24) | ((a & 0xFF00) << 40) | ((a & 0xFF) << 56)
555
);
556
557
return 1;
558
}
559
560
static const luaL_Reg int64lib[] = {
561
{"create", int64_create},
562
{"tonumber", int64_tonumber},
563
{"neg", int64_neg},
564
{"add", int64_add},
565
{"sub", int64_sub},
566
{"mul", int64_mul},
567
{"div", int64_div},
568
{"min", int64_min},
569
{"max", int64_max},
570
{"rem", int64_rem},
571
{"idiv", int64_idiv},
572
{"udiv", int64_udiv},
573
{"urem", int64_urem},
574
{"mod", int64_mod},
575
{"clamp", int64_clamp},
576
{"band", int64_band},
577
{"bor", int64_bor},
578
{"bnot", int64_bnot},
579
{"bxor", int64_bxor},
580
{"lt", int64_lt},
581
{"le", int64_le},
582
{"ult", int64_ult},
583
{"ule", int64_ule},
584
{"gt", int64_gt},
585
{"ge", int64_ge},
586
{"ugt", int64_ugt},
587
{"uge", int64_uge},
588
{"lshift", int64_lshift},
589
{"rshift", int64_rshift},
590
{"arshift", int64_arshift},
591
{"lrotate", int64_lrotate},
592
{"rrotate", int64_rrotate},
593
{"extract", int64_extract},
594
{"replace", int64_replace},
595
{"btest", int64_btest},
596
{"countrz", int64_countrz},
597
{"countlz", int64_countlz},
598
{"bswap", int64_bswap},
599
{"fromstring", int64_fromstring},
600
{NULL, NULL},
601
};
602
603
int luaopen_integer(lua_State* L)
604
{
605
luaL_register(L, LUA_INTLIBNAME, int64lib);
606
607
lua_pushinteger64(L, LLONG_MAX);
608
lua_setfield(L, -2, "maxsigned");
609
lua_pushinteger64(L, LLONG_MIN);
610
lua_setfield(L, -2, "minsigned");
611
612
return 1;
613
}
614
615