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.cjs
CHANGED
|
@@ -209,67 +209,171 @@ function visitArray(arr, visitor) {
|
|
|
209
209
|
arr[i] = mapExpression(arr[i], visitor);
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
|
-
function
|
|
212
|
+
function getExpressionChildren(expr) {
|
|
213
213
|
switch (expr.type) {
|
|
214
|
-
case "InterpolatedStringExpression":
|
|
214
|
+
case "InterpolatedStringExpression": {
|
|
215
|
+
const children = [];
|
|
215
216
|
for (const part of expr.parts) {
|
|
216
217
|
if (part.kind === "expression") {
|
|
217
|
-
|
|
218
|
+
children.push({
|
|
219
|
+
get: () => part.expression,
|
|
220
|
+
set: (v) => {
|
|
221
|
+
part.expression = v;
|
|
222
|
+
}
|
|
223
|
+
});
|
|
218
224
|
}
|
|
219
225
|
}
|
|
220
|
-
|
|
226
|
+
return children;
|
|
227
|
+
}
|
|
221
228
|
case "FunctionExpression":
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
229
|
+
return [];
|
|
230
|
+
case "TableExpression": {
|
|
231
|
+
const children = [];
|
|
225
232
|
for (const field of expr.fields) {
|
|
226
233
|
if (field.type === "TableFieldPositional") {
|
|
227
|
-
|
|
234
|
+
children.push({ get: () => field.value, set: (v) => {
|
|
235
|
+
field.value = v;
|
|
236
|
+
} });
|
|
228
237
|
} else if (field.type === "TableFieldNamed") {
|
|
229
|
-
|
|
238
|
+
children.push({ get: () => field.value, set: (v) => {
|
|
239
|
+
field.value = v;
|
|
240
|
+
} });
|
|
230
241
|
} else if (field.type === "TableFieldComputed") {
|
|
231
|
-
|
|
232
|
-
|
|
242
|
+
children.push({ get: () => field.key, set: (v) => {
|
|
243
|
+
field.key = v;
|
|
244
|
+
} });
|
|
245
|
+
children.push({ get: () => field.value, set: (v) => {
|
|
246
|
+
field.value = v;
|
|
247
|
+
} });
|
|
233
248
|
}
|
|
234
249
|
}
|
|
235
|
-
|
|
250
|
+
return children;
|
|
251
|
+
}
|
|
236
252
|
case "BinaryExpression":
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
253
|
+
return [
|
|
254
|
+
{ get: () => expr.left, set: (v) => {
|
|
255
|
+
expr.left = v;
|
|
256
|
+
} },
|
|
257
|
+
{ get: () => expr.right, set: (v) => {
|
|
258
|
+
expr.right = v;
|
|
259
|
+
} }
|
|
260
|
+
];
|
|
240
261
|
case "UnaryExpression":
|
|
241
|
-
|
|
242
|
-
|
|
262
|
+
return [{ get: () => expr.argument, set: (v) => {
|
|
263
|
+
expr.argument = v;
|
|
264
|
+
} }];
|
|
243
265
|
case "MemberExpression":
|
|
244
|
-
|
|
245
|
-
|
|
266
|
+
return [{ get: () => expr.object, set: (v) => {
|
|
267
|
+
expr.object = v;
|
|
268
|
+
} }];
|
|
246
269
|
case "IndexExpression":
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
270
|
+
return [
|
|
271
|
+
{ get: () => expr.object, set: (v) => {
|
|
272
|
+
expr.object = v;
|
|
273
|
+
} },
|
|
274
|
+
{ get: () => expr.index, set: (v) => {
|
|
275
|
+
expr.index = v;
|
|
276
|
+
} }
|
|
277
|
+
];
|
|
278
|
+
case "CallExpression": {
|
|
279
|
+
const children = [
|
|
280
|
+
{ get: () => expr.callee, set: (v) => {
|
|
281
|
+
expr.callee = v;
|
|
282
|
+
} }
|
|
283
|
+
];
|
|
284
|
+
for (let i = 0; i < expr.arguments.length; i++) {
|
|
285
|
+
const idx = i;
|
|
286
|
+
children.push({
|
|
287
|
+
get: () => expr.arguments[idx],
|
|
288
|
+
set: (v) => {
|
|
289
|
+
expr.arguments[idx] = v;
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
return children;
|
|
294
|
+
}
|
|
295
|
+
case "MethodCallExpression": {
|
|
296
|
+
const children = [
|
|
297
|
+
{ get: () => expr.object, set: (v) => {
|
|
298
|
+
expr.object = v;
|
|
299
|
+
} }
|
|
300
|
+
];
|
|
301
|
+
for (let i = 0; i < expr.arguments.length; i++) {
|
|
302
|
+
const idx = i;
|
|
303
|
+
children.push({
|
|
304
|
+
get: () => expr.arguments[idx],
|
|
305
|
+
set: (v) => {
|
|
306
|
+
expr.arguments[idx] = v;
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
return children;
|
|
311
|
+
}
|
|
258
312
|
case "ParenthesizedExpression":
|
|
259
|
-
|
|
260
|
-
|
|
313
|
+
return [{ get: () => expr.expression, set: (v) => {
|
|
314
|
+
expr.expression = v;
|
|
315
|
+
} }];
|
|
261
316
|
case "TypeAssertionExpression":
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
317
|
+
return [{ get: () => expr.expression, set: (v) => {
|
|
318
|
+
expr.expression = v;
|
|
319
|
+
} }];
|
|
320
|
+
case "IfElseExpression": {
|
|
321
|
+
const children = [];
|
|
265
322
|
for (const clause of expr.clauses) {
|
|
266
|
-
|
|
267
|
-
|
|
323
|
+
children.push({ get: () => clause.condition, set: (v) => {
|
|
324
|
+
clause.condition = v;
|
|
325
|
+
} });
|
|
326
|
+
children.push({ get: () => clause.body, set: (v) => {
|
|
327
|
+
clause.body = v;
|
|
328
|
+
} });
|
|
268
329
|
}
|
|
269
|
-
|
|
270
|
-
|
|
330
|
+
children.push({ get: () => expr.alternate, set: (v) => {
|
|
331
|
+
expr.alternate = v;
|
|
332
|
+
} });
|
|
333
|
+
return children;
|
|
334
|
+
}
|
|
335
|
+
default:
|
|
336
|
+
return [];
|
|
271
337
|
}
|
|
272
|
-
|
|
338
|
+
}
|
|
339
|
+
function mapExpression(root, visitor) {
|
|
340
|
+
if (root.type === "FunctionExpression") {
|
|
341
|
+
walkFunctionBody(root.func, visitor);
|
|
342
|
+
return visitor(root) ?? root;
|
|
343
|
+
}
|
|
344
|
+
let result = root;
|
|
345
|
+
const stack = [{
|
|
346
|
+
expr: root,
|
|
347
|
+
children: getExpressionChildren(root),
|
|
348
|
+
index: 0,
|
|
349
|
+
setInParent: (v) => {
|
|
350
|
+
result = v;
|
|
351
|
+
}
|
|
352
|
+
}];
|
|
353
|
+
while (stack.length > 0) {
|
|
354
|
+
const frame = stack[stack.length - 1];
|
|
355
|
+
if (frame.index < frame.children.length) {
|
|
356
|
+
const child = frame.children[frame.index];
|
|
357
|
+
frame.index++;
|
|
358
|
+
const childExpr = child.get();
|
|
359
|
+
if (childExpr.type === "FunctionExpression") {
|
|
360
|
+
walkFunctionBody(childExpr.func, visitor);
|
|
361
|
+
child.set(visitor(childExpr) ?? childExpr);
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
stack.push({
|
|
365
|
+
expr: childExpr,
|
|
366
|
+
children: getExpressionChildren(childExpr),
|
|
367
|
+
index: 0,
|
|
368
|
+
setInParent: child.set
|
|
369
|
+
});
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
const finished = visitor(frame.expr) ?? frame.expr;
|
|
373
|
+
frame.setInParent?.(finished);
|
|
374
|
+
stack.pop();
|
|
375
|
+
}
|
|
376
|
+
return result;
|
|
273
377
|
}
|
|
274
378
|
function walkFunctionBody(func, visitor) {
|
|
275
379
|
walkBlock(func.body, visitor);
|
|
@@ -355,6 +459,12 @@ function stringLiteral(value) {
|
|
|
355
459
|
function numberLiteral(value) {
|
|
356
460
|
return { type: "NumberLiteral", value, raw: String(value), line: POS, column: POS };
|
|
357
461
|
}
|
|
462
|
+
var vmStructuralNumbers = /* @__PURE__ */ new WeakSet();
|
|
463
|
+
function vmNumberLiteral(value) {
|
|
464
|
+
const node = numberLiteral(value);
|
|
465
|
+
vmStructuralNumbers.add(node);
|
|
466
|
+
return node;
|
|
467
|
+
}
|
|
358
468
|
function binary(operator, left, right) {
|
|
359
469
|
return { type: "BinaryExpression", operator, left, right, line: POS, column: POS };
|
|
360
470
|
}
|
|
@@ -487,11 +597,12 @@ function stringCharCall(bytes) {
|
|
|
487
597
|
return call(member(identifier("string"), "char"), bytes.map(numberLiteral));
|
|
488
598
|
}
|
|
489
599
|
function buildConcatChain(chunks) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
600
|
+
function build(lo, hi) {
|
|
601
|
+
if (hi - lo === 1) return stringCharCall(chunks[lo]);
|
|
602
|
+
const mid = lo + Math.floor((hi - lo) / 2);
|
|
603
|
+
return binary("..", build(lo, mid), build(mid, hi));
|
|
493
604
|
}
|
|
494
|
-
return
|
|
605
|
+
return build(0, chunks.length);
|
|
495
606
|
}
|
|
496
607
|
function shuffledIndices(n) {
|
|
497
608
|
const arr = Array.from({ length: n }, (_, i) => i);
|
|
@@ -583,12 +694,15 @@ function buildRecursiveStringExpr(chunks) {
|
|
|
583
694
|
function pickControlFlowStrategy() {
|
|
584
695
|
return Math.random() < 0.5 ? "forLoop" : "recursive";
|
|
585
696
|
}
|
|
697
|
+
var MAX_CHUNKS_PER_STRING = 2e4;
|
|
586
698
|
function runStringsToExpressions(program, options) {
|
|
587
699
|
const controlFlowProbability = options.controlFlowProbability ?? CONTROL_FLOW_PROBABILITY_DEFAULT;
|
|
588
700
|
transformExpressions(program, (expr) => {
|
|
589
701
|
if (expr.type !== "StringLiteral") return;
|
|
590
702
|
if (expr.value.length === 0) return;
|
|
591
703
|
const bytes = toUtf8Bytes(expr.value);
|
|
704
|
+
const estimatedChunks = Math.ceil(bytes.length / Math.max(1, options.min));
|
|
705
|
+
if (estimatedChunks > MAX_CHUNKS_PER_STRING) return;
|
|
592
706
|
const chunks = splitByteChunks(bytes, options.min, options.max);
|
|
593
707
|
if (chunks.length > 1 && Math.random() < controlFlowProbability) {
|
|
594
708
|
return pickControlFlowStrategy() === "forLoop" ? buildForLoopStringExpr(chunks) : buildRecursiveStringExpr(chunks);
|
|
@@ -761,6 +875,7 @@ function runNumbersToExpressions(program, options) {
|
|
|
761
875
|
const controlFlowProbability = options.controlFlowProbability ?? CONTROL_FLOW_PROBABILITY_DEFAULT2;
|
|
762
876
|
transformExpressions(program, (expr) => {
|
|
763
877
|
if (expr.type !== "NumberLiteral") return;
|
|
878
|
+
if (vmStructuralNumbers.has(expr)) return;
|
|
764
879
|
if (Number.isInteger(expr.value) && Math.random() < controlFlowProbability) {
|
|
765
880
|
return buildControlFlowNumberExpr(expr.value, options.min, options.max);
|
|
766
881
|
}
|
|
@@ -953,7 +1068,7 @@ function runConstantArray(program, options) {
|
|
|
953
1068
|
seen.add(k);
|
|
954
1069
|
order.push({ kind: "string", value: expr.value });
|
|
955
1070
|
}
|
|
956
|
-
} else if (expr.type === "NumberLiteral") {
|
|
1071
|
+
} else if (expr.type === "NumberLiteral" && !vmStructuralNumbers.has(expr)) {
|
|
957
1072
|
const k = keyOf("number", expr.value);
|
|
958
1073
|
if (!seen.has(k)) {
|
|
959
1074
|
seen.add(k);
|
|
@@ -973,11 +1088,11 @@ function runConstantArray(program, options) {
|
|
|
973
1088
|
transformExpressions(program, (expr) => {
|
|
974
1089
|
if (expr.type === "StringLiteral") {
|
|
975
1090
|
const idx = indexOf.get(keyOf("string", expr.value));
|
|
976
|
-
return index(identifier(arrayName),
|
|
1091
|
+
return index(identifier(arrayName), vmNumberLiteral(idx));
|
|
977
1092
|
}
|
|
978
|
-
if (expr.type === "NumberLiteral") {
|
|
1093
|
+
if (expr.type === "NumberLiteral" && !vmStructuralNumbers.has(expr)) {
|
|
979
1094
|
const idx = indexOf.get(keyOf("number", expr.value));
|
|
980
|
-
return index(identifier(arrayName),
|
|
1095
|
+
return index(identifier(arrayName), vmNumberLiteral(idx));
|
|
981
1096
|
}
|
|
982
1097
|
return void 0;
|
|
983
1098
|
});
|
|
@@ -1018,15 +1133,15 @@ function obfuscatedNumber(value) {
|
|
|
1018
1133
|
const variant = randomInt4(0, 2);
|
|
1019
1134
|
if (variant === 0) {
|
|
1020
1135
|
const a2 = randomInt4(0, value);
|
|
1021
|
-
return binary("+",
|
|
1136
|
+
return binary("+", vmNumberLiteral(a2), vmNumberLiteral(value - a2));
|
|
1022
1137
|
}
|
|
1023
1138
|
if (variant === 1) {
|
|
1024
1139
|
const a2 = randomInt4(0, 16777215);
|
|
1025
|
-
return binary("-",
|
|
1140
|
+
return binary("-", vmNumberLiteral(value + a2), vmNumberLiteral(a2));
|
|
1026
1141
|
}
|
|
1027
1142
|
const a = randomInt4(0, 16777215);
|
|
1028
1143
|
const b = (value ^ a) >>> 0;
|
|
1029
|
-
return call(member(identifier("bit32"), "bxor"), [
|
|
1144
|
+
return call(member(identifier("bit32"), "bxor"), [vmNumberLiteral(a), vmNumberLiteral(b)]);
|
|
1030
1145
|
}
|
|
1031
1146
|
function buildDecoderStatement(name) {
|
|
1032
1147
|
const dataParam = randomName3();
|
|
@@ -1037,17 +1152,17 @@ function buildDecoderStatement(name) {
|
|
|
1037
1152
|
const nKeysVar = randomName3();
|
|
1038
1153
|
const idxExpr = binary(
|
|
1039
1154
|
"+",
|
|
1040
|
-
binary("%", binary("-", identifier(iVar),
|
|
1041
|
-
|
|
1155
|
+
binary("%", binary("-", identifier(iVar), vmNumberLiteral(1)), identifier(nKeysVar)),
|
|
1156
|
+
vmNumberLiteral(1)
|
|
1042
1157
|
);
|
|
1043
1158
|
const keyByte = index(identifier(keysParam), idxExpr);
|
|
1044
1159
|
const mixed = call(member(identifier("bit32"), "band"), [
|
|
1045
|
-
call(member(identifier("bit32"), "lrotate"), [keyByte, binary("%", identifier(iVar),
|
|
1046
|
-
|
|
1160
|
+
call(member(identifier("bit32"), "lrotate"), [keyByte, binary("%", identifier(iVar), vmNumberLiteral(8))]),
|
|
1161
|
+
vmNumberLiteral(255)
|
|
1047
1162
|
]);
|
|
1048
1163
|
const posByte = call(member(identifier("bit32"), "band"), [
|
|
1049
1164
|
binary("*", identifier(iVar), identifier(multParam)),
|
|
1050
|
-
|
|
1165
|
+
vmNumberLiteral(255)
|
|
1051
1166
|
]);
|
|
1052
1167
|
const keystream = call(member(identifier("bit32"), "bxor"), [mixed, posByte]);
|
|
1053
1168
|
const finalByte = call(member(identifier("bit32"), "bxor"), [
|
|
@@ -1059,7 +1174,7 @@ function buildDecoderStatement(name) {
|
|
|
1059
1174
|
localStatement(outVar, table([])),
|
|
1060
1175
|
numericForStatement(
|
|
1061
1176
|
iVar,
|
|
1062
|
-
|
|
1177
|
+
vmNumberLiteral(1),
|
|
1063
1178
|
unary("#", identifier(dataParam)),
|
|
1064
1179
|
block([
|
|
1065
1180
|
assignmentStatement(
|
|
@@ -1087,7 +1202,7 @@ function runEncryptStrings(program, _options) {
|
|
|
1087
1202
|
const mult = randomInt4(1, 255);
|
|
1088
1203
|
const plainBytes = toUtf8Bytes2(expr.value);
|
|
1089
1204
|
const cipherBytes = plainBytes.map((b, idx) => b ^ keystreamByte(keys, mult, idx + 1));
|
|
1090
|
-
const dataTable = table(cipherBytes.map((b) => positionalField(
|
|
1205
|
+
const dataTable = table(cipherBytes.map((b) => positionalField(vmNumberLiteral(b))));
|
|
1091
1206
|
const keysTable = table(keys.map((k) => positionalField(obfuscatedNumber(k))));
|
|
1092
1207
|
const multExpr = obfuscatedNumber(mult);
|
|
1093
1208
|
return call(identifier(decoderName), [dataTable, keysTable, multExpr]);
|
|
@@ -1154,6 +1269,7 @@ function runEncryptNumbers(program, _options) {
|
|
|
1154
1269
|
let used = false;
|
|
1155
1270
|
transformExpressions(program, (expr) => {
|
|
1156
1271
|
if (expr.type !== "NumberLiteral") return;
|
|
1272
|
+
if (vmStructuralNumbers.has(expr)) return;
|
|
1157
1273
|
if (!isEncryptable(expr.value)) return;
|
|
1158
1274
|
used = true;
|
|
1159
1275
|
const keyA = randomInt5(1, 16777215);
|
|
@@ -1404,16 +1520,18 @@ function createProto(id) {
|
|
|
1404
1520
|
maxRegs: 0,
|
|
1405
1521
|
code: [],
|
|
1406
1522
|
consts: [],
|
|
1523
|
+
constIndex: /* @__PURE__ */ new Map(),
|
|
1407
1524
|
upvalDescs: [],
|
|
1408
1525
|
protos: []
|
|
1409
1526
|
};
|
|
1410
1527
|
}
|
|
1411
1528
|
function internConst(proto, value) {
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
}
|
|
1529
|
+
const existing = proto.constIndex.get(value);
|
|
1530
|
+
if (existing !== void 0) return existing;
|
|
1415
1531
|
proto.consts.push(value);
|
|
1416
|
-
|
|
1532
|
+
const idx = proto.consts.length - 1;
|
|
1533
|
+
proto.constIndex.set(value, idx);
|
|
1534
|
+
return idx;
|
|
1417
1535
|
}
|
|
1418
1536
|
|
|
1419
1537
|
// src/passes/vmify/registers.ts
|
|
@@ -2585,13 +2703,13 @@ function serializeConstValue(v) {
|
|
|
2585
2703
|
if (typeof v === "number") return numberLiteral(v);
|
|
2586
2704
|
return booleanLiteral(v);
|
|
2587
2705
|
}
|
|
2588
|
-
function serializeInstrs(proto
|
|
2706
|
+
function serializeInstrs(proto) {
|
|
2589
2707
|
const fields = proto.code.map((instr) => positionalField(
|
|
2590
2708
|
table([
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2709
|
+
positionalField(vmNumberLiteral(instr.op)),
|
|
2710
|
+
positionalField(vmNumberLiteral(instr.a)),
|
|
2711
|
+
positionalField(vmNumberLiteral(instr.b)),
|
|
2712
|
+
positionalField(vmNumberLiteral(instr.c))
|
|
2595
2713
|
])
|
|
2596
2714
|
));
|
|
2597
2715
|
return table(fields);
|
|
@@ -2600,17 +2718,17 @@ function serializeUpvalDescs(proto, names) {
|
|
|
2600
2718
|
const fields = proto.upvalDescs.map((d) => positionalField(
|
|
2601
2719
|
table([
|
|
2602
2720
|
namedField(names.kind, stringLiteral(d.kind)),
|
|
2603
|
-
namedField(names.index,
|
|
2721
|
+
namedField(names.index, vmNumberLiteral(d.index))
|
|
2604
2722
|
])
|
|
2605
2723
|
));
|
|
2606
2724
|
return table(fields);
|
|
2607
2725
|
}
|
|
2608
2726
|
function serializeProto(proto, names) {
|
|
2609
2727
|
const fields = [
|
|
2610
|
-
namedField(names.numParams,
|
|
2728
|
+
namedField(names.numParams, vmNumberLiteral(proto.numParams)),
|
|
2611
2729
|
namedField(names.hasVarargs, booleanLiteral(proto.hasVarargs)),
|
|
2612
|
-
namedField(names.maxRegs,
|
|
2613
|
-
namedField(names.code, serializeInstrs(proto
|
|
2730
|
+
namedField(names.maxRegs, vmNumberLiteral(proto.maxRegs)),
|
|
2731
|
+
namedField(names.code, serializeInstrs(proto)),
|
|
2614
2732
|
namedField(names.consts, serializeConsts(proto.consts)),
|
|
2615
2733
|
namedField(names.upvalDescs, serializeUpvalDescs(proto, names)),
|
|
2616
2734
|
namedField(names.protos, table(proto.protos.map((p) => positionalField(serializeProto(p, names)))))
|
|
@@ -2627,7 +2745,7 @@ local ${N.handlers} = {}
|
|
|
2627
2745
|
|
|
2628
2746
|
local function ${N.dispatch}(${N.frame}, pc)
|
|
2629
2747
|
local instr = ${N.frame}.${N.code}[pc]
|
|
2630
|
-
return ${N.handlers}[instr
|
|
2748
|
+
return ${N.handlers}[instr[1]](${N.frame}, pc, instr)
|
|
2631
2749
|
end
|
|
2632
2750
|
|
|
2633
2751
|
local function ${N.rk}(${N.frame}, x)
|
|
@@ -2640,156 +2758,156 @@ end
|
|
|
2640
2758
|
|
|
2641
2759
|
-- MOVE
|
|
2642
2760
|
${N.handlers}[${op(0 /* MOVE */)}] = function(${N.frame}, pc, instr)
|
|
2643
|
-
${N.frame}.${N.R}[instr
|
|
2761
|
+
${N.frame}.${N.R}[instr[2]] = ${N.frame}.${N.R}[instr[3]]
|
|
2644
2762
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2645
2763
|
end
|
|
2646
2764
|
|
|
2647
2765
|
-- LOADK
|
|
2648
2766
|
${N.handlers}[${op(1 /* LOADK */)}] = function(${N.frame}, pc, instr)
|
|
2649
|
-
${N.frame}.${N.R}[instr
|
|
2767
|
+
${N.frame}.${N.R}[instr[2]] = ${N.frame}.${N.K}[instr[3] + 1]
|
|
2650
2768
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2651
2769
|
end
|
|
2652
2770
|
|
|
2653
2771
|
-- LOADBOOL
|
|
2654
2772
|
${N.handlers}[${op(2 /* LOADBOOL */)}] = function(${N.frame}, pc, instr)
|
|
2655
|
-
${N.frame}.${N.R}[instr
|
|
2773
|
+
${N.frame}.${N.R}[instr[2]] = (instr[3] ~= 0)
|
|
2656
2774
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2657
2775
|
end
|
|
2658
2776
|
|
|
2659
2777
|
-- LOADNIL
|
|
2660
2778
|
${N.handlers}[${op(3 /* LOADNIL */)}] = function(${N.frame}, pc, instr)
|
|
2661
|
-
for i = instr
|
|
2779
|
+
for i = instr[2], instr[3] do ${N.frame}.${N.R}[i] = nil end
|
|
2662
2780
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2663
2781
|
end
|
|
2664
2782
|
|
|
2665
2783
|
-- GETUPVAL
|
|
2666
2784
|
${N.handlers}[${op(4 /* GETUPVAL */)}] = function(${N.frame}, pc, instr)
|
|
2667
|
-
${N.frame}.${N.R}[instr
|
|
2785
|
+
${N.frame}.${N.R}[instr[2]] = ${N.frame}.${N.upvals}[instr[3] + 1]
|
|
2668
2786
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2669
2787
|
end
|
|
2670
2788
|
|
|
2671
2789
|
-- SETUPVAL
|
|
2672
2790
|
${N.handlers}[${op(5 /* SETUPVAL */)}] = function(${N.frame}, pc, instr)
|
|
2673
|
-
${N.frame}.${N.upvals}[instr
|
|
2791
|
+
${N.frame}.${N.upvals}[instr[3] + 1] = ${N.frame}.${N.R}[instr[2]]
|
|
2674
2792
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2675
2793
|
end
|
|
2676
2794
|
|
|
2677
2795
|
-- GETGLOBAL (b\uB294 RK\uAC00 \uC544\uB2C8\uB77C \uC0C1\uC218\uD480 \uC21C\uC218 \uC778\uB371\uC2A4)
|
|
2678
2796
|
${N.handlers}[${op(6 /* GETGLOBAL */)}] = function(${N.frame}, pc, instr)
|
|
2679
|
-
${N.frame}.${N.R}[instr
|
|
2797
|
+
${N.frame}.${N.R}[instr[2]] = ${N.globals}[${N.frame}.${N.K}[instr[3] + 1]]
|
|
2680
2798
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2681
2799
|
end
|
|
2682
2800
|
|
|
2683
2801
|
-- SETGLOBAL
|
|
2684
2802
|
${N.handlers}[${op(7 /* SETGLOBAL */)}] = function(${N.frame}, pc, instr)
|
|
2685
|
-
${N.globals}[${N.frame}.${N.K}[instr
|
|
2803
|
+
${N.globals}[${N.frame}.${N.K}[instr[3] + 1]] = ${N.frame}.${N.R}[instr[2]]
|
|
2686
2804
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2687
2805
|
end
|
|
2688
2806
|
|
|
2689
2807
|
-- GETTABLE
|
|
2690
2808
|
${N.handlers}[${op(8 /* GETTABLE */)}] = function(${N.frame}, pc, instr)
|
|
2691
|
-
${N.frame}.${N.R}[instr
|
|
2809
|
+
${N.frame}.${N.R}[instr[2]] = ${N.frame}.${N.R}[instr[3]][${N.rk}(${N.frame}, instr[4])]
|
|
2692
2810
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2693
2811
|
end
|
|
2694
2812
|
|
|
2695
2813
|
-- SETTABLE
|
|
2696
2814
|
${N.handlers}[${op(9 /* SETTABLE */)}] = 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
|
|
|
2701
2819
|
-- NEWTABLE
|
|
2702
2820
|
${N.handlers}[${op(10 /* NEWTABLE */)}] = function(${N.frame}, pc, instr)
|
|
2703
|
-
${N.frame}.${N.R}[instr
|
|
2821
|
+
${N.frame}.${N.R}[instr[2]] = {}
|
|
2704
2822
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2705
2823
|
end
|
|
2706
2824
|
|
|
2707
2825
|
-- SELF (R[a] = R[b][key]; R[a+1] = R[b])
|
|
2708
2826
|
${N.handlers}[${op(11 /* SELF */)}] = function(${N.frame}, pc, instr)
|
|
2709
|
-
local obj = ${N.frame}.${N.R}[instr
|
|
2710
|
-
${N.frame}.${N.R}[instr
|
|
2711
|
-
${N.frame}.${N.R}[instr
|
|
2827
|
+
local obj = ${N.frame}.${N.R}[instr[3]]
|
|
2828
|
+
${N.frame}.${N.R}[instr[2]] = obj[${N.rk}(${N.frame}, instr[4])]
|
|
2829
|
+
${N.frame}.${N.R}[instr[2] + 1] = obj
|
|
2712
2830
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2713
2831
|
end
|
|
2714
2832
|
|
|
2715
2833
|
-- ADD SUB MUL DIV MOD POW
|
|
2716
2834
|
${N.handlers}[${op(12 /* ADD */)}] = function(${N.frame}, pc, instr)
|
|
2717
|
-
${N.frame}.${N.R}[instr
|
|
2835
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) + ${N.rk}(${N.frame}, instr[4])
|
|
2718
2836
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2719
2837
|
end
|
|
2720
2838
|
${N.handlers}[${op(13 /* SUB */)}] = 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
|
${N.handlers}[${op(14 /* MUL */)}] = function(${N.frame}, pc, instr)
|
|
2725
|
-
${N.frame}.${N.R}[instr
|
|
2843
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) * ${N.rk}(${N.frame}, instr[4])
|
|
2726
2844
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2727
2845
|
end
|
|
2728
2846
|
${N.handlers}[${op(15 /* DIV */)}] = function(${N.frame}, pc, instr)
|
|
2729
|
-
${N.frame}.${N.R}[instr
|
|
2847
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) / ${N.rk}(${N.frame}, instr[4])
|
|
2730
2848
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2731
2849
|
end
|
|
2732
2850
|
${N.handlers}[${op(16 /* MOD */)}] = function(${N.frame}, pc, instr)
|
|
2733
|
-
${N.frame}.${N.R}[instr
|
|
2851
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) % ${N.rk}(${N.frame}, instr[4])
|
|
2734
2852
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2735
2853
|
end
|
|
2736
2854
|
${N.handlers}[${op(17 /* POW */)}] = function(${N.frame}, pc, instr)
|
|
2737
|
-
${N.frame}.${N.R}[instr
|
|
2855
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) ^ ${N.rk}(${N.frame}, instr[4])
|
|
2738
2856
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2739
2857
|
end
|
|
2740
2858
|
|
|
2741
2859
|
-- IDIV (Luau \uBC14\uB2E5 \uB098\uB217\uC148)
|
|
2742
2860
|
${N.handlers}[${op(34 /* IDIV */)}] = function(${N.frame}, pc, instr)
|
|
2743
|
-
${N.frame}.${N.R}[instr
|
|
2861
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) // ${N.rk}(${N.frame}, instr[4])
|
|
2744
2862
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2745
2863
|
end
|
|
2746
2864
|
|
|
2747
2865
|
-- CONCAT
|
|
2748
2866
|
${N.handlers}[${op(18 /* CONCAT */)}] = function(${N.frame}, pc, instr)
|
|
2749
|
-
${N.frame}.${N.R}[instr
|
|
2867
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) .. ${N.rk}(${N.frame}, instr[4])
|
|
2750
2868
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2751
2869
|
end
|
|
2752
2870
|
|
|
2753
2871
|
-- UNM
|
|
2754
2872
|
${N.handlers}[${op(19 /* UNM */)}] = function(${N.frame}, pc, instr)
|
|
2755
|
-
${N.frame}.${N.R}[instr
|
|
2873
|
+
${N.frame}.${N.R}[instr[2]] = -${N.frame}.${N.R}[instr[3]]
|
|
2756
2874
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2757
2875
|
end
|
|
2758
2876
|
|
|
2759
2877
|
-- NOT
|
|
2760
2878
|
${N.handlers}[${op(20 /* NOT */)}] = function(${N.frame}, pc, instr)
|
|
2761
|
-
${N.frame}.${N.R}[instr
|
|
2879
|
+
${N.frame}.${N.R}[instr[2]] = not ${N.frame}.${N.R}[instr[3]]
|
|
2762
2880
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2763
2881
|
end
|
|
2764
2882
|
|
|
2765
2883
|
-- LEN
|
|
2766
2884
|
${N.handlers}[${op(21 /* LEN */)}] = function(${N.frame}, pc, instr)
|
|
2767
|
-
${N.frame}.${N.R}[instr
|
|
2885
|
+
${N.frame}.${N.R}[instr[2]] = #${N.frame}.${N.R}[instr[3]]
|
|
2768
2886
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2769
2887
|
end
|
|
2770
2888
|
|
|
2771
2889
|
-- JMP (pc += a)
|
|
2772
2890
|
${N.handlers}[${op(22 /* JMP */)}] = function(${N.frame}, pc, instr)
|
|
2773
|
-
return ${N.dispatch}(${N.frame}, pc + instr
|
|
2891
|
+
return ${N.dispatch}(${N.frame}, pc + instr[2])
|
|
2774
2892
|
end
|
|
2775
2893
|
|
|
2776
2894
|
-- EQ LT LE (\uAC12 \uC0DD\uC131\uD615 \uBE44\uAD50)
|
|
2777
2895
|
${N.handlers}[${op(23 /* EQ */)}] = function(${N.frame}, pc, instr)
|
|
2778
|
-
${N.frame}.${N.R}[instr
|
|
2896
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) == ${N.rk}(${N.frame}, instr[4])
|
|
2779
2897
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2780
2898
|
end
|
|
2781
2899
|
${N.handlers}[${op(24 /* LT */)}] = function(${N.frame}, pc, instr)
|
|
2782
|
-
${N.frame}.${N.R}[instr
|
|
2900
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) < ${N.rk}(${N.frame}, instr[4])
|
|
2783
2901
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2784
2902
|
end
|
|
2785
2903
|
${N.handlers}[${op(25 /* LE */)}] = function(${N.frame}, pc, instr)
|
|
2786
|
-
${N.frame}.${N.R}[instr
|
|
2904
|
+
${N.frame}.${N.R}[instr[2]] = ${N.rk}(${N.frame}, instr[3]) <= ${N.rk}(${N.frame}, instr[4])
|
|
2787
2905
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2788
2906
|
end
|
|
2789
2907
|
|
|
2790
2908
|
-- TEST (if (not R[a]) != (c!=0) then pc += 2 else pc += 1 \u2014 \uBCF4\uD1B5 \uB2E4\uC74C \uBA85\uB839\uC740 JMP)
|
|
2791
2909
|
${N.handlers}[${op(26 /* TEST */)}] = function(${N.frame}, pc, instr)
|
|
2792
|
-
if (not ${N.frame}.${N.R}[instr
|
|
2910
|
+
if (not ${N.frame}.${N.R}[instr[2]]) ~= (instr[4] ~= 0) then
|
|
2793
2911
|
return ${N.dispatch}(${N.frame}, pc + 2)
|
|
2794
2912
|
end
|
|
2795
2913
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
@@ -2797,7 +2915,7 @@ end
|
|
|
2797
2915
|
|
|
2798
2916
|
-- CALL
|
|
2799
2917
|
${N.handlers}[${op(27 /* CALL */)}] = function(${N.frame}, pc, instr)
|
|
2800
|
-
local a, b, c = instr
|
|
2918
|
+
local a, b, c = instr[2], instr[3], instr[4]
|
|
2801
2919
|
local fn = ${N.frame}.${N.R}[a]
|
|
2802
2920
|
local nargs
|
|
2803
2921
|
if b == 0 then
|
|
@@ -2822,7 +2940,7 @@ end
|
|
|
2822
2940
|
|
|
2823
2941
|
-- RETURN
|
|
2824
2942
|
${N.handlers}[${op(28 /* RETURN */)}] = function(${N.frame}, pc, instr)
|
|
2825
|
-
local a, b = instr
|
|
2943
|
+
local a, b = instr[2], instr[3]
|
|
2826
2944
|
if b == 0 then
|
|
2827
2945
|
return table.unpack(${N.frame}.${N.R}, a, (${N.frame}.${N.multiTop} or (a + 1)) - 1)
|
|
2828
2946
|
end
|
|
@@ -2831,14 +2949,14 @@ end
|
|
|
2831
2949
|
|
|
2832
2950
|
-- FORPREP
|
|
2833
2951
|
${N.handlers}[${op(29 /* FORPREP */)}] = function(${N.frame}, pc, instr)
|
|
2834
|
-
local a = instr
|
|
2952
|
+
local a = instr[2]
|
|
2835
2953
|
${N.frame}.${N.R}[a] = ${N.frame}.${N.R}[a] - ${N.frame}.${N.R}[a + 2]
|
|
2836
|
-
return ${N.dispatch}(${N.frame}, pc + instr
|
|
2954
|
+
return ${N.dispatch}(${N.frame}, pc + instr[3])
|
|
2837
2955
|
end
|
|
2838
2956
|
|
|
2839
2957
|
-- FORLOOP
|
|
2840
2958
|
${N.handlers}[${op(30 /* FORLOOP */)}] = function(${N.frame}, pc, instr)
|
|
2841
|
-
local a = instr
|
|
2959
|
+
local a = instr[2]
|
|
2842
2960
|
local step = ${N.frame}.${N.R}[a + 2]
|
|
2843
2961
|
${N.frame}.${N.R}[a] = ${N.frame}.${N.R}[a] + step
|
|
2844
2962
|
local ok
|
|
@@ -2849,26 +2967,26 @@ ${N.handlers}[${op(30 /* FORLOOP */)}] = function(${N.frame}, pc, instr)
|
|
|
2849
2967
|
end
|
|
2850
2968
|
if ok then
|
|
2851
2969
|
${N.frame}.${N.R}[a + 3] = ${N.frame}.${N.R}[a]
|
|
2852
|
-
return ${N.dispatch}(${N.frame}, pc + instr
|
|
2970
|
+
return ${N.dispatch}(${N.frame}, pc + instr[3])
|
|
2853
2971
|
end
|
|
2854
2972
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2855
2973
|
end
|
|
2856
2974
|
|
|
2857
2975
|
-- CLOSURE
|
|
2858
2976
|
${N.handlers}[${op(31 /* CLOSURE */)}] = function(${N.frame}, pc, instr)
|
|
2859
|
-
local childProto = ${N.frame}.${N.protos}[instr
|
|
2977
|
+
local childProto = ${N.frame}.${N.protos}[instr[3] + 1]
|
|
2860
2978
|
local n = #childProto.${N.upvalDescs}
|
|
2861
2979
|
local capturedUpvals = table.create(n)
|
|
2862
2980
|
for i = 1, n do
|
|
2863
2981
|
local desc = childProto.${N.upvalDescs}[i]
|
|
2864
2982
|
local captureInstr = ${N.frame}.${N.code}[pc + i]
|
|
2865
2983
|
if desc.${N.kind} == "local" then
|
|
2866
|
-
capturedUpvals[i] = ${N.frame}.${N.R}[captureInstr
|
|
2984
|
+
capturedUpvals[i] = ${N.frame}.${N.R}[captureInstr[3]]
|
|
2867
2985
|
else
|
|
2868
|
-
capturedUpvals[i] = ${N.frame}.${N.upvals}[captureInstr
|
|
2986
|
+
capturedUpvals[i] = ${N.frame}.${N.upvals}[captureInstr[3] + 1]
|
|
2869
2987
|
end
|
|
2870
2988
|
end
|
|
2871
|
-
${N.frame}.${N.R}[instr
|
|
2989
|
+
${N.frame}.${N.R}[instr[2]] = function(...)
|
|
2872
2990
|
return ${N.execute}(childProto, capturedUpvals, ...)
|
|
2873
2991
|
end
|
|
2874
2992
|
return ${N.dispatch}(${N.frame}, pc + 1 + n)
|
|
@@ -2876,22 +2994,22 @@ end
|
|
|
2876
2994
|
|
|
2877
2995
|
-- VARARG
|
|
2878
2996
|
${N.handlers}[${op(32 /* VARARG */)}] = function(${N.frame}, pc, instr)
|
|
2879
|
-
local count = instr
|
|
2997
|
+
local count = instr[3] == 0 and ${N.frame}.${N.nVarargs} or (instr[3] - 1)
|
|
2880
2998
|
for i = 1, count do
|
|
2881
|
-
${N.frame}.${N.R}[instr
|
|
2999
|
+
${N.frame}.${N.R}[instr[2] + i - 1] = ${N.frame}.${N.varargs}[i]
|
|
2882
3000
|
end
|
|
2883
|
-
if instr
|
|
2884
|
-
${N.frame}.${N.multiTop} = instr
|
|
3001
|
+
if instr[3] == 0 then
|
|
3002
|
+
${N.frame}.${N.multiTop} = instr[2] + count
|
|
2885
3003
|
end
|
|
2886
3004
|
return ${N.dispatch}(${N.frame}, pc + 1)
|
|
2887
3005
|
end
|
|
2888
3006
|
|
|
2889
3007
|
-- SETLIST
|
|
2890
3008
|
${N.handlers}[${op(33 /* SETLIST */)}] = function(${N.frame}, pc, instr)
|
|
2891
|
-
local tbl = ${N.frame}.${N.R}[instr
|
|
2892
|
-
local valuesBase = instr
|
|
3009
|
+
local tbl = ${N.frame}.${N.R}[instr[2]]
|
|
3010
|
+
local valuesBase = instr[3]
|
|
2893
3011
|
local top = ${N.frame}.${N.multiTop} or (valuesBase + 1)
|
|
2894
|
-
local startIdx = instr
|
|
3012
|
+
local startIdx = instr[4]
|
|
2895
3013
|
local n = top - valuesBase
|
|
2896
3014
|
for i = 0, n - 1 do
|
|
2897
3015
|
tbl[startIdx + i] = ${N.frame}.${N.R}[valuesBase + i]
|
|
@@ -2965,10 +3083,6 @@ function generateVmNames(random = Math.random) {
|
|
|
2965
3083
|
varargs: id(),
|
|
2966
3084
|
nVarargs: id(),
|
|
2967
3085
|
multiTop: id(),
|
|
2968
|
-
op: id(),
|
|
2969
|
-
a: id(),
|
|
2970
|
-
b: id(),
|
|
2971
|
-
c: id(),
|
|
2972
3086
|
numParams: id(),
|
|
2973
3087
|
hasVarargs: id(),
|
|
2974
3088
|
maxRegs: id(),
|
|
@@ -2980,6 +3094,12 @@ function generateVmNames(random = Math.random) {
|
|
|
2980
3094
|
}
|
|
2981
3095
|
|
|
2982
3096
|
// src/passes/Vmify.ts
|
|
3097
|
+
function markRuntimeNumbersAsStructural(body) {
|
|
3098
|
+
transformExpressions({ body }, (expr) => {
|
|
3099
|
+
if (expr.type === "NumberLiteral") vmStructuralNumbers.add(expr);
|
|
3100
|
+
return void 0;
|
|
3101
|
+
});
|
|
3102
|
+
}
|
|
2983
3103
|
function runVmify(program, options) {
|
|
2984
3104
|
const globalNames = options.builtinGlobals ?? DEFAULT_BUILTIN_GLOBALS;
|
|
2985
3105
|
const random = options.random ?? Math.random;
|
|
@@ -2993,6 +3113,7 @@ function runVmify(program, options) {
|
|
|
2993
3113
|
const runtimeSource = buildVmRuntimeSource(names, opcodeMap);
|
|
2994
3114
|
const runtimeProgram = import_luau_parser4.luauparser.parse(runtimeSource);
|
|
2995
3115
|
const runtimeStatements = runtimeProgram.body.statements;
|
|
3116
|
+
markRuntimeNumbersAsStructural(runtimeProgram.body);
|
|
2996
3117
|
const protoLiteral = serializeProto(topProto, names);
|
|
2997
3118
|
const newBody = [
|
|
2998
3119
|
localStatement(names.globals, globalsTable),
|
|
@@ -3007,10 +3128,10 @@ function runVmify(program, options) {
|
|
|
3007
3128
|
var PASS_ORDER = [
|
|
3008
3129
|
"Vmify",
|
|
3009
3130
|
"GlobalMapping",
|
|
3010
|
-
"StringsToExpressions",
|
|
3011
|
-
"NumbersToExpressions",
|
|
3012
3131
|
"RenameVariables",
|
|
3013
3132
|
"ConstantArray",
|
|
3133
|
+
"StringsToExpressions",
|
|
3134
|
+
"NumbersToExpressions",
|
|
3014
3135
|
"EncryptStrings",
|
|
3015
3136
|
"EncryptNumbers",
|
|
3016
3137
|
"InsertJunk",
|