-
Notifications
You must be signed in to change notification settings - Fork 207
Expand file tree
/
Copy pathfor_in_statement.lua
More file actions
102 lines (82 loc) · 3.93 KB
/
Copy pathfor_in_statement.lua
File metadata and controls
102 lines (82 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
-- This Script is Part of the Prometheus Obfuscator by levno-710
--
-- for_in_statement.lua
--
-- This Script contains the statement handler for the ForInStatement
local Ast = require("prometheus.ast");
return function(self, statement, funcDepth)
local scope = self.activeBlock.scope;
local expressionsLength = #statement.expressions;
local exprregs = {};
for i, expr in ipairs(statement.expressions) do
if(i == expressionsLength and expressionsLength < 3) then
local regs = self:compileExpression(expr, funcDepth, 4 - expressionsLength);
for i = 1, 4 - expressionsLength do
table.insert(exprregs, regs[i]);
end
else
if i <= 3 then
table.insert(exprregs, self:compileExpression(expr, funcDepth, 1)[1])
else
self:freeRegister(self:compileExpression(expr, funcDepth, 1)[1], false);
end
end
end
for i, reg in ipairs(exprregs) do
if reg and self.registers[reg] ~= self.VAR_REGISTER and reg ~= self.POS_REGISTER and reg ~= self.RETURN_REGISTER then
self.registers[reg] = self.VAR_REGISTER;
else
exprregs[i] = self:allocRegister(true);
self:addStatement(self:copyRegisters(scope, {exprregs[i]}, {reg}), {exprregs[i]}, {reg}, false);
end
end
local checkBlock = self:createBlock();
local bodyBlock = self:createBlock();
local finalBlock = self:createBlock();
statement.__start_block = checkBlock;
statement.__final_block = finalBlock;
self:addStatement(self:setPos(scope, checkBlock.id), {self.POS_REGISTER}, {}, false);
self:setActiveBlock(checkBlock);
local scope = self.activeBlock.scope;
local varRegs = {};
for i, id in ipairs(statement.ids) do
varRegs[i] = self:getVarRegister(statement.scope, id, funcDepth)
end
self:addStatement(Ast.AssignmentStatement({
self:registerAssignment(scope, exprregs[3]),
varRegs[2] and self:registerAssignment(scope, varRegs[2]),
}, {
Ast.FunctionCallExpression(self:register(scope, exprregs[1]), {
self:register(scope, exprregs[2]),
self:register(scope, exprregs[3]),
})
}), {exprregs[3], varRegs[2]}, {exprregs[1], exprregs[2], exprregs[3]}, true);
self:addStatement(Ast.AssignmentStatement({
self:posAssignment(scope)
}, {
Ast.OrExpression(Ast.AndExpression(self:register(scope, exprregs[3]), Ast.NumberExpression(bodyBlock.id)), Ast.NumberExpression(finalBlock.id))
}), {self.POS_REGISTER}, {exprregs[3]}, false);
self:setActiveBlock(bodyBlock);
local scope = self.activeBlock.scope;
self:addStatement(self:copyRegisters(scope, {varRegs[1]}, {exprregs[3]}), {varRegs[1]}, {exprregs[3]}, false);
for i=3, #varRegs do
self:addStatement(self:setRegister(scope, varRegs[i], Ast.NilExpression()), {varRegs[i]}, {}, false);
end
for i, id in ipairs(statement.ids) do
if(self:isUpvalue(statement.scope, id)) then
local varreg = varRegs[i];
local tmpReg = self:allocRegister(false);
scope:addReferenceToHigherScope(self.scope, self.allocUpvalFunction);
self:addStatement(self:setRegister(scope, tmpReg, Ast.FunctionCallExpression(Ast.VariableExpression(self.scope, self.allocUpvalFunction), {})), {tmpReg}, {}, false);
self:addStatement(self:setUpvalueMember(scope, self:register(scope, tmpReg), self:register(scope, varreg)), {}, {tmpReg, varreg}, true);
self:addStatement(self:copyRegisters(scope, {varreg}, {tmpReg}), {varreg}, {tmpReg}, false);
self:freeRegister(tmpReg, false);
end
end
self:compileBlock(statement.body, funcDepth);
self:addStatement(self:setPos(scope, checkBlock.id), {self.POS_REGISTER}, {}, false);
self:setActiveBlock(finalBlock);
for i, _ in ipairs(exprregs) do
self:freeRegister(exprregs[i], true)
end
end;