@rbxts/zyntex-sdk 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1118 @@
1
+ --[[
2
+ FiOne
3
+ Copyright (C) 2021 Rerumu
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ ]]
18
+ --
19
+ local bit = bit or bit32 or require("bit")
20
+
21
+ if not table.create then
22
+ function table.create(_)
23
+ return {}
24
+ end
25
+ end
26
+
27
+ if not table.unpack then
28
+ table.unpack = unpack
29
+ end
30
+
31
+ if not table.pack then
32
+ function table.pack(...)
33
+ return { n = select("#", ...), ... }
34
+ end
35
+ end
36
+
37
+ if not table.move then
38
+ function table.move(src, first, last, offset, dst)
39
+ for i = 0, last - first do
40
+ dst[offset + i] = src[first + i]
41
+ end
42
+ end
43
+ end
44
+
45
+ local lua_bc_to_state
46
+ local lua_wrap_state
47
+ local stm_lua_func
48
+
49
+ -- SETLIST config
50
+ local FIELDS_PER_FLUSH = 50
51
+
52
+ -- remap for better lookup
53
+ local OPCODE_RM = {
54
+ -- level 1
55
+ [22] = 18, -- JMP
56
+ [31] = 8, -- FORLOOP
57
+ [33] = 28, -- TFORLOOP
58
+ -- level 2
59
+ [0] = 3, -- MOVE
60
+ [1] = 13, -- LOADK
61
+ [2] = 23, -- LOADBOOL
62
+ [26] = 33, -- TEST
63
+ -- level 3
64
+ [12] = 1, -- ADD
65
+ [13] = 6, -- SUB
66
+ [14] = 10, -- MUL
67
+ [15] = 16, -- DIV
68
+ [16] = 20, -- MOD
69
+ [17] = 26, -- POW
70
+ [18] = 30, -- UNM
71
+ [19] = 36, -- NOT
72
+ -- level 4
73
+ [3] = 0, -- LOADNIL
74
+ [4] = 2, -- GETUPVAL
75
+ [5] = 4, -- GETGLOBAL
76
+ [6] = 7, -- GETTABLE
77
+ [7] = 9, -- SETGLOBAL
78
+ [8] = 12, -- SETUPVAL
79
+ [9] = 14, -- SETTABLE
80
+ [10] = 17, -- NEWTABLE
81
+ [20] = 19, -- LEN
82
+ [21] = 22, -- CONCAT
83
+ [23] = 24, -- EQ
84
+ [24] = 27, -- LT
85
+ [25] = 29, -- LE
86
+ [27] = 32, -- TESTSET
87
+ [32] = 34, -- FORPREP
88
+ [34] = 37, -- SETLIST
89
+ -- level 5
90
+ [11] = 5, -- SELF
91
+ [28] = 11, -- CALL
92
+ [29] = 15, -- TAILCALL
93
+ [30] = 21, -- RETURN
94
+ [35] = 25, -- CLOSE
95
+ [36] = 31, -- CLOSURE
96
+ [37] = 35, -- VARARG
97
+ }
98
+
99
+ -- opcode types for getting values
100
+ local OPCODE_T = {
101
+ [0] = "ABC",
102
+ "ABx",
103
+ "ABC",
104
+ "ABC",
105
+ "ABC",
106
+ "ABx",
107
+ "ABC",
108
+ "ABx",
109
+ "ABC",
110
+ "ABC",
111
+ "ABC",
112
+ "ABC",
113
+ "ABC",
114
+ "ABC",
115
+ "ABC",
116
+ "ABC",
117
+ "ABC",
118
+ "ABC",
119
+ "ABC",
120
+ "ABC",
121
+ "ABC",
122
+ "ABC",
123
+ "AsBx",
124
+ "ABC",
125
+ "ABC",
126
+ "ABC",
127
+ "ABC",
128
+ "ABC",
129
+ "ABC",
130
+ "ABC",
131
+ "ABC",
132
+ "AsBx",
133
+ "AsBx",
134
+ "ABC",
135
+ "ABC",
136
+ "ABC",
137
+ "ABx",
138
+ "ABC",
139
+ }
140
+
141
+ local OPCODE_M = {
142
+ [0] = { b = "OpArgR", c = "OpArgN" },
143
+ { b = "OpArgK", c = "OpArgN" },
144
+ { b = "OpArgU", c = "OpArgU" },
145
+ { b = "OpArgR", c = "OpArgN" },
146
+ { b = "OpArgU", c = "OpArgN" },
147
+ { b = "OpArgK", c = "OpArgN" },
148
+ { b = "OpArgR", c = "OpArgK" },
149
+ { b = "OpArgK", c = "OpArgN" },
150
+ { b = "OpArgU", c = "OpArgN" },
151
+ { b = "OpArgK", c = "OpArgK" },
152
+ { b = "OpArgU", c = "OpArgU" },
153
+ { b = "OpArgR", c = "OpArgK" },
154
+ { b = "OpArgK", c = "OpArgK" },
155
+ { b = "OpArgK", c = "OpArgK" },
156
+ { b = "OpArgK", c = "OpArgK" },
157
+ { b = "OpArgK", c = "OpArgK" },
158
+ { b = "OpArgK", c = "OpArgK" },
159
+ { b = "OpArgK", c = "OpArgK" },
160
+ { b = "OpArgR", c = "OpArgN" },
161
+ { b = "OpArgR", c = "OpArgN" },
162
+ { b = "OpArgR", c = "OpArgN" },
163
+ { b = "OpArgR", c = "OpArgR" },
164
+ { b = "OpArgR", c = "OpArgN" },
165
+ { b = "OpArgK", c = "OpArgK" },
166
+ { b = "OpArgK", c = "OpArgK" },
167
+ { b = "OpArgK", c = "OpArgK" },
168
+ { b = "OpArgR", c = "OpArgU" },
169
+ { b = "OpArgR", c = "OpArgU" },
170
+ { b = "OpArgU", c = "OpArgU" },
171
+ { b = "OpArgU", c = "OpArgU" },
172
+ { b = "OpArgU", c = "OpArgN" },
173
+ { b = "OpArgR", c = "OpArgN" },
174
+ { b = "OpArgR", c = "OpArgN" },
175
+ { b = "OpArgN", c = "OpArgU" },
176
+ { b = "OpArgU", c = "OpArgU" },
177
+ { b = "OpArgN", c = "OpArgN" },
178
+ { b = "OpArgU", c = "OpArgN" },
179
+ { b = "OpArgU", c = "OpArgN" },
180
+ }
181
+
182
+ -- int rd_int_basic(string src, int s, int e, int d)
183
+ -- @src - Source binary string
184
+ -- @s - Start index of a little endian integer
185
+ -- @e - End index of the integer
186
+ -- @d - Direction of the loop
187
+ local function rd_int_basic(src, s, e, d)
188
+ local num = 0
189
+
190
+ -- if bb[l] > 127 then -- signed negative
191
+ -- num = num - 256 ^ l
192
+ -- bb[l] = bb[l] - 128
193
+ -- end
194
+
195
+ for i = s, e, d do
196
+ local mul = 256 ^ math.abs(i - s)
197
+
198
+ num = num + mul * string.byte(src, i, i)
199
+ end
200
+
201
+ return num
202
+ end
203
+
204
+ -- float rd_flt_basic(byte f1..8)
205
+ -- @f1..4 - The 4 bytes composing a little endian float
206
+ local function rd_flt_basic(f1, f2, f3, f4)
207
+ local sign = (-1) ^ bit.rshift(f4, 7)
208
+ local exp = bit.rshift(f3, 7) + bit.lshift(bit.band(f4, 0x7F), 1)
209
+ local frac = f1 + bit.lshift(f2, 8) + bit.lshift(bit.band(f3, 0x7F), 16)
210
+ local normal = 1
211
+
212
+ if exp == 0 then
213
+ if frac == 0 then
214
+ return sign * 0
215
+ else
216
+ normal = 0
217
+ exp = 1
218
+ end
219
+ elseif exp == 0x7F then
220
+ if frac == 0 then
221
+ return sign * (1 / 0)
222
+ else
223
+ return sign * (0 / 0)
224
+ end
225
+ end
226
+
227
+ return sign * 2 ^ (exp - 127) * (1 + normal / 2 ^ 23)
228
+ end
229
+
230
+ -- double rd_dbl_basic(byte f1..8)
231
+ -- @f1..8 - The 8 bytes composing a little endian double
232
+ local function rd_dbl_basic(f1, f2, f3, f4, f5, f6, f7, f8)
233
+ local sign = (-1) ^ bit.rshift(f8, 7)
234
+ local exp = bit.lshift(bit.band(f8, 0x7F), 4) + bit.rshift(f7, 4)
235
+ local frac = bit.band(f7, 0x0F) * 2 ^ 48
236
+ local normal = 1
237
+
238
+ frac = frac + (f6 * 2 ^ 40) + (f5 * 2 ^ 32) + (f4 * 2 ^ 24) + (f3 * 2 ^ 16) + (f2 * 2 ^ 8) + f1 -- help
239
+
240
+ if exp == 0 then
241
+ if frac == 0 then
242
+ return sign * 0
243
+ else
244
+ normal = 0
245
+ exp = 1
246
+ end
247
+ elseif exp == 0x7FF then
248
+ if frac == 0 then
249
+ return sign * (1 / 0)
250
+ else
251
+ return sign * (0 / 0)
252
+ end
253
+ end
254
+
255
+ return sign * 2 ^ (exp - 1023) * (normal + frac / 2 ^ 52)
256
+ end
257
+
258
+ -- int rd_int_le(string src, int s, int e)
259
+ -- @src - Source binary string
260
+ -- @s - Start index of a little endian integer
261
+ -- @e - End index of the integer
262
+ local function rd_int_le(src, s, e)
263
+ return rd_int_basic(src, s, e - 1, 1)
264
+ end
265
+
266
+ -- int rd_int_be(string src, int s, int e)
267
+ -- @src - Source binary string
268
+ -- @s - Start index of a big endian integer
269
+ -- @e - End index of the integer
270
+ local function rd_int_be(src, s, e)
271
+ return rd_int_basic(src, e - 1, s, -1)
272
+ end
273
+
274
+ -- float rd_flt_le(string src, int s)
275
+ -- @src - Source binary string
276
+ -- @s - Start index of little endian float
277
+ local function rd_flt_le(src, s)
278
+ return rd_flt_basic(string.byte(src, s, s + 3))
279
+ end
280
+
281
+ -- float rd_flt_be(string src, int s)
282
+ -- @src - Source binary string
283
+ -- @s - Start index of big endian float
284
+ local function rd_flt_be(src, s)
285
+ local f1, f2, f3, f4 = string.byte(src, s, s + 3)
286
+ return rd_flt_basic(f4, f3, f2, f1)
287
+ end
288
+
289
+ -- double rd_dbl_le(string src, int s)
290
+ -- @src - Source binary string
291
+ -- @s - Start index of little endian double
292
+ local function rd_dbl_le(src, s)
293
+ return rd_dbl_basic(string.byte(src, s, s + 7))
294
+ end
295
+
296
+ -- double rd_dbl_be(string src, int s)
297
+ -- @src - Source binary string
298
+ -- @s - Start index of big endian double
299
+ local function rd_dbl_be(src, s)
300
+ local f1, f2, f3, f4, f5, f6, f7, f8 = string.byte(src, s, s + 7) -- same
301
+ return rd_dbl_basic(f8, f7, f6, f5, f4, f3, f2, f1)
302
+ end
303
+
304
+ -- to avoid nested ifs in deserializing
305
+ local float_types = {
306
+ [4] = { little = rd_flt_le, big = rd_flt_be },
307
+ [8] = { little = rd_dbl_le, big = rd_dbl_be },
308
+ }
309
+
310
+ -- byte stm_byte(Stream S)
311
+ -- @S - Stream object to read from
312
+ local function stm_byte(S)
313
+ local idx = S.index
314
+ local bt = string.byte(S.source, idx, idx)
315
+
316
+ S.index = idx + 1
317
+ return bt
318
+ end
319
+
320
+ -- string stm_string(Stream S, int len)
321
+ -- @S - Stream object to read from
322
+ -- @len - Length of string being read
323
+ local function stm_string(S, len)
324
+ local pos = S.index + len
325
+ local str = string.sub(S.source, S.index, pos - 1)
326
+
327
+ S.index = pos
328
+ return str
329
+ end
330
+
331
+ -- string stm_lstring(Stream S)
332
+ -- @S - Stream object to read from
333
+ local function stm_lstring(S)
334
+ local len = S:s_szt()
335
+ local str
336
+
337
+ if len ~= 0 then
338
+ str = string.sub(stm_string(S, len), 1, -2)
339
+ end
340
+
341
+ return str
342
+ end
343
+
344
+ -- fn cst_int_rdr(string src, int len, fn func)
345
+ -- @len - Length of type for reader
346
+ -- @func - Reader callback
347
+ local function cst_int_rdr(len, func)
348
+ return function(S)
349
+ local pos = S.index + len
350
+ local int = func(S.source, S.index, pos)
351
+ S.index = pos
352
+
353
+ return int
354
+ end
355
+ end
356
+
357
+ -- fn cst_flt_rdr(string src, int len, fn func)
358
+ -- @len - Length of type for reader
359
+ -- @func - Reader callback
360
+ local function cst_flt_rdr(len, func)
361
+ return function(S)
362
+ local flt = func(S.source, S.index)
363
+ S.index = S.index + len
364
+
365
+ return flt
366
+ end
367
+ end
368
+
369
+ local function stm_inst_list(S)
370
+ local len = S:s_int()
371
+ local list = table.create(len)
372
+
373
+ for i = 1, len do
374
+ local ins = S:s_ins()
375
+ local op = bit.band(ins, 0x3F)
376
+ local args = OPCODE_T[op]
377
+ local mode = OPCODE_M[op]
378
+ local data = { value = ins, op = OPCODE_RM[op], A = bit.band(bit.rshift(ins, 6), 0xFF) }
379
+
380
+ if args == "ABC" then
381
+ data.B = bit.band(bit.rshift(ins, 23), 0x1FF)
382
+ data.C = bit.band(bit.rshift(ins, 14), 0x1FF)
383
+ data.is_KB = mode.b == "OpArgK" and data.B > 0xFF -- post process optimization
384
+ data.is_KC = mode.c == "OpArgK" and data.C > 0xFF
385
+ elseif args == "ABx" then
386
+ data.Bx = bit.band(bit.rshift(ins, 14), 0x3FFFF)
387
+ data.is_K = mode.b == "OpArgK"
388
+ elseif args == "AsBx" then
389
+ data.sBx = bit.band(bit.rshift(ins, 14), 0x3FFFF) - 131071
390
+ end
391
+
392
+ list[i] = data
393
+ end
394
+
395
+ return list
396
+ end
397
+
398
+ local function stm_const_list(S)
399
+ local len = S:s_int()
400
+ local list = table.create(len)
401
+
402
+ for i = 1, len do
403
+ local tt = stm_byte(S)
404
+ local k
405
+
406
+ if tt == 1 then
407
+ k = stm_byte(S) ~= 0
408
+ elseif tt == 3 then
409
+ k = S:s_num()
410
+ elseif tt == 4 then
411
+ k = stm_lstring(S)
412
+ end
413
+
414
+ list[i] = k -- offset +1 during instruction decode
415
+ end
416
+
417
+ return list
418
+ end
419
+
420
+ local function stm_sub_list(S, src)
421
+ local len = S:s_int()
422
+ local list = table.create(len)
423
+
424
+ for i = 1, len do
425
+ list[i] = stm_lua_func(S, src) -- offset +1 in CLOSURE
426
+ end
427
+
428
+ return list
429
+ end
430
+
431
+ local function stm_line_list(S)
432
+ local len = S:s_int()
433
+ local list = table.create(len)
434
+
435
+ for i = 1, len do
436
+ list[i] = S:s_int()
437
+ end
438
+
439
+ return list
440
+ end
441
+
442
+ local function stm_loc_list(S)
443
+ local len = S:s_int()
444
+ local list = table.create(len)
445
+
446
+ for i = 1, len do
447
+ list[i] = { varname = stm_lstring(S), startpc = S:s_int(), endpc = S:s_int() }
448
+ end
449
+
450
+ return list
451
+ end
452
+
453
+ local function stm_upval_list(S)
454
+ local len = S:s_int()
455
+ local list = table.create(len)
456
+
457
+ for i = 1, len do
458
+ list[i] = stm_lstring(S)
459
+ end
460
+
461
+ return list
462
+ end
463
+
464
+ function stm_lua_func(S, psrc)
465
+ local proto = {}
466
+ local src = stm_lstring(S) or psrc -- source is propagated
467
+
468
+ proto.source = src -- source name
469
+
470
+ S:s_int() -- line defined
471
+ S:s_int() -- last line defined
472
+
473
+ proto.num_upval = stm_byte(S) -- num upvalues
474
+ proto.num_param = stm_byte(S) -- num params
475
+
476
+ stm_byte(S) -- vararg flag
477
+ proto.max_stack = stm_byte(S) -- max stack size
478
+
479
+ proto.code = stm_inst_list(S)
480
+ proto.const = stm_const_list(S)
481
+ proto.subs = stm_sub_list(S, src)
482
+ proto.lines = stm_line_list(S)
483
+
484
+ stm_loc_list(S)
485
+ stm_upval_list(S)
486
+
487
+ -- post process optimization
488
+ for _, v in ipairs(proto.code) do
489
+ if v.is_K then
490
+ v.const = proto.const[v.Bx + 1] -- offset for 1 based index
491
+ else
492
+ if v.is_KB then
493
+ v.const_B = proto.const[v.B - 0xFF]
494
+ end
495
+
496
+ if v.is_KC then
497
+ v.const_C = proto.const[v.C - 0xFF]
498
+ end
499
+ end
500
+ end
501
+
502
+ return proto
503
+ end
504
+
505
+ function lua_bc_to_state(src)
506
+ -- func reader
507
+ local rdr_func
508
+
509
+ -- header flags
510
+ local little
511
+ local size_int
512
+ local size_szt
513
+ local size_ins
514
+ local size_num
515
+ local flag_int
516
+
517
+ -- stream object
518
+ local stream = {
519
+ -- data
520
+ index = 1,
521
+ source = src,
522
+ }
523
+
524
+ assert(stm_string(stream, 4) == "\27Lua", "invalid Lua signature")
525
+ assert(stm_byte(stream) == 0x51, "invalid Lua version")
526
+ assert(stm_byte(stream) == 0, "invalid Lua format")
527
+
528
+ little = stm_byte(stream) ~= 0
529
+ size_int = stm_byte(stream)
530
+ size_szt = stm_byte(stream)
531
+ size_ins = stm_byte(stream)
532
+ size_num = stm_byte(stream)
533
+ flag_int = stm_byte(stream) ~= 0
534
+
535
+ rdr_func = little and rd_int_le or rd_int_be
536
+ stream.s_int = cst_int_rdr(size_int, rdr_func)
537
+ stream.s_szt = cst_int_rdr(size_szt, rdr_func)
538
+ stream.s_ins = cst_int_rdr(size_ins, rdr_func)
539
+
540
+ if flag_int then
541
+ stream.s_num = cst_int_rdr(size_num, rdr_func)
542
+ elseif float_types[size_num] then
543
+ stream.s_num = cst_flt_rdr(size_num, float_types[size_num][little and "little" or "big"])
544
+ else
545
+ error("unsupported float size")
546
+ end
547
+
548
+ return stm_lua_func(stream, "@virtual")
549
+ end
550
+
551
+ local function close_lua_upvalues(list, index)
552
+ for i, uv in pairs(list) do
553
+ if uv.index >= index then
554
+ uv.value = uv.store[uv.index] -- store value
555
+ uv.store = uv
556
+ uv.index = "value" -- self reference
557
+ list[i] = nil
558
+ end
559
+ end
560
+ end
561
+
562
+ local function open_lua_upvalue(list, index, memory)
563
+ local prev = list[index]
564
+
565
+ if not prev then
566
+ prev = { index = index, store = memory }
567
+ list[index] = prev
568
+ end
569
+
570
+ return prev
571
+ end
572
+
573
+ local function on_lua_error(failed, err)
574
+ local src = failed.source
575
+ local line = failed.lines[failed.pc - 1]
576
+
577
+ error(string.format("%s:%i: %s", src, line, err), 0)
578
+ end
579
+
580
+ local function run_lua_func(state, env, upvals)
581
+ local code = state.code
582
+ local subs = state.subs
583
+ local vararg = state.vararg
584
+
585
+ local top_index = -1
586
+ local open_list = {}
587
+ local memory = state.memory
588
+ local pc = state.pc
589
+
590
+ while true do
591
+ local inst = code[pc]
592
+ local op = inst.op
593
+ pc = pc + 1
594
+
595
+ if op < 18 then
596
+ if op < 8 then
597
+ if op < 3 then
598
+ if op < 1 then
599
+ --[[LOADNIL]]
600
+ for i = inst.A, inst.B do
601
+ memory[i] = nil
602
+ end
603
+ elseif op > 1 then
604
+ --[[GETUPVAL]]
605
+ local uv = upvals[inst.B]
606
+
607
+ memory[inst.A] = uv.store[uv.index]
608
+ else
609
+ --[[ADD]]
610
+ local lhs, rhs
611
+
612
+ if inst.is_KB then
613
+ lhs = inst.const_B
614
+ else
615
+ lhs = memory[inst.B]
616
+ end
617
+
618
+ if inst.is_KC then
619
+ rhs = inst.const_C
620
+ else
621
+ rhs = memory[inst.C]
622
+ end
623
+
624
+ memory[inst.A] = lhs + rhs
625
+ end
626
+ elseif op > 3 then
627
+ if op < 6 then
628
+ if op > 4 then
629
+ --[[SELF]]
630
+ local A = inst.A
631
+ local B = inst.B
632
+ local index
633
+
634
+ if inst.is_KC then
635
+ index = inst.const_C
636
+ else
637
+ index = memory[inst.C]
638
+ end
639
+
640
+ memory[A + 1] = memory[B]
641
+ memory[A] = memory[B][index]
642
+ else
643
+ --[[GETGLOBAL]]
644
+ memory[inst.A] = env[inst.const]
645
+ end
646
+ elseif op > 6 then
647
+ --[[GETTABLE]]
648
+ local index
649
+
650
+ if inst.is_KC then
651
+ index = inst.const_C
652
+ else
653
+ index = memory[inst.C]
654
+ end
655
+
656
+ memory[inst.A] = memory[inst.B][index]
657
+ else
658
+ --[[SUB]]
659
+ local lhs, rhs
660
+
661
+ if inst.is_KB then
662
+ lhs = inst.const_B
663
+ else
664
+ lhs = memory[inst.B]
665
+ end
666
+
667
+ if inst.is_KC then
668
+ rhs = inst.const_C
669
+ else
670
+ rhs = memory[inst.C]
671
+ end
672
+
673
+ memory[inst.A] = lhs - rhs
674
+ end
675
+ else --[[MOVE]]
676
+ memory[inst.A] = memory[inst.B]
677
+ end
678
+ elseif op > 8 then
679
+ if op < 13 then
680
+ if op < 10 then
681
+ --[[SETGLOBAL]]
682
+ env[inst.const] = memory[inst.A]
683
+ elseif op > 10 then
684
+ if op < 12 then
685
+ --[[CALL]]
686
+ local A = inst.A
687
+ local B = inst.B
688
+ local C = inst.C
689
+ local params
690
+
691
+ if B == 0 then
692
+ params = top_index - A
693
+ else
694
+ params = B - 1
695
+ end
696
+
697
+ local ret_list = table.pack(memory[A](table.unpack(memory, A + 1, A + params)))
698
+ local ret_num = ret_list.n
699
+
700
+ if C == 0 then
701
+ top_index = A + ret_num - 1
702
+ else
703
+ ret_num = C - 1
704
+ end
705
+
706
+ table.move(ret_list, 1, ret_num, A, memory)
707
+ else
708
+ --[[SETUPVAL]]
709
+ local uv = upvals[inst.B]
710
+
711
+ uv.store[uv.index] = memory[inst.A]
712
+ end
713
+ else
714
+ --[[MUL]]
715
+ local lhs, rhs
716
+
717
+ if inst.is_KB then
718
+ lhs = inst.const_B
719
+ else
720
+ lhs = memory[inst.B]
721
+ end
722
+
723
+ if inst.is_KC then
724
+ rhs = inst.const_C
725
+ else
726
+ rhs = memory[inst.C]
727
+ end
728
+
729
+ memory[inst.A] = lhs * rhs
730
+ end
731
+ elseif op > 13 then
732
+ if op < 16 then
733
+ if op > 14 then
734
+ --[[TAILCALL]]
735
+ local A = inst.A
736
+ local B = inst.B
737
+ local params
738
+
739
+ if B == 0 then
740
+ params = top_index - A
741
+ else
742
+ params = B - 1
743
+ end
744
+
745
+ close_lua_upvalues(open_list, 0)
746
+
747
+ return memory[A](table.unpack(memory, A + 1, A + params))
748
+ else
749
+ --[[SETTABLE]]
750
+ local index, value
751
+
752
+ if inst.is_KB then
753
+ index = inst.const_B
754
+ else
755
+ index = memory[inst.B]
756
+ end
757
+
758
+ if inst.is_KC then
759
+ value = inst.const_C
760
+ else
761
+ value = memory[inst.C]
762
+ end
763
+
764
+ memory[inst.A][index] = value
765
+ end
766
+ elseif op > 16 then
767
+ --[[NEWTABLE]]
768
+ memory[inst.A] = {}
769
+ else
770
+ --[[DIV]]
771
+ local lhs, rhs
772
+
773
+ if inst.is_KB then
774
+ lhs = inst.const_B
775
+ else
776
+ lhs = memory[inst.B]
777
+ end
778
+
779
+ if inst.is_KC then
780
+ rhs = inst.const_C
781
+ else
782
+ rhs = memory[inst.C]
783
+ end
784
+
785
+ memory[inst.A] = lhs / rhs
786
+ end
787
+ else
788
+ --[[LOADK]]
789
+ memory[inst.A] = inst.const
790
+ end
791
+ else
792
+ --[[FORLOOP]]
793
+ local A = inst.A
794
+ local step = memory[A + 2]
795
+ local index = memory[A] + step
796
+ local limit = memory[A + 1]
797
+ local loops
798
+
799
+ if step == math.abs(step) then
800
+ loops = index <= limit
801
+ else
802
+ loops = index >= limit
803
+ end
804
+
805
+ if loops then
806
+ memory[A] = index
807
+ memory[A + 3] = index
808
+ pc = pc + inst.sBx
809
+ end
810
+ end
811
+ elseif op > 18 then
812
+ if op < 28 then
813
+ if op < 23 then
814
+ if op < 20 then
815
+ --[[LEN]]
816
+ memory[inst.A] = #memory[inst.B]
817
+ elseif op > 20 then
818
+ if op < 22 then
819
+ --[[RETURN]]
820
+ local A = inst.A
821
+ local B = inst.B
822
+ local len
823
+
824
+ if B == 0 then
825
+ len = top_index - A + 1
826
+ else
827
+ len = B - 1
828
+ end
829
+
830
+ close_lua_upvalues(open_list, 0)
831
+
832
+ return table.unpack(memory, A, A + len - 1)
833
+ else
834
+ --[[CONCAT]]
835
+ local B = inst.B
836
+ local str = memory[B]
837
+
838
+ for i = B + 1, inst.C do
839
+ str = str .. memory[i]
840
+ end
841
+
842
+ memory[inst.A] = str
843
+ end
844
+ else
845
+ --[[MOD]]
846
+ local lhs, rhs
847
+
848
+ if inst.is_KB then
849
+ lhs = inst.const_B
850
+ else
851
+ lhs = memory[inst.B]
852
+ end
853
+
854
+ if inst.is_KC then
855
+ rhs = inst.const_C
856
+ else
857
+ rhs = memory[inst.C]
858
+ end
859
+
860
+ memory[inst.A] = lhs % rhs
861
+ end
862
+ elseif op > 23 then
863
+ if op < 26 then
864
+ if op > 24 then
865
+ --[[CLOSE]]
866
+ close_lua_upvalues(open_list, inst.A)
867
+ else
868
+ --[[EQ]]
869
+ local lhs, rhs
870
+
871
+ if inst.is_KB then
872
+ lhs = inst.const_B
873
+ else
874
+ lhs = memory[inst.B]
875
+ end
876
+
877
+ if inst.is_KC then
878
+ rhs = inst.const_C
879
+ else
880
+ rhs = memory[inst.C]
881
+ end
882
+
883
+ if (lhs == rhs) == (inst.A ~= 0) then
884
+ pc = pc + code[pc].sBx
885
+ end
886
+
887
+ pc = pc + 1
888
+ end
889
+ elseif op > 26 then
890
+ --[[LT]]
891
+ local lhs, rhs
892
+
893
+ if inst.is_KB then
894
+ lhs = inst.const_B
895
+ else
896
+ lhs = memory[inst.B]
897
+ end
898
+
899
+ if inst.is_KC then
900
+ rhs = inst.const_C
901
+ else
902
+ rhs = memory[inst.C]
903
+ end
904
+
905
+ if (lhs < rhs) == (inst.A ~= 0) then
906
+ pc = pc + code[pc].sBx
907
+ end
908
+
909
+ pc = pc + 1
910
+ else
911
+ --[[POW]]
912
+ local lhs, rhs
913
+
914
+ if inst.is_KB then
915
+ lhs = inst.const_B
916
+ else
917
+ lhs = memory[inst.B]
918
+ end
919
+
920
+ if inst.is_KC then
921
+ rhs = inst.const_C
922
+ else
923
+ rhs = memory[inst.C]
924
+ end
925
+
926
+ memory[inst.A] = lhs ^ rhs
927
+ end
928
+ else
929
+ --[[LOADBOOL]]
930
+ memory[inst.A] = inst.B ~= 0
931
+
932
+ if inst.C ~= 0 then
933
+ pc = pc + 1
934
+ end
935
+ end
936
+ elseif op > 28 then
937
+ if op < 33 then
938
+ if op < 30 then
939
+ --[[LE]]
940
+ local lhs, rhs
941
+
942
+ if inst.is_KB then
943
+ lhs = inst.const_B
944
+ else
945
+ lhs = memory[inst.B]
946
+ end
947
+
948
+ if inst.is_KC then
949
+ rhs = inst.const_C
950
+ else
951
+ rhs = memory[inst.C]
952
+ end
953
+
954
+ if (lhs <= rhs) == (inst.A ~= 0) then
955
+ pc = pc + code[pc].sBx
956
+ end
957
+
958
+ pc = pc + 1
959
+ elseif op > 30 then
960
+ if op < 32 then
961
+ --[[CLOSURE]]
962
+ local sub = subs[inst.Bx + 1] -- offset for 1 based index
963
+ local nups = sub.num_upval
964
+ local uvlist
965
+
966
+ if nups ~= 0 then
967
+ uvlist = {}
968
+
969
+ for i = 1, nups do
970
+ local pseudo = code[pc + i - 1]
971
+
972
+ if pseudo.op == OPCODE_RM[0] then -- @MOVE
973
+ uvlist[i - 1] = open_lua_upvalue(open_list, pseudo.B, memory)
974
+ elseif pseudo.op == OPCODE_RM[4] then -- @GETUPVAL
975
+ uvlist[i - 1] = upvals[pseudo.B]
976
+ end
977
+ end
978
+
979
+ pc = pc + nups
980
+ end
981
+
982
+ memory[inst.A] = lua_wrap_state(sub, env, uvlist)
983
+ else
984
+ --[[TESTSET]]
985
+ local A = inst.A
986
+ local B = inst.B
987
+
988
+ if (not memory[B]) ~= (inst.C ~= 0) then
989
+ memory[A] = memory[B]
990
+ pc = pc + code[pc].sBx
991
+ end
992
+ pc = pc + 1
993
+ end
994
+ else
995
+ --[[UNM]]
996
+ memory[inst.A] = -memory[inst.B]
997
+ end
998
+ elseif op > 33 then
999
+ if op < 36 then
1000
+ if op > 34 then
1001
+ --[[VARARG]]
1002
+ local A = inst.A
1003
+ local len = inst.B
1004
+
1005
+ if len == 0 then
1006
+ len = vararg.len
1007
+ top_index = A + len - 1
1008
+ end
1009
+
1010
+ table.move(vararg.list, 1, len, A, memory)
1011
+ else
1012
+ --[[FORPREP]]
1013
+ local A = inst.A
1014
+ local init, limit, step
1015
+
1016
+ init = assert(tonumber(memory[A]), "`for` initial value must be a number")
1017
+ limit = assert(tonumber(memory[A + 1]), "`for` limit must be a number")
1018
+ step = assert(tonumber(memory[A + 2]), "`for` step must be a number")
1019
+
1020
+ memory[A] = init - step
1021
+ memory[A + 1] = limit
1022
+ memory[A + 2] = step
1023
+
1024
+ pc = pc + inst.sBx
1025
+ end
1026
+ elseif op > 36 then
1027
+ --[[SETLIST]]
1028
+ local A = inst.A
1029
+ local C = inst.C
1030
+ local len = inst.B
1031
+ local tab = memory[A]
1032
+ local offset
1033
+
1034
+ if len == 0 then
1035
+ len = top_index - A
1036
+ end
1037
+
1038
+ if C == 0 then
1039
+ C = inst[pc].value
1040
+ pc = pc + 1
1041
+ end
1042
+
1043
+ offset = (C - 1) * FIELDS_PER_FLUSH
1044
+
1045
+ table.move(memory, A + 1, A + len, offset + 1, tab)
1046
+ else
1047
+ --[[NOT]]
1048
+ memory[inst.A] = not memory[inst.B]
1049
+ end
1050
+ else
1051
+ --[[TEST]]
1052
+ if (not memory[inst.A]) ~= (inst.C ~= 0) then
1053
+ pc = pc + code[pc].sBx
1054
+ end
1055
+ pc = pc + 1
1056
+ end
1057
+ else
1058
+ --[[TFORLOOP]]
1059
+ local A = inst.A
1060
+ local base = A + 3
1061
+
1062
+ local vals = { memory[A](memory[A + 1], memory[A + 2]) }
1063
+
1064
+ table.move(vals, 1, inst.C, base, memory)
1065
+
1066
+ if memory[base] ~= nil then
1067
+ memory[A + 2] = memory[base]
1068
+ pc = pc + code[pc].sBx
1069
+ end
1070
+
1071
+ pc = pc + 1
1072
+ end
1073
+ else
1074
+ --[[JMP]]
1075
+ pc = pc + inst.sBx
1076
+ end
1077
+
1078
+ state.pc = pc
1079
+ end
1080
+ end
1081
+
1082
+ function lua_wrap_state(proto, env, upval)
1083
+ local function wrapped(...)
1084
+ local passed = table.pack(...)
1085
+ local memory = table.create(proto.max_stack)
1086
+ local vararg = { len = 0, list = {} }
1087
+
1088
+ table.move(passed, 1, proto.num_param, 0, memory)
1089
+
1090
+ if proto.num_param < passed.n then
1091
+ local start = proto.num_param + 1
1092
+ local len = passed.n - proto.num_param
1093
+
1094
+ vararg.len = len
1095
+ table.move(passed, start, start + len - 1, 1, vararg.list)
1096
+ end
1097
+
1098
+ local state = { vararg = vararg, memory = memory, code = proto.code, subs = proto.subs, pc = 1 }
1099
+
1100
+ local result = table.pack(pcall(run_lua_func, state, env, upval))
1101
+
1102
+ if result[1] then
1103
+ return table.unpack(result, 2, result.n)
1104
+ else
1105
+ local failed = { pc = state.pc, source = proto.source, lines = proto.lines }
1106
+
1107
+ on_lua_error(failed, result[2])
1108
+
1109
+ return
1110
+ end
1111
+ end
1112
+
1113
+ return wrapped
1114
+ end
1115
+
1116
+ return function(bCode, env)
1117
+ return lua_wrap_state(lua_bc_to_state(bCode), env or getfenv(0))
1118
+ end