luau-obfuscator 1.0.0 → 1.0.1

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.
@@ -1,32 +1,32 @@
1
- import type { Program } from "luau-parser"
2
- import {
3
- block, functionBody, functionExpression, paren, call, vararg, returnStatement,
4
- } from "./nodeFactory"
5
-
6
- export interface WrapInFunctionOptions {}
7
-
8
- /**
9
- * 전체 프로그램을:
10
- * return (function(...)
11
- * <원래 코드>
12
- * end)(...)
13
- * 로 감쌈.
14
- *
15
- * - `return`을 쓰는 이유: Script/LocalScript에서는 top-level return이 그냥 청크를
16
- * 조기 종료시킬 뿐 무해하고, ModuleScript라면 IIFE의 결과값이 그대로 require()
17
- * 호출자에게 전달돼야 하므로 필요함. 즉 스크립트 종류를 가리지 않고 안전.
18
- * - `...`을 파라미터로 받아서 다시 그대로 넘겨주는 이유: 원본 청크가 최상위에서
19
- * `...`(스크립트 인자)을 참조하는 경우를 대비. 그냥 지워버리면 그런 코드가
20
- * 깨짐.
21
- *
22
- * 반드시 파이프라인 맨 마지막 근처에서 실행돼야 함 — 이 패스 이후에 실행되는
23
- * 다른 패스가 top-level 스코프를 순회/변형한다면 이미 감싸인 함수 내부까지
24
- * 안 보고 지나칠 수 있음.
25
- */
26
- export function runWrapInFunction(program: Program, _options: WrapInFunctionOptions): void {
27
- const innerBody = program.body
28
- const wrapper = functionExpression(functionBody([], innerBody, true))
29
- const iife = call(paren(wrapper), [vararg()])
30
-
31
- program.body = block([returnStatement([iife])])
1
+ import type { Program } from "luau-parser"
2
+ import {
3
+ block, functionBody, functionExpression, paren, call, vararg, returnStatement,
4
+ } from "./nodeFactory"
5
+
6
+ export interface WrapInFunctionOptions {}
7
+
8
+ /**
9
+ * 전체 프로그램을:
10
+ * return (function(...)
11
+ * <원래 코드>
12
+ * end)(...)
13
+ * 로 감쌈.
14
+ *
15
+ * - `return`을 쓰는 이유: Script/LocalScript에서는 top-level return이 그냥 청크를
16
+ * 조기 종료시킬 뿐 무해하고, ModuleScript라면 IIFE의 결과값이 그대로 require()
17
+ * 호출자에게 전달돼야 하므로 필요함. 즉 스크립트 종류를 가리지 않고 안전.
18
+ * - `...`을 파라미터로 받아서 다시 그대로 넘겨주는 이유: 원본 청크가 최상위에서
19
+ * `...`(스크립트 인자)을 참조하는 경우를 대비. 그냥 지워버리면 그런 코드가
20
+ * 깨짐.
21
+ *
22
+ * 반드시 파이프라인 맨 마지막 근처에서 실행돼야 함 — 이 패스 이후에 실행되는
23
+ * 다른 패스가 top-level 스코프를 순회/변형한다면 이미 감싸인 함수 내부까지
24
+ * 안 보고 지나칠 수 있음.
25
+ */
26
+ export function runWrapInFunction(program: Program, _options: WrapInFunctionOptions): void {
27
+ const innerBody = program.body
28
+ const wrapper = functionExpression(functionBody([], innerBody, true))
29
+ const iife = call(paren(wrapper), [vararg()])
30
+
31
+ program.body = block([returnStatement([iife])])
32
32
  }
@@ -5,7 +5,7 @@ import type {
5
5
  LocalStatement, LocalFunctionStatement, FunctionBody, FunctionParameter,
6
6
  TypedIdentifier, Block, Statement, AssignmentStatement, NumericForStatement,
7
7
  ReturnStatement, DoStatement, IfStatement, IfClause, VarargExpression,
8
- FunctionExpression,
8
+ FunctionExpression, BooleanLiteral, NilLiteral, WhileStatement,
9
9
  } from "luau-parser"
10
10
 
11
11
  /** 합성 노드는 실제 소스 위치가 없으므로 0으로 채움(printer는 구조만 봄). */
@@ -67,6 +67,18 @@ export function positionalField(value: Expression): TableField {
67
67
  return { type: "TableFieldPositional", value }
68
68
  }
69
69
 
70
+ export function namedField(name: string, value: Expression): TableField {
71
+ return { type: "TableFieldNamed", name: identifier(name), value }
72
+ }
73
+
74
+ export function booleanLiteral(value: boolean): BooleanLiteral {
75
+ return { type: "BooleanLiteral", value, line: POS, column: POS }
76
+ }
77
+
78
+ export function nilLiteral(): NilLiteral {
79
+ return { type: "NilLiteral", line: POS, column: POS }
80
+ }
81
+
70
82
  export function localStatement(name: string, init: Expression): LocalStatement {
71
83
  return {
72
84
  type: "LocalStatement",
@@ -138,6 +150,10 @@ export function ifStatement(clauses: IfClause[], alternate?: Block): IfStatement
138
150
  return { type: "IfStatement", clauses, alternate, line: POS, column: POS }
139
151
  }
140
152
 
153
+ export function whileStatement(condition: Expression, body: Block): WhileStatement {
154
+ return { type: "WhileStatement", condition, body, line: POS, column: POS }
155
+ }
156
+
141
157
  export function vararg(): VarargExpression {
142
158
  return { type: "VarargExpression", line: POS, column: POS }
143
159
  }
@@ -0,0 +1,50 @@
1
+ import type { Instr } from "./opcodes"
2
+
3
+ /** 상수 풀에 들어갈 수 있는 값. */
4
+ export type ConstValue = string | number | boolean | null
5
+
6
+ /**
7
+ * upvalue 하나가 부모 함수 기준으로 어디서 오는지.
8
+ * - "local": 부모 함수의 레지스터(박스)를 그대로 캡처
9
+ * - "upval": 부모 함수 자신의 upvalue를 한 단계 더 전달(중첩 클로저)
10
+ */
11
+ export interface UpvalDesc {
12
+ kind: "local" | "upval"
13
+ index: number
14
+ }
15
+
16
+ /** 함수 하나(최상위 청크 포함)에 대응하는 컴파일 결과. Lua의 Proto와 동일한 역할. */
17
+ export interface Proto {
18
+ id: number
19
+ numParams: number
20
+ hasVarargs: boolean
21
+ maxRegs: number
22
+ code: Instr[]
23
+ consts: ConstValue[]
24
+ /** 이 함수가 캡처하는 upvalue들이 "부모" 기준 어디서 오는지. */
25
+ upvalDescs: UpvalDesc[]
26
+ /** 중첩 함수 표현식들. CLOSURE 명령의 B는 이 배열의 인덱스. */
27
+ protos: Proto[]
28
+ }
29
+
30
+ export function createProto(id: number): Proto {
31
+ return {
32
+ id,
33
+ numParams: 0,
34
+ hasVarargs: false,
35
+ maxRegs: 0,
36
+ code: [],
37
+ consts: [],
38
+ upvalDescs: [],
39
+ protos: [],
40
+ }
41
+ }
42
+
43
+ /** 상수 풀에 값 추가(중복 제거) 후 인덱스 반환. */
44
+ export function internConst(proto: Proto, value: ConstValue): number {
45
+ for (let i = 0; i < proto.consts.length; i++) {
46
+ if (proto.consts[i] === value) return i
47
+ }
48
+ proto.consts.push(value)
49
+ return proto.consts.length - 1
50
+ }