Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/VM/src/lbuiltins.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
// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details
3
#include "lbuiltins.h"
4
5
#include "lstate.h"
6
#include "lstring.h"
7
#include "ltable.h"
8
#include "lgc.h"
9
#include "lnumutils.h"
10
#include "ldo.h"
11
#include "lbuffer.h"
12
13
#include <math.h>
14
#include <string.h>
15
16
#ifdef _MSC_VER
17
#include <intrin.h>
18
#endif
19
20
#ifdef LUAU_TARGET_SSE41
21
#include <smmintrin.h>
22
23
#ifndef _MSC_VER
24
#include <cpuid.h> // on MSVC this comes from intrin.h
25
#endif
26
#endif
27
28
LUAU_FASTFLAG(LuauIntegerType)
29
30
// luauF functions implement FASTCALL instruction that performs a direct execution of some builtin functions from the VM
31
// The rule of thumb is that FASTCALL functions can not call user code, yield, fail, or reallocate stack.
32
// If types of the arguments mismatch, luauF_* needs to return -1 and the execution will fall back to the usual call path
33
// If luauF_* succeeds, it needs to return *all* requested arguments, filling results with nil as appropriate.
34
// On input, nparams refers to the actual number of arguments (0+), whereas nresults contains LUA_MULTRET for arbitrary returns or 0+ for a
35
// fixed-length return
36
// Because of this, and the fact that "extra" returned values will be ignored, implementations below typically check that nresults is <= expected
37
// number, which covers the LUA_MULTRET case.
38
39
static int luauF_assert(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
40
{
41
if (nparams >= 1 && nresults == 0 && !l_isfalse(arg0))
42
{
43
return 0;
44
}
45
46
return -1;
47
}
48
49
static int luauF_abs(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
50
{
51
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
52
{
53
double a1 = nvalue(arg0);
54
setnvalue(res, fabs(a1));
55
return 1;
56
}
57
58
return -1;
59
}
60
61
static int luauF_acos(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
62
{
63
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
64
{
65
double a1 = nvalue(arg0);
66
setnvalue(res, acos(a1));
67
return 1;
68
}
69
70
return -1;
71
}
72
73
static int luauF_asin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
74
{
75
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
76
{
77
double a1 = nvalue(arg0);
78
setnvalue(res, asin(a1));
79
return 1;
80
}
81
82
return -1;
83
}
84
85
static int luauF_atan2(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
86
{
87
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
88
{
89
double a1 = nvalue(arg0);
90
double a2 = nvalue(args);
91
setnvalue(res, atan2(a1, a2));
92
return 1;
93
}
94
95
return -1;
96
}
97
98
static int luauF_atan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
99
{
100
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
101
{
102
double a1 = nvalue(arg0);
103
setnvalue(res, atan(a1));
104
return 1;
105
}
106
107
return -1;
108
}
109
110
LUAU_FASTMATH_BEGIN
111
static int luauF_ceil(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
112
{
113
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
114
{
115
double a1 = nvalue(arg0);
116
setnvalue(res, ceil(a1));
117
return 1;
118
}
119
120
return -1;
121
}
122
LUAU_FASTMATH_END
123
124
static int luauF_cosh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
125
{
126
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
127
{
128
double a1 = nvalue(arg0);
129
setnvalue(res, cosh(a1));
130
return 1;
131
}
132
133
return -1;
134
}
135
136
static int luauF_cos(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
137
{
138
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
139
{
140
double a1 = nvalue(arg0);
141
setnvalue(res, cos(a1));
142
return 1;
143
}
144
145
return -1;
146
}
147
148
static int luauF_deg(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
149
{
150
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
151
{
152
double a1 = nvalue(arg0);
153
const double rpd = (3.14159265358979323846 / 180.0);
154
setnvalue(res, a1 / rpd);
155
return 1;
156
}
157
158
return -1;
159
}
160
161
static int luauF_exp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
162
{
163
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
164
{
165
double a1 = nvalue(arg0);
166
setnvalue(res, exp(a1));
167
return 1;
168
}
169
170
return -1;
171
}
172
173
LUAU_FASTMATH_BEGIN
174
static int luauF_floor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
175
{
176
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
177
{
178
double a1 = nvalue(arg0);
179
setnvalue(res, floor(a1));
180
return 1;
181
}
182
183
return -1;
184
}
185
LUAU_FASTMATH_END
186
187
static int luauF_fmod(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
188
{
189
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
190
{
191
double a1 = nvalue(arg0);
192
double a2 = nvalue(args);
193
setnvalue(res, fmod(a1, a2));
194
return 1;
195
}
196
197
return -1;
198
}
199
200
static int luauF_frexp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
201
{
202
if (nparams >= 1 && nresults <= 2 && ttisnumber(arg0))
203
{
204
double a1 = nvalue(arg0);
205
int e;
206
double f = frexp(a1, &e);
207
setnvalue(res, f);
208
setnvalue(res + 1, double(e));
209
return 2;
210
}
211
212
return -1;
213
}
214
215
static int luauF_ldexp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
216
{
217
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
218
{
219
double a1 = nvalue(arg0);
220
double a2 = nvalue(args);
221
setnvalue(res, ldexp(a1, int(a2)));
222
return 1;
223
}
224
225
return -1;
226
}
227
228
static int luauF_log10(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
229
{
230
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
231
{
232
double a1 = nvalue(arg0);
233
setnvalue(res, log10(a1));
234
return 1;
235
}
236
237
return -1;
238
}
239
240
static int luauF_log(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
241
{
242
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
243
{
244
double a1 = nvalue(arg0);
245
246
if (nparams == 1)
247
{
248
setnvalue(res, log(a1));
249
return 1;
250
}
251
else if (ttisnumber(args))
252
{
253
double a2 = nvalue(args);
254
255
if (a2 == 2.0)
256
{
257
setnvalue(res, log2(a1));
258
return 1;
259
}
260
else if (a2 == 10.0)
261
{
262
setnvalue(res, log10(a1));
263
return 1;
264
}
265
else
266
{
267
setnvalue(res, log(a1) / log(a2));
268
return 1;
269
}
270
}
271
}
272
273
return -1;
274
}
275
276
static int luauF_max(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
277
{
278
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
279
{
280
double a1 = nvalue(arg0);
281
double a2 = nvalue(args);
282
283
double r = (a2 > a1) ? a2 : a1;
284
285
for (int i = 3; i <= nparams; ++i)
286
{
287
if (!ttisnumber(args + (i - 2)))
288
return -1;
289
290
double a = nvalue(args + (i - 2));
291
292
r = (a > r) ? a : r;
293
}
294
295
setnvalue(res, r);
296
return 1;
297
}
298
299
return -1;
300
}
301
302
static int luauF_min(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
303
{
304
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
305
{
306
double a1 = nvalue(arg0);
307
double a2 = nvalue(args);
308
309
double r = (a2 < a1) ? a2 : a1;
310
311
for (int i = 3; i <= nparams; ++i)
312
{
313
if (!ttisnumber(args + (i - 2)))
314
return -1;
315
316
double a = nvalue(args + (i - 2));
317
318
r = (a < r) ? a : r;
319
}
320
321
setnvalue(res, r);
322
return 1;
323
}
324
325
return -1;
326
}
327
328
static int luauF_modf(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
329
{
330
if (nparams >= 1 && nresults <= 2 && ttisnumber(arg0))
331
{
332
double a1 = nvalue(arg0);
333
double ip;
334
double fp = modf(a1, &ip);
335
setnvalue(res, ip);
336
setnvalue(res + 1, fp);
337
return 2;
338
}
339
340
return -1;
341
}
342
343
static int luauF_pow(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
344
{
345
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
346
{
347
double a1 = nvalue(arg0);
348
double a2 = nvalue(args);
349
setnvalue(res, pow(a1, a2));
350
return 1;
351
}
352
353
return -1;
354
}
355
356
static int luauF_rad(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
357
{
358
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
359
{
360
double a1 = nvalue(arg0);
361
const double rpd = (3.14159265358979323846 / 180.0);
362
setnvalue(res, a1 * rpd);
363
return 1;
364
}
365
366
return -1;
367
}
368
369
static int luauF_sinh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
370
{
371
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
372
{
373
double a1 = nvalue(arg0);
374
setnvalue(res, sinh(a1));
375
return 1;
376
}
377
378
return -1;
379
}
380
381
static int luauF_sin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
382
{
383
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
384
{
385
double a1 = nvalue(arg0);
386
setnvalue(res, sin(a1));
387
return 1;
388
}
389
390
return -1;
391
}
392
393
LUAU_FASTMATH_BEGIN
394
static int luauF_sqrt(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
395
{
396
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
397
{
398
double a1 = nvalue(arg0);
399
setnvalue(res, sqrt(a1));
400
return 1;
401
}
402
403
return -1;
404
}
405
LUAU_FASTMATH_END
406
407
static int luauF_tanh(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
408
{
409
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
410
{
411
double a1 = nvalue(arg0);
412
setnvalue(res, tanh(a1));
413
return 1;
414
}
415
416
return -1;
417
}
418
419
static int luauF_tan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
420
{
421
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
422
{
423
double a1 = nvalue(arg0);
424
setnvalue(res, tan(a1));
425
return 1;
426
}
427
428
return -1;
429
}
430
431
static int luauF_arshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
432
{
433
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
434
{
435
double a1 = nvalue(arg0);
436
double a2 = nvalue(args);
437
438
unsigned u;
439
luai_num2unsigned(u, a1);
440
int s = int(a2);
441
442
// note: we only specialize fast-path that doesn't require further conditionals (negative shifts and shifts greater or equal to bit width can
443
// be handled generically)
444
if (unsigned(s) < 32)
445
{
446
// note: technically right shift of negative values is UB, but this behavior is getting defined in C++20 and all compilers do the right
447
// (shift) thing.
448
uint32_t r = int32_t(u) >> s;
449
450
setnvalue(res, double(r));
451
return 1;
452
}
453
}
454
455
return -1;
456
}
457
458
static int luauF_band(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
459
{
460
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
461
{
462
double a1 = nvalue(arg0);
463
double a2 = nvalue(args);
464
465
unsigned u1, u2;
466
luai_num2unsigned(u1, a1);
467
luai_num2unsigned(u2, a2);
468
469
uint32_t r = u1 & u2;
470
471
for (int i = 3; i <= nparams; ++i)
472
{
473
if (!ttisnumber(args + (i - 2)))
474
return -1;
475
476
double a = nvalue(args + (i - 2));
477
unsigned u;
478
luai_num2unsigned(u, a);
479
480
r &= u;
481
}
482
483
setnvalue(res, double(r));
484
return 1;
485
}
486
487
return -1;
488
}
489
490
static int luauF_bnot(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
491
{
492
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
493
{
494
double a1 = nvalue(arg0);
495
unsigned u;
496
luai_num2unsigned(u, a1);
497
498
uint32_t r = ~u;
499
500
setnvalue(res, double(r));
501
return 1;
502
}
503
504
return -1;
505
}
506
507
static int luauF_bor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
508
{
509
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
510
{
511
double a1 = nvalue(arg0);
512
double a2 = nvalue(args);
513
514
unsigned u1, u2;
515
luai_num2unsigned(u1, a1);
516
luai_num2unsigned(u2, a2);
517
518
uint32_t r = u1 | u2;
519
520
for (int i = 3; i <= nparams; ++i)
521
{
522
if (!ttisnumber(args + (i - 2)))
523
return -1;
524
525
double a = nvalue(args + (i - 2));
526
unsigned u;
527
luai_num2unsigned(u, a);
528
529
r |= u;
530
}
531
532
setnvalue(res, double(r));
533
return 1;
534
}
535
536
return -1;
537
}
538
539
static int luauF_bxor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
540
{
541
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
542
{
543
double a1 = nvalue(arg0);
544
double a2 = nvalue(args);
545
546
unsigned u1, u2;
547
luai_num2unsigned(u1, a1);
548
luai_num2unsigned(u2, a2);
549
550
uint32_t r = u1 ^ u2;
551
552
for (int i = 3; i <= nparams; ++i)
553
{
554
if (!ttisnumber(args + (i - 2)))
555
return -1;
556
557
double a = nvalue(args + (i - 2));
558
unsigned u;
559
luai_num2unsigned(u, a);
560
561
r ^= u;
562
}
563
564
setnvalue(res, double(r));
565
return 1;
566
}
567
568
return -1;
569
}
570
571
static int luauF_btest(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
572
{
573
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
574
{
575
double a1 = nvalue(arg0);
576
double a2 = nvalue(args);
577
578
unsigned u1, u2;
579
luai_num2unsigned(u1, a1);
580
luai_num2unsigned(u2, a2);
581
582
uint32_t r = u1 & u2;
583
584
for (int i = 3; i <= nparams; ++i)
585
{
586
if (!ttisnumber(args + (i - 2)))
587
return -1;
588
589
double a = nvalue(args + (i - 2));
590
unsigned u;
591
luai_num2unsigned(u, a);
592
593
r &= u;
594
}
595
596
setbvalue(res, r != 0);
597
return 1;
598
}
599
600
return -1;
601
}
602
603
static int luauF_extract(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
604
{
605
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
606
{
607
double a1 = nvalue(arg0);
608
double a2 = nvalue(args);
609
610
unsigned n;
611
luai_num2unsigned(n, a1);
612
int f = int(a2);
613
614
if (nparams == 2)
615
{
616
if (unsigned(f) < 32)
617
{
618
uint32_t m = 1;
619
uint32_t r = (n >> f) & m;
620
621
setnvalue(res, double(r));
622
return 1;
623
}
624
}
625
else if (ttisnumber(args + 1))
626
{
627
double a3 = nvalue(args + 1);
628
int w = int(a3);
629
630
if (f >= 0 && w > 0 && f + w <= 32)
631
{
632
uint32_t m = ~(0xfffffffeu << (w - 1));
633
uint32_t r = (n >> f) & m;
634
635
setnvalue(res, double(r));
636
return 1;
637
}
638
}
639
}
640
641
return -1;
642
}
643
644
static int luauF_lrotate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
645
{
646
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
647
{
648
double a1 = nvalue(arg0);
649
double a2 = nvalue(args);
650
651
unsigned u;
652
luai_num2unsigned(u, a1);
653
int s = int(a2);
654
655
// MSVC doesn't recognize the rotate form that is UB-safe
656
#ifdef _MSC_VER
657
uint32_t r = _rotl(u, s);
658
#else
659
uint32_t r = (u << (s & 31)) | (u >> ((32 - s) & 31));
660
#endif
661
662
setnvalue(res, double(r));
663
return 1;
664
}
665
666
return -1;
667
}
668
669
static int luauF_lshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
670
{
671
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
672
{
673
double a1 = nvalue(arg0);
674
double a2 = nvalue(args);
675
676
unsigned u;
677
luai_num2unsigned(u, a1);
678
int s = int(a2);
679
680
// note: we only specialize fast-path that doesn't require further conditionals (negative shifts and shifts greater or equal to bit width can
681
// be handled generically)
682
if (unsigned(s) < 32)
683
{
684
uint32_t r = u << s;
685
686
setnvalue(res, double(r));
687
return 1;
688
}
689
}
690
691
return -1;
692
}
693
694
static int luauF_replace(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
695
{
696
if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1))
697
{
698
double a1 = nvalue(arg0);
699
double a2 = nvalue(args);
700
double a3 = nvalue(args + 1);
701
702
unsigned n, v;
703
luai_num2unsigned(n, a1);
704
luai_num2unsigned(v, a2);
705
int f = int(a3);
706
707
if (nparams == 3)
708
{
709
if (unsigned(f) < 32)
710
{
711
uint32_t m = 1;
712
uint32_t r = (n & ~(m << f)) | ((v & m) << f);
713
714
setnvalue(res, double(r));
715
return 1;
716
}
717
}
718
else if (ttisnumber(args + 2))
719
{
720
double a4 = nvalue(args + 2);
721
int w = int(a4);
722
723
if (f >= 0 && w > 0 && f + w <= 32)
724
{
725
uint32_t m = ~(0xfffffffeu << (w - 1));
726
uint32_t r = (n & ~(m << f)) | ((v & m) << f);
727
728
setnvalue(res, double(r));
729
return 1;
730
}
731
}
732
}
733
734
return -1;
735
}
736
737
static int luauF_rrotate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
738
{
739
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
740
{
741
double a1 = nvalue(arg0);
742
double a2 = nvalue(args);
743
744
unsigned u;
745
luai_num2unsigned(u, a1);
746
int s = int(a2);
747
748
// MSVC doesn't recognize the rotate form that is UB-safe
749
#ifdef _MSC_VER
750
uint32_t r = _rotr(u, s);
751
#else
752
uint32_t r = (u >> (s & 31)) | (u << ((32 - s) & 31));
753
#endif
754
755
setnvalue(res, double(r));
756
return 1;
757
}
758
759
return -1;
760
}
761
762
static int luauF_rshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
763
{
764
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
765
{
766
double a1 = nvalue(arg0);
767
double a2 = nvalue(args);
768
769
unsigned u;
770
luai_num2unsigned(u, a1);
771
int s = int(a2);
772
773
// note: we only specialize fast-path that doesn't require further conditionals (negative shifts and shifts greater or equal to bit width can
774
// be handled generically)
775
if (unsigned(s) < 32)
776
{
777
uint32_t r = u >> s;
778
779
setnvalue(res, double(r));
780
return 1;
781
}
782
}
783
784
return -1;
785
}
786
787
static int luauF_type(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
788
{
789
if (nparams >= 1 && nresults <= 1)
790
{
791
int tt = ttype(arg0);
792
TString* ttname = L->global->ttname[tt];
793
794
setsvalue(L, res, ttname);
795
return 1;
796
}
797
798
return -1;
799
}
800
801
static int luauF_byte(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
802
{
803
if (nparams >= 2 && ttisstring(arg0) && ttisnumber(args))
804
{
805
TString* ts = tsvalue(arg0);
806
int i = int(nvalue(args));
807
int j = (nparams >= 3) ? (ttisnumber(args + 1) ? int(nvalue(args + 1)) : 0) : i;
808
809
if (i >= 1 && j >= i && j <= int(ts->len))
810
{
811
int c = j - i + 1;
812
const char* s = getstr(ts);
813
814
// for vararg returns, we only support a single result
815
// this is because this frees us from concerns about stack space
816
if (c == (nresults < 0 ? 1 : nresults))
817
{
818
for (int k = 0; k < c; ++k)
819
{
820
setnvalue(res + k, uint8_t(s[i + k - 1]));
821
}
822
823
return c;
824
}
825
}
826
}
827
828
return -1;
829
}
830
831
static int luauF_char(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
832
{
833
char buffer[8];
834
835
if (nparams < int(sizeof(buffer)) && nresults <= 1)
836
{
837
if (luaC_needsGC(L))
838
return -1; // we can't call luaC_checkGC so fall back to C implementation
839
840
if (nparams >= 1)
841
{
842
if (!ttisnumber(arg0))
843
return -1;
844
845
int ch = int(nvalue(arg0));
846
847
if ((unsigned char)(ch) != ch)
848
return -1;
849
850
buffer[0] = ch;
851
}
852
853
for (int i = 2; i <= nparams; ++i)
854
{
855
if (!ttisnumber(args + (i - 2)))
856
return -1;
857
858
int ch = int(nvalue(args + (i - 2)));
859
860
if ((unsigned char)(ch) != ch)
861
return -1;
862
863
buffer[i - 1] = ch;
864
}
865
866
buffer[nparams] = 0;
867
868
setsvalue(L, res, luaS_newlstr(L, buffer, nparams));
869
return 1;
870
}
871
872
return -1;
873
}
874
875
static int luauF_len(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
876
{
877
if (nparams >= 1 && nresults <= 1 && ttisstring(arg0))
878
{
879
TString* ts = tsvalue(arg0);
880
881
setnvalue(res, int(ts->len));
882
return 1;
883
}
884
885
return -1;
886
}
887
888
static int luauF_typeof(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
889
{
890
if (nparams >= 1 && nresults <= 1)
891
{
892
const TString* ttname = luaT_objtypenamestr(L, arg0);
893
894
setsvalue(L, res, ttname);
895
return 1;
896
}
897
898
return -1;
899
}
900
901
static int luauF_sub(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
902
{
903
if (nparams >= 3 && nresults <= 1 && ttisstring(arg0) && ttisnumber(args) && ttisnumber(args + 1))
904
{
905
TString* ts = tsvalue(arg0);
906
int i = int(nvalue(args));
907
int j = int(nvalue(args + 1));
908
909
if (luaC_needsGC(L))
910
return -1; // we can't call luaC_checkGC so fall back to C implementation
911
912
if (i >= 1 && j >= i && unsigned(j - 1) < unsigned(ts->len))
913
{
914
setsvalue(L, res, luaS_newlstr(L, getstr(ts) + (i - 1), j - i + 1));
915
return 1;
916
}
917
}
918
919
return -1;
920
}
921
922
static int luauF_clamp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
923
{
924
if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1))
925
{
926
double v = nvalue(arg0);
927
double min = nvalue(args);
928
double max = nvalue(args + 1);
929
930
if (min <= max)
931
{
932
double r = v < min ? min : v;
933
r = r > max ? max : r;
934
935
setnvalue(res, r);
936
return 1;
937
}
938
}
939
940
return -1;
941
}
942
943
static int luauF_sign(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
944
{
945
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
946
{
947
double v = nvalue(arg0);
948
setnvalue(res, v > 0.0 ? 1.0 : v < 0.0 ? -1.0 : 0.0);
949
return 1;
950
}
951
952
return -1;
953
}
954
955
LUAU_FASTMATH_BEGIN
956
static int luauF_round(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
957
{
958
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
959
{
960
double v = nvalue(arg0);
961
setnvalue(res, round(v));
962
return 1;
963
}
964
965
return -1;
966
}
967
LUAU_FASTMATH_END
968
969
static int luauF_rawequal(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
970
{
971
if (nparams >= 2 && nresults <= 1)
972
{
973
setbvalue(res, luaO_rawequalObj(arg0, args));
974
return 1;
975
}
976
977
return -1;
978
}
979
980
static int luauF_rawget(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
981
{
982
if (nparams >= 2 && nresults <= 1 && ttistable(arg0))
983
{
984
setobj2s(L, res, luaH_get(hvalue(arg0), args));
985
return 1;
986
}
987
988
return -1;
989
}
990
991
static int luauF_rawset(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
992
{
993
if (nparams >= 3 && nresults <= 1 && ttistable(arg0))
994
{
995
const TValue* key = args;
996
if (ttisnil(key))
997
return -1;
998
else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
999
return -1;
1000
else if (ttisvector(key) && luai_vecisnan(vvalue(key)))
1001
return -1;
1002
1003
LuaTable* t = hvalue(arg0);
1004
if (t->readonly)
1005
return -1;
1006
1007
setobj2s(L, res, arg0);
1008
setobj2t(L, luaH_set(L, t, args), args + 1);
1009
luaC_barriert(L, t, args + 1);
1010
return 1;
1011
}
1012
1013
return -1;
1014
}
1015
1016
static int luauF_tinsert(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1017
{
1018
if (nparams == 2 && nresults <= 0 && ttistable(arg0))
1019
{
1020
LuaTable* t = hvalue(arg0);
1021
if (t->readonly)
1022
return -1;
1023
1024
int pos = luaH_getn(t) + 1;
1025
setobj2t(L, luaH_setnum(L, t, pos), args);
1026
luaC_barriert(L, t, args);
1027
return 0;
1028
}
1029
1030
return -1;
1031
}
1032
1033
static int luauF_tunpack(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1034
{
1035
if (nparams >= 1 && nresults < 0 && ttistable(arg0))
1036
{
1037
LuaTable* t = hvalue(arg0);
1038
int n = -1;
1039
1040
if (nparams == 1)
1041
n = luaH_getn(t);
1042
else if (nparams == 3 && ttisnumber(args) && ttisnumber(args + 1) && nvalue(args) == 1.0)
1043
n = int(nvalue(args + 1));
1044
1045
if (n >= 0 && n <= t->sizearray && cast_int(L->stack_last - res) >= n && n + nparams <= LUAI_MAXCSTACK)
1046
{
1047
TValue* array = t->array;
1048
for (int i = 0; i < n; ++i)
1049
setobj2s(L, res + i, array + i);
1050
expandstacklimit(L, res + n);
1051
return n;
1052
}
1053
}
1054
1055
return -1;
1056
}
1057
1058
static int luauF_vector(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1059
{
1060
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args))
1061
{
1062
float x = (float)nvalue(arg0);
1063
float y = (float)nvalue(args);
1064
float z = 0.0f;
1065
1066
if (nparams >= 3)
1067
{
1068
if (!ttisnumber(args + 1))
1069
return -1;
1070
z = (float)nvalue(args + 1);
1071
}
1072
1073
#if LUA_VECTOR_SIZE == 4
1074
float w = 0.0f;
1075
if (nparams >= 4)
1076
{
1077
if (!ttisnumber(args + 2))
1078
return -1;
1079
w = (float)nvalue(args + 2);
1080
}
1081
setvvalue(res, x, y, z, w);
1082
#else
1083
setvvalue(res, x, y, z, 0.0f);
1084
#endif
1085
1086
return 1;
1087
}
1088
1089
return -1;
1090
}
1091
1092
static int luauF_countlz(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1093
{
1094
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
1095
{
1096
double a1 = nvalue(arg0);
1097
1098
unsigned n;
1099
luai_num2unsigned(n, a1);
1100
1101
#ifdef _MSC_VER
1102
unsigned long rl;
1103
int r = _BitScanReverse(&rl, n) ? 31 - int(rl) : 32;
1104
#else
1105
int r = n == 0 ? 32 : __builtin_clz(n);
1106
#endif
1107
1108
setnvalue(res, double(r));
1109
return 1;
1110
}
1111
1112
return -1;
1113
}
1114
1115
static int luauF_countrz(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1116
{
1117
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
1118
{
1119
double a1 = nvalue(arg0);
1120
1121
unsigned n;
1122
luai_num2unsigned(n, a1);
1123
1124
#ifdef _MSC_VER
1125
unsigned long rl;
1126
int r = _BitScanForward(&rl, n) ? int(rl) : 32;
1127
#else
1128
int r = n == 0 ? 32 : __builtin_ctz(n);
1129
#endif
1130
1131
setnvalue(res, double(r));
1132
return 1;
1133
}
1134
1135
return -1;
1136
}
1137
1138
static int luauF_select(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1139
{
1140
if (nparams == 1 && nresults == 1)
1141
{
1142
int n = cast_int(L->base - L->ci->func) - clvalue(L->ci->func)->l.p->numparams - 1;
1143
1144
if (ttisnumber(arg0))
1145
{
1146
int i = int(nvalue(arg0));
1147
1148
// i >= 1 && i <= n
1149
if (unsigned(i - 1) < unsigned(n))
1150
{
1151
setobj2s(L, res, L->base - n + (i - 1));
1152
return 1;
1153
}
1154
// note: for now we don't handle negative case (wrap around) and defer to fallback
1155
}
1156
else if (ttisstring(arg0) && *svalue(arg0) == '#')
1157
{
1158
setnvalue(res, double(n));
1159
return 1;
1160
}
1161
}
1162
1163
return -1;
1164
}
1165
1166
static int luauF_rawlen(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1167
{
1168
if (nparams >= 1 && nresults <= 1)
1169
{
1170
if (ttistable(arg0))
1171
{
1172
LuaTable* h = hvalue(arg0);
1173
setnvalue(res, double(luaH_getn(h)));
1174
return 1;
1175
}
1176
else if (ttisstring(arg0))
1177
{
1178
TString* ts = tsvalue(arg0);
1179
setnvalue(res, double(ts->len));
1180
return 1;
1181
}
1182
}
1183
1184
return -1;
1185
}
1186
1187
static int luauF_extractk(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1188
{
1189
// args is known to contain a number constant with packed in-range f/w
1190
if (nparams >= 2 && nresults <= 1 && ttisnumber(arg0))
1191
{
1192
double a1 = nvalue(arg0);
1193
double a2 = nvalue(args);
1194
1195
unsigned n;
1196
luai_num2unsigned(n, a1);
1197
int fw = int(a2);
1198
1199
int f = fw & 31;
1200
int w1 = fw >> 5;
1201
1202
uint32_t m = ~(0xfffffffeu << w1);
1203
uint32_t r = (n >> f) & m;
1204
1205
setnvalue(res, double(r));
1206
return 1;
1207
}
1208
1209
return -1;
1210
}
1211
1212
static int luauF_getmetatable(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1213
{
1214
if (nparams >= 1 && nresults <= 1)
1215
{
1216
LuaTable* mt = NULL;
1217
if (ttistable(arg0))
1218
mt = hvalue(arg0)->metatable;
1219
else if (ttisuserdata(arg0))
1220
mt = uvalue(arg0)->metatable;
1221
else
1222
mt = L->global->mt[ttype(arg0)];
1223
1224
const TValue* mtv = mt ? luaH_getstr(mt, L->global->tmname[TM_METATABLE]) : luaO_nilobject;
1225
if (!ttisnil(mtv))
1226
{
1227
setobj2s(L, res, mtv);
1228
return 1;
1229
}
1230
1231
if (mt)
1232
{
1233
sethvalue(L, res, mt);
1234
return 1;
1235
}
1236
else
1237
{
1238
setnilvalue(res);
1239
return 1;
1240
}
1241
}
1242
1243
return -1;
1244
}
1245
1246
static int luauF_setmetatable(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1247
{
1248
// note: setmetatable(_, nil) is rare so we use fallback for it to optimize the fast path
1249
if (nparams >= 2 && nresults <= 1 && ttistable(arg0) && ttistable(args))
1250
{
1251
LuaTable* t = hvalue(arg0);
1252
if (t->readonly || t->metatable != NULL)
1253
return -1; // note: overwriting non-null metatable is very rare but it requires __metatable check
1254
1255
LuaTable* mt = hvalue(args);
1256
t->metatable = mt;
1257
luaC_objbarrier(L, t, mt);
1258
1259
sethvalue(L, res, t);
1260
return 1;
1261
}
1262
1263
return -1;
1264
}
1265
1266
static int luauF_tonumber(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1267
{
1268
if (nparams == 1 && nresults <= 1)
1269
{
1270
double num;
1271
1272
if (ttisnumber(arg0))
1273
{
1274
setnvalue(res, nvalue(arg0));
1275
return 1;
1276
}
1277
else if (ttisstring(arg0) && luaO_str2d(svalue(arg0), &num))
1278
{
1279
setnvalue(res, num);
1280
return 1;
1281
}
1282
else
1283
{
1284
setnilvalue(res);
1285
return 1;
1286
}
1287
}
1288
1289
return -1;
1290
}
1291
1292
static int luauF_tostring(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1293
{
1294
if (nparams >= 1 && nresults <= 1)
1295
{
1296
switch (ttype(arg0))
1297
{
1298
case LUA_TNIL:
1299
{
1300
TString* s = L->global->ttname[LUA_TNIL];
1301
setsvalue(L, res, s);
1302
return 1;
1303
}
1304
case LUA_TBOOLEAN:
1305
{
1306
TString* s = bvalue(arg0) ? luaS_newliteral(L, "true") : luaS_newliteral(L, "false");
1307
setsvalue(L, res, s);
1308
return 1;
1309
}
1310
case LUA_TNUMBER:
1311
{
1312
if (luaC_needsGC(L))
1313
return -1; // we can't call luaC_checkGC so fall back to C implementation
1314
1315
char s[LUAI_MAXNUM2STR];
1316
char* e = luai_num2str(s, nvalue(arg0));
1317
setsvalue(L, res, luaS_newlstr(L, s, e - s));
1318
return 1;
1319
}
1320
case LUA_TSTRING:
1321
{
1322
setsvalue(L, res, tsvalue(arg0));
1323
return 1;
1324
}
1325
case LUA_TINTEGER:
1326
if (FFlag::LuauIntegerType)
1327
{
1328
if (luaC_needsGC(L))
1329
return -1; // we can't call luaC_checkGC so fall back to C implementation
1330
1331
char s[LUAI_MAXINT2STR];
1332
char* e = luai_int2str(s, lvalue(arg0));
1333
setsvalue(L, res, luaS_newlstr(L, s, e - s));
1334
return 1;
1335
}
1336
}
1337
1338
// fall back to generic C implementation
1339
}
1340
1341
return -1;
1342
}
1343
1344
static int luauF_byteswap(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1345
{
1346
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
1347
{
1348
double a1 = nvalue(arg0);
1349
unsigned n;
1350
luai_num2unsigned(n, a1);
1351
1352
n = (n << 24) | ((n << 8) & 0xff0000) | ((n >> 8) & 0xff00) | (n >> 24);
1353
1354
setnvalue(res, double(n));
1355
return 1;
1356
}
1357
1358
return -1;
1359
}
1360
1361
// because offset is limited to an integer, a single 64bit comparison can be used and will not overflow
1362
#define checkoutofbounds(offset, len, accessize) (uint64_t(unsigned(offset)) + (accessize - 1) >= uint64_t(len))
1363
1364
template<typename T>
1365
static int luauF_readinteger(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1366
{
1367
#if !defined(LUAU_BIG_ENDIAN)
1368
if (nparams >= 2 && nresults <= 1 && ttisbuffer(arg0) && ttisnumber(args))
1369
{
1370
int offset;
1371
luai_num2int(offset, nvalue(args));
1372
if (checkoutofbounds(offset, bufvalue(arg0)->len, sizeof(T)))
1373
return -1;
1374
1375
T val;
1376
memcpy(&val, (char*)bufvalue(arg0)->data + unsigned(offset), sizeof(T));
1377
setnvalue(res, double(val));
1378
return 1;
1379
}
1380
#endif
1381
1382
return -1;
1383
}
1384
1385
template<typename T>
1386
static int luauF_writeinteger(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1387
{
1388
#if !defined(LUAU_BIG_ENDIAN)
1389
if (nparams >= 3 && nresults <= 0 && ttisbuffer(arg0) && ttisnumber(args) && ttisnumber(args + 1))
1390
{
1391
int offset;
1392
luai_num2int(offset, nvalue(args));
1393
if (checkoutofbounds(offset, bufvalue(arg0)->len, sizeof(T)))
1394
return -1;
1395
1396
unsigned value;
1397
double incoming = nvalue(args + 1);
1398
luai_num2unsigned(value, incoming);
1399
1400
T val = T(value);
1401
memcpy((char*)bufvalue(arg0)->data + unsigned(offset), &val, sizeof(T));
1402
return 0;
1403
}
1404
#endif
1405
1406
return -1;
1407
}
1408
1409
template<typename T>
1410
static int luauF_readfp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1411
{
1412
#if !defined(LUAU_BIG_ENDIAN)
1413
if (nparams >= 2 && nresults <= 1 && ttisbuffer(arg0) && ttisnumber(args))
1414
{
1415
int offset;
1416
luai_num2int(offset, nvalue(args));
1417
if (checkoutofbounds(offset, bufvalue(arg0)->len, sizeof(T)))
1418
return -1;
1419
1420
T val;
1421
#ifdef _MSC_VER
1422
// avoid memcpy path on MSVC because it results in integer stack copy + floating-point ops on stack
1423
val = *(T*)((char*)bufvalue(arg0)->data + unsigned(offset));
1424
#else
1425
memcpy(&val, (char*)bufvalue(arg0)->data + unsigned(offset), sizeof(T));
1426
#endif
1427
setnvalue(res, double(val));
1428
return 1;
1429
}
1430
#endif
1431
1432
return -1;
1433
}
1434
1435
template<typename T>
1436
static int luauF_writefp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1437
{
1438
#if !defined(LUAU_BIG_ENDIAN)
1439
if (nparams >= 3 && nresults <= 0 && ttisbuffer(arg0) && ttisnumber(args) && ttisnumber(args + 1))
1440
{
1441
int offset;
1442
luai_num2int(offset, nvalue(args));
1443
if (checkoutofbounds(offset, bufvalue(arg0)->len, sizeof(T)))
1444
return -1;
1445
1446
T val = T(nvalue(args + 1));
1447
#ifdef _MSC_VER
1448
// avoid memcpy path on MSVC because it results in integer stack copy + floating-point ops on stack
1449
*(T*)((char*)bufvalue(arg0)->data + unsigned(offset)) = val;
1450
#else
1451
memcpy((char*)bufvalue(arg0)->data + unsigned(offset), &val, sizeof(T));
1452
#endif
1453
return 0;
1454
}
1455
#endif
1456
1457
return -1;
1458
}
1459
1460
static int luauF_vectormagnitude(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1461
{
1462
if (nparams >= 1 && nresults <= 1 && ttisvector(arg0))
1463
{
1464
const float* v = vvalue(arg0);
1465
1466
#if LUA_VECTOR_SIZE == 4
1467
setnvalue(res, sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]));
1468
#else
1469
setnvalue(res, sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]));
1470
#endif
1471
1472
return 1;
1473
}
1474
1475
return -1;
1476
}
1477
1478
static int luauF_vectornormalize(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1479
{
1480
if (nparams >= 1 && nresults <= 1 && ttisvector(arg0))
1481
{
1482
const float* v = vvalue(arg0);
1483
1484
#if LUA_VECTOR_SIZE == 4
1485
float invSqrt = 1.0f / sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]);
1486
1487
setvvalue(res, v[0] * invSqrt, v[1] * invSqrt, v[2] * invSqrt, v[3] * invSqrt);
1488
#else
1489
float invSqrt = 1.0f / sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
1490
1491
setvvalue(res, v[0] * invSqrt, v[1] * invSqrt, v[2] * invSqrt, 0.0f);
1492
#endif
1493
1494
return 1;
1495
}
1496
1497
return -1;
1498
}
1499
1500
static int luauF_vectorcross(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1501
{
1502
if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args))
1503
{
1504
const float* a = vvalue(arg0);
1505
const float* b = vvalue(args);
1506
1507
// same for 3- and 4- wide vectors
1508
setvvalue(res, a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0], 0.0f);
1509
return 1;
1510
}
1511
1512
return -1;
1513
}
1514
1515
static int luauF_vectordot(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1516
{
1517
if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args))
1518
{
1519
const float* a = vvalue(arg0);
1520
const float* b = vvalue(args);
1521
1522
#if LUA_VECTOR_SIZE == 4
1523
setnvalue(res, a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]);
1524
#else
1525
setnvalue(res, a[0] * b[0] + a[1] * b[1] + a[2] * b[2]);
1526
#endif
1527
1528
return 1;
1529
}
1530
1531
return -1;
1532
}
1533
1534
static int luauF_vectorfloor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1535
{
1536
if (nparams >= 1 && nresults <= 1 && ttisvector(arg0))
1537
{
1538
const float* v = vvalue(arg0);
1539
1540
#if LUA_VECTOR_SIZE == 4
1541
setvvalue(res, floorf(v[0]), floorf(v[1]), floorf(v[2]), floorf(v[3]));
1542
#else
1543
setvvalue(res, floorf(v[0]), floorf(v[1]), floorf(v[2]), 0.0f);
1544
#endif
1545
1546
return 1;
1547
}
1548
1549
return -1;
1550
}
1551
1552
static int luauF_vectorceil(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1553
{
1554
if (nparams >= 1 && nresults <= 1 && ttisvector(arg0))
1555
{
1556
const float* v = vvalue(arg0);
1557
1558
#if LUA_VECTOR_SIZE == 4
1559
setvvalue(res, ceilf(v[0]), ceilf(v[1]), ceilf(v[2]), ceilf(v[3]));
1560
#else
1561
setvvalue(res, ceilf(v[0]), ceilf(v[1]), ceilf(v[2]), 0.0f);
1562
#endif
1563
1564
return 1;
1565
}
1566
1567
return -1;
1568
}
1569
1570
static int luauF_vectorabs(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1571
{
1572
if (nparams >= 1 && nresults <= 1 && ttisvector(arg0))
1573
{
1574
const float* v = vvalue(arg0);
1575
1576
#if LUA_VECTOR_SIZE == 4
1577
setvvalue(res, fabsf(v[0]), fabsf(v[1]), fabsf(v[2]), fabsf(v[3]));
1578
#else
1579
setvvalue(res, fabsf(v[0]), fabsf(v[1]), fabsf(v[2]), 0.0f);
1580
#endif
1581
1582
return 1;
1583
}
1584
1585
return -1;
1586
}
1587
1588
static int luauF_vectorsign(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1589
{
1590
if (nparams >= 1 && nresults <= 1 && ttisvector(arg0))
1591
{
1592
const float* v = vvalue(arg0);
1593
1594
#if LUA_VECTOR_SIZE == 4
1595
setvvalue(res, luaui_signf(v[0]), luaui_signf(v[1]), luaui_signf(v[2]), luaui_signf(v[3]));
1596
#else
1597
setvvalue(res, luaui_signf(v[0]), luaui_signf(v[1]), luaui_signf(v[2]), 0.0f);
1598
#endif
1599
1600
return 1;
1601
}
1602
1603
return -1;
1604
}
1605
1606
static int luauF_vectorclamp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1607
{
1608
if (nparams >= 3 && nresults <= 1 && ttisvector(arg0) && ttisvector(args) && ttisvector(args + 1))
1609
{
1610
const float* v = vvalue(arg0);
1611
const float* min = vvalue(args);
1612
const float* max = vvalue(args + 1);
1613
1614
if (min[0] <= max[0] && min[1] <= max[1] && min[2] <= max[2])
1615
{
1616
#if LUA_VECTOR_SIZE == 4
1617
setvvalue(
1618
res,
1619
luaui_clampf(v[0], min[0], max[0]),
1620
luaui_clampf(v[1], min[1], max[1]),
1621
luaui_clampf(v[2], min[2], max[2]),
1622
luaui_clampf(v[3], min[3], max[3])
1623
);
1624
#else
1625
setvvalue(res, luaui_clampf(v[0], min[0], max[0]), luaui_clampf(v[1], min[1], max[1]), luaui_clampf(v[2], min[2], max[2]), 0.0f);
1626
#endif
1627
1628
return 1;
1629
}
1630
}
1631
1632
return -1;
1633
}
1634
1635
static int luauF_vectormin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1636
{
1637
if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args))
1638
{
1639
const float* a = vvalue(arg0);
1640
const float* b = vvalue(args);
1641
1642
float result[4];
1643
1644
result[0] = (b[0] < a[0]) ? b[0] : a[0];
1645
result[1] = (b[1] < a[1]) ? b[1] : a[1];
1646
result[2] = (b[2] < a[2]) ? b[2] : a[2];
1647
1648
#if LUA_VECTOR_SIZE == 4
1649
result[3] = (b[3] < a[3]) ? b[3] : a[3];
1650
#else
1651
result[3] = 0.0f;
1652
#endif
1653
1654
for (int i = 3; i <= nparams; ++i)
1655
{
1656
if (!ttisvector(args + (i - 2)))
1657
return -1;
1658
1659
const float* c = vvalue(args + (i - 2));
1660
1661
result[0] = (c[0] < result[0]) ? c[0] : result[0];
1662
result[1] = (c[1] < result[1]) ? c[1] : result[1];
1663
result[2] = (c[2] < result[2]) ? c[2] : result[2];
1664
#if LUA_VECTOR_SIZE == 4
1665
result[3] = (c[3] < result[3]) ? c[3] : result[3];
1666
#endif
1667
}
1668
1669
setvvalue(res, result[0], result[1], result[2], result[3]);
1670
return 1;
1671
}
1672
1673
return -1;
1674
}
1675
1676
static int luauF_vectormax(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1677
{
1678
if (nparams >= 2 && nresults <= 1 && ttisvector(arg0) && ttisvector(args))
1679
{
1680
const float* a = vvalue(arg0);
1681
const float* b = vvalue(args);
1682
1683
float result[4];
1684
1685
result[0] = (b[0] > a[0]) ? b[0] : a[0];
1686
result[1] = (b[1] > a[1]) ? b[1] : a[1];
1687
result[2] = (b[2] > a[2]) ? b[2] : a[2];
1688
1689
#if LUA_VECTOR_SIZE == 4
1690
result[3] = (b[3] > a[3]) ? b[3] : a[3];
1691
#else
1692
result[3] = 0.0f;
1693
#endif
1694
1695
for (int i = 3; i <= nparams; ++i)
1696
{
1697
if (!ttisvector(args + (i - 2)))
1698
return -1;
1699
1700
const float* c = vvalue(args + (i - 2));
1701
1702
result[0] = (c[0] > result[0]) ? c[0] : result[0];
1703
result[1] = (c[1] > result[1]) ? c[1] : result[1];
1704
result[2] = (c[2] > result[2]) ? c[2] : result[2];
1705
#if LUA_VECTOR_SIZE == 4
1706
result[3] = (c[3] > result[3]) ? c[3] : result[3];
1707
#endif
1708
}
1709
1710
setvvalue(res, result[0], result[1], result[2], result[3]);
1711
return 1;
1712
}
1713
1714
return -1;
1715
}
1716
1717
static int luauF_vectorlerp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1718
{
1719
if (nparams >= 3 && nresults <= 1 && ttisvector(arg0) && ttisvector(args) && ttisnumber(args + 1))
1720
{
1721
const float* a = vvalue(arg0);
1722
const float* b = vvalue(args);
1723
const float t = static_cast<float>(nvalue(args + 1));
1724
1725
#if LUA_VECTOR_SIZE == 4
1726
setvvalue(res, luai_lerpf(a[0], b[0], t), luai_lerpf(a[1], b[1], t), luai_lerpf(a[2], b[2], t), luai_lerpf(a[3], b[3], t));
1727
#else
1728
setvvalue(res, luai_lerpf(a[0], b[0], t), luai_lerpf(a[1], b[1], t), luai_lerpf(a[2], b[2], t), 0.0f);
1729
#endif
1730
1731
return 1;
1732
}
1733
1734
return -1;
1735
}
1736
1737
static int luauF_lerp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1738
{
1739
if (nparams >= 3 && nresults <= 1 && ttisnumber(arg0) && ttisnumber(args) && ttisnumber(args + 1))
1740
{
1741
double a = nvalue(arg0);
1742
double b = nvalue(args);
1743
double t = nvalue(args + 1);
1744
1745
double r = (t == 1.0) ? b : a + (b - a) * t;
1746
1747
setnvalue(res, r);
1748
return 1;
1749
}
1750
1751
return -1;
1752
}
1753
1754
static int luauF_isnan(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1755
{
1756
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
1757
{
1758
double x = nvalue(arg0);
1759
1760
setbvalue(res, isnan(x));
1761
return 1;
1762
}
1763
1764
return -1;
1765
}
1766
1767
static int luauF_isinf(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1768
{
1769
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
1770
{
1771
double x = nvalue(arg0);
1772
1773
setbvalue(res, isinf(x));
1774
return 1;
1775
}
1776
1777
return -1;
1778
}
1779
1780
static int luauF_isfinite(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1781
{
1782
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
1783
{
1784
double x = nvalue(arg0);
1785
1786
setbvalue(res, isfinite(x));
1787
return 1;
1788
}
1789
1790
return -1;
1791
}
1792
1793
static int luauF_integertonumber(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1794
{
1795
if (nparams >= 1 && nresults <= 1 && ttisinteger(arg0))
1796
{
1797
setnvalue(res, cast_num(lvalue(arg0)));
1798
return 1;
1799
}
1800
1801
return -1;
1802
}
1803
1804
static int luauF_integeradd(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1805
{
1806
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
1807
{
1808
int64_t a1 = lvalue(arg0);
1809
int64_t a2 = lvalue(args);
1810
setlvalue(res, (int64_t)((uint64_t)a1 + (uint64_t)a2));
1811
return 1;
1812
}
1813
1814
return -1;
1815
}
1816
1817
static int luauF_integersub(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1818
{
1819
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
1820
{
1821
int64_t a1 = lvalue(arg0);
1822
int64_t a2 = lvalue(args);
1823
setlvalue(res, (int64_t)((uint64_t)a1 - (uint64_t)a2));
1824
return 1;
1825
}
1826
1827
return -1;
1828
}
1829
1830
static int luauF_integerneg(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1831
{
1832
if (nparams >= 1 && nresults <= 1 && ttisinteger(arg0))
1833
{
1834
setlvalue(res, (int64_t)(~(uint64_t)lvalue(arg0) + 1));
1835
return 1;
1836
}
1837
1838
return -1;
1839
}
1840
1841
static int luauF_integerdiv(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1842
{
1843
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
1844
{
1845
int64_t a = lvalue(arg0);
1846
int64_t b = lvalue(args);
1847
1848
if ((b == 0) || ((a == LLONG_MIN) && (b == -1)))
1849
return -1;
1850
1851
setlvalue(res, a / b);
1852
return 1;
1853
}
1854
1855
return -1;
1856
}
1857
1858
static int luauF_integerudiv(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1859
{
1860
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
1861
{
1862
uint64_t a = (uint64_t)lvalue(arg0);
1863
uint64_t b = (uint64_t)lvalue(args);
1864
1865
if (b == 0)
1866
return -1;
1867
1868
setlvalue(res, a / b);
1869
return 1;
1870
}
1871
1872
return -1;
1873
}
1874
1875
static int luauF_integerband(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1876
{
1877
if (nparams >= 1 && nresults <= 1 && ttisinteger(arg0))
1878
{
1879
uint64_t r = (uint64_t)lvalue(arg0);
1880
1881
for (int i = 2; i <= nparams; ++i)
1882
{
1883
if (!ttisinteger(args + (i - 2)))
1884
return -1;
1885
1886
r &= (uint64_t)lvalue(args + (i - 2));
1887
}
1888
1889
setlvalue(res, r);
1890
return 1;
1891
}
1892
1893
return -1;
1894
}
1895
1896
static int luauF_integerbor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1897
{
1898
if (nparams >= 1 && nresults <= 1 && ttisinteger(arg0))
1899
{
1900
uint64_t r = (uint64_t)lvalue(arg0);
1901
1902
for (int i = 2; i <= nparams; ++i)
1903
{
1904
if (!ttisinteger(args + (i - 2)))
1905
return -1;
1906
1907
r |= (uint64_t)lvalue(args + (i - 2));
1908
}
1909
1910
setlvalue(res, r);
1911
return 1;
1912
}
1913
1914
return -1;
1915
}
1916
1917
static int luauF_integerbxor(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1918
{
1919
if (nparams >= 1 && nresults <= 1 && ttisinteger(arg0))
1920
{
1921
uint64_t r = (uint64_t)lvalue(arg0);
1922
1923
for (int i = 2; i <= nparams; ++i)
1924
{
1925
if (!ttisinteger(args + (i - 2)))
1926
return -1;
1927
1928
r ^= (uint64_t)lvalue(args + (i - 2));
1929
}
1930
1931
setlvalue(res, r);
1932
return 1;
1933
}
1934
1935
return -1;
1936
}
1937
1938
static int luauF_integerbnot(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1939
{
1940
if (nparams >= 1 && nresults <= 1 && ttisinteger(arg0))
1941
{
1942
setlvalue(res, ~(uint64_t)lvalue(arg0));
1943
return 1;
1944
}
1945
1946
return -1;
1947
}
1948
1949
static int luauF_integerbswap(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1950
{
1951
if (nparams >= 1 && nresults <= 1 && ttisinteger(arg0))
1952
{
1953
uint64_t a = (uint64_t)lvalue(arg0);
1954
1955
setlvalue(
1956
res,
1957
(a >> 56) | ((a & 0xFF000000000000) >> 40) | ((a & 0xFF0000000000) >> 24) | ((a & 0xFF00000000) >> 8) | ((a & 0xFF000000) << 8) |
1958
((a & 0xFF0000) << 24) | ((a & 0xFF00) << 40) | ((a & 0xFF) << 56)
1959
);
1960
1961
return 1;
1962
}
1963
1964
return -1;
1965
}
1966
1967
static int luauF_integerbtest(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1968
{
1969
if (nparams >= 1 && nresults <= 1 && ttisinteger(arg0))
1970
{
1971
uint64_t r = (uint64_t)lvalue(arg0);
1972
1973
for (int i = 2; i <= nparams; ++i)
1974
{
1975
if (!ttisinteger(args + (i - 2)))
1976
return -1;
1977
1978
r &= (uint64_t)lvalue(args + (i - 2));
1979
}
1980
1981
setbvalue(res, (r != 0));
1982
return 1;
1983
}
1984
1985
return -1;
1986
}
1987
1988
static int luauF_integerlt(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
1989
{
1990
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
1991
{
1992
int64_t a = lvalue(arg0);
1993
int64_t b = lvalue(args);
1994
1995
setbvalue(res, a < b);
1996
return 1;
1997
}
1998
1999
return -1;
2000
}
2001
2002
static int luauF_integerle(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2003
{
2004
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2005
{
2006
int64_t a = lvalue(arg0);
2007
int64_t b = lvalue(args);
2008
2009
setbvalue(res, a <= b);
2010
return 1;
2011
}
2012
2013
return -1;
2014
}
2015
2016
static int luauF_integergt(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2017
{
2018
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2019
{
2020
int64_t a = lvalue(arg0);
2021
int64_t b = lvalue(args);
2022
2023
setbvalue(res, a > b);
2024
return 1;
2025
}
2026
2027
return -1;
2028
}
2029
2030
static int luauF_integerge(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2031
{
2032
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2033
{
2034
int64_t a = lvalue(arg0);
2035
int64_t b = lvalue(args);
2036
2037
setbvalue(res, a >= b);
2038
return 1;
2039
}
2040
2041
return -1;
2042
}
2043
2044
static int luauF_integerult(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2045
{
2046
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2047
{
2048
uint64_t a = (uint64_t)lvalue(arg0);
2049
uint64_t b = (uint64_t)lvalue(args);
2050
2051
setbvalue(res, a < b);
2052
return 1;
2053
}
2054
2055
return -1;
2056
}
2057
2058
static int luauF_integerule(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2059
{
2060
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2061
{
2062
uint64_t a = (uint64_t)lvalue(arg0);
2063
uint64_t b = (uint64_t)lvalue(args);
2064
2065
setbvalue(res, a <= b);
2066
return 1;
2067
}
2068
2069
return -1;
2070
}
2071
2072
static int luauF_integerugt(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2073
{
2074
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2075
{
2076
uint64_t a = (uint64_t)lvalue(arg0);
2077
uint64_t b = (uint64_t)lvalue(args);
2078
2079
setbvalue(res, a > b);
2080
return 1;
2081
}
2082
2083
return -1;
2084
}
2085
2086
static int luauF_integeruge(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2087
{
2088
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2089
{
2090
uint64_t a = (uint64_t)lvalue(arg0);
2091
uint64_t b = (uint64_t)lvalue(args);
2092
2093
setbvalue(res, a >= b);
2094
return 1;
2095
}
2096
2097
return -1;
2098
}
2099
2100
static int luauF_integerurem(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2101
{
2102
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2103
{
2104
uint64_t a = (uint64_t)lvalue(arg0);
2105
uint64_t b = (uint64_t)lvalue(args);
2106
2107
if (b == 0)
2108
return -1;
2109
2110
setlvalue(res, a % b);
2111
return 1;
2112
}
2113
2114
return -1;
2115
}
2116
2117
static int luauF_integerrem(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2118
{
2119
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2120
{
2121
int64_t a = lvalue(arg0);
2122
int64_t b = lvalue(args);
2123
2124
if (b == 0)
2125
return -1;
2126
2127
setlvalue(res, ((a == LLONG_MIN) && (b == -1)) ? 0 : (a % b));
2128
2129
return 1;
2130
}
2131
2132
return -1;
2133
}
2134
2135
static int luauF_integercountlz(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2136
{
2137
if (nparams >= 1 && nresults <= 1 && ttisinteger(arg0))
2138
{
2139
uint64_t n = (uint64_t)lvalue(arg0);
2140
int result;
2141
#ifdef _MSC_VER
2142
#ifdef _WIN64
2143
unsigned long rl;
2144
result = _BitScanReverse64(&rl, n) ? 63 - int(rl) : 64;
2145
#else
2146
unsigned long rl;
2147
if (_BitScanReverse(&rl, uint32_t(n >> 32)))
2148
result = 31 - int(rl);
2149
else
2150
result = _BitScanReverse(&rl, uint32_t(n)) ? 63 - int(rl) : 64;
2151
#endif
2152
#else
2153
result = (n == 0) ? 64 : __builtin_clzll(n);
2154
#endif
2155
2156
setlvalue(res, result);
2157
2158
return 1;
2159
}
2160
2161
return -1;
2162
}
2163
2164
static int luauF_integercountrz(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2165
{
2166
if (nparams >= 1 && nresults <= 1 && ttisinteger(arg0))
2167
{
2168
uint64_t n = (uint64_t)lvalue(arg0);
2169
int result;
2170
#ifdef _MSC_VER
2171
#ifdef _WIN64
2172
unsigned long rl;
2173
result = _BitScanForward64(&rl, n) ? int(rl) : 64;
2174
#else
2175
unsigned long rl;
2176
if (_BitScanForward(&rl, uint32_t(n)))
2177
result = int(rl);
2178
else
2179
result = _BitScanForward(&rl, uint32_t(n >> 32)) ? int(rl) + 32 : 64;
2180
#endif
2181
#else
2182
result = (n == 0) ? 64 : __builtin_ctzll(n);
2183
#endif
2184
2185
setlvalue(res, result);
2186
2187
return 1;
2188
}
2189
2190
return -1;
2191
}
2192
2193
static int luauF_integerextract(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2194
{
2195
if ((nparams >= 3) && !ttisinteger(args + 1))
2196
return -1;
2197
2198
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2199
{
2200
int64_t n = lvalue(arg0);
2201
int64_t f = lvalue(args);
2202
int64_t w = (nparams >= 3) ? lvalue(args + 1) : 1;
2203
2204
if ((f < 0) || (f > 63) || (w < 1) || (w > 64) || ((f + w) > 64))
2205
return -1;
2206
2207
setlvalue(res, (((uint64_t)n) >> f) & ((0xFFFFFFFFFFFFFFFFULL) >> (64 - w)));
2208
return 1;
2209
}
2210
2211
return -1;
2212
}
2213
2214
static int luauF_integerclamp(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2215
{
2216
if (nparams >= 3 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args) && ttisinteger(args + 1))
2217
{
2218
int64_t a = lvalue(arg0);
2219
int64_t rmin = lvalue(args);
2220
int64_t rmax = lvalue(args + 1);
2221
2222
if (rmin > rmax)
2223
return -1;
2224
2225
setlvalue(res, (a < rmin) ? rmin : ((a > rmax) ? rmax : a));
2226
return 1;
2227
}
2228
2229
return -1;
2230
}
2231
2232
static int luauF_integerlrotate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2233
{
2234
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2235
{
2236
uint64_t n = (uint64_t)lvalue(arg0);
2237
unsigned s = (unsigned)((uint64_t)lvalue(args) % 64);
2238
2239
setlvalue(res, s != 0 ? (n << s) | (n >> (64 - s)) : n);
2240
2241
return 1;
2242
}
2243
2244
return -1;
2245
}
2246
2247
static int luauF_integerrrotate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2248
{
2249
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2250
{
2251
uint64_t n = (uint64_t)lvalue(arg0);
2252
unsigned s = (unsigned)((uint64_t)lvalue(args) % 64);
2253
2254
setlvalue(res, s != 0 ? (n >> s) | (n << (64 - s)) : n);
2255
2256
return 1;
2257
}
2258
2259
return -1;
2260
}
2261
2262
static int luauF_integerlshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2263
{
2264
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2265
{
2266
uint64_t n = (uint64_t)lvalue(arg0);
2267
int64_t i = lvalue(args);
2268
2269
setlvalue(res, ((i >= -63) && (i <= 63)) ? ((i < 0) ? (n >> (-i)) : (n << i)) : 0);
2270
2271
return 1;
2272
}
2273
2274
return -1;
2275
}
2276
2277
static int luauF_integerarshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2278
{
2279
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2280
{
2281
int64_t n = lvalue(arg0);
2282
int64_t i = lvalue(args);
2283
2284
if ((i >= -63) && (i <= 63))
2285
{
2286
setlvalue(res, (i < 0) ? (int64_t)((uint64_t)n << (-i)) : (n >> i));
2287
}
2288
else if (i < -63)
2289
{
2290
setlvalue(res, 0);
2291
}
2292
else
2293
{
2294
setlvalue(res, (n < 0) ? -1 : 0);
2295
}
2296
2297
return 1;
2298
}
2299
2300
return -1;
2301
}
2302
2303
static int luauF_integerrshift(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2304
{
2305
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2306
{
2307
uint64_t n = (uint64_t)lvalue(arg0);
2308
int64_t i = lvalue(args);
2309
2310
setlvalue(res, ((i >= -63) && (i <= 63)) ? ((i < 0) ? (n << (-i)) : (n >> i)) : 0);
2311
2312
return 1;
2313
}
2314
2315
return -1;
2316
}
2317
2318
static int luauF_integermin(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2319
{
2320
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2321
{
2322
int64_t a1 = lvalue(arg0);
2323
int64_t a2 = lvalue(args);
2324
2325
int64_t r = (a2 < a1) ? a2 : a1;
2326
2327
for (int i = 3; i <= nparams; ++i)
2328
{
2329
if (!ttisinteger(args + (i - 2)))
2330
return -1;
2331
2332
int64_t a = lvalue(args + (i - 2));
2333
2334
r = (a < r) ? a : r;
2335
}
2336
2337
setlvalue(res, r);
2338
return 1;
2339
}
2340
2341
return -1;
2342
}
2343
2344
static int luauF_integermax(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2345
{
2346
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2347
{
2348
int64_t a1 = lvalue(arg0);
2349
int64_t a2 = lvalue(args);
2350
2351
int64_t r = (a2 < a1) ? a1 : a2;
2352
2353
for (int i = 3; i <= nparams; ++i)
2354
{
2355
if (!ttisinteger(args + (i - 2)))
2356
return -1;
2357
2358
int64_t a = lvalue(args + (i - 2));
2359
2360
r = (a > r) ? a : r;
2361
}
2362
2363
setlvalue(res, r);
2364
return 1;
2365
}
2366
2367
return -1;
2368
}
2369
2370
static int luauF_integermul(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2371
{
2372
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2373
{
2374
int64_t a1 = lvalue(arg0);
2375
int64_t a2 = lvalue(args);
2376
setlvalue(res, (int64_t)((uint64_t)a1 * (uint64_t)a2));
2377
return 1;
2378
}
2379
2380
return -1;
2381
}
2382
2383
static int luauF_integermod(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2384
{
2385
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2386
{
2387
int64_t a1 = lvalue(arg0);
2388
int64_t a2 = lvalue(args);
2389
2390
if (a2 == 0)
2391
return -1;
2392
2393
if ((a1 == LLONG_MIN) && (a2 == -1))
2394
{
2395
setlvalue(res, 0);
2396
return 1;
2397
}
2398
2399
int64_t remainder = a1 % a2;
2400
if (remainder && ((a1 < 0) != (a2 < 0)))
2401
remainder += a2;
2402
2403
setlvalue(res, remainder);
2404
return 1;
2405
}
2406
2407
return -1;
2408
}
2409
2410
static int luauF_integeridiv(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2411
{
2412
if (nparams >= 2 && nresults <= 1 && ttisinteger(arg0) && ttisinteger(args))
2413
{
2414
int64_t a1 = lvalue(arg0);
2415
int64_t a2 = lvalue(args);
2416
if (a2 == 0)
2417
return -1;
2418
if ((a1 == LLONG_MIN) && (a2 == -1))
2419
return -1;
2420
2421
int64_t result = a1 / a2;
2422
if ((result < 0) && (a1 % a2))
2423
{
2424
setlvalue(res, result - 1);
2425
}
2426
else
2427
{
2428
setlvalue(res, result);
2429
}
2430
return 1;
2431
}
2432
2433
return -1;
2434
}
2435
2436
static int luauF_integercreate(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2437
{
2438
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
2439
{
2440
double a1 = nvalue(arg0);
2441
2442
if (a1 >= -9223372036854775808.0 && a1 < 9223372036854775808.0)
2443
{
2444
int64_t x = (int64_t)a1;
2445
if ((double)x == a1)
2446
{
2447
setlvalue(res, x);
2448
return 1;
2449
}
2450
}
2451
2452
setnilvalue(res);
2453
return 1;
2454
}
2455
2456
return -1;
2457
}
2458
2459
static int luauF_missing(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2460
{
2461
return -1;
2462
}
2463
2464
#ifdef LUAU_TARGET_SSE41
2465
template<int Rounding>
2466
LUAU_TARGET_SSE41 inline double roundsd_sse41(double v)
2467
{
2468
__m128d av = _mm_set_sd(v);
2469
__m128d rv = _mm_round_sd(av, av, Rounding | _MM_FROUND_NO_EXC);
2470
return _mm_cvtsd_f64(rv);
2471
}
2472
2473
LUAU_TARGET_SSE41 static int luauF_floor_sse41(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2474
{
2475
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
2476
{
2477
double a1 = nvalue(arg0);
2478
setnvalue(res, roundsd_sse41<_MM_FROUND_TO_NEG_INF>(a1));
2479
return 1;
2480
}
2481
2482
return -1;
2483
}
2484
2485
LUAU_TARGET_SSE41 static int luauF_ceil_sse41(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2486
{
2487
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
2488
{
2489
double a1 = nvalue(arg0);
2490
setnvalue(res, roundsd_sse41<_MM_FROUND_TO_POS_INF>(a1));
2491
return 1;
2492
}
2493
2494
return -1;
2495
}
2496
2497
LUAU_TARGET_SSE41 static int luauF_round_sse41(lua_State* L, StkId res, TValue* arg0, int nresults, StkId args, int nparams)
2498
{
2499
if (nparams >= 1 && nresults <= 1 && ttisnumber(arg0))
2500
{
2501
double a1 = nvalue(arg0);
2502
// roundsd only supports bankers rounding natively, so we need to emulate rounding by using truncation
2503
// offset is prevfloat(0.5), which is important so that we round prevfloat(0.5) to 0.
2504
const double offset = 0.49999999999999994;
2505
setnvalue(res, roundsd_sse41<_MM_FROUND_TO_ZERO>(a1 + (a1 < 0 ? -offset : offset)));
2506
return 1;
2507
}
2508
2509
return -1;
2510
}
2511
2512
static bool luau_hassse41()
2513
{
2514
int cpuinfo[4] = {};
2515
#ifdef _MSC_VER
2516
__cpuid(cpuinfo, 1);
2517
#else
2518
__cpuid(1, cpuinfo[0], cpuinfo[1], cpuinfo[2], cpuinfo[3]);
2519
#endif
2520
2521
// We require SSE4.1 support for ROUNDSD
2522
// https://en.wikipedia.org/wiki/CPUID#EAX=1:_Processor_Info_and_Feature_Bits
2523
return (cpuinfo[2] & (1 << 19)) != 0;
2524
}
2525
#endif
2526
2527
const luau_FastFunction luauF_table[256] = {
2528
NULL,
2529
luauF_assert,
2530
2531
luauF_abs,
2532
luauF_acos,
2533
luauF_asin,
2534
luauF_atan2,
2535
luauF_atan,
2536
2537
#ifdef LUAU_TARGET_SSE41
2538
luau_hassse41() ? luauF_ceil_sse41 : luauF_ceil,
2539
#else
2540
luauF_ceil,
2541
#endif
2542
2543
luauF_cosh,
2544
luauF_cos,
2545
luauF_deg,
2546
luauF_exp,
2547
2548
#ifdef LUAU_TARGET_SSE41
2549
luau_hassse41() ? luauF_floor_sse41 : luauF_floor,
2550
#else
2551
luauF_floor,
2552
#endif
2553
2554
luauF_fmod,
2555
luauF_frexp,
2556
luauF_ldexp,
2557
luauF_log10,
2558
luauF_log,
2559
luauF_max,
2560
luauF_min,
2561
luauF_modf,
2562
luauF_pow,
2563
luauF_rad,
2564
luauF_sinh,
2565
luauF_sin,
2566
luauF_sqrt,
2567
luauF_tanh,
2568
luauF_tan,
2569
2570
luauF_arshift,
2571
luauF_band,
2572
luauF_bnot,
2573
luauF_bor,
2574
luauF_bxor,
2575
luauF_btest,
2576
luauF_extract,
2577
luauF_lrotate,
2578
luauF_lshift,
2579
luauF_replace,
2580
luauF_rrotate,
2581
luauF_rshift,
2582
2583
luauF_type,
2584
2585
luauF_byte,
2586
luauF_char,
2587
luauF_len,
2588
2589
luauF_typeof,
2590
2591
luauF_sub,
2592
2593
luauF_clamp,
2594
luauF_sign,
2595
2596
#ifdef LUAU_TARGET_SSE41
2597
luau_hassse41() ? luauF_round_sse41 : luauF_round,
2598
#else
2599
luauF_round,
2600
#endif
2601
2602
luauF_rawset,
2603
luauF_rawget,
2604
luauF_rawequal,
2605
2606
luauF_tinsert,
2607
luauF_tunpack,
2608
2609
luauF_vector,
2610
2611
luauF_countlz,
2612
luauF_countrz,
2613
2614
luauF_select,
2615
2616
luauF_rawlen,
2617
2618
luauF_extractk,
2619
2620
luauF_getmetatable,
2621
luauF_setmetatable,
2622
2623
luauF_tonumber,
2624
luauF_tostring,
2625
2626
luauF_byteswap,
2627
2628
luauF_readinteger<int8_t>,
2629
luauF_readinteger<uint8_t>,
2630
luauF_writeinteger<uint8_t>,
2631
luauF_readinteger<int16_t>,
2632
luauF_readinteger<uint16_t>,
2633
luauF_writeinteger<uint16_t>,
2634
luauF_readinteger<int32_t>,
2635
luauF_readinteger<uint32_t>,
2636
luauF_writeinteger<uint32_t>,
2637
luauF_readfp<float>,
2638
luauF_writefp<float>,
2639
luauF_readfp<double>,
2640
luauF_writefp<double>,
2641
2642
luauF_vectormagnitude,
2643
luauF_vectornormalize,
2644
luauF_vectorcross,
2645
luauF_vectordot,
2646
luauF_vectorfloor,
2647
luauF_vectorceil,
2648
luauF_vectorabs,
2649
luauF_vectorsign,
2650
luauF_vectorclamp,
2651
luauF_vectormin,
2652
luauF_vectormax,
2653
2654
luauF_lerp,
2655
2656
luauF_vectorlerp,
2657
2658
luauF_isnan,
2659
luauF_isinf,
2660
luauF_isfinite,
2661
2662
luauF_integercreate,
2663
luauF_integertonumber,
2664
luauF_integerneg,
2665
luauF_integeradd,
2666
luauF_integersub,
2667
luauF_integermul,
2668
luauF_integerdiv,
2669
luauF_integermin,
2670
luauF_integermax,
2671
luauF_integerrem,
2672
luauF_integeridiv,
2673
luauF_integerudiv,
2674
luauF_integerurem,
2675
luauF_integermod,
2676
luauF_integerclamp,
2677
luauF_integerband,
2678
luauF_integerbor,
2679
luauF_integerbnot,
2680
luauF_integerbxor,
2681
luauF_integerlt,
2682
luauF_integerle,
2683
luauF_integerult,
2684
luauF_integerule,
2685
luauF_integergt,
2686
luauF_integerge,
2687
luauF_integerugt,
2688
luauF_integeruge,
2689
luauF_integerlshift,
2690
luauF_integerrshift,
2691
luauF_integerarshift,
2692
luauF_integerlrotate,
2693
luauF_integerrrotate,
2694
luauF_integerextract,
2695
luauF_integerbtest,
2696
luauF_integercountrz,
2697
luauF_integercountlz,
2698
luauF_integerbswap,
2699
2700
// When adding builtins, add them above this line; what follows is 64 "dummy" entries with luauF_missing fallback.
2701
// This is important so that older versions of the runtime that don't support newer builtins automatically fall back via luauF_missing.
2702
// Given the builtin addition velocity this should always provide a larger compatibility window than bytecode versions suggest.
2703
#define MISSING8 luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing, luauF_missing
2704
2705
MISSING8,
2706
MISSING8,
2707
MISSING8,
2708
MISSING8,
2709
MISSING8,
2710
MISSING8,
2711
MISSING8,
2712
MISSING8,
2713
2714
#undef MISSING8
2715
};
2716
2717