lua-obfuscator 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.
Files changed (98) hide show
  1. package/.github/workflows/release.yml +40 -0
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +32 -18
  4. package/dist/prometheus/LICENSE +661 -661
  5. package/dist/prometheus/build.bat +9 -9
  6. package/dist/prometheus/doc/README.md +11 -11
  7. package/dist/prometheus/doc/SUMMARY.md +27 -27
  8. package/dist/prometheus/doc/advanced/using-prometheus-in-your-lua-application.md +31 -31
  9. package/dist/prometheus/doc/getting-started/command-line-options.md +13 -13
  10. package/dist/prometheus/doc/getting-started/installation.md +11 -11
  11. package/dist/prometheus/doc/getting-started/obfuscating-your-first-script.md +50 -50
  12. package/dist/prometheus/doc/getting-started/presets.md +10 -10
  13. package/dist/prometheus/doc/getting-started/the-config-object.md +58 -58
  14. package/dist/prometheus/doc/getting-started/writing-a-custom-config-file.md +56 -56
  15. package/dist/prometheus/doc/steps/anti-tamper.md +11 -11
  16. package/dist/prometheus/doc/steps/constantarray.md +71 -71
  17. package/dist/prometheus/doc/steps/encryptstrings.md +86 -86
  18. package/dist/prometheus/doc/steps/proxifylocals.md +47 -47
  19. package/dist/prometheus/doc/steps/splitstrings.md +40 -40
  20. package/dist/prometheus/doc/steps/vmify.md +9 -9
  21. package/dist/prometheus/doc/steps/wrapinfunction.md +29 -29
  22. package/dist/prometheus/readme.md +57 -57
  23. package/dist/prometheus/readme.txt +4 -4
  24. package/package.json +5 -1
  25. package/src/index.ts +93 -75
  26. package/tsconfig.json +12 -12
  27. package/src/prometheus/.editorconfig +0 -4
  28. package/src/prometheus/.gitattributes +0 -2
  29. package/src/prometheus/.gitbook.yaml +0 -1
  30. package/src/prometheus/.github/ISSUE_TEMPLATE/bug_report.md +0 -25
  31. package/src/prometheus/.github/workflows/Build.yml +0 -49
  32. package/src/prometheus/.github/workflows/Test.yml +0 -19
  33. package/src/prometheus/LICENSE +0 -661
  34. package/src/prometheus/benchmark.lua +0 -34
  35. package/src/prometheus/build.bat +0 -10
  36. package/src/prometheus/cli.lua +0 -12
  37. package/src/prometheus/doc/README.md +0 -11
  38. package/src/prometheus/doc/SUMMARY.md +0 -27
  39. package/src/prometheus/doc/advanced/using-prometheus-in-your-lua-application.md +0 -31
  40. package/src/prometheus/doc/getting-started/command-line-options.md +0 -13
  41. package/src/prometheus/doc/getting-started/installation.md +0 -11
  42. package/src/prometheus/doc/getting-started/obfuscating-your-first-script.md +0 -50
  43. package/src/prometheus/doc/getting-started/presets.md +0 -10
  44. package/src/prometheus/doc/getting-started/the-config-object.md +0 -58
  45. package/src/prometheus/doc/getting-started/writing-a-custom-config-file.md +0 -56
  46. package/src/prometheus/doc/steps/anti-tamper.md +0 -11
  47. package/src/prometheus/doc/steps/constantarray.md +0 -71
  48. package/src/prometheus/doc/steps/encryptstrings.md +0 -86
  49. package/src/prometheus/doc/steps/proxifylocals.md +0 -47
  50. package/src/prometheus/doc/steps/splitstrings.md +0 -40
  51. package/src/prometheus/doc/steps/vmify.md +0 -9
  52. package/src/prometheus/doc/steps/wrapinfunction.md +0 -29
  53. package/src/prometheus/prometheus-main.lua +0 -1
  54. package/src/prometheus/readme.md +0 -57
  55. package/src/prometheus/readme.txt +0 -5
  56. package/src/prometheus/src/cli.lua +0 -154
  57. package/src/prometheus/src/colors.lua +0 -61
  58. package/src/prometheus/src/highlightlua.lua +0 -61
  59. package/src/prometheus/src/logger.lua +0 -62
  60. package/src/prometheus/src/presets.lua +0 -174
  61. package/src/prometheus/src/prometheus/ast.lua +0 -792
  62. package/src/prometheus/src/prometheus/bit.lua +0 -521
  63. package/src/prometheus/src/prometheus/compiler/compiler.lua +0 -2365
  64. package/src/prometheus/src/prometheus/enums.lua +0 -106
  65. package/src/prometheus/src/prometheus/namegenerators/Il.lua +0 -41
  66. package/src/prometheus/src/prometheus/namegenerators/confuse.lua +0 -169
  67. package/src/prometheus/src/prometheus/namegenerators/mangled.lua +0 -26
  68. package/src/prometheus/src/prometheus/namegenerators/mangled_shuffled.lua +0 -35
  69. package/src/prometheus/src/prometheus/namegenerators/number.lua +0 -11
  70. package/src/prometheus/src/prometheus/namegenerators.lua +0 -7
  71. package/src/prometheus/src/prometheus/parser.lua +0 -969
  72. package/src/prometheus/src/prometheus/pipeline.lua +0 -250
  73. package/src/prometheus/src/prometheus/randomLiterals.lua +0 -41
  74. package/src/prometheus/src/prometheus/randomStrings.lua +0 -24
  75. package/src/prometheus/src/prometheus/scope.lua +0 -332
  76. package/src/prometheus/src/prometheus/step.lua +0 -79
  77. package/src/prometheus/src/prometheus/steps/AddVararg.lua +0 -33
  78. package/src/prometheus/src/prometheus/steps/AntiTamper.lua +0 -194
  79. package/src/prometheus/src/prometheus/steps/ConstantArray.lua +0 -521
  80. package/src/prometheus/src/prometheus/steps/EncryptStrings.lua +0 -239
  81. package/src/prometheus/src/prometheus/steps/NumbersToExpressions.lua +0 -82
  82. package/src/prometheus/src/prometheus/steps/ProxifyLocals.lua +0 -313
  83. package/src/prometheus/src/prometheus/steps/SplitStrings.lua +0 -338
  84. package/src/prometheus/src/prometheus/steps/Vmify.lua +0 -30
  85. package/src/prometheus/src/prometheus/steps/Watermark.lua +0 -61
  86. package/src/prometheus/src/prometheus/steps/WatermarkCheck.lua +0 -50
  87. package/src/prometheus/src/prometheus/steps/WrapInFunction.lua +0 -45
  88. package/src/prometheus/src/prometheus/steps.lua +0 -12
  89. package/src/prometheus/src/prometheus/tokenizer.lua +0 -546
  90. package/src/prometheus/src/prometheus/unparser.lua +0 -866
  91. package/src/prometheus/src/prometheus/util.lua +0 -297
  92. package/src/prometheus/src/prometheus/visitast.lua +0 -245
  93. package/src/prometheus/src/prometheus.lua +0 -71
  94. package/src/prometheus/tests/closures.lua +0 -12
  95. package/src/prometheus/tests/fibonacci.lua +0 -10
  96. package/src/prometheus/tests/loops.lua +0 -8
  97. package/src/prometheus/tests/primes.lua +0 -18
  98. package/src/prometheus/tests.lua +0 -149
@@ -1,2365 +0,0 @@
1
- -- This Script is Part of the Prometheus Obfuscator by Levno_710
2
- --
3
- -- compiler.lua
4
- -- This Script contains the new Compiler
5
-
6
- -- The max Number of variables used as registers
7
- local MAX_REGS = 100;
8
- local MAX_REGS_MUL = 0;
9
-
10
- local Compiler = {};
11
-
12
- local Ast = require("prometheus.ast");
13
- local Scope = require("prometheus.scope");
14
- local logger = require("logger");
15
- local util = require("prometheus.util");
16
- local visitast = require("prometheus.visitast")
17
- local randomStrings = require("prometheus.randomStrings")
18
-
19
- local lookupify = util.lookupify;
20
- local AstKind = Ast.AstKind;
21
-
22
- local unpack = unpack or table.unpack;
23
-
24
- function Compiler:new()
25
- local compiler = {
26
- blocks = {};
27
- registers = {
28
- };
29
- activeBlock = nil;
30
- registersForVar = {};
31
- usedRegisters = 0;
32
- maxUsedRegister = 0;
33
- registerVars = {};
34
-
35
- VAR_REGISTER = newproxy(false);
36
- RETURN_ALL = newproxy(false);
37
- POS_REGISTER = newproxy(false);
38
- RETURN_REGISTER = newproxy(false);
39
- UPVALUE = newproxy(false);
40
-
41
- BIN_OPS = lookupify{
42
- AstKind.LessThanExpression,
43
- AstKind.GreaterThanExpression,
44
- AstKind.LessThanOrEqualsExpression,
45
- AstKind.GreaterThanOrEqualsExpression,
46
- AstKind.NotEqualsExpression,
47
- AstKind.EqualsExpression,
48
- AstKind.StrCatExpression,
49
- AstKind.AddExpression,
50
- AstKind.SubExpression,
51
- AstKind.MulExpression,
52
- AstKind.DivExpression,
53
- AstKind.ModExpression,
54
- AstKind.PowExpression,
55
- };
56
- };
57
-
58
- setmetatable(compiler, self);
59
- self.__index = self;
60
-
61
- return compiler;
62
- end
63
-
64
- function Compiler:createBlock()
65
- local id;
66
- repeat
67
- id = math.random(0, 2^24)
68
- until not self.usedBlockIds[id];
69
- self.usedBlockIds[id] = true;
70
-
71
- local scope = Scope:new(self.containerFuncScope);
72
- local block = {
73
- id = id;
74
- statements = {
75
-
76
- };
77
- scope = scope;
78
- advanceToNextBlock = true;
79
- };
80
- table.insert(self.blocks, block);
81
- return block;
82
- end
83
-
84
- function Compiler:setActiveBlock(block)
85
- self.activeBlock = block;
86
- end
87
-
88
- function Compiler:addStatement(statement, writes, reads, usesUpvals)
89
- if(self.activeBlock.advanceToNextBlock) then
90
- table.insert(self.activeBlock.statements, {
91
- statement = statement,
92
- writes = lookupify(writes),
93
- reads = lookupify(reads),
94
- usesUpvals = usesUpvals or false,
95
- });
96
- end
97
- end
98
-
99
- function Compiler:compile(ast)
100
- self.blocks = {};
101
- self.registers = {};
102
- self.activeBlock = nil;
103
- self.registersForVar = {};
104
- self.scopeFunctionDepths = {};
105
- self.maxUsedRegister = 0;
106
- self.usedRegisters = 0;
107
- self.registerVars = {};
108
- self.usedBlockIds = {};
109
-
110
- self.upvalVars = {};
111
- self.registerUsageStack = {};
112
-
113
- self.upvalsProxyLenReturn = math.random(-2^22, 2^22);
114
-
115
- local newGlobalScope = Scope:newGlobal();
116
- local psc = Scope:new(newGlobalScope, nil);
117
-
118
- local _, getfenvVar = newGlobalScope:resolve("getfenv");
119
- local _, tableVar = newGlobalScope:resolve("table");
120
- local _, unpackVar = newGlobalScope:resolve("unpack");
121
- local _, envVar = newGlobalScope:resolve("_ENV");
122
- local _, newproxyVar = newGlobalScope:resolve("newproxy");
123
- local _, setmetatableVar = newGlobalScope:resolve("setmetatable");
124
- local _, getmetatableVar = newGlobalScope:resolve("getmetatable");
125
- local _, selectVar = newGlobalScope:resolve("select");
126
-
127
- psc:addReferenceToHigherScope(newGlobalScope, getfenvVar, 2);
128
- psc:addReferenceToHigherScope(newGlobalScope, tableVar);
129
- psc:addReferenceToHigherScope(newGlobalScope, unpackVar);
130
- psc:addReferenceToHigherScope(newGlobalScope, envVar);
131
- psc:addReferenceToHigherScope(newGlobalScope, newproxyVar);
132
- psc:addReferenceToHigherScope(newGlobalScope, setmetatableVar);
133
- psc:addReferenceToHigherScope(newGlobalScope, getmetatableVar);
134
-
135
- self.scope = Scope:new(psc);
136
- self.envVar = self.scope:addVariable();
137
- self.containerFuncVar = self.scope:addVariable();
138
- self.unpackVar = self.scope:addVariable();
139
- self.newproxyVar = self.scope:addVariable();
140
- self.setmetatableVar = self.scope:addVariable();
141
- self.getmetatableVar = self.scope:addVariable();
142
- self.selectVar = self.scope:addVariable();
143
-
144
- local argVar = self.scope:addVariable();
145
-
146
- self.containerFuncScope = Scope:new(self.scope);
147
- self.whileScope = Scope:new(self.containerFuncScope);
148
-
149
- self.posVar = self.containerFuncScope:addVariable();
150
- self.argsVar = self.containerFuncScope:addVariable();
151
- self.currentUpvaluesVar = self.containerFuncScope:addVariable();
152
- self.detectGcCollectVar = self.containerFuncScope:addVariable();
153
- self.returnVar = self.containerFuncScope:addVariable();
154
-
155
- -- Upvalues Handling
156
- self.upvaluesTable = self.scope:addVariable();
157
- self.upvaluesReferenceCountsTable = self.scope:addVariable();
158
- self.allocUpvalFunction = self.scope:addVariable();
159
- self.currentUpvalId = self.scope:addVariable();
160
-
161
- -- Gc Handling for Upvalues
162
- self.upvaluesProxyFunctionVar = self.scope:addVariable();
163
- self.upvaluesGcFunctionVar = self.scope:addVariable();
164
- self.freeUpvalueFunc = self.scope:addVariable();
165
-
166
- self.createClosureVars = {};
167
- self.createVarargClosureVar = self.scope:addVariable();
168
- local createClosureScope = Scope:new(self.scope);
169
- local createClosurePosArg = createClosureScope:addVariable();
170
- local createClosureUpvalsArg = createClosureScope:addVariable();
171
- local createClosureProxyObject = createClosureScope:addVariable();
172
- local createClosureFuncVar = createClosureScope:addVariable();
173
-
174
- local createClosureSubScope = Scope:new(createClosureScope);
175
-
176
- local upvalEntries = {};
177
- local upvalueIds = {};
178
- self.getUpvalueId = function(self, scope, id)
179
- local expression;
180
- local scopeFuncDepth = self.scopeFunctionDepths[scope];
181
- if(scopeFuncDepth == 0) then
182
- if upvalueIds[id] then
183
- return upvalueIds[id];
184
- end
185
- expression = Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.allocUpvalFunction), {});
186
- else
187
- logger:error("Unresolved Upvalue, this error should not occur!");
188
- end
189
- table.insert(upvalEntries, Ast.TableEntry(expression));
190
- local uid = #upvalEntries;
191
- upvalueIds[id] = uid;
192
- return uid;
193
- end
194
-
195
- -- Reference to Higher Scopes
196
- createClosureSubScope:addReferenceToHigherScope(self.scope, self.containerFuncVar);
197
- createClosureSubScope:addReferenceToHigherScope(createClosureScope, createClosurePosArg)
198
- createClosureSubScope:addReferenceToHigherScope(createClosureScope, createClosureUpvalsArg, 1)
199
- createClosureScope:addReferenceToHigherScope(self.scope, self.upvaluesProxyFunctionVar)
200
- createClosureSubScope:addReferenceToHigherScope(createClosureScope, createClosureProxyObject);
201
-
202
- -- Invoke Compiler
203
- self:compileTopNode(ast);
204
-
205
- local functionNodeAssignments = {
206
- {
207
- var = Ast.AssignmentVariable(self.scope, self.containerFuncVar),
208
- val = Ast.FunctionLiteralExpression({
209
- Ast.VariableExpression(self.containerFuncScope, self.posVar),
210
- Ast.VariableExpression(self.containerFuncScope, self.argsVar),
211
- Ast.VariableExpression(self.containerFuncScope, self.currentUpvaluesVar),
212
- Ast.VariableExpression(self.containerFuncScope, self.detectGcCollectVar)
213
- }, self:emitContainerFuncBody());
214
- }, {
215
- var = Ast.AssignmentVariable(self.scope, self.createVarargClosureVar),
216
- val = Ast.FunctionLiteralExpression({
217
- Ast.VariableExpression(createClosureScope, createClosurePosArg),
218
- Ast.VariableExpression(createClosureScope, createClosureUpvalsArg),
219
- },
220
- Ast.Block({
221
- Ast.LocalVariableDeclaration(createClosureScope, {
222
- createClosureProxyObject
223
- }, {
224
- Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.upvaluesProxyFunctionVar), {
225
- Ast.VariableExpression(createClosureScope, createClosureUpvalsArg)
226
- })
227
- }),
228
- Ast.LocalVariableDeclaration(createClosureScope, {createClosureFuncVar},{
229
- Ast.FunctionLiteralExpression({
230
- Ast.VarargExpression();
231
- },
232
- Ast.Block({
233
- Ast.ReturnStatement{
234
- Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.containerFuncVar), {
235
- Ast.VariableExpression(createClosureScope, createClosurePosArg),
236
- Ast.TableConstructorExpression({Ast.TableEntry(Ast.VarargExpression())}),
237
- Ast.VariableExpression(createClosureScope, createClosureUpvalsArg), -- Upvalues
238
- Ast.VariableExpression(createClosureScope, createClosureProxyObject)
239
- })
240
- }
241
- }, createClosureSubScope)
242
- );
243
- });
244
- Ast.ReturnStatement{Ast.VariableExpression(createClosureScope, createClosureFuncVar)};
245
- }, createClosureScope)
246
- );
247
- }, {
248
- var = Ast.AssignmentVariable(self.scope, self.upvaluesTable),
249
- val = Ast.TableConstructorExpression({}),
250
- }, {
251
- var = Ast.AssignmentVariable(self.scope, self.upvaluesReferenceCountsTable),
252
- val = Ast.TableConstructorExpression({}),
253
- }, {
254
- var = Ast.AssignmentVariable(self.scope, self.allocUpvalFunction),
255
- val = self:createAllocUpvalFunction(),
256
- }, {
257
- var = Ast.AssignmentVariable(self.scope, self.currentUpvalId),
258
- val = Ast.NumberExpression(0),
259
- }, {
260
- var = Ast.AssignmentVariable(self.scope, self.upvaluesProxyFunctionVar),
261
- val = self:createUpvaluesProxyFunc(),
262
- }, {
263
- var = Ast.AssignmentVariable(self.scope, self.upvaluesGcFunctionVar),
264
- val = self:createUpvaluesGcFunc(),
265
- }, {
266
- var = Ast.AssignmentVariable(self.scope, self.freeUpvalueFunc),
267
- val = self:createFreeUpvalueFunc(),
268
- },
269
- }
270
-
271
- local tbl = {
272
- Ast.VariableExpression(self.scope, self.containerFuncVar),
273
- Ast.VariableExpression(self.scope, self.createVarargClosureVar),
274
- Ast.VariableExpression(self.scope, self.upvaluesTable),
275
- Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable),
276
- Ast.VariableExpression(self.scope, self.allocUpvalFunction),
277
- Ast.VariableExpression(self.scope, self.currentUpvalId),
278
- Ast.VariableExpression(self.scope, self.upvaluesProxyFunctionVar),
279
- Ast.VariableExpression(self.scope, self.upvaluesGcFunctionVar),
280
- Ast.VariableExpression(self.scope, self.freeUpvalueFunc),
281
- };
282
- for i, entry in pairs(self.createClosureVars) do
283
- table.insert(functionNodeAssignments, entry);
284
- table.insert(tbl, Ast.VariableExpression(entry.var.scope, entry.var.id));
285
- end
286
-
287
- util.shuffle(functionNodeAssignments);
288
- local assignmentStatLhs, assignmentStatRhs = {}, {};
289
- for i, v in ipairs(functionNodeAssignments) do
290
- assignmentStatLhs[i] = v.var;
291
- assignmentStatRhs[i] = v.val;
292
- end
293
-
294
- -- Emit Code
295
- local functionNode = Ast.FunctionLiteralExpression({
296
- Ast.VariableExpression(self.scope, self.envVar),
297
- Ast.VariableExpression(self.scope, self.unpackVar),
298
- Ast.VariableExpression(self.scope, self.newproxyVar),
299
- Ast.VariableExpression(self.scope, self.setmetatableVar),
300
- Ast.VariableExpression(self.scope, self.getmetatableVar),
301
- Ast.VariableExpression(self.scope, self.selectVar),
302
- Ast.VariableExpression(self.scope, argVar),
303
- unpack(util.shuffle(tbl))
304
- }, Ast.Block({
305
- Ast.AssignmentStatement(assignmentStatLhs, assignmentStatRhs);
306
- Ast.ReturnStatement{
307
- Ast.FunctionCallExpression(Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.createVarargClosureVar), {
308
- Ast.NumberExpression(self.startBlockId);
309
- Ast.TableConstructorExpression(upvalEntries);
310
- }), {Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.unpackVar), {Ast.VariableExpression(self.scope, argVar)})});
311
- }
312
- }, self.scope));
313
-
314
- return Ast.TopNode(Ast.Block({
315
- Ast.ReturnStatement{Ast.FunctionCallExpression(functionNode, {
316
- Ast.OrExpression(Ast.AndExpression(Ast.VariableExpression(newGlobalScope, getfenvVar), Ast.FunctionCallExpression(Ast.VariableExpression(newGlobalScope, getfenvVar), {})), Ast.VariableExpression(newGlobalScope, envVar));
317
- Ast.OrExpression(Ast.VariableExpression(newGlobalScope, unpackVar), Ast.IndexExpression(Ast.VariableExpression(newGlobalScope, tableVar), Ast.StringExpression("unpack")));
318
- Ast.VariableExpression(newGlobalScope, newproxyVar);
319
- Ast.VariableExpression(newGlobalScope, setmetatableVar);
320
- Ast.VariableExpression(newGlobalScope, getmetatableVar);
321
- Ast.VariableExpression(newGlobalScope, selectVar);
322
- Ast.TableConstructorExpression({
323
- Ast.TableEntry(Ast.VarargExpression());
324
- })
325
- })};
326
- }, psc), newGlobalScope);
327
- end
328
-
329
- function Compiler:getCreateClosureVar(argCount)
330
- if not self.createClosureVars[argCount] then
331
- local var = Ast.AssignmentVariable(self.scope, self.scope:addVariable());
332
- local createClosureScope = Scope:new(self.scope);
333
- local createClosureSubScope = Scope:new(createClosureScope);
334
-
335
- local createClosurePosArg = createClosureScope:addVariable();
336
- local createClosureUpvalsArg = createClosureScope:addVariable();
337
- local createClosureProxyObject = createClosureScope:addVariable();
338
- local createClosureFuncVar = createClosureScope:addVariable();
339
-
340
- createClosureSubScope:addReferenceToHigherScope(self.scope, self.containerFuncVar);
341
- createClosureSubScope:addReferenceToHigherScope(createClosureScope, createClosurePosArg)
342
- createClosureSubScope:addReferenceToHigherScope(createClosureScope, createClosureUpvalsArg, 1)
343
- createClosureScope:addReferenceToHigherScope(self.scope, self.upvaluesProxyFunctionVar)
344
- createClosureSubScope:addReferenceToHigherScope(createClosureScope, createClosureProxyObject);
345
-
346
- local argsTb, argsTb2 = {}, {};
347
- for i = 1, argCount do
348
- local arg = createClosureSubScope:addVariable()
349
- argsTb[i] = Ast.VariableExpression(createClosureSubScope, arg);
350
- argsTb2[i] = Ast.TableEntry(Ast.VariableExpression(createClosureSubScope, arg));
351
- end
352
-
353
- local val = Ast.FunctionLiteralExpression({
354
- Ast.VariableExpression(createClosureScope, createClosurePosArg),
355
- Ast.VariableExpression(createClosureScope, createClosureUpvalsArg),
356
- }, Ast.Block({
357
- Ast.LocalVariableDeclaration(createClosureScope, {
358
- createClosureProxyObject
359
- }, {
360
- Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.upvaluesProxyFunctionVar), {
361
- Ast.VariableExpression(createClosureScope, createClosureUpvalsArg)
362
- })
363
- }),
364
- Ast.LocalVariableDeclaration(createClosureScope, {createClosureFuncVar},{
365
- Ast.FunctionLiteralExpression(argsTb,
366
- Ast.Block({
367
- Ast.ReturnStatement{
368
- Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.containerFuncVar), {
369
- Ast.VariableExpression(createClosureScope, createClosurePosArg),
370
- Ast.TableConstructorExpression(argsTb2),
371
- Ast.VariableExpression(createClosureScope, createClosureUpvalsArg), -- Upvalues
372
- Ast.VariableExpression(createClosureScope, createClosureProxyObject)
373
- })
374
- }
375
- }, createClosureSubScope)
376
- );
377
- });
378
- Ast.ReturnStatement{Ast.VariableExpression(createClosureScope, createClosureFuncVar)}
379
- }, createClosureScope)
380
- );
381
- self.createClosureVars[argCount] = {
382
- var = var,
383
- val = val,
384
- }
385
- end
386
-
387
-
388
- local var = self.createClosureVars[argCount].var;
389
- return var.scope, var.id;
390
- end
391
-
392
- function Compiler:pushRegisterUsageInfo()
393
- table.insert(self.registerUsageStack, {
394
- usedRegisters = self.usedRegisters;
395
- registers = self.registers;
396
- });
397
- self.usedRegisters = 0;
398
- self.registers = {};
399
- end
400
-
401
- function Compiler:popRegisterUsageInfo()
402
- local info = table.remove(self.registerUsageStack);
403
- self.usedRegisters = info.usedRegisters;
404
- self.registers = info.registers;
405
- end
406
-
407
- function Compiler:createUpvaluesGcFunc()
408
- local scope = Scope:new(self.scope);
409
- local selfVar = scope:addVariable();
410
-
411
- local iteratorVar = scope:addVariable();
412
- local valueVar = scope:addVariable();
413
-
414
- local whileScope = Scope:new(scope);
415
- whileScope:addReferenceToHigherScope(self.scope, self.upvaluesReferenceCountsTable, 3);
416
- whileScope:addReferenceToHigherScope(scope, valueVar, 3);
417
- whileScope:addReferenceToHigherScope(scope, iteratorVar, 3);
418
-
419
- local ifScope = Scope:new(whileScope);
420
- ifScope:addReferenceToHigherScope(self.scope, self.upvaluesReferenceCountsTable, 1);
421
- ifScope:addReferenceToHigherScope(self.scope, self.upvaluesTable, 1);
422
-
423
-
424
- return Ast.FunctionLiteralExpression({Ast.VariableExpression(scope, selfVar)}, Ast.Block({
425
- Ast.LocalVariableDeclaration(scope, {iteratorVar, valueVar}, {Ast.NumberExpression(1), Ast.IndexExpression(Ast.VariableExpression(scope, selfVar), Ast.NumberExpression(1))}),
426
- Ast.WhileStatement(Ast.Block({
427
- Ast.AssignmentStatement({
428
- Ast.AssignmentIndexing(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.VariableExpression(scope, valueVar)),
429
- Ast.AssignmentVariable(scope, iteratorVar),
430
- }, {
431
- Ast.SubExpression(Ast.IndexExpression(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.VariableExpression(scope, valueVar)), Ast.NumberExpression(1)),
432
- Ast.AddExpression(unpack(util.shuffle{Ast.VariableExpression(scope, iteratorVar), Ast.NumberExpression(1)})),
433
- }),
434
- Ast.IfStatement(Ast.EqualsExpression(unpack(util.shuffle{Ast.IndexExpression(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.VariableExpression(scope, valueVar)), Ast.NumberExpression(0)})), Ast.Block({
435
- Ast.AssignmentStatement({
436
- Ast.AssignmentIndexing(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.VariableExpression(scope, valueVar)),
437
- Ast.AssignmentIndexing(Ast.VariableExpression(self.scope, self.upvaluesTable), Ast.VariableExpression(scope, valueVar)),
438
- }, {
439
- Ast.NilExpression(),
440
- Ast.NilExpression(),
441
- })
442
- }, ifScope), {}, nil),
443
- Ast.AssignmentStatement({
444
- Ast.AssignmentVariable(scope, valueVar),
445
- }, {
446
- Ast.IndexExpression(Ast.VariableExpression(scope, selfVar), Ast.VariableExpression(scope, iteratorVar)),
447
- }),
448
- }, whileScope), Ast.VariableExpression(scope, valueVar), scope);
449
- }, scope));
450
- end
451
-
452
- function Compiler:createFreeUpvalueFunc()
453
- local scope = Scope:new(self.scope);
454
- local argVar = scope:addVariable();
455
- local ifScope = Scope:new(scope);
456
- ifScope:addReferenceToHigherScope(scope, argVar, 3);
457
- scope:addReferenceToHigherScope(self.scope, self.upvaluesReferenceCountsTable, 2);
458
- return Ast.FunctionLiteralExpression({Ast.VariableExpression(scope, argVar)}, Ast.Block({
459
- Ast.AssignmentStatement({
460
- Ast.AssignmentIndexing(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.VariableExpression(scope, argVar))
461
- }, {
462
- Ast.SubExpression(Ast.IndexExpression(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.VariableExpression(scope, argVar)), Ast.NumberExpression(1));
463
- }),
464
- Ast.IfStatement(Ast.EqualsExpression(unpack(util.shuffle{Ast.IndexExpression(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.VariableExpression(scope, argVar)), Ast.NumberExpression(0)})), Ast.Block({
465
- Ast.AssignmentStatement({
466
- Ast.AssignmentIndexing(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.VariableExpression(scope, argVar)),
467
- Ast.AssignmentIndexing(Ast.VariableExpression(self.scope, self.upvaluesTable), Ast.VariableExpression(scope, argVar)),
468
- }, {
469
- Ast.NilExpression(),
470
- Ast.NilExpression(),
471
- })
472
- }, ifScope), {}, nil)
473
- }, scope))
474
- end
475
-
476
- function Compiler:createUpvaluesProxyFunc()
477
- local scope = Scope:new(self.scope);
478
- scope:addReferenceToHigherScope(self.scope, self.newproxyVar);
479
-
480
- local entriesVar = scope:addVariable();
481
-
482
- local ifScope = Scope:new(scope);
483
- local proxyVar = ifScope:addVariable();
484
- local metatableVar = ifScope:addVariable();
485
- local elseScope = Scope:new(scope);
486
- ifScope:addReferenceToHigherScope(self.scope, self.newproxyVar);
487
- ifScope:addReferenceToHigherScope(self.scope, self.getmetatableVar);
488
- ifScope:addReferenceToHigherScope(self.scope, self.upvaluesGcFunctionVar);
489
- ifScope:addReferenceToHigherScope(scope, entriesVar);
490
- elseScope:addReferenceToHigherScope(self.scope, self.setmetatableVar);
491
- elseScope:addReferenceToHigherScope(scope, entriesVar);
492
- elseScope:addReferenceToHigherScope(self.scope, self.upvaluesGcFunctionVar);
493
-
494
- local forScope = Scope:new(scope);
495
- local forArg = forScope:addVariable();
496
- forScope:addReferenceToHigherScope(self.scope, self.upvaluesReferenceCountsTable, 2);
497
- forScope:addReferenceToHigherScope(scope, entriesVar, 2);
498
-
499
- return Ast.FunctionLiteralExpression({Ast.VariableExpression(scope, entriesVar)}, Ast.Block({
500
- Ast.ForStatement(forScope, forArg, Ast.NumberExpression(1), Ast.LenExpression(Ast.VariableExpression(scope, entriesVar)), Ast.NumberExpression(1), Ast.Block({
501
- Ast.AssignmentStatement({
502
- Ast.AssignmentIndexing(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.IndexExpression(Ast.VariableExpression(scope, entriesVar), Ast.VariableExpression(forScope, forArg)))
503
- }, {
504
- Ast.AddExpression(unpack(util.shuffle{
505
- Ast.IndexExpression(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.IndexExpression(Ast.VariableExpression(scope, entriesVar), Ast.VariableExpression(forScope, forArg))),
506
- Ast.NumberExpression(1),
507
- }))
508
- })
509
- }, forScope), scope);
510
- Ast.IfStatement(Ast.VariableExpression(self.scope, self.newproxyVar), Ast.Block({
511
- Ast.LocalVariableDeclaration(ifScope, {proxyVar}, {
512
- Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.newproxyVar), {
513
- Ast.BooleanExpression(true)
514
- });
515
- });
516
- Ast.LocalVariableDeclaration(ifScope, {metatableVar}, {
517
- Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.getmetatableVar), {
518
- Ast.VariableExpression(ifScope, proxyVar);
519
- });
520
- });
521
- Ast.AssignmentStatement({
522
- Ast.AssignmentIndexing(Ast.VariableExpression(ifScope, metatableVar), Ast.StringExpression("__index")),
523
- Ast.AssignmentIndexing(Ast.VariableExpression(ifScope, metatableVar), Ast.StringExpression("__gc")),
524
- Ast.AssignmentIndexing(Ast.VariableExpression(ifScope, metatableVar), Ast.StringExpression("__len")),
525
- }, {
526
- Ast.VariableExpression(scope, entriesVar),
527
- Ast.VariableExpression(self.scope, self.upvaluesGcFunctionVar),
528
- Ast.FunctionLiteralExpression({}, Ast.Block({
529
- Ast.ReturnStatement({Ast.NumberExpression(self.upvalsProxyLenReturn)})
530
- }, Scope:new(ifScope)));
531
- });
532
- Ast.ReturnStatement({
533
- Ast.VariableExpression(ifScope, proxyVar)
534
- })
535
- }, ifScope), {}, Ast.Block({
536
- Ast.ReturnStatement({Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.setmetatableVar), {
537
- Ast.TableConstructorExpression({}),
538
- Ast.TableConstructorExpression({
539
- Ast.KeyedTableEntry(Ast.StringExpression("__gc"), Ast.VariableExpression(self.scope, self.upvaluesGcFunctionVar)),
540
- Ast.KeyedTableEntry(Ast.StringExpression("__index"), Ast.VariableExpression(scope, entriesVar)),
541
- Ast.KeyedTableEntry(Ast.StringExpression("__len"), Ast.FunctionLiteralExpression({}, Ast.Block({
542
- Ast.ReturnStatement({Ast.NumberExpression(self.upvalsProxyLenReturn)})
543
- }, Scope:new(ifScope)))),
544
- })
545
- })})
546
- }, elseScope));
547
- }, scope));
548
- end
549
-
550
- function Compiler:createAllocUpvalFunction()
551
- local scope = Scope:new(self.scope);
552
- scope:addReferenceToHigherScope(self.scope, self.currentUpvalId, 4);
553
- scope:addReferenceToHigherScope(self.scope, self.upvaluesReferenceCountsTable, 1);
554
-
555
- return Ast.FunctionLiteralExpression({}, Ast.Block({
556
- Ast.AssignmentStatement({
557
- Ast.AssignmentVariable(self.scope, self.currentUpvalId),
558
- },{
559
- Ast.AddExpression(unpack(util.shuffle({
560
- Ast.VariableExpression(self.scope, self.currentUpvalId),
561
- Ast.NumberExpression(1),
562
- }))),
563
- }
564
- ),
565
- Ast.AssignmentStatement({
566
- Ast.AssignmentIndexing(Ast.VariableExpression(self.scope, self.upvaluesReferenceCountsTable), Ast.VariableExpression(self.scope, self.currentUpvalId)),
567
- }, {
568
- Ast.NumberExpression(1),
569
- }),
570
- Ast.ReturnStatement({
571
- Ast.VariableExpression(self.scope, self.currentUpvalId),
572
- })
573
- }, scope));
574
- end
575
-
576
- function Compiler:emitContainerFuncBody()
577
- local blocks = {};
578
-
579
- util.shuffle(self.blocks);
580
-
581
- for _, block in ipairs(self.blocks) do
582
- local id = block.id;
583
- local blockstats = block.statements;
584
-
585
- -- Shuffle Blockstats
586
- for i = 2, #blockstats do
587
- local stat = blockstats[i];
588
- local reads = stat.reads;
589
- local writes = stat.writes;
590
- local maxShift = 0;
591
- local usesUpvals = stat.usesUpvals;
592
- for shift = 1, i - 1 do
593
- local stat2 = blockstats[i - shift];
594
-
595
- if stat2.usesUpvals and usesUpvals then
596
- break;
597
- end
598
-
599
- local reads2 = stat2.reads;
600
- local writes2 = stat2.writes;
601
- local f = true;
602
-
603
- for r, b in pairs(reads2) do
604
- if(writes[r]) then
605
- f = false;
606
- break;
607
- end
608
- end
609
-
610
- if f then
611
- for r, b in pairs(writes2) do
612
- if(writes[r]) then
613
- f = false;
614
- break;
615
- end
616
- if(reads[r]) then
617
- f = false;
618
- break;
619
- end
620
- end
621
- end
622
-
623
- if not f then
624
- break
625
- end
626
-
627
- maxShift = shift;
628
- end
629
-
630
- local shift = math.random(0, maxShift);
631
- for j = 1, shift do
632
- blockstats[i - j], blockstats[i - j + 1] = blockstats[i - j + 1], blockstats[i - j];
633
- end
634
- end
635
-
636
- blockstats = {};
637
- for i, stat in ipairs(block.statements) do
638
- table.insert(blockstats, stat.statement);
639
- end
640
-
641
- table.insert(blocks, { id = id, block = Ast.Block(blockstats, block.scope) });
642
- end
643
-
644
- table.sort(blocks, function(a, b)
645
- return a.id < b.id;
646
- end);
647
-
648
- local function buildIfBlock(scope, id, lBlock, rBlock)
649
- return Ast.Block({
650
- Ast.IfStatement(Ast.LessThanExpression(self:pos(scope), Ast.NumberExpression(id)), lBlock, {}, rBlock);
651
- }, scope);
652
- end
653
-
654
- local function buildWhileBody(tb, l, r, pScope, scope)
655
- local len = r - l + 1;
656
- if len == 1 then
657
- tb[r].block.scope:setParent(pScope);
658
- return tb[r].block;
659
- elseif len == 0 then
660
- return nil;
661
- end
662
-
663
- local mid = l + math.ceil(len / 2);
664
- local bound = math.random(tb[mid - 1].id + 1, tb[mid].id);
665
- local ifScope = scope or Scope:new(pScope);
666
-
667
- local lBlock = buildWhileBody(tb, l, mid - 1, ifScope);
668
- local rBlock = buildWhileBody(tb, mid, r, ifScope);
669
-
670
- return buildIfBlock(ifScope, bound, lBlock, rBlock);
671
- end
672
-
673
- local whileBody = buildWhileBody(blocks, 1, #blocks, self.containerFuncScope, self.whileScope);
674
-
675
- self.whileScope:addReferenceToHigherScope(self.containerFuncScope, self.returnVar, 1);
676
- self.whileScope:addReferenceToHigherScope(self.containerFuncScope, self.posVar);
677
-
678
- self.containerFuncScope:addReferenceToHigherScope(self.scope, self.unpackVar);
679
-
680
- local declarations = {
681
- self.returnVar,
682
- }
683
-
684
- for i, var in pairs(self.registerVars) do
685
- if(i ~= MAX_REGS) then
686
- table.insert(declarations, var);
687
- end
688
- end
689
-
690
- local stats = {
691
- Ast.LocalVariableDeclaration(self.containerFuncScope, util.shuffle(declarations), {});
692
- Ast.WhileStatement(whileBody, Ast.VariableExpression(self.containerFuncScope, self.posVar));
693
- Ast.AssignmentStatement({
694
- Ast.AssignmentVariable(self.containerFuncScope, self.posVar)
695
- }, {
696
- Ast.LenExpression(Ast.VariableExpression(self.containerFuncScope, self.detectGcCollectVar))
697
- }),
698
- Ast.ReturnStatement{
699
- Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.unpackVar), {
700
- Ast.VariableExpression(self.containerFuncScope, self.returnVar)
701
- });
702
- }
703
- }
704
-
705
- if self.maxUsedRegister >= MAX_REGS then
706
- table.insert(stats, 1, Ast.LocalVariableDeclaration(self.containerFuncScope, {self.registerVars[MAX_REGS]}, {Ast.TableConstructorExpression({})}));
707
- end
708
-
709
- return Ast.Block(stats, self.containerFuncScope);
710
- end
711
-
712
- function Compiler:freeRegister(id, force)
713
- if force or not (self.registers[id] == self.VAR_REGISTER) then
714
- self.usedRegisters = self.usedRegisters - 1;
715
- self.registers[id] = false
716
- end
717
- end
718
-
719
- function Compiler:isVarRegister(id)
720
- return self.registers[id] == self.VAR_REGISTER;
721
- end
722
-
723
- function Compiler:allocRegister(isVar)
724
- self.usedRegisters = self.usedRegisters + 1;
725
-
726
- if not isVar then
727
- -- POS register can be temporarily used
728
- if not self.registers[self.POS_REGISTER] then
729
- self.registers[self.POS_REGISTER] = true;
730
- return self.POS_REGISTER;
731
- end
732
-
733
- -- RETURN register can be temporarily used
734
- if not self.registers[self.RETURN_REGISTER] then
735
- self.registers[self.RETURN_REGISTER] = true;
736
- return self.RETURN_REGISTER;
737
- end
738
- end
739
-
740
-
741
- local id = 0;
742
- if self.usedRegisters < MAX_REGS * MAX_REGS_MUL then
743
- repeat
744
- id = math.random(1, MAX_REGS - 1);
745
- until not self.registers[id];
746
- else
747
- repeat
748
- id = id + 1;
749
- until not self.registers[id];
750
- end
751
-
752
- if id > self.maxUsedRegister then
753
- self.maxUsedRegister = id;
754
- end
755
-
756
- if(isVar) then
757
- self.registers[id] = self.VAR_REGISTER;
758
- else
759
- self.registers[id] = true
760
- end
761
- return id;
762
- end
763
-
764
- function Compiler:isUpvalue(scope, id)
765
- return self.upvalVars[scope] and self.upvalVars[scope][id];
766
- end
767
-
768
- function Compiler:makeUpvalue(scope, id)
769
- if(not self.upvalVars[scope]) then
770
- self.upvalVars[scope] = {}
771
- end
772
- self.upvalVars[scope][id] = true;
773
- end
774
-
775
- function Compiler:getVarRegister(scope, id, functionDepth, potentialId)
776
- if(not self.registersForVar[scope]) then
777
- self.registersForVar[scope] = {};
778
- self.scopeFunctionDepths[scope] = functionDepth;
779
- end
780
-
781
- local reg = self.registersForVar[scope][id];
782
- if not reg then
783
- if potentialId and self.registers[potentialId] ~= self.VAR_REGISTER and potentialId ~= self.POS_REGISTER and potentialId ~= self.RETURN_REGISTER then
784
- self.registers[potentialId] = self.VAR_REGISTER;
785
- reg = potentialId;
786
- else
787
- reg = self:allocRegister(true);
788
- end
789
- self.registersForVar[scope][id] = reg;
790
- end
791
- return reg;
792
- end
793
-
794
- function Compiler:getRegisterVarId(id)
795
- local varId = self.registerVars[id];
796
- if not varId then
797
- varId = self.containerFuncScope:addVariable();
798
- self.registerVars[id] = varId;
799
- end
800
- return varId;
801
- end
802
-
803
- -- Maybe convert ids to strings
804
- function Compiler:register(scope, id)
805
- if id == self.POS_REGISTER then
806
- return self:pos(scope);
807
- end
808
-
809
- if id == self.RETURN_REGISTER then
810
- return self:getReturn(scope);
811
- end
812
-
813
- if id < MAX_REGS then
814
- local vid = self:getRegisterVarId(id);
815
- scope:addReferenceToHigherScope(self.containerFuncScope, vid);
816
- return Ast.VariableExpression(self.containerFuncScope, vid);
817
- end
818
-
819
- local vid = self:getRegisterVarId(MAX_REGS);
820
- scope:addReferenceToHigherScope(self.containerFuncScope, vid);
821
- return Ast.IndexExpression(Ast.VariableExpression(self.containerFuncScope, vid), Ast.NumberExpression((id - MAX_REGS) + 1));
822
- end
823
-
824
- function Compiler:registerList(scope, ids)
825
- local l = {};
826
- for i, id in ipairs(ids) do
827
- table.insert(l, self:register(scope, id));
828
- end
829
- return l;
830
- end
831
-
832
- function Compiler:registerAssignment(scope, id)
833
- if id == self.POS_REGISTER then
834
- return self:posAssignment(scope);
835
- end
836
- if id == self.RETURN_REGISTER then
837
- return self:returnAssignment(scope);
838
- end
839
-
840
- if id < MAX_REGS then
841
- local vid = self:getRegisterVarId(id);
842
- scope:addReferenceToHigherScope(self.containerFuncScope, vid);
843
- return Ast.AssignmentVariable(self.containerFuncScope, vid);
844
- end
845
-
846
- local vid = self:getRegisterVarId(MAX_REGS);
847
- scope:addReferenceToHigherScope(self.containerFuncScope, vid);
848
- return Ast.AssignmentIndexing(Ast.VariableExpression(self.containerFuncScope, vid), Ast.NumberExpression((id - MAX_REGS) + 1));
849
- end
850
-
851
- -- Maybe convert ids to strings
852
- function Compiler:setRegister(scope, id, val, compundArg)
853
- if(compundArg) then
854
- return compundArg(self:registerAssignment(scope, id), val);
855
- end
856
- return Ast.AssignmentStatement({
857
- self:registerAssignment(scope, id)
858
- }, {
859
- val
860
- });
861
- end
862
-
863
- function Compiler:setRegisters(scope, ids, vals)
864
- local idStats = {};
865
- for i, id in ipairs(ids) do
866
- table.insert(idStats, self:registerAssignment(scope, id));
867
- end
868
-
869
- return Ast.AssignmentStatement(idStats, vals);
870
- end
871
-
872
- function Compiler:copyRegisters(scope, to, from)
873
- local idStats = {};
874
- local vals = {};
875
- for i, id in ipairs(to) do
876
- local from = from[i];
877
- if(from ~= id) then
878
- table.insert(idStats, self:registerAssignment(scope, id));
879
- table.insert(vals, self:register(scope, from));
880
- end
881
- end
882
-
883
- if(#idStats > 0 and #vals > 0) then
884
- return Ast.AssignmentStatement(idStats, vals);
885
- end
886
- end
887
-
888
- function Compiler:resetRegisters()
889
- self.registers = {};
890
- end
891
-
892
- function Compiler:pos(scope)
893
- scope:addReferenceToHigherScope(self.containerFuncScope, self.posVar);
894
- return Ast.VariableExpression(self.containerFuncScope, self.posVar);
895
- end
896
-
897
- function Compiler:posAssignment(scope)
898
- scope:addReferenceToHigherScope(self.containerFuncScope, self.posVar);
899
- return Ast.AssignmentVariable(self.containerFuncScope, self.posVar);
900
- end
901
-
902
- function Compiler:args(scope)
903
- scope:addReferenceToHigherScope(self.containerFuncScope, self.argsVar);
904
- return Ast.VariableExpression(self.containerFuncScope, self.argsVar);
905
- end
906
-
907
- function Compiler:unpack(scope)
908
- scope:addReferenceToHigherScope(self.scope, self.unpackVar);
909
- return Ast.VariableExpression(self.scope, self.unpackVar);
910
- end
911
-
912
- function Compiler:env(scope)
913
- scope:addReferenceToHigherScope(self.scope, self.envVar);
914
- return Ast.VariableExpression(self.scope, self.envVar);
915
- end
916
-
917
- function Compiler:jmp(scope, to)
918
- scope:addReferenceToHigherScope(self.containerFuncScope, self.posVar);
919
- return Ast.AssignmentStatement({Ast.AssignmentVariable(self.containerFuncScope, self.posVar)},{to});
920
- end
921
-
922
- function Compiler:setPos(scope, val)
923
- if not val then
924
-
925
- local v = Ast.IndexExpression(self:env(scope), randomStrings.randomStringNode(math.random(12, 14))); --Ast.NilExpression();
926
- scope:addReferenceToHigherScope(self.containerFuncScope, self.posVar);
927
- return Ast.AssignmentStatement({Ast.AssignmentVariable(self.containerFuncScope, self.posVar)}, {v});
928
- end
929
- scope:addReferenceToHigherScope(self.containerFuncScope, self.posVar);
930
- return Ast.AssignmentStatement({Ast.AssignmentVariable(self.containerFuncScope, self.posVar)}, {Ast.NumberExpression(val) or Ast.NilExpression()});
931
- end
932
-
933
- function Compiler:setReturn(scope, val)
934
- scope:addReferenceToHigherScope(self.containerFuncScope, self.returnVar);
935
- return Ast.AssignmentStatement({Ast.AssignmentVariable(self.containerFuncScope, self.returnVar)}, {val});
936
- end
937
-
938
- function Compiler:getReturn(scope)
939
- scope:addReferenceToHigherScope(self.containerFuncScope, self.returnVar);
940
- return Ast.VariableExpression(self.containerFuncScope, self.returnVar);
941
- end
942
-
943
- function Compiler:returnAssignment(scope)
944
- scope:addReferenceToHigherScope(self.containerFuncScope, self.returnVar);
945
- return Ast.AssignmentVariable(self.containerFuncScope, self.returnVar);
946
- end
947
-
948
- function Compiler:setUpvalueMember(scope, idExpr, valExpr, compoundConstructor)
949
- scope:addReferenceToHigherScope(self.scope, self.upvaluesTable);
950
- if compoundConstructor then
951
- return compoundConstructor(Ast.AssignmentIndexing(Ast.VariableExpression(self.scope, self.upvaluesTable), idExpr), valExpr);
952
- end
953
- return Ast.AssignmentStatement({Ast.AssignmentIndexing(Ast.VariableExpression(self.scope, self.upvaluesTable), idExpr)}, {valExpr});
954
- end
955
-
956
- function Compiler:getUpvalueMember(scope, idExpr)
957
- scope:addReferenceToHigherScope(self.scope, self.upvaluesTable);
958
- return Ast.IndexExpression(Ast.VariableExpression(self.scope, self.upvaluesTable), idExpr);
959
- end
960
-
961
- function Compiler:compileTopNode(node)
962
- -- Create Initial Block
963
- local startBlock = self:createBlock();
964
- local scope = startBlock.scope;
965
- self.startBlockId = startBlock.id;
966
- self:setActiveBlock(startBlock);
967
-
968
- local varAccessLookup = lookupify{
969
- AstKind.AssignmentVariable,
970
- AstKind.VariableExpression,
971
- AstKind.FunctionDeclaration,
972
- AstKind.LocalFunctionDeclaration,
973
- }
974
-
975
- local functionLookup = lookupify{
976
- AstKind.FunctionDeclaration,
977
- AstKind.LocalFunctionDeclaration,
978
- AstKind.FunctionLiteralExpression,
979
- AstKind.TopNode,
980
- }
981
- -- Collect Upvalues
982
- visitast(node, function(node, data)
983
- if node.kind == AstKind.Block then
984
- node.scope.__depth = data.functionData.depth;
985
- end
986
-
987
- if varAccessLookup[node.kind] then
988
- if not node.scope.isGlobal then
989
- if node.scope.__depth < data.functionData.depth then
990
- if not self:isUpvalue(node.scope, node.id) then
991
- self:makeUpvalue(node.scope, node.id);
992
- end
993
- end
994
- end
995
- end
996
- end, nil, nil)
997
-
998
- self.varargReg = self:allocRegister(true);
999
- scope:addReferenceToHigherScope(self.containerFuncScope, self.argsVar);
1000
- scope:addReferenceToHigherScope(self.scope, self.selectVar);
1001
- scope:addReferenceToHigherScope(self.scope, self.unpackVar);
1002
- self:addStatement(self:setRegister(scope, self.varargReg, Ast.VariableExpression(self.containerFuncScope, self.argsVar)), {self.varargReg}, {}, false);
1003
-
1004
- -- Compile Block
1005
- self:compileBlock(node.body, 0);
1006
- if(self.activeBlock.advanceToNextBlock) then
1007
- self:addStatement(self:setPos(self.activeBlock.scope, nil), {self.POS_REGISTER}, {}, false);
1008
- self:addStatement(self:setReturn(self.activeBlock.scope, Ast.TableConstructorExpression({})), {self.RETURN_REGISTER}, {}, false)
1009
- self.activeBlock.advanceToNextBlock = false;
1010
- end
1011
-
1012
- self:resetRegisters();
1013
- end
1014
-
1015
- function Compiler:compileFunction(node, funcDepth)
1016
- funcDepth = funcDepth + 1;
1017
- local oldActiveBlock = self.activeBlock;
1018
-
1019
- local upperVarargReg = self.varargReg;
1020
- self.varargReg = nil;
1021
-
1022
- local upvalueExpressions = {};
1023
- local upvalueIds = {};
1024
- local usedRegs = {};
1025
-
1026
- local oldGetUpvalueId = self.getUpvalueId;
1027
- self.getUpvalueId = function(self, scope, id)
1028
- if(not upvalueIds[scope]) then
1029
- upvalueIds[scope] = {};
1030
- end
1031
- if(upvalueIds[scope][id]) then
1032
- return upvalueIds[scope][id];
1033
- end
1034
- local scopeFuncDepth = self.scopeFunctionDepths[scope];
1035
- local expression;
1036
- if(scopeFuncDepth == funcDepth) then
1037
- oldActiveBlock.scope:addReferenceToHigherScope(self.scope, self.allocUpvalFunction);
1038
- expression = Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.allocUpvalFunction), {});
1039
- elseif(scopeFuncDepth == funcDepth - 1) then
1040
- local varReg = self:getVarRegister(scope, id, scopeFuncDepth, nil);
1041
- expression = self:register(oldActiveBlock.scope, varReg);
1042
- table.insert(usedRegs, varReg);
1043
- else
1044
- local higherId = oldGetUpvalueId(self, scope, id);
1045
- oldActiveBlock.scope:addReferenceToHigherScope(self.containerFuncScope, self.currentUpvaluesVar);
1046
- expression = Ast.IndexExpression(Ast.VariableExpression(self.containerFuncScope, self.currentUpvaluesVar), Ast.NumberExpression(higherId));
1047
- end
1048
- table.insert(upvalueExpressions, Ast.TableEntry(expression));
1049
- local uid = #upvalueExpressions;
1050
- upvalueIds[scope][id] = uid;
1051
- return uid;
1052
- end
1053
-
1054
- local block = self:createBlock();
1055
- self:setActiveBlock(block);
1056
- local scope = self.activeBlock.scope;
1057
- self:pushRegisterUsageInfo();
1058
- for i, arg in ipairs(node.args) do
1059
- if(arg.kind == AstKind.VariableExpression) then
1060
- if(self:isUpvalue(arg.scope, arg.id)) then
1061
- scope:addReferenceToHigherScope(self.scope, self.allocUpvalFunction);
1062
- local argReg = self:getVarRegister(arg.scope, arg.id, funcDepth, nil);
1063
- self:addStatement(self:setRegister(scope, argReg, Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.allocUpvalFunction), {})), {argReg}, {}, false);
1064
- self:addStatement(self:setUpvalueMember(scope, self:register(scope, argReg), Ast.IndexExpression(Ast.VariableExpression(self.containerFuncScope, self.argsVar), Ast.NumberExpression(i))), {}, {argReg}, true);
1065
- else
1066
- local argReg = self:getVarRegister(arg.scope, arg.id, funcDepth, nil);
1067
- scope:addReferenceToHigherScope(self.containerFuncScope, self.argsVar);
1068
- self:addStatement(self:setRegister(scope, argReg, Ast.IndexExpression(Ast.VariableExpression(self.containerFuncScope, self.argsVar), Ast.NumberExpression(i))), {argReg}, {}, false);
1069
- end
1070
- else
1071
- self.varargReg = self:allocRegister(true);
1072
- scope:addReferenceToHigherScope(self.containerFuncScope, self.argsVar);
1073
- scope:addReferenceToHigherScope(self.scope, self.selectVar);
1074
- scope:addReferenceToHigherScope(self.scope, self.unpackVar);
1075
- self:addStatement(self:setRegister(scope, self.varargReg, Ast.TableConstructorExpression({
1076
- Ast.TableEntry(Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.selectVar), {
1077
- Ast.NumberExpression(i);
1078
- Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.unpackVar), {
1079
- Ast.VariableExpression(self.containerFuncScope, self.argsVar),
1080
- });
1081
- })),
1082
- })), {self.varargReg}, {}, false);
1083
- end
1084
- end
1085
-
1086
- self:compileBlock(node.body, funcDepth);
1087
- if(self.activeBlock.advanceToNextBlock) then
1088
- self:addStatement(self:setPos(self.activeBlock.scope, nil), {self.POS_REGISTER}, {}, false);
1089
- self:addStatement(self:setReturn(self.activeBlock.scope, Ast.TableConstructorExpression({})), {self.RETURN_REGISTER}, {}, false);
1090
- self.activeBlock.advanceToNextBlock = false;
1091
- end
1092
-
1093
- if(self.varargReg) then
1094
- self:freeRegister(self.varargReg, true);
1095
- end
1096
- self.varargReg = upperVarargReg;
1097
- self.getUpvalueId = oldGetUpvalueId;
1098
-
1099
- self:popRegisterUsageInfo();
1100
- self:setActiveBlock(oldActiveBlock);
1101
-
1102
- local scope = self.activeBlock.scope;
1103
-
1104
- local retReg = self:allocRegister(false);
1105
-
1106
- local isVarargFunction = #node.args > 0 and node.args[#node.args].kind == AstKind.VarargExpression;
1107
-
1108
- local retrieveExpression
1109
- if isVarargFunction then
1110
- scope:addReferenceToHigherScope(self.scope, self.createVarargClosureVar);
1111
- retrieveExpression = Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.createVarargClosureVar), {
1112
- Ast.NumberExpression(block.id),
1113
- Ast.TableConstructorExpression(upvalueExpressions)
1114
- });
1115
- else
1116
- local varScope, var = self:getCreateClosureVar(#node.args + math.random(0, 5));
1117
- scope:addReferenceToHigherScope(varScope, var);
1118
- retrieveExpression = Ast.FunctionCallExpression(Ast.VariableExpression(varScope, var), {
1119
- Ast.NumberExpression(block.id),
1120
- Ast.TableConstructorExpression(upvalueExpressions)
1121
- });
1122
- end
1123
-
1124
- self:addStatement(self:setRegister(scope, retReg, retrieveExpression), {retReg}, usedRegs, false);
1125
- return retReg;
1126
- end
1127
-
1128
- function Compiler:compileBlock(block, funcDepth)
1129
- for i, stat in ipairs(block.statements) do
1130
- self:compileStatement(stat, funcDepth);
1131
- end
1132
-
1133
- local scope = self.activeBlock.scope;
1134
- for id, name in ipairs(block.scope.variables) do
1135
- local varReg = self:getVarRegister(block.scope, id, funcDepth, nil);
1136
- if self:isUpvalue(block.scope, id) then
1137
- scope:addReferenceToHigherScope(self.scope, self.freeUpvalueFunc);
1138
- self:addStatement(self:setRegister(scope, varReg, Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.freeUpvalueFunc), {
1139
- self:register(scope, varReg)
1140
- })), {varReg}, {varReg}, false);
1141
- else
1142
- self:addStatement(self:setRegister(scope, varReg, Ast.NilExpression()), {varReg}, {}, false);
1143
- end
1144
- self:freeRegister(varReg, true);
1145
- end
1146
- end
1147
-
1148
- function Compiler:compileStatement(statement, funcDepth)
1149
- local scope = self.activeBlock.scope;
1150
- -- Return Statement
1151
- if(statement.kind == AstKind.ReturnStatement) then
1152
- local entries = {};
1153
- local regs = {};
1154
-
1155
- for i, expr in ipairs(statement.args) do
1156
- if i == #statement.args and (expr.kind == AstKind.FunctionCallExpression or expr.kind == AstKind.PassSelfFunctionCallExpression or expr.kind == AstKind.VarargExpression) then
1157
- local reg = self:compileExpression(expr, funcDepth, self.RETURN_ALL)[1];
1158
- table.insert(entries, Ast.TableEntry(Ast.FunctionCallExpression(
1159
- self:unpack(scope),
1160
- {self:register(scope, reg)})));
1161
- table.insert(regs, reg);
1162
- else
1163
- local reg = self:compileExpression(expr, funcDepth, 1)[1];
1164
- table.insert(entries, Ast.TableEntry(self:register(scope, reg)));
1165
- table.insert(regs, reg);
1166
- end
1167
- end
1168
-
1169
- for _, reg in ipairs(regs) do
1170
- self:freeRegister(reg, false);
1171
- end
1172
-
1173
- self:addStatement(self:setReturn(scope, Ast.TableConstructorExpression(entries)), {self.RETURN_REGISTER}, regs, false);
1174
- self:addStatement(self:setPos(self.activeBlock.scope, nil), {self.POS_REGISTER}, {}, false);
1175
- self.activeBlock.advanceToNextBlock = false;
1176
- return;
1177
- end
1178
-
1179
- -- Local Variable Declaration
1180
- if(statement.kind == AstKind.LocalVariableDeclaration) then
1181
- local exprregs = {};
1182
- for i, expr in ipairs(statement.expressions) do
1183
- if(i == #statement.expressions and #statement.ids > #statement.expressions) then
1184
- local regs = self:compileExpression(expr, funcDepth, #statement.ids - #statement.expressions + 1);
1185
- for i, reg in ipairs(regs) do
1186
- table.insert(exprregs, reg);
1187
- end
1188
- else
1189
- if statement.ids[i] or expr.kind == AstKind.FunctionCallExpression or expr.kind == AstKind.PassSelfFunctionCallExpression then
1190
- local reg = self:compileExpression(expr, funcDepth, 1)[1];
1191
- table.insert(exprregs, reg);
1192
- end
1193
- end
1194
- end
1195
-
1196
- if #exprregs == 0 then
1197
- for i=1, #statement.ids do
1198
- table.insert(exprregs, self:compileExpression(Ast.NilExpression(), funcDepth, 1)[1]);
1199
- end
1200
- end
1201
-
1202
- for i, id in ipairs(statement.ids) do
1203
- if(exprregs[i]) then
1204
- if(self:isUpvalue(statement.scope, id)) then
1205
- local varreg = self:getVarRegister(statement.scope, id, funcDepth);
1206
- local varReg = self:getVarRegister(statement.scope, id, funcDepth, nil);
1207
- scope:addReferenceToHigherScope(self.scope, self.allocUpvalFunction);
1208
- self:addStatement(self:setRegister(scope, varReg, Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.allocUpvalFunction), {})), {varReg}, {}, false);
1209
- self:addStatement(self:setUpvalueMember(scope, self:register(scope, varReg), self:register(scope, exprregs[i])), {}, {varReg, exprregs[i]}, true);
1210
- self:freeRegister(exprregs[i], false);
1211
- else
1212
- local varreg = self:getVarRegister(statement.scope, id, funcDepth, exprregs[i]);
1213
- self:addStatement(self:copyRegisters(scope, {varreg}, {exprregs[i]}), {varreg}, {exprregs[i]}, false);
1214
- self:freeRegister(exprregs[i], false);
1215
- end
1216
- end
1217
- end
1218
-
1219
- if not self.scopeFunctionDepths[statement.scope] then
1220
- self.scopeFunctionDepths[statement.scope] = funcDepth;
1221
- end
1222
-
1223
- return;
1224
- end
1225
-
1226
- -- Function Call Statement
1227
- if(statement.kind == AstKind.FunctionCallStatement) then
1228
- local baseReg = self:compileExpression(statement.base, funcDepth, 1)[1];
1229
- local retReg = self:allocRegister(false);
1230
- local regs = {};
1231
- local args = {};
1232
-
1233
- for i, expr in ipairs(statement.args) do
1234
- if i == #statement.args and (expr.kind == AstKind.FunctionCallExpression or expr.kind == AstKind.PassSelfFunctionCallExpression or expr.kind == AstKind.VarargExpression) then
1235
- local reg = self:compileExpression(expr, funcDepth, self.RETURN_ALL)[1];
1236
- table.insert(args, Ast.FunctionCallExpression(
1237
- self:unpack(scope),
1238
- {self:register(scope, reg)}));
1239
- table.insert(regs, reg);
1240
- else
1241
- local reg = self:compileExpression(expr, funcDepth, 1)[1];
1242
- table.insert(args, self:register(scope, reg));
1243
- table.insert(regs, reg);
1244
- end
1245
- end
1246
-
1247
- self:addStatement(self:setRegister(scope, retReg, Ast.FunctionCallExpression(self:register(scope, baseReg), args)), {retReg}, {baseReg, unpack(regs)}, true);
1248
- self:freeRegister(baseReg, false);
1249
- self:freeRegister(retReg, false);
1250
- for i, reg in ipairs(regs) do
1251
- self:freeRegister(reg, false);
1252
- end
1253
-
1254
- return;
1255
- end
1256
-
1257
- -- Pass Self Function Call Statement
1258
- if(statement.kind == AstKind.PassSelfFunctionCallStatement) then
1259
- local baseReg = self:compileExpression(statement.base, funcDepth, 1)[1];
1260
- local tmpReg = self:allocRegister(false);
1261
- local args = { self:register(scope, baseReg) };
1262
- local regs = { baseReg };
1263
-
1264
- for i, expr in ipairs(statement.args) do
1265
- if i == #statement.args and (expr.kind == AstKind.FunctionCallExpression or expr.kind == AstKind.PassSelfFunctionCallExpression or expr.kind == AstKind.VarargExpression) then
1266
- local reg = self:compileExpression(expr, funcDepth, self.RETURN_ALL)[1];
1267
- table.insert(args, Ast.FunctionCallExpression(
1268
- self:unpack(scope),
1269
- {self:register(scope, reg)}));
1270
- table.insert(regs, reg);
1271
- else
1272
- local reg = self:compileExpression(expr, funcDepth, 1)[1];
1273
- table.insert(args, self:register(scope, reg));
1274
- table.insert(regs, reg);
1275
- end
1276
- end
1277
- self:addStatement(self:setRegister(scope, tmpReg, Ast.StringExpression(statement.passSelfFunctionName)), {tmpReg}, {}, false);
1278
- self:addStatement(self:setRegister(scope, tmpReg, Ast.IndexExpression(self:register(scope, baseReg), self:register(scope, tmpReg))), {tmpReg}, {tmpReg, baseReg}, false);
1279
-
1280
- self:addStatement(self:setRegister(scope, tmpReg, Ast.FunctionCallExpression(self:register(scope, tmpReg), args)), {tmpReg}, {tmpReg, unpack(regs)}, true);
1281
-
1282
- self:freeRegister(tmpReg, false);
1283
- for i, reg in ipairs(regs) do
1284
- self:freeRegister(reg, false);
1285
- end
1286
-
1287
- return;
1288
- end
1289
-
1290
- -- Local Function Declaration
1291
- if(statement.kind == AstKind.LocalFunctionDeclaration) then
1292
-
1293
- if(self:isUpvalue(statement.scope, statement.id)) then
1294
- local varReg = self:getVarRegister(statement.scope, statement.id, funcDepth, nil);
1295
- scope:addReferenceToHigherScope(self.scope, self.allocUpvalFunction);
1296
- self:addStatement(self:setRegister(scope, varReg, Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.allocUpvalFunction), {})), {varReg}, {}, false);
1297
- local retReg = self:compileFunction(statement, funcDepth);
1298
- self:addStatement(self:setUpvalueMember(scope, self:register(scope, varReg), self:register(scope, retReg)), {}, {varReg, retReg}, true);
1299
- self:freeRegister(retReg, false);
1300
- else
1301
- local retReg = self:compileFunction(statement, funcDepth);
1302
- local varReg = self:getVarRegister(statement.scope, statement.id, funcDepth, retReg);
1303
- self:addStatement(self:copyRegisters(scope, {varReg}, {retReg}), {varReg}, {retReg}, false);
1304
- self:freeRegister(retReg, false);
1305
- end
1306
- return;
1307
- end
1308
-
1309
- -- Function Declaration
1310
- if(statement.kind == AstKind.FunctionDeclaration) then
1311
- local retReg = self:compileFunction(statement, funcDepth);
1312
- if(#statement.indices > 0) then
1313
- local tblReg;
1314
- if statement.scope.isGlobal then
1315
- tblReg = self:allocRegister(false);
1316
- self:addStatement(self:setRegister(scope, tblReg, Ast.StringExpression(statement.scope:getVariableName(statement.id))), {tblReg}, {}, false);
1317
- self:addStatement(self:setRegister(scope, tblReg, Ast.IndexExpression(self:env(scope), self:register(scope, tblReg))), {tblReg}, {tblReg}, true);
1318
- else
1319
- if self.scopeFunctionDepths[statement.scope] == funcDepth then
1320
- if self:isUpvalue(statement.scope, statement.id) then
1321
- tblReg = self:allocRegister(false);
1322
- local reg = self:getVarRegister(statement.scope, statement.id, funcDepth);
1323
- self:addStatement(self:setRegister(scope, tblReg, self:getUpvalueMember(scope, self:register(scope, reg))), {tblReg}, {reg}, true);
1324
- else
1325
- tblReg = self:getVarRegister(statement.scope, statement.id, funcDepth, retReg);
1326
- end
1327
- else
1328
- tblReg = self:allocRegister(false);
1329
- local upvalId = self:getUpvalueId(statement.scope, statement.id);
1330
- scope:addReferenceToHigherScope(self.containerFuncScope, self.currentUpvaluesVar);
1331
- self:addStatement(self:setRegister(scope, tblReg, self:getUpvalueMember(scope, Ast.IndexExpression(Ast.VariableExpression(self.containerFuncScope, self.currentUpvaluesVar), Ast.NumberExpression(upvalId)))), {tblReg}, {}, true);
1332
- end
1333
- end
1334
-
1335
- for i = 1, #statement.indices - 1 do
1336
- local index = statement.indices[i];
1337
- local indexReg = self:compileExpression(Ast.StringExpression(index), funcDepth, 1)[1];
1338
- local tblRegOld = tblReg;
1339
- tblReg = self:allocRegister(false);
1340
- self:addStatement(self:setRegister(scope, tblReg, Ast.IndexExpression(self:register(scope, tblRegOld), self:register(scope, indexReg))), {tblReg}, {tblReg, indexReg}, false);
1341
- self:freeRegister(tblRegOld, false);
1342
- self:freeRegister(indexReg, false);
1343
- end
1344
-
1345
- local index = statement.indices[#statement.indices];
1346
- local indexReg = self:compileExpression(Ast.StringExpression(index), funcDepth, 1)[1];
1347
- self:addStatement(Ast.AssignmentStatement({
1348
- Ast.AssignmentIndexing(self:register(scope, tblReg), self:register(scope, indexReg)),
1349
- }, {
1350
- self:register(scope, retReg),
1351
- }), {}, {tblReg, indexReg, retReg}, true);
1352
- self:freeRegister(indexReg, false);
1353
- self:freeRegister(tblReg, false);
1354
- self:freeRegister(retReg, false);
1355
-
1356
- return;
1357
- end
1358
- if statement.scope.isGlobal then
1359
- local tmpReg = self:allocRegister(false);
1360
- self:addStatement(self:setRegister(scope, tmpReg, Ast.StringExpression(statement.scope:getVariableName(statement.id))), {tmpReg}, {}, false);
1361
- self:addStatement(Ast.AssignmentStatement({Ast.AssignmentIndexing(self:env(scope), self:register(scope, tmpReg))},
1362
- {self:register(scope, retReg)}), {}, {tmpReg, retReg}, true);
1363
- self:freeRegister(tmpReg, false);
1364
- else
1365
- if self.scopeFunctionDepths[statement.scope] == funcDepth then
1366
- if self:isUpvalue(statement.scope, statement.id) then
1367
- local reg = self:getVarRegister(statement.scope, statement.id, funcDepth);
1368
- self:addStatement(self:setUpvalueMember(scope, self:register(scope, reg), self:register(scope, retReg)), {}, {reg, retReg}, true);
1369
- else
1370
- local reg = self:getVarRegister(statement.scope, statement.id, funcDepth, retReg);
1371
- if reg ~= retReg then
1372
- self:addStatement(self:setRegister(scope, reg, self:register(scope, retReg)), {reg}, {retReg}, false);
1373
- end
1374
- end
1375
- else
1376
- local upvalId = self:getUpvalueId(statement.scope, statement.id);
1377
- scope:addReferenceToHigherScope(self.containerFuncScope, self.currentUpvaluesVar);
1378
- self:addStatement(self:setUpvalueMember(scope, Ast.IndexExpression(Ast.VariableExpression(self.containerFuncScope, self.currentUpvaluesVar), Ast.NumberExpression(upvalId)), self:register(scope, retReg)), {}, {retReg}, true);
1379
- end
1380
- end
1381
- self:freeRegister(retReg, false);
1382
- return;
1383
- end
1384
-
1385
- -- Assignment Statement
1386
- if(statement.kind == AstKind.AssignmentStatement) then
1387
- local exprregs = {};
1388
- local assignmentIndexingRegs = {};
1389
- for i, primaryExpr in ipairs(statement.lhs) do
1390
- if(primaryExpr.kind == AstKind.AssignmentIndexing) then
1391
- assignmentIndexingRegs [i] = {
1392
- base = self:compileExpression(primaryExpr.base, funcDepth, 1)[1],
1393
- index = self:compileExpression(primaryExpr.index, funcDepth, 1)[1],
1394
- };
1395
- end
1396
- end
1397
-
1398
- for i, expr in ipairs(statement.rhs) do
1399
- if(i == #statement.rhs and #statement.lhs > #statement.rhs) then
1400
- local regs = self:compileExpression(expr, funcDepth, #statement.lhs - #statement.rhs + 1);
1401
-
1402
- for i, reg in ipairs(regs) do
1403
- if(self:isVarRegister(reg)) then
1404
- local ro = reg;
1405
- reg = self:allocRegister(false);
1406
- self:addStatement(self:copyRegisters(scope, {reg}, {ro}), {reg}, {ro}, false);
1407
- end
1408
- table.insert(exprregs, reg);
1409
- end
1410
- else
1411
- if statement.lhs[i] or expr.kind == AstKind.FunctionCallExpression or expr.kind == AstKind.PassSelfFunctionCallExpression then
1412
- local reg = self:compileExpression(expr, funcDepth, 1)[1];
1413
- if(self:isVarRegister(reg)) then
1414
- local ro = reg;
1415
- reg = self:allocRegister(false);
1416
- self:addStatement(self:copyRegisters(scope, {reg}, {ro}), {reg}, {ro}, false);
1417
- end
1418
- table.insert(exprregs, reg);
1419
- end
1420
- end
1421
- end
1422
-
1423
- for i, primaryExpr in ipairs(statement.lhs) do
1424
- if primaryExpr.kind == AstKind.AssignmentVariable then
1425
- if primaryExpr.scope.isGlobal then
1426
- local tmpReg = self:allocRegister(false);
1427
- self:addStatement(self:setRegister(scope, tmpReg, Ast.StringExpression(primaryExpr.scope:getVariableName(primaryExpr.id))), {tmpReg}, {}, false);
1428
- self:addStatement(Ast.AssignmentStatement({Ast.AssignmentIndexing(self:env(scope), self:register(scope, tmpReg))},
1429
- {self:register(scope, exprregs[i])}), {}, {tmpReg, exprregs[i]}, true);
1430
- self:freeRegister(tmpReg, false);
1431
- else
1432
- if self.scopeFunctionDepths[primaryExpr.scope] == funcDepth then
1433
- if self:isUpvalue(primaryExpr.scope, primaryExpr.id) then
1434
- local reg = self:getVarRegister(primaryExpr.scope, primaryExpr.id, funcDepth);
1435
- self:addStatement(self:setUpvalueMember(scope, self:register(scope, reg), self:register(scope, exprregs[i])), {}, {reg, exprregs[i]}, true);
1436
- else
1437
- local reg = self:getVarRegister(primaryExpr.scope, primaryExpr.id, funcDepth, exprregs[i]);
1438
- if reg ~= exprregs[i] then
1439
- self:addStatement(self:setRegister(scope, reg, self:register(scope, exprregs[i])), {reg}, {exprregs[i]}, false);
1440
- end
1441
- end
1442
- else
1443
- local upvalId = self:getUpvalueId(primaryExpr.scope, primaryExpr.id);
1444
- scope:addReferenceToHigherScope(self.containerFuncScope, self.currentUpvaluesVar);
1445
- self:addStatement(self:setUpvalueMember(scope, Ast.IndexExpression(Ast.VariableExpression(self.containerFuncScope, self.currentUpvaluesVar), Ast.NumberExpression(upvalId)), self:register(scope, exprregs[i])), {}, {exprregs[i]}, true);
1446
- end
1447
- end
1448
- elseif primaryExpr.kind == AstKind.AssignmentIndexing then
1449
- local baseReg = assignmentIndexingRegs[i].base;
1450
- local indexReg = assignmentIndexingRegs[i].index;
1451
- self:addStatement(Ast.AssignmentStatement({
1452
- Ast.AssignmentIndexing(self:register(scope, baseReg), self:register(scope, indexReg))
1453
- }, {
1454
- self:register(scope, exprregs[i])
1455
- }), {}, {exprregs[i], baseReg, indexReg}, true);
1456
- self:freeRegister(exprregs[i], false);
1457
- self:freeRegister(baseReg, false);
1458
- self:freeRegister(indexReg, false);
1459
- else
1460
- error(string.format("Invalid Assignment lhs: %s", statement.lhs));
1461
- end
1462
- end
1463
-
1464
- return
1465
- end
1466
-
1467
- -- If Statement
1468
- if(statement.kind == AstKind.IfStatement) then
1469
- local conditionReg = self:compileExpression(statement.condition, funcDepth, 1)[1];
1470
- local finalBlock = self:createBlock();
1471
-
1472
- local nextBlock
1473
- if statement.elsebody or #statement.elseifs > 0 then
1474
- nextBlock = self:createBlock();
1475
- else
1476
- nextBlock = finalBlock;
1477
- end
1478
- local innerBlock = self:createBlock();
1479
-
1480
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.OrExpression(Ast.AndExpression(self:register(scope, conditionReg), Ast.NumberExpression(innerBlock.id)), Ast.NumberExpression(nextBlock.id))), {self.POS_REGISTER}, {conditionReg}, false);
1481
-
1482
- self:freeRegister(conditionReg, false);
1483
-
1484
- self:setActiveBlock(innerBlock);
1485
- scope = innerBlock.scope
1486
- self:compileBlock(statement.body, funcDepth);
1487
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.NumberExpression(finalBlock.id)), {self.POS_REGISTER}, {}, false);
1488
-
1489
- for i, eif in ipairs(statement.elseifs) do
1490
- self:setActiveBlock(nextBlock);
1491
- conditionReg = self:compileExpression(eif.condition, funcDepth, 1)[1];
1492
- local innerBlock = self:createBlock();
1493
- if statement.elsebody or i < #statement.elseifs then
1494
- nextBlock = self:createBlock();
1495
- else
1496
- nextBlock = finalBlock;
1497
- end
1498
- local scope = self.activeBlock.scope;
1499
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.OrExpression(Ast.AndExpression(self:register(scope, conditionReg), Ast.NumberExpression(innerBlock.id)), Ast.NumberExpression(nextBlock.id))), {self.POS_REGISTER}, {conditionReg}, false);
1500
-
1501
- self:freeRegister(conditionReg, false);
1502
-
1503
- self:setActiveBlock(innerBlock);
1504
- scope = innerBlock.scope;
1505
- self:compileBlock(eif.body, funcDepth);
1506
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.NumberExpression(finalBlock.id)), {self.POS_REGISTER}, {}, false);
1507
- end
1508
-
1509
- if statement.elsebody then
1510
- self:setActiveBlock(nextBlock);
1511
- self:compileBlock(statement.elsebody, funcDepth);
1512
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.NumberExpression(finalBlock.id)), {self.POS_REGISTER}, {}, false);
1513
- end
1514
-
1515
- self:setActiveBlock(finalBlock);
1516
-
1517
- return;
1518
- end
1519
-
1520
- -- Do Statement
1521
- if(statement.kind == AstKind.DoStatement) then
1522
- self:compileBlock(statement.body, funcDepth);
1523
- return;
1524
- end
1525
-
1526
- -- While Statement
1527
- if(statement.kind == AstKind.WhileStatement) then
1528
- local innerBlock = self:createBlock();
1529
- local finalBlock = self:createBlock();
1530
- local checkBlock = self:createBlock();
1531
-
1532
- statement.__start_block = checkBlock;
1533
- statement.__final_block = finalBlock;
1534
-
1535
- self:addStatement(self:setPos(scope, checkBlock.id), {self.POS_REGISTER}, {}, false);
1536
-
1537
- self:setActiveBlock(checkBlock);
1538
- local scope = self.activeBlock.scope;
1539
- local conditionReg = self:compileExpression(statement.condition, funcDepth, 1)[1];
1540
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.OrExpression(Ast.AndExpression(self:register(scope, conditionReg), Ast.NumberExpression(innerBlock.id)), Ast.NumberExpression(finalBlock.id))), {self.POS_REGISTER}, {conditionReg}, false);
1541
- self:freeRegister(conditionReg, false);
1542
-
1543
- self:setActiveBlock(innerBlock);
1544
- local scope = self.activeBlock.scope;
1545
- self:compileBlock(statement.body, funcDepth);
1546
- self:addStatement(self:setPos(scope, checkBlock.id), {self.POS_REGISTER}, {}, false);
1547
- self:setActiveBlock(finalBlock);
1548
- return;
1549
- end
1550
-
1551
- -- Repeat Statement
1552
- if(statement.kind == AstKind.RepeatStatement) then
1553
- local innerBlock = self:createBlock();
1554
- local finalBlock = self:createBlock();
1555
- local checkBlock = self:createBlock();
1556
- statement.__start_block = checkBlock;
1557
- statement.__final_block = finalBlock;
1558
-
1559
- local conditionReg = self:compileExpression(statement.condition, funcDepth, 1)[1];
1560
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.NumberExpression(innerBlock.id)), {self.POS_REGISTER}, {}, false);
1561
- self:freeRegister(conditionReg, false);
1562
-
1563
- self:setActiveBlock(innerBlock);
1564
- self:compileBlock(statement.body, funcDepth);
1565
- local scope = self.activeBlock.scope
1566
- self:addStatement(self:setPos(scope, checkBlock.id), {self.POS_REGISTER}, {}, false);
1567
- self:setActiveBlock(checkBlock);
1568
- local scope = self.activeBlock.scope;
1569
- local conditionReg = self:compileExpression(statement.condition, funcDepth, 1)[1];
1570
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.OrExpression(Ast.AndExpression(self:register(scope, conditionReg), Ast.NumberExpression(finalBlock.id)), Ast.NumberExpression(innerBlock.id))), {self.POS_REGISTER}, {conditionReg}, false);
1571
- self:freeRegister(conditionReg, false);
1572
-
1573
- self:setActiveBlock(finalBlock);
1574
-
1575
- return;
1576
- end
1577
-
1578
- -- For Statement
1579
- if(statement.kind == AstKind.ForStatement) then
1580
- local checkBlock = self:createBlock();
1581
- local innerBlock = self:createBlock();
1582
- local finalBlock = self:createBlock();
1583
-
1584
- statement.__start_block = checkBlock;
1585
- statement.__final_block = finalBlock;
1586
-
1587
- local posState = self.registers[self.POS_REGISTER];
1588
- self.registers[self.POS_REGISTER] = self.VAR_REGISTER;
1589
-
1590
- local initialReg = self:compileExpression(statement.initialValue, funcDepth, 1)[1];
1591
-
1592
- local finalExprReg = self:compileExpression(statement.finalValue, funcDepth, 1)[1];
1593
- local finalReg = self:allocRegister(false);
1594
- self:addStatement(self:copyRegisters(scope, {finalReg}, {finalExprReg}), {finalReg}, {finalExprReg}, false);
1595
- self:freeRegister(finalExprReg);
1596
-
1597
- local incrementExprReg = self:compileExpression(statement.incrementBy, funcDepth, 1)[1];
1598
- local incrementReg = self:allocRegister(false);
1599
- self:addStatement(self:copyRegisters(scope, {incrementReg}, {incrementExprReg}), {incrementReg}, {incrementExprReg}, false);
1600
- self:freeRegister(incrementExprReg);
1601
-
1602
- local tmpReg = self:allocRegister(false);
1603
- self:addStatement(self:setRegister(scope, tmpReg, Ast.NumberExpression(0)), {tmpReg}, {}, false);
1604
- local incrementIsNegReg = self:allocRegister(false);
1605
- self:addStatement(self:setRegister(scope, incrementIsNegReg, Ast.LessThanExpression(self:register(scope, incrementReg), self:register(scope, tmpReg))), {incrementIsNegReg}, {incrementReg, tmpReg}, false);
1606
- self:freeRegister(tmpReg);
1607
-
1608
- local currentReg = self:allocRegister(true);
1609
- self:addStatement(self:setRegister(scope, currentReg, Ast.SubExpression(self:register(scope, initialReg), self:register(scope, incrementReg))), {currentReg}, {initialReg, incrementReg}, false);
1610
- self:freeRegister(initialReg);
1611
-
1612
- self:addStatement(self:jmp(scope, Ast.NumberExpression(checkBlock.id)), {self.POS_REGISTER}, {}, false);
1613
-
1614
- self:setActiveBlock(checkBlock);
1615
-
1616
- scope = checkBlock.scope;
1617
- self:addStatement(self:setRegister(scope, currentReg, Ast.AddExpression(self:register(scope, currentReg), self:register(scope, incrementReg))), {currentReg}, {currentReg, incrementReg}, false);
1618
- local tmpReg1 = self:allocRegister(false);
1619
- local tmpReg2 = self:allocRegister(false);
1620
- self:addStatement(self:setRegister(scope, tmpReg2, Ast.NotExpression(self:register(scope, incrementIsNegReg))), {tmpReg2}, {incrementIsNegReg}, false);
1621
- self:addStatement(self:setRegister(scope, tmpReg1, Ast.LessThanOrEqualsExpression(self:register(scope, currentReg), self:register(scope, finalReg))), {tmpReg1}, {currentReg, finalReg}, false);
1622
- self:addStatement(self:setRegister(scope, tmpReg1, Ast.AndExpression(self:register(scope, tmpReg2), self:register(scope, tmpReg1))), {tmpReg1}, {tmpReg1, tmpReg2}, false);
1623
- self:addStatement(self:setRegister(scope, tmpReg2, Ast.GreaterThanOrEqualsExpression(self:register(scope, currentReg), self:register(scope, finalReg))), {tmpReg2}, {currentReg, finalReg}, false);
1624
- self:addStatement(self:setRegister(scope, tmpReg2, Ast.AndExpression(self:register(scope, incrementIsNegReg), self:register(scope, tmpReg2))), {tmpReg2}, {tmpReg2, incrementIsNegReg}, false);
1625
- self:addStatement(self:setRegister(scope, tmpReg1, Ast.OrExpression(self:register(scope, tmpReg2), self:register(scope, tmpReg1))), {tmpReg1}, {tmpReg1, tmpReg2}, false);
1626
- self:freeRegister(tmpReg2);
1627
- tmpReg2 = self:compileExpression(Ast.NumberExpression(innerBlock.id), funcDepth, 1)[1];
1628
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.AndExpression(self:register(scope, tmpReg1), self:register(scope, tmpReg2))), {self.POS_REGISTER}, {tmpReg1, tmpReg2}, false);
1629
- self:freeRegister(tmpReg2);
1630
- self:freeRegister(tmpReg1);
1631
- tmpReg2 = self:compileExpression(Ast.NumberExpression(finalBlock.id), funcDepth, 1)[1];
1632
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.OrExpression(self:register(scope, self.POS_REGISTER), self:register(scope, tmpReg2))), {self.POS_REGISTER}, {self.POS_REGISTER, tmpReg2}, false);
1633
- self:freeRegister(tmpReg2);
1634
-
1635
- self:setActiveBlock(innerBlock);
1636
- scope = innerBlock.scope;
1637
- self.registers[self.POS_REGISTER] = posState;
1638
-
1639
- local varReg = self:getVarRegister(statement.scope, statement.id, funcDepth, nil);
1640
-
1641
- if(self:isUpvalue(statement.scope, statement.id)) then
1642
- scope:addReferenceToHigherScope(self.scope, self.allocUpvalFunction);
1643
- self:addStatement(self:setRegister(scope, varReg, Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.allocUpvalFunction), {})), {varReg}, {}, false);
1644
- self:addStatement(self:setUpvalueMember(scope, self:register(scope, varReg), self:register(scope, currentReg)), {}, {varReg, currentReg}, true);
1645
- else
1646
- self:addStatement(self:setRegister(scope, varReg, self:register(scope, currentReg)), {varReg}, {currentReg}, false);
1647
- end
1648
-
1649
-
1650
- self:compileBlock(statement.body, funcDepth);
1651
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.NumberExpression(checkBlock.id)), {self.POS_REGISTER}, {}, false);
1652
-
1653
- self.registers[self.POS_REGISTER] = self.VAR_REGISTER;
1654
- self:freeRegister(finalReg);
1655
- self:freeRegister(incrementIsNegReg);
1656
- self:freeRegister(incrementReg);
1657
- self:freeRegister(currentReg, true);
1658
-
1659
- self.registers[self.POS_REGISTER] = posState;
1660
- self:setActiveBlock(finalBlock);
1661
-
1662
- return;
1663
- end
1664
-
1665
- -- For In Statement
1666
- if(statement.kind == AstKind.ForInStatement) then
1667
- local expressionsLength = #statement.expressions;
1668
- local exprregs = {};
1669
- for i, expr in ipairs(statement.expressions) do
1670
- if(i == expressionsLength and expressionsLength < 3) then
1671
- local regs = self:compileExpression(expr, funcDepth, 4 - expressionsLength);
1672
- for i = 1, 4 - expressionsLength do
1673
- table.insert(exprregs, regs[i]);
1674
- end
1675
- else
1676
- if i <= 3 then
1677
- table.insert(exprregs, self:compileExpression(expr, funcDepth, 1)[1])
1678
- else
1679
- self:freeRegister(self:compileExpression(expr, funcDepth, 1)[1], false);
1680
- end
1681
- end
1682
- end
1683
-
1684
- for i, reg in ipairs(exprregs) do
1685
- if reg and self.registers[reg] ~= self.VAR_REGISTER and reg ~= self.POS_REGISTER and reg ~= self.RETURN_REGISTER then
1686
- self.registers[reg] = self.VAR_REGISTER;
1687
- else
1688
- exprregs[i] = self:allocRegister(true);
1689
- self:addStatement(self:copyRegisters(scope, {exprregs[i]}, {reg}), {exprregs[i]}, {reg}, false);
1690
- end
1691
- end
1692
-
1693
- local checkBlock = self:createBlock();
1694
- local bodyBlock = self:createBlock();
1695
- local finalBlock = self:createBlock();
1696
-
1697
- statement.__start_block = checkBlock;
1698
- statement.__final_block = finalBlock;
1699
-
1700
- self:addStatement(self:setPos(scope, checkBlock.id), {self.POS_REGISTER}, {}, false);
1701
-
1702
- self:setActiveBlock(checkBlock);
1703
- local scope = self.activeBlock.scope;
1704
-
1705
- local varRegs = {};
1706
- for i, id in ipairs(statement.ids) do
1707
- varRegs[i] = self:getVarRegister(statement.scope, id, funcDepth)
1708
- end
1709
-
1710
- self:addStatement(Ast.AssignmentStatement({
1711
- self:registerAssignment(scope, exprregs[3]),
1712
- varRegs[2] and self:registerAssignment(scope, varRegs[2]),
1713
- }, {
1714
- Ast.FunctionCallExpression(self:register(scope, exprregs[1]), {
1715
- self:register(scope, exprregs[2]),
1716
- self:register(scope, exprregs[3]),
1717
- })
1718
- }), {exprregs[3], varRegs[2]}, {exprregs[1], exprregs[2], exprregs[3]}, true);
1719
-
1720
- self:addStatement(Ast.AssignmentStatement({
1721
- self:posAssignment(scope)
1722
- }, {
1723
- Ast.OrExpression(Ast.AndExpression(self:register(scope, exprregs[3]), Ast.NumberExpression(bodyBlock.id)), Ast.NumberExpression(finalBlock.id))
1724
- }), {self.POS_REGISTER}, {exprregs[3]}, false);
1725
-
1726
- self:setActiveBlock(bodyBlock);
1727
- local scope = self.activeBlock.scope;
1728
- self:addStatement(self:copyRegisters(scope, {varRegs[1]}, {exprregs[3]}), {varRegs[1]}, {exprregs[3]}, false);
1729
- for i=3, #varRegs do
1730
- self:addStatement(self:setRegister(scope, varRegs[i], Ast.NilExpression()), {varRegs[i]}, {}, false);
1731
- end
1732
-
1733
- -- Upvalue fix
1734
- for i, id in ipairs(statement.ids) do
1735
- if(self:isUpvalue(statement.scope, id)) then
1736
- local varreg = varRegs[i];
1737
- local tmpReg = self:allocRegister(false);
1738
- scope:addReferenceToHigherScope(self.scope, self.allocUpvalFunction);
1739
- self:addStatement(self:setRegister(scope, tmpReg, Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.allocUpvalFunction), {})), {tmpReg}, {}, false);
1740
- self:addStatement(self:setUpvalueMember(scope, self:register(scope, tmpReg), self:register(scope, varreg)), {}, {tmpReg, varreg}, true);
1741
- self:addStatement(self:copyRegisters(scope, {varreg}, {tmpReg}), {varreg}, {tmpReg}, false);
1742
- self:freeRegister(tmpReg, false);
1743
- end
1744
- end
1745
-
1746
- self:compileBlock(statement.body, funcDepth);
1747
- self:addStatement(self:setPos(scope, checkBlock.id), {self.POS_REGISTER}, {}, false);
1748
- self:setActiveBlock(finalBlock);
1749
-
1750
- for i, reg in ipairs(exprregs) do
1751
- self:freeRegister(exprregs[i], true)
1752
- end
1753
-
1754
- return;
1755
- end
1756
-
1757
- -- Do Statement
1758
- if(statement.kind == AstKind.DoStatement) then
1759
- self:compileBlock(statement.body, funcDepth);
1760
- return;
1761
- end
1762
-
1763
- -- Break Statement
1764
- if(statement.kind == AstKind.BreakStatement) then
1765
- local toFreeVars = {};
1766
- local statScope;
1767
- repeat
1768
- statScope = statScope and statScope.parentScope or statement.scope;
1769
- for id, name in ipairs(statScope.variables) do
1770
- table.insert(toFreeVars, {
1771
- scope = statScope,
1772
- id = id;
1773
- });
1774
- end
1775
- until statScope == statement.loop.body.scope;
1776
-
1777
- for i, var in pairs(toFreeVars) do
1778
- local varScope, id = var.scope, var.id;
1779
- local varReg = self:getVarRegister(varScope, id, nil, nil);
1780
- if self:isUpvalue(varScope, id) then
1781
- scope:addReferenceToHigherScope(self.scope, self.freeUpvalueFunc);
1782
- self:addStatement(self:setRegister(scope, varReg, Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.freeUpvalueFunc), {
1783
- self:register(scope, varReg)
1784
- })), {varReg}, {varReg}, false);
1785
- else
1786
- self:addStatement(self:setRegister(scope, varReg, Ast.NilExpression()), {varReg}, {}, false);
1787
- end
1788
- end
1789
-
1790
- self:addStatement(self:setPos(scope, statement.loop.__final_block.id), {self.POS_REGISTER}, {}, false);
1791
- self.activeBlock.advanceToNextBlock = false;
1792
- return;
1793
- end
1794
-
1795
- -- Continue Statement
1796
- if(statement.kind == AstKind.ContinueStatement) then
1797
- local toFreeVars = {};
1798
- local statScope;
1799
- repeat
1800
- statScope = statScope and statScope.parentScope or statement.scope;
1801
- for id, name in pairs(statScope.variables) do
1802
- table.insert(toFreeVars, {
1803
- scope = statScope,
1804
- id = id;
1805
- });
1806
- end
1807
- until statScope == statement.loop.body.scope;
1808
-
1809
- for i, var in ipairs(toFreeVars) do
1810
- local varScope, id = var.scope, var.id;
1811
- local varReg = self:getVarRegister(varScope, id, nil, nil);
1812
- if self:isUpvalue(varScope, id) then
1813
- scope:addReferenceToHigherScope(self.scope, self.freeUpvalueFunc);
1814
- self:addStatement(self:setRegister(scope, varReg, Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.freeUpvalueFunc), {
1815
- self:register(scope, varReg)
1816
- })), {varReg}, {varReg}, false);
1817
- else
1818
- self:addStatement(self:setRegister(scope, varReg, Ast.NilExpression()), {varReg}, {}, false);
1819
- end
1820
- end
1821
-
1822
- self:addStatement(self:setPos(scope, statement.loop.__start_block.id), {self.POS_REGISTER}, {}, false);
1823
- self.activeBlock.advanceToNextBlock = false;
1824
- return;
1825
- end
1826
-
1827
- -- Compound Statements
1828
- local compoundConstructors = {
1829
- [AstKind.CompoundAddStatement] = Ast.CompoundAddStatement,
1830
- [AstKind.CompoundSubStatement] = Ast.CompoundSubStatement,
1831
- [AstKind.CompoundMulStatement] = Ast.CompoundMulStatement,
1832
- [AstKind.CompoundDivStatement] = Ast.CompoundDivStatement,
1833
- [AstKind.CompoundModStatement] = Ast.CompoundModStatement,
1834
- [AstKind.CompoundPowStatement] = Ast.CompoundPowStatement,
1835
- [AstKind.CompoundConcatStatement] = Ast.CompoundConcatStatement,
1836
- }
1837
- if compoundConstructors[statement.kind] then
1838
- local compoundConstructor = compoundConstructors[statement.kind];
1839
- if statement.lhs.kind == AstKind.AssignmentIndexing then
1840
- local indexing = statement.lhs;
1841
- local baseReg = self:compileExpression(indexing.base, funcDepth, 1)[1];
1842
- local indexReg = self:compileExpression(indexing.index, funcDepth, 1)[1];
1843
- local valueReg = self:compileExpression(statement.rhs, funcDepth, 1)[1];
1844
-
1845
- self:addStatement(compoundConstructor(Ast.AssignmentIndexing(self:register(scope, baseReg), self:register(scope, indexReg)), self:register(scope, valueReg)), {}, {baseReg, indexReg, valueReg}, true);
1846
- else
1847
- local valueReg = self:compileExpression(statement.rhs, funcDepth, 1)[1];
1848
- local primaryExpr = statement.lhs;
1849
- if primaryExpr.scope.isGlobal then
1850
- local tmpReg = self:allocRegister(false);
1851
- self:addStatement(self:setRegister(scope, tmpReg, Ast.StringExpression(primaryExpr.scope:getVariableName(primaryExpr.id))), {tmpReg}, {}, false);
1852
- self:addStatement(Ast.AssignmentStatement({Ast.AssignmentIndexing(self:env(scope), self:register(scope, tmpReg))},
1853
- {self:register(scope, valueReg)}), {}, {tmpReg, valueReg}, true);
1854
- self:freeRegister(tmpReg, false);
1855
- else
1856
- if self.scopeFunctionDepths[primaryExpr.scope] == funcDepth then
1857
- if self:isUpvalue(primaryExpr.scope, primaryExpr.id) then
1858
- local reg = self:getVarRegister(primaryExpr.scope, primaryExpr.id, funcDepth);
1859
- self:addStatement(self:setUpvalueMember(scope, self:register(scope, reg), self:register(scope, valueReg), compoundConstructor), {}, {reg, valueReg}, true);
1860
- else
1861
- local reg = self:getVarRegister(primaryExpr.scope, primaryExpr.id, funcDepth, valueReg);
1862
- if reg ~= valueReg then
1863
- self:addStatement(self:setRegister(scope, reg, self:register(scope, valueReg), compoundConstructor), {reg}, {valueReg}, false);
1864
- end
1865
- end
1866
- else
1867
- local upvalId = self:getUpvalueId(primaryExpr.scope, primaryExpr.id);
1868
- scope:addReferenceToHigherScope(self.containerFuncScope, self.currentUpvaluesVar);
1869
- self:addStatement(self:setUpvalueMember(scope, Ast.IndexExpression(Ast.VariableExpression(self.containerFuncScope, self.currentUpvaluesVar), Ast.NumberExpression(upvalId)), self:register(scope, valueReg), compoundConstructor), {}, {valueReg}, true);
1870
- end
1871
- end
1872
- end
1873
- return;
1874
- end
1875
-
1876
- logger:error(string.format("%s is not a compileable statement!", statement.kind));
1877
- end
1878
-
1879
- function Compiler:compileExpression(expression, funcDepth, numReturns)
1880
- local scope = self.activeBlock.scope;
1881
-
1882
- -- String Expression
1883
- if(expression.kind == AstKind.StringExpression) then
1884
- local regs = {};
1885
- for i=1, numReturns, 1 do
1886
- regs[i] = self:allocRegister();
1887
- if(i == 1) then
1888
- self:addStatement(self:setRegister(scope, regs[i], Ast.StringExpression(expression.value)), {regs[i]}, {}, false);
1889
- else
1890
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
1891
- end
1892
- end
1893
- return regs;
1894
- end
1895
-
1896
- -- Number Expression
1897
- if(expression.kind == AstKind.NumberExpression) then
1898
- local regs = {};
1899
- for i=1, numReturns do
1900
- regs[i] = self:allocRegister();
1901
- if(i == 1) then
1902
- self:addStatement(self:setRegister(scope, regs[i], Ast.NumberExpression(expression.value)), {regs[i]}, {}, false);
1903
- else
1904
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
1905
- end
1906
- end
1907
- return regs;
1908
- end
1909
-
1910
- -- Boolean Expression
1911
- if(expression.kind == AstKind.BooleanExpression) then
1912
- local regs = {};
1913
- for i=1, numReturns do
1914
- regs[i] = self:allocRegister();
1915
- if(i == 1) then
1916
- self:addStatement(self:setRegister(scope, regs[i], Ast.BooleanExpression(expression.value)), {regs[i]}, {}, false);
1917
- else
1918
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
1919
- end
1920
- end
1921
- return regs;
1922
- end
1923
-
1924
- -- Nil Expression
1925
- if(expression.kind == AstKind.NilExpression) then
1926
- local regs = {};
1927
- for i=1, numReturns do
1928
- regs[i] = self:allocRegister();
1929
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
1930
- end
1931
- return regs;
1932
- end
1933
-
1934
- -- Variable Expression
1935
- if(expression.kind == AstKind.VariableExpression) then
1936
- local regs = {};
1937
- for i=1, numReturns do
1938
- if(i == 1) then
1939
- if(expression.scope.isGlobal) then
1940
- -- Global Variable
1941
- regs[i] = self:allocRegister(false);
1942
- local tmpReg = self:allocRegister(false);
1943
- self:addStatement(self:setRegister(scope, tmpReg, Ast.StringExpression(expression.scope:getVariableName(expression.id))), {tmpReg}, {}, false);
1944
- self:addStatement(self:setRegister(scope, regs[i], Ast.IndexExpression(self:env(scope), self:register(scope, tmpReg))), {regs[i]}, {tmpReg}, true);
1945
- self:freeRegister(tmpReg, false);
1946
- else
1947
- -- Local Variable
1948
- if(self.scopeFunctionDepths[expression.scope] == funcDepth) then
1949
- if self:isUpvalue(expression.scope, expression.id) then
1950
- local reg = self:allocRegister(false);
1951
- local varReg = self:getVarRegister(expression.scope, expression.id, funcDepth, nil);
1952
- self:addStatement(self:setRegister(scope, reg, self:getUpvalueMember(scope, self:register(scope, varReg))), {reg}, {varReg}, true);
1953
- regs[i] = reg;
1954
- else
1955
- regs[i] = self:getVarRegister(expression.scope, expression.id, funcDepth, nil);
1956
- end
1957
- else
1958
- local reg = self:allocRegister(false);
1959
- local upvalId = self:getUpvalueId(expression.scope, expression.id);
1960
- scope:addReferenceToHigherScope(self.containerFuncScope, self.currentUpvaluesVar);
1961
- self:addStatement(self:setRegister(scope, reg, self:getUpvalueMember(scope, Ast.IndexExpression(Ast.VariableExpression(self.containerFuncScope, self.currentUpvaluesVar), Ast.NumberExpression(upvalId)))), {reg}, {}, true);
1962
- regs[i] = reg;
1963
- end
1964
- end
1965
- else
1966
- regs[i] = self:allocRegister();
1967
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
1968
- end
1969
- end
1970
- return regs;
1971
- end
1972
-
1973
- -- Function Call Expression
1974
- if(expression.kind == AstKind.FunctionCallExpression) then
1975
- local baseReg = self:compileExpression(expression.base, funcDepth, 1)[1];
1976
-
1977
- local retRegs = {};
1978
- local returnAll = numReturns == self.RETURN_ALL;
1979
- if returnAll then
1980
- retRegs[1] = self:allocRegister(false);
1981
- else
1982
- for i = 1, numReturns do
1983
- retRegs[i] = self:allocRegister(false);
1984
- end
1985
- end
1986
-
1987
- local regs = {};
1988
- local args = {};
1989
- for i, expr in ipairs(expression.args) do
1990
- if i == #expression.args and (expr.kind == AstKind.FunctionCallExpression or expr.kind == AstKind.PassSelfFunctionCallExpression or expr.kind == AstKind.VarargExpression) then
1991
- local reg = self:compileExpression(expr, funcDepth, self.RETURN_ALL)[1];
1992
- table.insert(args, Ast.FunctionCallExpression(
1993
- self:unpack(scope),
1994
- {self:register(scope, reg)}));
1995
- table.insert(regs, reg);
1996
- else
1997
- local reg = self:compileExpression(expr, funcDepth, 1)[1];
1998
- table.insert(args, self:register(scope, reg));
1999
- table.insert(regs, reg);
2000
- end
2001
- end
2002
-
2003
- if(returnAll) then
2004
- self:addStatement(self:setRegister(scope, retRegs[1], Ast.TableConstructorExpression{Ast.TableEntry(Ast.FunctionCallExpression(self:register(scope, baseReg), args))}), {retRegs[1]}, {baseReg, unpack(regs)}, true);
2005
- else
2006
- if(numReturns > 1) then
2007
- local tmpReg = self:allocRegister(false);
2008
-
2009
- self:addStatement(self:setRegister(scope, tmpReg, Ast.TableConstructorExpression{Ast.TableEntry(Ast.FunctionCallExpression(self:register(scope, baseReg), args))}), {tmpReg}, {baseReg, unpack(regs)}, true);
2010
-
2011
- for i, reg in ipairs(retRegs) do
2012
- self:addStatement(self:setRegister(scope, reg, Ast.IndexExpression(self:register(scope, tmpReg), Ast.NumberExpression(i))), {reg}, {tmpReg}, false);
2013
- end
2014
-
2015
- self:freeRegister(tmpReg, false);
2016
- else
2017
- self:addStatement(self:setRegister(scope, retRegs[1], Ast.FunctionCallExpression(self:register(scope, baseReg), args)), {retRegs[1]}, {baseReg, unpack(regs)}, true);
2018
- end
2019
- end
2020
-
2021
- self:freeRegister(baseReg, false);
2022
- for i, reg in ipairs(regs) do
2023
- self:freeRegister(reg, false);
2024
- end
2025
-
2026
- return retRegs;
2027
- end
2028
-
2029
- -- Pass Self Function Call Expression
2030
- if(expression.kind == AstKind.PassSelfFunctionCallExpression) then
2031
- local baseReg = self:compileExpression(expression.base, funcDepth, 1)[1];
2032
- local retRegs = {};
2033
- local returnAll = numReturns == self.RETURN_ALL;
2034
- if returnAll then
2035
- retRegs[1] = self:allocRegister(false);
2036
- else
2037
- for i = 1, numReturns do
2038
- retRegs[i] = self:allocRegister(false);
2039
- end
2040
- end
2041
-
2042
- local args = { self:register(scope, baseReg) };
2043
- local regs = { baseReg };
2044
-
2045
- for i, expr in ipairs(expression.args) do
2046
- if i == #expression.args and (expr.kind == AstKind.FunctionCallExpression or expr.kind == AstKind.PassSelfFunctionCallExpression or expr.kind == AstKind.VarargExpression) then
2047
- local reg = self:compileExpression(expr, funcDepth, self.RETURN_ALL)[1];
2048
- table.insert(args, Ast.FunctionCallExpression(
2049
- self:unpack(scope),
2050
- {self:register(scope, reg)}));
2051
- table.insert(regs, reg);
2052
- else
2053
- local reg = self:compileExpression(expr, funcDepth, 1)[1];
2054
- table.insert(args, self:register(scope, reg));
2055
- table.insert(regs, reg);
2056
- end
2057
- end
2058
-
2059
- if(returnAll or numReturns > 1) then
2060
- local tmpReg = self:allocRegister(false);
2061
-
2062
- self:addStatement(self:setRegister(scope, tmpReg, Ast.StringExpression(expression.passSelfFunctionName)), {tmpReg}, {}, false);
2063
- self:addStatement(self:setRegister(scope, tmpReg, Ast.IndexExpression(self:register(scope, baseReg), self:register(scope, tmpReg))), {tmpReg}, {baseReg, tmpReg}, false);
2064
-
2065
- if returnAll then
2066
- self:addStatement(self:setRegister(scope, retRegs[1], Ast.TableConstructorExpression{Ast.TableEntry(Ast.FunctionCallExpression(self:register(scope, tmpReg), args))}), {retRegs[1]}, {tmpReg, unpack(regs)}, true);
2067
- else
2068
- self:addStatement(self:setRegister(scope, tmpReg, Ast.TableConstructorExpression{Ast.TableEntry(Ast.FunctionCallExpression(self:register(scope, tmpReg), args))}), {tmpReg}, {tmpReg, unpack(regs)}, true);
2069
-
2070
- for i, reg in ipairs(retRegs) do
2071
- self:addStatement(self:setRegister(scope, reg, Ast.IndexExpression(self:register(scope, tmpReg), Ast.NumberExpression(i))), {reg}, {tmpReg}, false);
2072
- end
2073
- end
2074
-
2075
- self:freeRegister(tmpReg, false);
2076
- else
2077
- local tmpReg = retRegs[1] or self:allocRegister(false);
2078
-
2079
- self:addStatement(self:setRegister(scope, tmpReg, Ast.StringExpression(expression.passSelfFunctionName)), {tmpReg}, {}, false);
2080
- self:addStatement(self:setRegister(scope, tmpReg, Ast.IndexExpression(self:register(scope, baseReg), self:register(scope, tmpReg))), {tmpReg}, {baseReg, tmpReg}, false);
2081
-
2082
- self:addStatement(self:setRegister(scope, retRegs[1], Ast.FunctionCallExpression(self:register(scope, tmpReg), args)), {retRegs[1]}, {baseReg, unpack(regs)}, true);
2083
- end
2084
-
2085
- for i, reg in ipairs(regs) do
2086
- self:freeRegister(reg, false);
2087
- end
2088
-
2089
- return retRegs;
2090
- end
2091
-
2092
- -- Index Expression
2093
- if(expression.kind == AstKind.IndexExpression) then
2094
- local regs = {};
2095
- for i=1, numReturns do
2096
- regs[i] = self:allocRegister();
2097
- if(i == 1) then
2098
- local baseReg = self:compileExpression(expression.base, funcDepth, 1)[1];
2099
- local indexReg = self:compileExpression(expression.index, funcDepth, 1)[1];
2100
-
2101
- self:addStatement(self:setRegister(scope, regs[i], Ast.IndexExpression(self:register(scope, baseReg), self:register(scope, indexReg))), {regs[i]}, {baseReg, indexReg}, true);
2102
- self:freeRegister(baseReg, false);
2103
- self:freeRegister(indexReg, false)
2104
- else
2105
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
2106
- end
2107
- end
2108
- return regs;
2109
- end
2110
-
2111
- -- Binary Operations
2112
- if(self.BIN_OPS[expression.kind]) then
2113
- local regs = {};
2114
- for i=1, numReturns do
2115
- regs[i] = self:allocRegister();
2116
- if(i == 1) then
2117
- local lhsReg = self:compileExpression(expression.lhs, funcDepth, 1)[1];
2118
- local rhsReg = self:compileExpression(expression.rhs, funcDepth, 1)[1];
2119
-
2120
- self:addStatement(self:setRegister(scope, regs[i], Ast[expression.kind](self:register(scope, lhsReg), self:register(scope, rhsReg))), {regs[i]}, {lhsReg, rhsReg}, true);
2121
- self:freeRegister(rhsReg, false);
2122
- self:freeRegister(lhsReg, false)
2123
- else
2124
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
2125
- end
2126
- end
2127
- return regs;
2128
- end
2129
-
2130
- if(expression.kind == AstKind.NotExpression) then
2131
- local regs = {};
2132
- for i=1, numReturns do
2133
- regs[i] = self:allocRegister();
2134
- if(i == 1) then
2135
- local rhsReg = self:compileExpression(expression.rhs, funcDepth, 1)[1];
2136
-
2137
- self:addStatement(self:setRegister(scope, regs[i], Ast.NotExpression(self:register(scope, rhsReg))), {regs[i]}, {rhsReg}, false);
2138
- self:freeRegister(rhsReg, false)
2139
- else
2140
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
2141
- end
2142
- end
2143
- return regs;
2144
- end
2145
-
2146
- if(expression.kind == AstKind.NegateExpression) then
2147
- local regs = {};
2148
- for i=1, numReturns do
2149
- regs[i] = self:allocRegister();
2150
- if(i == 1) then
2151
- local rhsReg = self:compileExpression(expression.rhs, funcDepth, 1)[1];
2152
-
2153
- self:addStatement(self:setRegister(scope, regs[i], Ast.NegateExpression(self:register(scope, rhsReg))), {regs[i]}, {rhsReg}, true);
2154
- self:freeRegister(rhsReg, false)
2155
- else
2156
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
2157
- end
2158
- end
2159
- return regs;
2160
- end
2161
-
2162
- if(expression.kind == AstKind.LenExpression) then
2163
- local regs = {};
2164
- for i=1, numReturns do
2165
- regs[i] = self:allocRegister();
2166
- if(i == 1) then
2167
- local rhsReg = self:compileExpression(expression.rhs, funcDepth, 1)[1];
2168
-
2169
- self:addStatement(self:setRegister(scope, regs[i], Ast.LenExpression(self:register(scope, rhsReg))), {regs[i]}, {rhsReg}, true);
2170
- self:freeRegister(rhsReg, false)
2171
- else
2172
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
2173
- end
2174
- end
2175
- return regs;
2176
- end
2177
-
2178
- if(expression.kind == AstKind.OrExpression) then
2179
- local posState = self.registers[self.POS_REGISTER];
2180
- self.registers[self.POS_REGISTER] = self.VAR_REGISTER;
2181
-
2182
- local regs = {};
2183
- for i=1, numReturns do
2184
- regs[i] = self:allocRegister();
2185
- if(i ~= 1) then
2186
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
2187
- end
2188
- end
2189
-
2190
- local resReg = regs[1];
2191
- local tmpReg;
2192
-
2193
- if posState then
2194
- tmpReg = self:allocRegister(false);
2195
- self:addStatement(self:copyRegisters(scope, {tmpReg}, {self.POS_REGISTER}), {tmpReg}, {self.POS_REGISTER}, false);
2196
- end
2197
-
2198
- local lhsReg = self:compileExpression(expression.lhs, funcDepth, 1)[1];
2199
- if(expression.rhs.isConstant) then
2200
- local rhsReg = self:compileExpression(expression.rhs, funcDepth, 1)[1];
2201
- self:addStatement(self:setRegister(scope, resReg, Ast.OrExpression(self:register(scope, lhsReg), self:register(scope, rhsReg))), {resReg}, {lhsReg, rhsReg}, false);
2202
- if tmpReg then
2203
- self:freeRegister(tmpReg, false);
2204
- end
2205
- self:freeRegister(lhsReg, false);
2206
- self:freeRegister(rhsReg, false);
2207
- return regs;
2208
- end
2209
-
2210
- local block1, block2 = self:createBlock(), self:createBlock();
2211
- self:addStatement(self:copyRegisters(scope, {resReg}, {lhsReg}), {resReg}, {lhsReg}, false);
2212
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.OrExpression(Ast.AndExpression(self:register(scope, lhsReg), Ast.NumberExpression(block2.id)), Ast.NumberExpression(block1.id))), {self.POS_REGISTER}, {lhsReg}, false);
2213
- self:freeRegister(lhsReg, false);
2214
-
2215
- do
2216
- self:setActiveBlock(block1);
2217
- local scope = block1.scope;
2218
- local rhsReg = self:compileExpression(expression.rhs, funcDepth, 1)[1];
2219
- self:addStatement(self:copyRegisters(scope, {resReg}, {rhsReg}), {resReg}, {rhsReg}, false);
2220
- self:freeRegister(rhsReg, false);
2221
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.NumberExpression(block2.id)), {self.POS_REGISTER}, {}, false);
2222
- end
2223
-
2224
- self.registers[self.POS_REGISTER] = posState;
2225
-
2226
- self:setActiveBlock(block2);
2227
- scope = block2.scope;
2228
-
2229
- if tmpReg then
2230
- self:addStatement(self:copyRegisters(scope, {self.POS_REGISTER}, {tmpReg}), {self.POS_REGISTER}, {tmpReg}, false);
2231
- self:freeRegister(tmpReg, false);
2232
- end
2233
-
2234
- return regs;
2235
- end
2236
-
2237
- if(expression.kind == AstKind.AndExpression) then
2238
- local posState = self.registers[self.POS_REGISTER];
2239
- self.registers[self.POS_REGISTER] = self.VAR_REGISTER;
2240
-
2241
- local regs = {};
2242
- for i=1, numReturns do
2243
- regs[i] = self:allocRegister();
2244
- if(i ~= 1) then
2245
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
2246
- end
2247
- end
2248
-
2249
- local resReg = regs[1];
2250
- local tmpReg;
2251
-
2252
- if posState then
2253
- tmpReg = self:allocRegister(false);
2254
- self:addStatement(self:copyRegisters(scope, {tmpReg}, {self.POS_REGISTER}), {tmpReg}, {self.POS_REGISTER}, false);
2255
- end
2256
-
2257
-
2258
- local lhsReg = self:compileExpression(expression.lhs, funcDepth, 1)[1];
2259
- if(expression.rhs.isConstant) then
2260
- local rhsReg = self:compileExpression(expression.rhs, funcDepth, 1)[1];
2261
- self:addStatement(self:setRegister(scope, resReg, Ast.AndExpression(self:register(scope, lhsReg), self:register(scope, rhsReg))), {resReg}, {lhsReg, rhsReg}, false);
2262
- if tmpReg then
2263
- self:freeRegister(tmpReg, false);
2264
- end
2265
- self:freeRegister(lhsReg, false);
2266
- self:freeRegister(rhsReg, false)
2267
- return regs;
2268
- end
2269
-
2270
-
2271
- local block1, block2 = self:createBlock(), self:createBlock();
2272
- self:addStatement(self:copyRegisters(scope, {resReg}, {lhsReg}), {resReg}, {lhsReg}, false);
2273
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.OrExpression(Ast.AndExpression(self:register(scope, lhsReg), Ast.NumberExpression(block1.id)), Ast.NumberExpression(block2.id))), {self.POS_REGISTER}, {lhsReg}, false);
2274
- self:freeRegister(lhsReg, false);
2275
- do
2276
- self:setActiveBlock(block1);
2277
- scope = block1.scope;
2278
- local rhsReg = self:compileExpression(expression.rhs, funcDepth, 1)[1];
2279
- self:addStatement(self:copyRegisters(scope, {resReg}, {rhsReg}), {resReg}, {rhsReg}, false);
2280
- self:freeRegister(rhsReg, false);
2281
- self:addStatement(self:setRegister(scope, self.POS_REGISTER, Ast.NumberExpression(block2.id)), {self.POS_REGISTER}, {}, false);
2282
- end
2283
-
2284
- self.registers[self.POS_REGISTER] = posState;
2285
-
2286
- self:setActiveBlock(block2);
2287
- scope = block2.scope;
2288
-
2289
- if tmpReg then
2290
- self:addStatement(self:copyRegisters(scope, {self.POS_REGISTER}, {tmpReg}), {self.POS_REGISTER}, {tmpReg}, false);
2291
- self:freeRegister(tmpReg, false);
2292
- end
2293
-
2294
- return regs;
2295
- end
2296
-
2297
- if(expression.kind == AstKind.TableConstructorExpression) then
2298
- local regs = {};
2299
- for i=1, numReturns do
2300
- regs[i] = self:allocRegister();
2301
- if(i == 1) then
2302
- local entries = {};
2303
- local entryRegs = {};
2304
- for i, entry in ipairs(expression.entries) do
2305
- if(entry.kind == AstKind.TableEntry) then
2306
- local value = entry.value;
2307
- if i == #expression.entries and (value.kind == AstKind.FunctionCallExpression or value.kind == AstKind.PassSelfFunctionCallExpression or value.kind == AstKind.VarargExpression) then
2308
- local reg = self:compileExpression(entry.value, funcDepth, self.RETURN_ALL)[1];
2309
- table.insert(entries, Ast.TableEntry(Ast.FunctionCallExpression(
2310
- self:unpack(scope),
2311
- {self:register(scope, reg)})));
2312
- table.insert(entryRegs, reg);
2313
- else
2314
- local reg = self:compileExpression(entry.value, funcDepth, 1)[1];
2315
- table.insert(entries, Ast.TableEntry(self:register(scope, reg)));
2316
- table.insert(entryRegs, reg);
2317
- end
2318
- else
2319
- local keyReg = self:compileExpression(entry.key, funcDepth, 1)[1];
2320
- local valReg = self:compileExpression(entry.value, funcDepth, 1)[1];
2321
- table.insert(entries, Ast.KeyedTableEntry(self:register(scope, keyReg), self:register(scope, valReg)));
2322
- table.insert(entryRegs, valReg);
2323
- table.insert(entryRegs, keyReg);
2324
- end
2325
- end
2326
- self:addStatement(self:setRegister(scope, regs[i], Ast.TableConstructorExpression(entries)), {regs[i]}, entryRegs, false);
2327
- for i, reg in ipairs(entryRegs) do
2328
- self:freeRegister(reg, false);
2329
- end
2330
- else
2331
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
2332
- end
2333
- end
2334
- return regs;
2335
- end
2336
-
2337
- if(expression.kind == AstKind.FunctionLiteralExpression) then
2338
- local regs = {};
2339
- for i=1, numReturns do
2340
- if(i == 1) then
2341
- regs[i] = self:compileFunction(expression, funcDepth);
2342
- else
2343
- regs[i] = self:allocRegister();
2344
- self:addStatement(self:setRegister(scope, regs[i], Ast.NilExpression()), {regs[i]}, {}, false);
2345
- end
2346
- end
2347
- return regs;
2348
- end
2349
-
2350
- if(expression.kind == AstKind.VarargExpression) then
2351
- if numReturns == self.RETURN_ALL then
2352
- return {self.varargReg};
2353
- end
2354
- local regs = {};
2355
- for i=1, numReturns do
2356
- regs[i] = self:allocRegister(false);
2357
- self:addStatement(self:setRegister(scope, regs[i], Ast.IndexExpression(self:register(scope, self.varargReg), Ast.NumberExpression(i))), {regs[i]}, {self.varargReg}, false);
2358
- end
2359
- return regs;
2360
- end
2361
-
2362
- logger:error(string.format("%s is not an compliable expression!", expression.kind));
2363
- end
2364
-
2365
- return Compiler;