luau-obfuscator 1.0.1 → 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.
- package/dist/index.cjs +246 -125
- package/dist/index.js +246 -125
- package/generated/grammers.luau +13643 -0
- package/generated/tests.luau +5567 -0
- package/package.json +1 -1
- package/scripts/test.js +20 -12
- package/src/passes/ConstantArray.ts +6 -5
- package/src/passes/EncryptNumbers.ts +2 -1
- package/src/passes/EncryptStrings.ts +11 -11
- package/src/passes/NumbersToExpressions.ts +4 -1
- package/src/passes/StringsToExpressions.ts +29 -5
- package/src/passes/Vmify.ts +16 -2
- package/src/passes/nodeFactory.ts +19 -0
- package/src/passes/vmify/chunk.ts +9 -5
- package/src/passes/vmify/names.ts +2 -8
- package/src/passes/vmify/runtime.ts +49 -49
- package/src/passes/vmify/serialize.ts +11 -11
- package/src/passes/walk.ts +141 -43
- package/src/pipeline.ts +3 -6
- package/generated/final.luau +0 -63216
- package/generated/smoketest.luau +0 -24339
- /package/{scripts/example.luau → smoketest/grammers.luau} +0 -0
- /package/{scripts/smoketest.luau → smoketest/tests.luau} +0 -0
package/dist/index.js
CHANGED
|
@@ -181,67 +181,171 @@ function visitArray(arr, visitor) {
|
|
|
181
181
|
arr[i] = mapExpression(arr[i], visitor);
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
|
-
function
|
|
184
|
+
function getExpressionChildren(expr) {
|
|
185
185
|
switch (expr.type) {
|
|
186
|
-
case "InterpolatedStringExpression":
|
|
186
|
+
case "InterpolatedStringExpression": {
|
|
187
|
+
const children = [];
|
|
187
188
|
for (const part of expr.parts) {
|
|
188
189
|
if (part.kind === "expression") {
|
|
189
|
-
|
|
190
|
+
children.push({
|
|
191
|
+
get: () => part.expression,
|
|
192
|
+
set: (v) => {
|
|
193
|
+
part.expression = v;
|
|
194
|
+
}
|
|
195
|
+
});
|
|
190
196
|
}
|
|
191
197
|
}
|
|
192
|
-
|
|
198
|
+
return children;
|
|
199
|
+
}
|
|
193
200
|
case "FunctionExpression":
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
201
|
+
return [];
|
|
202
|
+
case "TableExpression": {
|
|
203
|
+
const children = [];
|
|
197
204
|
for (const field of expr.fields) {
|
|
198
205
|
if (field.type === "TableFieldPositional") {
|
|
199
|
-
|
|
206
|
+
children.push({ get: () => field.value, set: (v) => {
|
|
207
|
+
field.value = v;
|
|
208
|
+
} });
|
|
200
209
|
} else if (field.type === "TableFieldNamed") {
|
|
201
|
-
|
|
210
|
+
children.push({ get: () => field.value, set: (v) => {
|
|
211
|
+
field.value = v;
|
|
212
|
+
} });
|
|
202
213
|
} else if (field.type === "TableFieldComputed") {
|
|
203
|
-
|
|
204
|
-
|
|
214
|
+
children.push({ get: () => field.key, set: (v) => {
|
|
215
|
+
field.key = v;
|
|
216
|
+
} });
|
|
217
|
+
children.push({ get: () => field.value, set: (v) => {
|
|
218
|
+
field.value = v;
|
|
219
|
+
} });
|
|
205
220
|
}
|
|
206
221
|
}
|
|
207
|
-
|
|
222
|
+
return children;
|
|
223
|
+
}
|
|
208
224
|
case "BinaryExpression":
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
225
|
+
return [
|
|
226
|
+
{ get: () => expr.left, set: (v) => {
|
|
227
|
+
expr.left = v;
|
|
228
|
+
} },
|
|
229
|
+
{ get: () => expr.right, set: (v) => {
|
|
230
|
+
expr.right = v;
|
|
231
|
+
} }
|
|
232
|
+
];
|
|
212
233
|
case "UnaryExpression":
|
|
213
|
-
|
|
214
|
-
|
|
234
|
+
return [{ get: () => expr.argument, set: (v) => {
|
|
235
|
+
expr.argument = v;
|
|
236
|
+
} }];
|
|
215
237
|
case "MemberExpression":
|
|
216
|
-
|
|
217
|
-
|
|
238
|
+
return [{ get: () => expr.object, set: (v) => {
|
|
239
|
+
expr.object = v;
|
|
240
|
+
} }];
|
|
218
241
|
case "IndexExpression":
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
242
|
+
return [
|
|
243
|
+
{ get: () => expr.object, set: (v) => {
|
|
244
|
+
expr.object = v;
|
|
245
|
+
} },
|
|
246
|
+
{ get: () => expr.index, set: (v) => {
|
|
247
|
+
expr.index = v;
|
|
248
|
+
} }
|
|
249
|
+
];
|
|
250
|
+
case "CallExpression": {
|
|
251
|
+
const children = [
|
|
252
|
+
{ get: () => expr.callee, set: (v) => {
|
|
253
|
+
expr.callee = v;
|
|
254
|
+
} }
|
|
255
|
+
];
|
|
256
|
+
for (let i = 0; i < expr.arguments.length; i++) {
|
|
257
|
+
const idx = i;
|
|
258
|
+
children.push({
|
|
259
|
+
get: () => expr.arguments[idx],
|
|
260
|
+
set: (v) => {
|
|
261
|
+
expr.arguments[idx] = v;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
return children;
|
|
266
|
+
}
|
|
267
|
+
case "MethodCallExpression": {
|
|
268
|
+
const children = [
|
|
269
|
+
{ get: () => expr.object, set: (v) => {
|
|
270
|
+
expr.object = v;
|
|
271
|
+
} }
|
|
272
|
+
];
|
|
273
|
+
for (let i = 0; i < expr.arguments.length; i++) {
|
|
274
|
+
const idx = i;
|
|
275
|
+
children.push({
|
|
276
|
+
get: () => expr.arguments[idx],
|
|
277
|
+
set: (v) => {
|
|
278
|
+
expr.arguments[idx] = v;
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
return children;
|
|
283
|
+
}
|
|
230
284
|
case "ParenthesizedExpression":
|
|
231
|
-
|
|
232
|
-
|
|
285
|
+
return [{ get: () => expr.expression, set: (v) => {
|
|
286
|
+
expr.expression = v;
|
|
287
|
+
} }];
|
|
233
288
|
case "TypeAssertionExpression":
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
289
|
+
return [{ get: () => expr.expression, set: (v) => {
|
|
290
|
+
expr.expression = v;
|
|
291
|
+
} }];
|
|
292
|
+
case "IfElseExpression": {
|
|
293
|
+
const children = [];
|
|
237
294
|
for (const clause of expr.clauses) {
|
|
238
|
-
|
|
239
|
-
|
|
295
|
+
children.push({ get: () => clause.condition, set: (v) => {
|
|
296
|
+
clause.condition = v;
|
|
297
|
+
} });
|
|
298
|
+
children.push({ get: () => clause.body, set: (v) => {
|
|
299
|
+
clause.body = v;
|
|
300
|
+
} });
|
|
240
301
|
}
|
|
241
|
-
|
|
242
|
-
|
|
302
|
+
children.push({ get: () => expr.alternate, set: (v) => {
|
|
303
|
+
expr.alternate = v;
|
|
304
|
+
} });
|
|
305
|
+
return children;
|
|
306
|
+
}
|
|
307
|
+
default:
|
|
308
|
+
return [];
|
|
243
309
|
}
|
|
244
|
-
|
|
310
|
+
}
|
|
311
|
+
function mapExpression(root, visitor) {
|
|
312
|
+
if (root.type === "FunctionExpression") {
|
|
313
|
+
walkFunctionBody(root.func, visitor);
|
|
314
|
+
return visitor(root) ?? root;
|
|
315
|
+
}
|
|
316
|
+
let result = root;
|
|
317
|
+
const stack = [{
|
|
318
|
+
expr: root,
|
|
319
|
+
children: getExpressionChildren(root),
|
|
320
|
+
index: 0,
|
|
321
|
+
setInParent: (v) => {
|
|
322
|
+
result = v;
|
|
323
|
+
}
|
|
324
|
+
}];
|
|
325
|
+
while (stack.length > 0) {
|
|
326
|
+
const frame = stack[stack.length - 1];
|
|
327
|
+
if (frame.index < frame.children.length) {
|
|
328
|
+
const child = frame.children[frame.index];
|
|
329
|
+
frame.index++;
|
|
330
|
+
const childExpr = child.get();
|
|
331
|
+
if (childExpr.type === "FunctionExpression") {
|
|
332
|
+
walkFunctionBody(childExpr.func, visitor);
|
|
333
|
+
child.set(visitor(childExpr) ?? childExpr);
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
stack.push({
|
|
337
|
+
expr: childExpr,
|
|
338
|
+
children: getExpressionChildren(childExpr),
|
|
339
|
+
index: 0,
|
|
340
|
+
setInParent: child.set
|
|
341
|
+
});
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
const finished = visitor(frame.expr) ?? frame.expr;
|
|
345
|
+
frame.setInParent?.(finished);
|
|
346
|
+
stack.pop();
|
|
347
|
+
}
|
|
348
|
+
return result;
|
|
245
349
|
}
|
|
246
350
|
function walkFunctionBody(func, visitor) {
|
|
247
351
|
walkBlock(func.body, visitor);
|
|
@@ -327,6 +431,12 @@ function stringLiteral(value) {
|
|
|
327
431
|
function numberLiteral(value) {
|
|
328
432
|
return { type: "NumberLiteral", value, raw: String(value), line: POS, column: POS };
|
|
329
433
|
}
|
|
434
|
+
var vmStructuralNumbers = /* @__PURE__ */ new WeakSet();
|
|
435
|
+
function vmNumberLiteral(value) {
|
|
436
|
+
const node = numberLiteral(value);
|
|
437
|
+
vmStructuralNumbers.add(node);
|
|
438
|
+
return node;
|
|
439
|
+
}
|
|
330
440
|
function binary(operator, left, right) {
|
|
331
441
|
return { type: "BinaryExpression", operator, left, right, line: POS, column: POS };
|
|
332
442
|
}
|
|
@@ -459,11 +569,12 @@ function stringCharCall(bytes) {
|
|
|
459
569
|
return call(member(identifier("string"), "char"), bytes.map(numberLiteral));
|
|
460
570
|
}
|
|
461
571
|
function buildConcatChain(chunks) {
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
572
|
+
function build(lo, hi) {
|
|
573
|
+
if (hi - lo === 1) return stringCharCall(chunks[lo]);
|
|
574
|
+
const mid = lo + Math.floor((hi - lo) / 2);
|
|
575
|
+
return binary("..", build(lo, mid), build(mid, hi));
|
|
465
576
|
}
|
|
466
|
-
return
|
|
577
|
+
return build(0, chunks.length);
|
|
467
578
|
}
|
|
468
579
|
function shuffledIndices(n) {
|
|
469
580
|
const arr = Array.from({ length: n }, (_, i) => i);
|
|
@@ -555,12 +666,15 @@ function buildRecursiveStringExpr(chunks) {
|
|
|
555
666
|
function pickControlFlowStrategy() {
|
|
556
667
|
return Math.random() < 0.5 ? "forLoop" : "recursive";
|
|
557
668
|
}
|
|
669
|
+
var MAX_CHUNKS_PER_STRING = 2e4;
|
|
558
670
|
function runStringsToExpressions(program, options) {
|
|
559
671
|
const controlFlowProbability = options.controlFlowProbability ?? CONTROL_FLOW_PROBABILITY_DEFAULT;
|
|
560
672
|
transformExpressions(program, (expr) => {
|
|
561
673
|
if (expr.type !== "StringLiteral") return;
|
|
562
674
|
if (expr.value.length === 0) return;
|
|
563
675
|
const bytes = toUtf8Bytes(expr.value);
|
|
676
|
+
const estimatedChunks = Math.ceil(bytes.length / Math.max(1, options.min));
|
|
677
|
+
if (estimatedChunks > MAX_CHUNKS_PER_STRING) return;
|
|
564
678
|
const chunks = splitByteChunks(bytes, options.min, options.max);
|
|
565
679
|
if (chunks.length > 1 && Math.random() < controlFlowProbability) {
|
|
566
680
|
return pickControlFlowStrategy() === "forLoop" ? buildForLoopStringExpr(chunks) : buildRecursiveStringExpr(chunks);
|
|
@@ -733,6 +847,7 @@ function runNumbersToExpressions(program, options) {
|
|
|
733
847
|
const controlFlowProbability = options.controlFlowProbability ?? CONTROL_FLOW_PROBABILITY_DEFAULT2;
|
|
734
848
|
transformExpressions(program, (expr) => {
|
|
735
849
|
if (expr.type !== "NumberLiteral") return;
|
|
850
|
+
if (vmStructuralNumbers.has(expr)) return;
|
|
736
851
|
if (Number.isInteger(expr.value) && Math.random() < controlFlowProbability) {
|
|
737
852
|
return buildControlFlowNumberExpr(expr.value, options.min, options.max);
|
|
738
853
|
}
|
|
@@ -925,7 +1040,7 @@ function runConstantArray(program, options) {
|
|
|
925
1040
|
seen.add(k);
|
|
926
1041
|
order.push({ kind: "string", value: expr.value });
|
|
927
1042
|
}
|
|
928
|
-
} else if (expr.type === "NumberLiteral") {
|
|
1043
|
+
} else if (expr.type === "NumberLiteral" && !vmStructuralNumbers.has(expr)) {
|
|
929
1044
|
const k = keyOf("number", expr.value);
|
|
930
1045
|
if (!seen.has(k)) {
|
|
931
1046
|
seen.add(k);
|
|
@@ -945,11 +1060,11 @@ function runConstantArray(program, options) {
|
|
|
945
1060
|
transformExpressions(program, (expr) => {
|
|
946
1061
|
if (expr.type === "StringLiteral") {
|
|
947
1062
|
const idx = indexOf.get(keyOf("string", expr.value));
|
|
948
|
-
return index(identifier(arrayName),
|
|
1063
|
+
return index(identifier(arrayName), vmNumberLiteral(idx));
|
|
949
1064
|
}
|
|
950
|
-
if (expr.type === "NumberLiteral") {
|
|
1065
|
+
if (expr.type === "NumberLiteral" && !vmStructuralNumbers.has(expr)) {
|
|
951
1066
|
const idx = indexOf.get(keyOf("number", expr.value));
|
|
952
|
-
return index(identifier(arrayName),
|
|
1067
|
+
return index(identifier(arrayName), vmNumberLiteral(idx));
|
|
953
1068
|
}
|
|
954
1069
|
return void 0;
|
|
955
1070
|
});
|
|
@@ -990,15 +1105,15 @@ function obfuscatedNumber(value) {
|
|
|
990
1105
|
const variant = randomInt4(0, 2);
|
|
991
1106
|
if (variant === 0) {
|
|
992
1107
|
const a2 = randomInt4(0, value);
|
|
993
|
-
return binary("+",
|
|
1108
|
+
return binary("+", vmNumberLiteral(a2), vmNumberLiteral(value - a2));
|
|
994
1109
|
}
|
|
995
1110
|
if (variant === 1) {
|
|
996
1111
|
const a2 = randomInt4(0, 16777215);
|
|
997
|
-
return binary("-",
|
|
1112
|
+
return binary("-", vmNumberLiteral(value + a2), vmNumberLiteral(a2));
|
|
998
1113
|
}
|
|
999
1114
|
const a = randomInt4(0, 16777215);
|
|
1000
1115
|
const b = (value ^ a) >>> 0;
|
|
1001
|
-
return call(member(identifier("bit32"), "bxor"), [
|
|
1116
|
+
return call(member(identifier("bit32"), "bxor"), [vmNumberLiteral(a), vmNumberLiteral(b)]);
|
|
1002
1117
|
}
|
|
1003
1118
|
function buildDecoderStatement(name) {
|
|
1004
1119
|
const dataParam = randomName3();
|
|
@@ -1009,17 +1124,17 @@ function buildDecoderStatement(name) {
|
|
|
1009
1124
|
const nKeysVar = randomName3();
|
|
1010
1125
|
const idxExpr = binary(
|
|
1011
1126
|
"+",
|
|
1012
|
-
binary("%", binary("-", identifier(iVar),
|
|
1013
|
-
|
|
1127
|
+
binary("%", binary("-", identifier(iVar), vmNumberLiteral(1)), identifier(nKeysVar)),
|
|
1128
|
+
vmNumberLiteral(1)
|
|
1014
1129
|
);
|
|
1015
1130
|
const keyByte = index(identifier(keysParam), idxExpr);
|
|
1016
1131
|
const mixed = call(member(identifier("bit32"), "band"), [
|
|
1017
|
-
call(member(identifier("bit32"), "lrotate"), [keyByte, binary("%", identifier(iVar),
|
|
1018
|
-
|
|
1132
|
+
call(member(identifier("bit32"), "lrotate"), [keyByte, binary("%", identifier(iVar), vmNumberLiteral(8))]),
|
|
1133
|
+
vmNumberLiteral(255)
|
|
1019
1134
|
]);
|
|
1020
1135
|
const posByte = call(member(identifier("bit32"), "band"), [
|
|
1021
1136
|
binary("*", identifier(iVar), identifier(multParam)),
|
|
1022
|
-
|
|
1137
|
+
vmNumberLiteral(255)
|
|
1023
1138
|
]);
|
|
1024
1139
|
const keystream = call(member(identifier("bit32"), "bxor"), [mixed, posByte]);
|
|
1025
1140
|
const finalByte = call(member(identifier("bit32"), "bxor"), [
|
|
@@ -1031,7 +1146,7 @@ function buildDecoderStatement(name) {
|
|
|
1031
1146
|
localStatement(outVar, table([])),
|
|
1032
1147
|
numericForStatement(
|
|
1033
1148
|
iVar,
|
|
1034
|
-
|
|
1149
|
+
vmNumberLiteral(1),
|
|
1035
1150
|
unary("#", identifier(dataParam)),
|
|
1036
1151
|
block([
|
|
1037
1152
|
assignmentStatement(
|
|
@@ -1059,7 +1174,7 @@ function runEncryptStrings(program, _options) {
|
|
|
1059
1174
|
const mult = randomInt4(1, 255);
|
|
1060
1175
|
const plainBytes = toUtf8Bytes2(expr.value);
|
|
1061
1176
|
const cipherBytes = plainBytes.map((b, idx) => b ^ keystreamByte(keys, mult, idx + 1));
|
|
1062
|
-
const dataTable = table(cipherBytes.map((b) => positionalField(
|
|
1177
|
+
const dataTable = table(cipherBytes.map((b) => positionalField(vmNumberLiteral(b))));
|
|
1063
1178
|
const keysTable = table(keys.map((k) => positionalField(obfuscatedNumber(k))));
|
|
1064
1179
|
const multExpr = obfuscatedNumber(mult);
|
|
1065
1180
|
return call(identifier(decoderName), [dataTable, keysTable, multExpr]);
|
|
@@ -1126,6 +1241,7 @@ function runEncryptNumbers(program, _options) {
|
|
|
1126
1241
|
let used = false;
|
|
1127
1242
|
transformExpressions(program, (expr) => {
|
|
1128
1243
|
if (expr.type !== "NumberLiteral") return;
|
|
1244
|
+
if (vmStructuralNumbers.has(expr)) return;
|
|
1129
1245
|
if (!isEncryptable(expr.value)) return;
|
|
1130
1246
|
used = true;
|
|
1131
1247
|
const keyA = randomInt5(1, 16777215);
|
|
@@ -1376,16 +1492,18 @@ function createProto(id) {
|
|
|
1376
1492
|
maxRegs: 0,
|
|
1377
1493
|
code: [],
|
|
1378
1494
|
consts: [],
|
|
1495
|
+
constIndex: /* @__PURE__ */ new Map(),
|
|
1379
1496
|
upvalDescs: [],
|
|
1380
1497
|
protos: []
|
|
1381
1498
|
};
|
|
1382
1499
|
}
|
|
1383
1500
|
function internConst(proto, value) {
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
}
|
|
1501
|
+
const existing = proto.constIndex.get(value);
|
|
1502
|
+
if (existing !== void 0) return existing;
|
|
1387
1503
|
proto.consts.push(value);
|
|
1388
|
-
|
|
1504
|
+
const idx = proto.consts.length - 1;
|
|
1505
|
+
proto.constIndex.set(value, idx);
|
|
1506
|
+
return idx;
|
|
1389
1507
|
}
|
|
1390
1508
|
|
|
1391
1509
|
// src/passes/vmify/registers.ts
|
|
@@ -2557,13 +2675,13 @@ function serializeConstValue(v) {
|
|
|
2557
2675
|
if (typeof v === "number") return numberLiteral(v);
|
|
2558
2676
|
return booleanLiteral(v);
|
|
2559
2677
|
}
|
|
2560
|
-
function serializeInstrs(proto
|
|
2678
|
+
function serializeInstrs(proto) {
|
|
2561
2679
|
const fields = proto.code.map((instr) => positionalField(
|
|
2562
2680
|
table([
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2681
|
+
positionalField(vmNumberLiteral(instr.op)),
|
|
2682
|
+
positionalField(vmNumberLiteral(instr.a)),
|
|
2683
|
+
positionalField(vmNumberLiteral(instr.b)),
|
|
2684
|
+
positionalField(vmNumberLiteral(instr.c))
|
|
2567
2685
|
])
|
|
2568
2686
|
));
|
|
2569
2687
|
return table(fields);
|
|
@@ -2572,17 +2690,17 @@ function serializeUpvalDescs(proto, names) {
|
|
|
2572
2690
|
const fields = proto.upvalDescs.map((d) => positionalField(
|
|
2573
2691
|
table([
|
|
2574
2692
|
namedField(names.kind, stringLiteral(d.kind)),
|
|
2575
|
-
namedField(names.index,
|
|
2693
|
+
namedField(names.index, vmNumberLiteral(d.index))
|
|
2576
2694
|
])
|
|
2577
2695
|
));
|
|
2578
2696
|
return table(fields);
|
|
2579
2697
|
}
|
|
2580
2698
|
function serializeProto(proto, names) {
|
|
2581
2699
|
const fields = [
|
|
2582
|
-
namedField(names.numParams,
|
|
2700
|
+
namedField(names.numParams, vmNumberLiteral(proto.numParams)),
|
|
2583
2701
|
namedField(names.hasVarargs, booleanLiteral(proto.hasVarargs)),
|
|
2584
|
-
namedField(names.maxRegs,
|
|
2585
|
-
namedField(names.code, serializeInstrs(proto
|
|
2702
|
+
namedField(names.maxRegs, vmNumberLiteral(proto.maxRegs)),
|
|
2703
|
+
namedField(names.code, serializeInstrs(proto)),
|
|
2586
2704
|
namedField(names.consts, serializeConsts(proto.consts)),
|
|
2587
2705
|
namedField(names.upvalDescs, serializeUpvalDescs(proto, names)),
|
|
2588
2706
|
namedField(names.protos, table(proto.protos.map((p) => positionalField(serializeProto(p, names)))))
|
|
@@ -2599,7 +2717,7 @@ local ${N.handlers} = {}
|
|
|
2599
2717
|
|
|
2600
2718
|
local function ${N.dispatch}(${N.frame}, pc)
|
|
2601
2719
|
local instr = ${N.frame}.${N.code}[pc]
|
|
2602
|
-
return ${N.handlers}[instr
|
|
2720
|
+
return ${N.handlers}[instr[1]](${N.frame}, pc, instr)
|
|
2603
2721
|
end
|
|
2604
2722
|
|
|
2605
2723
|
local function ${N.rk}(${N.frame}, x)
|
|
@@ -2612,156 +2730,156 @@ end
|
|
|
2612
2730
|
|
|
2613
2731
|
-- MOVE
|
|
2614
2732
|
${N.handlers}[${op(0 /* MOVE */)}] = function(${N.frame}, pc, instr)
|
|
2615
|
-
${N.frame}.${N.R}[instr
|
|
2733
|
+
${N.frame}.${N.R}[instr[2]] = ${N.frame}.${N.R}[instr[3]]
|
|
2616
2734
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2617
2735
|
end
|
|
2618
2736
|
|
|
2619
2737
|
-- LOADK
|
|
2620
2738
|
${N.handlers}[${op(1 /* LOADK */)}] = function(${N.frame}, pc, instr)
|
|
2621
|
-
${N.frame}.${N.R}[instr
|
|
2739
|
+
${N.frame}.${N.R}[instr[2]] = ${N.frame}.${N.K}[instr[3] + 1]
|
|
2622
2740
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2623
2741
|
end
|
|
2624
2742
|
|
|
2625
2743
|
-- LOADBOOL
|
|
2626
2744
|
${N.handlers}[${op(2 /* LOADBOOL */)}] = function(${N.frame}, pc, instr)
|
|
2627
|
-
${N.frame}.${N.R}[instr
|
|
2745
|
+
${N.frame}.${N.R}[instr[2]] = (instr[3] ~= 0)
|
|
2628
2746
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2629
2747
|
end
|
|
2630
2748
|
|
|
2631
2749
|
-- LOADNIL
|
|
2632
2750
|
${N.handlers}[${op(3 /* LOADNIL */)}] = function(${N.frame}, pc, instr)
|
|
2633
|
-
for i = instr
|
|
2751
|
+
for i = instr[2], instr[3] do ${N.frame}.${N.R}[i] = nil end
|
|
2634
2752
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2635
2753
|
end
|
|
2636
2754
|
|
|
2637
2755
|
-- GETUPVAL
|
|
2638
2756
|
${N.handlers}[${op(4 /* GETUPVAL */)}] = function(${N.frame}, pc, instr)
|
|
2639
|
-
${N.frame}.${N.R}[instr
|
|
2757
|
+
${N.frame}.${N.R}[instr[2]] = ${N.frame}.${N.upvals}[instr[3] + 1]
|
|
2640
2758
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2641
2759
|
end
|
|
2642
2760
|
|
|
2643
2761
|
-- SETUPVAL
|
|
2644
2762
|
${N.handlers}[${op(5 /* SETUPVAL */)}] = function(${N.frame}, pc, instr)
|
|
2645
|
-
${N.frame}.${N.upvals}[instr
|
|
2763
|
+
${N.frame}.${N.upvals}[instr[3] + 1] = ${N.frame}.${N.R}[instr[2]]
|
|
2646
2764
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2647
2765
|
end
|
|
2648
2766
|
|
|
2649
2767
|
-- GETGLOBAL (b\uB294 RK\uAC00 \uC544\uB2C8\uB77C \uC0C1\uC218\uD480 \uC21C\uC218 \uC778\uB371\uC2A4)
|
|
2650
2768
|
${N.handlers}[${op(6 /* GETGLOBAL */)}] = function(${N.frame}, pc, instr)
|
|
2651
|
-
${N.frame}.${N.R}[instr
|
|
2769
|
+
${N.frame}.${N.R}[instr[2]] = ${N.globals}[${N.frame}.${N.K}[instr[3] + 1]]
|
|
2652
2770
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2653
2771
|
end
|
|
2654
2772
|
|
|
2655
2773
|
-- SETGLOBAL
|
|
2656
2774
|
${N.handlers}[${op(7 /* SETGLOBAL */)}] = function(${N.frame}, pc, instr)
|
|
2657
|
-
${N.globals}[${N.frame}.${N.K}[instr
|
|
2775
|
+
${N.globals}[${N.frame}.${N.K}[instr[3] + 1]] = ${N.frame}.${N.R}[instr[2]]
|
|
2658
2776
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2659
2777
|
end
|
|
2660
2778
|
|
|
2661
2779
|
-- GETTABLE
|
|
2662
2780
|
${N.handlers}[${op(8 /* GETTABLE */)}] = function(${N.frame}, pc, instr)
|
|
2663
|
-
${N.frame}.${N.R}[instr
|
|
2781
|
+
${N.frame}.${N.R}[instr[2]] = ${N.frame}.${N.R}[instr[3]][${N.rk}(${N.frame}, instr[4])]
|
|
2664
2782
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2665
2783
|
end
|
|
2666
2784
|
|
|
2667
2785
|
-- SETTABLE
|
|
2668
2786
|
${N.handlers}[${op(9 /* SETTABLE */)}] = function(${N.frame}, pc, instr)
|
|
2669
|
-
${N.frame}.${N.R}[instr
|
|
2787
|
+
${N.frame}.${N.R}[instr[2]][${N.rk}(${N.frame}, instr[3])] = ${N.rk}(${N.frame}, instr[4])
|
|
2670
2788
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2671
2789
|
end
|
|
2672
2790
|
|
|
2673
2791
|
-- NEWTABLE
|
|
2674
2792
|
${N.handlers}[${op(10 /* NEWTABLE */)}] = function(${N.frame}, pc, instr)
|
|
2675
|
-
${N.frame}.${N.R}[instr
|
|
2793
|
+
${N.frame}.${N.R}[instr[2]] = {}
|
|
2676
2794
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2677
2795
|
end
|
|
2678
2796
|
|
|
2679
2797
|
-- SELF (R[a] = R[b][key]; R[a+1] = R[b])
|
|
2680
2798
|
${N.handlers}[${op(11 /* SELF */)}] = function(${N.frame}, pc, instr)
|
|
2681
|
-
local obj = ${N.frame}.${N.R}[instr
|
|
2682
|
-
${N.frame}.${N.R}[instr
|
|
2683
|
-
${N.frame}.${N.R}[instr
|
|
2799
|
+
local obj = ${N.frame}.${N.R}[instr[3]]
|
|
2800
|
+
${N.frame}.${N.R}[instr[2]] = obj[${N.rk}(${N.frame}, instr[4])]
|
|
2801
|
+
${N.frame}.${N.R}[instr[2] + 1] = obj
|
|
2684
2802
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2685
2803
|
end
|
|
2686
2804
|
|
|
2687
2805
|
-- ADD SUB MUL DIV MOD POW
|
|
2688
2806
|
${N.handlers}[${op(12 /* ADD */)}] = function(${N.frame}, pc, instr)
|
|
2689
|
-
${N.frame}.${N.R}[instr
|
|
2807
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) + ${N.rk}(${N.frame}, instr[4])
|
|
2690
2808
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2691
2809
|
end
|
|
2692
2810
|
${N.handlers}[${op(13 /* SUB */)}] = function(${N.frame}, pc, instr)
|
|
2693
|
-
${N.frame}.${N.R}[instr
|
|
2811
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) - ${N.rk}(${N.frame}, instr[4])
|
|
2694
2812
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2695
2813
|
end
|
|
2696
2814
|
${N.handlers}[${op(14 /* MUL */)}] = function(${N.frame}, pc, instr)
|
|
2697
|
-
${N.frame}.${N.R}[instr
|
|
2815
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) * ${N.rk}(${N.frame}, instr[4])
|
|
2698
2816
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2699
2817
|
end
|
|
2700
2818
|
${N.handlers}[${op(15 /* DIV */)}] = function(${N.frame}, pc, instr)
|
|
2701
|
-
${N.frame}.${N.R}[instr
|
|
2819
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) / ${N.rk}(${N.frame}, instr[4])
|
|
2702
2820
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2703
2821
|
end
|
|
2704
2822
|
${N.handlers}[${op(16 /* MOD */)}] = function(${N.frame}, pc, instr)
|
|
2705
|
-
${N.frame}.${N.R}[instr
|
|
2823
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) % ${N.rk}(${N.frame}, instr[4])
|
|
2706
2824
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2707
2825
|
end
|
|
2708
2826
|
${N.handlers}[${op(17 /* POW */)}] = function(${N.frame}, pc, instr)
|
|
2709
|
-
${N.frame}.${N.R}[instr
|
|
2827
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) ^ ${N.rk}(${N.frame}, instr[4])
|
|
2710
2828
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2711
2829
|
end
|
|
2712
2830
|
|
|
2713
2831
|
-- IDIV (Luau \uBC14\uB2E5 \uB098\uB217\uC148)
|
|
2714
2832
|
${N.handlers}[${op(34 /* IDIV */)}] = function(${N.frame}, pc, instr)
|
|
2715
|
-
${N.frame}.${N.R}[instr
|
|
2833
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) // ${N.rk}(${N.frame}, instr[4])
|
|
2716
2834
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2717
2835
|
end
|
|
2718
2836
|
|
|
2719
2837
|
-- CONCAT
|
|
2720
2838
|
${N.handlers}[${op(18 /* CONCAT */)}] = function(${N.frame}, pc, instr)
|
|
2721
|
-
${N.frame}.${N.R}[instr
|
|
2839
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) .. ${N.rk}(${N.frame}, instr[4])
|
|
2722
2840
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2723
2841
|
end
|
|
2724
2842
|
|
|
2725
2843
|
-- UNM
|
|
2726
2844
|
${N.handlers}[${op(19 /* UNM */)}] = function(${N.frame}, pc, instr)
|
|
2727
|
-
${N.frame}.${N.R}[instr
|
|
2845
|
+
${N.frame}.${N.R}[instr[2]] = -${N.frame}.${N.R}[instr[3]]
|
|
2728
2846
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2729
2847
|
end
|
|
2730
2848
|
|
|
2731
2849
|
-- NOT
|
|
2732
2850
|
${N.handlers}[${op(20 /* NOT */)}] = function(${N.frame}, pc, instr)
|
|
2733
|
-
${N.frame}.${N.R}[instr
|
|
2851
|
+
${N.frame}.${N.R}[instr[2]] = not ${N.frame}.${N.R}[instr[3]]
|
|
2734
2852
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2735
2853
|
end
|
|
2736
2854
|
|
|
2737
2855
|
-- LEN
|
|
2738
2856
|
${N.handlers}[${op(21 /* LEN */)}] = function(${N.frame}, pc, instr)
|
|
2739
|
-
${N.frame}.${N.R}[instr
|
|
2857
|
+
${N.frame}.${N.R}[instr[2]] = #${N.frame}.${N.R}[instr[3]]
|
|
2740
2858
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2741
2859
|
end
|
|
2742
2860
|
|
|
2743
2861
|
-- JMP (pc += a)
|
|
2744
2862
|
${N.handlers}[${op(22 /* JMP */)}] = function(${N.frame}, pc, instr)
|
|
2745
|
-
return ${N.dispatch}(${N.frame}, pc + instr
|
|
2863
|
+
return ${N.dispatch}(${N.frame}, pc + instr[2])
|
|
2746
2864
|
end
|
|
2747
2865
|
|
|
2748
2866
|
-- EQ LT LE (\uAC12 \uC0DD\uC131\uD615 \uBE44\uAD50)
|
|
2749
2867
|
${N.handlers}[${op(23 /* EQ */)}] = function(${N.frame}, pc, instr)
|
|
2750
|
-
${N.frame}.${N.R}[instr
|
|
2868
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) == ${N.rk}(${N.frame}, instr[4])
|
|
2751
2869
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2752
2870
|
end
|
|
2753
2871
|
${N.handlers}[${op(24 /* LT */)}] = function(${N.frame}, pc, instr)
|
|
2754
|
-
${N.frame}.${N.R}[instr
|
|
2872
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) < ${N.rk}(${N.frame}, instr[4])
|
|
2755
2873
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2756
2874
|
end
|
|
2757
2875
|
${N.handlers}[${op(25 /* LE */)}] = function(${N.frame}, pc, instr)
|
|
2758
|
-
${N.frame}.${N.R}[instr
|
|
2876
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) <= ${N.rk}(${N.frame}, instr[4])
|
|
2759
2877
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2760
2878
|
end
|
|
2761
2879
|
|
|
2762
2880
|
-- TEST (if (not R[a]) != (c!=0) then pc += 2 else pc += 1 \u2014 \uBCF4\uD1B5 \uB2E4\uC74C \uBA85\uB839\uC740 JMP)
|
|
2763
2881
|
${N.handlers}[${op(26 /* TEST */)}] = function(${N.frame}, pc, instr)
|
|
2764
|
-
if (not ${N.frame}.${N.R}[instr
|
|
2882
|
+
if (not ${N.frame}.${N.R}[instr[2]]) ~= (instr[4] ~= 0) then
|
|
2765
2883
|
return ${N.dispatch}(${N.frame}, pc + 2)
|
|
2766
2884
|
end
|
|
2767
2885
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
@@ -2769,7 +2887,7 @@ end
|
|
|
2769
2887
|
|
|
2770
2888
|
-- CALL
|
|
2771
2889
|
${N.handlers}[${op(27 /* CALL */)}] = function(${N.frame}, pc, instr)
|
|
2772
|
-
local a, b, c = instr
|
|
2890
|
+
local a, b, c = instr[2], instr[3], instr[4]
|
|
2773
2891
|
local fn = ${N.frame}.${N.R}[a]
|
|
2774
2892
|
local nargs
|
|
2775
2893
|
if b == 0 then
|
|
@@ -2794,7 +2912,7 @@ end
|
|
|
2794
2912
|
|
|
2795
2913
|
-- RETURN
|
|
2796
2914
|
${N.handlers}[${op(28 /* RETURN */)}] = function(${N.frame}, pc, instr)
|
|
2797
|
-
local a, b = instr
|
|
2915
|
+
local a, b = instr[2], instr[3]
|
|
2798
2916
|
if b == 0 then
|
|
2799
2917
|
return table.unpack(${N.frame}.${N.R}, a, (${N.frame}.${N.multiTop} or (a + 1)) - 1)
|
|
2800
2918
|
end
|
|
@@ -2803,14 +2921,14 @@ end
|
|
|
2803
2921
|
|
|
2804
2922
|
-- FORPREP
|
|
2805
2923
|
${N.handlers}[${op(29 /* FORPREP */)}] = function(${N.frame}, pc, instr)
|
|
2806
|
-
local a = instr
|
|
2924
|
+
local a = instr[2]
|
|
2807
2925
|
${N.frame}.${N.R}[a] = ${N.frame}.${N.R}[a] - ${N.frame}.${N.R}[a + 2]
|
|
2808
|
-
return ${N.dispatch}(${N.frame}, pc + instr
|
|
2926
|
+
return ${N.dispatch}(${N.frame}, pc + instr[3])
|
|
2809
2927
|
end
|
|
2810
2928
|
|
|
2811
2929
|
-- FORLOOP
|
|
2812
2930
|
${N.handlers}[${op(30 /* FORLOOP */)}] = function(${N.frame}, pc, instr)
|
|
2813
|
-
local a = instr
|
|
2931
|
+
local a = instr[2]
|
|
2814
2932
|
local step = ${N.frame}.${N.R}[a + 2]
|
|
2815
2933
|
${N.frame}.${N.R}[a] = ${N.frame}.${N.R}[a] + step
|
|
2816
2934
|
local ok
|
|
@@ -2821,26 +2939,26 @@ ${N.handlers}[${op(30 /* FORLOOP */)}] = function(${N.frame}, pc, instr)
|
|
|
2821
2939
|
end
|
|
2822
2940
|
if ok then
|
|
2823
2941
|
${N.frame}.${N.R}[a + 3] = ${N.frame}.${N.R}[a]
|
|
2824
|
-
return ${N.dispatch}(${N.frame}, pc + instr
|
|
2942
|
+
return ${N.dispatch}(${N.frame}, pc + instr[3])
|
|
2825
2943
|
end
|
|
2826
2944
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2827
2945
|
end
|
|
2828
2946
|
|
|
2829
2947
|
-- CLOSURE
|
|
2830
2948
|
${N.handlers}[${op(31 /* CLOSURE */)}] = function(${N.frame}, pc, instr)
|
|
2831
|
-
local childProto = ${N.frame}.${N.protos}[instr
|
|
2949
|
+
local childProto = ${N.frame}.${N.protos}[instr[3] + 1]
|
|
2832
2950
|
local n = #childProto.${N.upvalDescs}
|
|
2833
2951
|
local capturedUpvals = table.create(n)
|
|
2834
2952
|
for i = 1, n do
|
|
2835
2953
|
local desc = childProto.${N.upvalDescs}[i]
|
|
2836
2954
|
local captureInstr = ${N.frame}.${N.code}[pc + i]
|
|
2837
2955
|
if desc.${N.kind} == "local" then
|
|
2838
|
-
capturedUpvals[i] = ${N.frame}.${N.R}[captureInstr
|
|
2956
|
+
capturedUpvals[i] = ${N.frame}.${N.R}[captureInstr[3]]
|
|
2839
2957
|
else
|
|
2840
|
-
capturedUpvals[i] = ${N.frame}.${N.upvals}[captureInstr
|
|
2958
|
+
capturedUpvals[i] = ${N.frame}.${N.upvals}[captureInstr[3] + 1]
|
|
2841
2959
|
end
|
|
2842
2960
|
end
|
|
2843
|
-
${N.frame}.${N.R}[instr
|
|
2961
|
+
${N.frame}.${N.R}[instr[2]] = function(...)
|
|
2844
2962
|
return ${N.execute}(childProto, capturedUpvals, ...)
|
|
2845
2963
|
end
|
|
2846
2964
|
return ${N.dispatch}(${N.frame}, pc + 1 + n)
|
|
@@ -2848,22 +2966,22 @@ end
|
|
|
2848
2966
|
|
|
2849
2967
|
-- VARARG
|
|
2850
2968
|
${N.handlers}[${op(32 /* VARARG */)}] = function(${N.frame}, pc, instr)
|
|
2851
|
-
local count = instr
|
|
2969
|
+
local count = instr[3] == 0 and ${N.frame}.${N.nVarargs} or (instr[3] - 1)
|
|
2852
2970
|
for i = 1, count do
|
|
2853
|
-
${N.frame}.${N.R}[instr
|
|
2971
|
+
${N.frame}.${N.R}[instr[2] + i - 1] = ${N.frame}.${N.varargs}[i]
|
|
2854
2972
|
end
|
|
2855
|
-
if instr
|
|
2856
|
-
${N.frame}.${N.multiTop} = instr
|
|
2973
|
+
if instr[3] == 0 then
|
|
2974
|
+
${N.frame}.${N.multiTop} = instr[2] + count
|
|
2857
2975
|
end
|
|
2858
2976
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2859
2977
|
end
|
|
2860
2978
|
|
|
2861
2979
|
-- SETLIST
|
|
2862
2980
|
${N.handlers}[${op(33 /* SETLIST */)}] = function(${N.frame}, pc, instr)
|
|
2863
|
-
local tbl = ${N.frame}.${N.R}[instr
|
|
2864
|
-
local valuesBase = instr
|
|
2981
|
+
local tbl = ${N.frame}.${N.R}[instr[2]]
|
|
2982
|
+
local valuesBase = instr[3]
|
|
2865
2983
|
local top = ${N.frame}.${N.multiTop} or (valuesBase + 1)
|
|
2866
|
-
local startIdx = instr
|
|
2984
|
+
local startIdx = instr[4]
|
|
2867
2985
|
local n = top - valuesBase
|
|
2868
2986
|
for i = 0, n - 1 do
|
|
2869
2987
|
tbl[startIdx + i] = ${N.frame}.${N.R}[valuesBase + i]
|
|
@@ -2937,10 +3055,6 @@ function generateVmNames(random = Math.random) {
|
|
|
2937
3055
|
varargs: id(),
|
|
2938
3056
|
nVarargs: id(),
|
|
2939
3057
|
multiTop: id(),
|
|
2940
|
-
op: id(),
|
|
2941
|
-
a: id(),
|
|
2942
|
-
b: id(),
|
|
2943
|
-
c: id(),
|
|
2944
3058
|
numParams: id(),
|
|
2945
3059
|
hasVarargs: id(),
|
|
2946
3060
|
maxRegs: id(),
|
|
@@ -2952,6 +3066,12 @@ function generateVmNames(random = Math.random) {
|
|
|
2952
3066
|
}
|
|
2953
3067
|
|
|
2954
3068
|
// src/passes/Vmify.ts
|
|
3069
|
+
function markRuntimeNumbersAsStructural(body) {
|
|
3070
|
+
transformExpressions({ body }, (expr) => {
|
|
3071
|
+
if (expr.type === "NumberLiteral") vmStructuralNumbers.add(expr);
|
|
3072
|
+
return void 0;
|
|
3073
|
+
});
|
|
3074
|
+
}
|
|
2955
3075
|
function runVmify(program, options) {
|
|
2956
3076
|
const globalNames = options.builtinGlobals ?? DEFAULT_BUILTIN_GLOBALS;
|
|
2957
3077
|
const random = options.random ?? Math.random;
|
|
@@ -2965,6 +3085,7 @@ function runVmify(program, options) {
|
|
|
2965
3085
|
const runtimeSource = buildVmRuntimeSource(names, opcodeMap);
|
|
2966
3086
|
const runtimeProgram = luauparser2.parse(runtimeSource);
|
|
2967
3087
|
const runtimeStatements = runtimeProgram.body.statements;
|
|
3088
|
+
markRuntimeNumbersAsStructural(runtimeProgram.body);
|
|
2968
3089
|
const protoLiteral = serializeProto(topProto, names);
|
|
2969
3090
|
const newBody = [
|
|
2970
3091
|
localStatement(names.globals, globalsTable),
|
|
@@ -2979,10 +3100,10 @@ function runVmify(program, options) {
|
|
|
2979
3100
|
var PASS_ORDER = [
|
|
2980
3101
|
"Vmify",
|
|
2981
3102
|
"GlobalMapping",
|
|
2982
|
-
"StringsToExpressions",
|
|
2983
|
-
"NumbersToExpressions",
|
|
2984
3103
|
"RenameVariables",
|
|
2985
3104
|
"ConstantArray",
|
|
3105
|
+
"StringsToExpressions",
|
|
3106
|
+
"NumbersToExpressions",
|
|
2986
3107
|
"EncryptStrings",
|
|
2987
3108
|
"EncryptNumbers",
|
|
2988
3109
|
"InsertJunk",
|