-- This Script is Part of the Prometheus Obfuscator by levno-710 -- -- assignment.lua -- -- This Script contains the statement handler for the AssignmentStatement. local Ast = require("prometheus.ast"); local AstKind = Ast.AstKind; return function(self, statement, funcDepth) local scope = self.activeBlock.scope; local exprregs = {}; local assignmentIndexingRegs = {}; for i, primaryExpr in ipairs(statement.lhs) do if(primaryExpr.kind == AstKind.AssignmentIndexing) then assignmentIndexingRegs [i] = { base = self:compileExpression(primaryExpr.base, funcDepth, 1)[1], index = self:compileExpression(primaryExpr.index, funcDepth, 1)[1], }; end end for i, expr in ipairs(statement.rhs) do if(i == #statement.rhs and #statement.lhs > #statement.rhs) then local regs = self:compileExpression(expr, funcDepth, #statement.lhs - #statement.rhs + 1); for i, reg in ipairs(regs) do if(self:isVarRegister(reg)) then local ro = reg; reg = self:allocRegister(false); self:addStatement(self:copyRegisters(scope, {reg}, {ro}), {reg}, {ro}, false); end table.insert(exprregs, reg); end else if statement.lhs[i] or expr.kind == AstKind.FunctionCallExpression or expr.kind == AstKind.PassSelfFunctionCallExpression then local reg = self:compileExpression(expr, funcDepth, 1)[1]; if(self:isVarRegister(reg)) then local ro = reg; reg = self:allocRegister(false); self:addStatement(self:copyRegisters(scope, {reg}, {ro}), {reg}, {ro}, false); end table.insert(exprregs, reg); end end end for i, primaryExpr in ipairs(statement.lhs) do if primaryExpr.kind == AstKind.AssignmentVariable then if primaryExpr.scope.isGlobal then local tmpReg = self:allocRegister(false); self:addStatement(self:setRegister(scope, tmpReg, Ast.StringExpression(primaryExpr.scope:getVariableName(primaryExpr.id))), {tmpReg}, {}, false); self:addStatement(Ast.AssignmentStatement({Ast.AssignmentIndexing(self:env(scope), self:register(scope, tmpReg))}, {self:register(scope, exprregs[i])}), {}, {tmpReg, exprregs[i]}, true); self:freeRegister(tmpReg, false); else if self.scopeFunctionDepths[primaryExpr.scope] == funcDepth then if self:isUpvalue(primaryExpr.scope, primaryExpr.id) then local reg = self:getVarRegister(primaryExpr.scope, primaryExpr.id, funcDepth); self:addStatement(self:setUpvalueMember(scope, self:register(scope, reg), self:register(scope, exprregs[i])), {}, {reg, exprregs[i]}, true); else local reg = self:getVarRegister(primaryExpr.scope, primaryExpr.id, funcDepth, exprregs[i]); if reg ~= exprregs[i] then self:addStatement(self:setRegister(scope, reg, self:register(scope, exprregs[i])), {reg}, {exprregs[i]}, false); end end else local upvalId = self:getUpvalueId(primaryExpr.scope, primaryExpr.id); scope:addReferenceToHigherScope(self.containerFuncScope, self.currentUpvaluesVar); self:addStatement(self:setUpvalueMember(scope, Ast.IndexExpression(Ast.VariableExpression(self.containerFuncScope, self.currentUpvaluesVar), Ast.NumberExpression(upvalId)), self:register(scope, exprregs[i])), {}, {exprregs[i]}, true); end end elseif primaryExpr.kind == AstKind.AssignmentIndexing then local baseReg = assignmentIndexingRegs[i].base; local indexReg = assignmentIndexingRegs[i].index; self:addStatement(Ast.AssignmentStatement({ Ast.AssignmentIndexing(self:register(scope, baseReg), self:register(scope, indexReg)) }, { self:register(scope, exprregs[i]) }), {}, {exprregs[i], baseReg, indexReg}, true); self:freeRegister(exprregs[i], false); self:freeRegister(baseReg, false); self:freeRegister(indexReg, false); else error(string.format("Invalid Assignment lhs: %s", statement.lhs)); end end end;