public IfThenEndBlock(LFunction function, Branch branch, unluac.util.Stack<Branch> stack, Registers r) : base(function, branch.begin == branch.end ? branch.begin - 1 : branch.begin, branch.begin == branch.end ? branch.begin - 1 : branch.end) { this.branch = branch; this.stack = stack; this.r = r; statements = new List<Statement>(branch.end - branch.begin + 1); }
public virtual Branch popSetCondition(unluac.util.Stack<Branch> stack, int assignEnd) { //System.err.println("assign end " + assignEnd); stack.push(new AssignNode(assignEnd - 1, assignEnd, assignEnd)); //Invert argument doesn't matter because begin == end Branch rtn = _helper_popSetCondition(stack, false, assignEnd); return rtn; }
public virtual Branch popCompareSetCondition(unluac.util.Stack<Branch> stack, int assignEnd) { Branch top = stack.pop(); bool invert = false; if(code.B(top.begin) == 0) //top = top.invert(); invert = true; top.begin = assignEnd; top.end = assignEnd; stack.push(top); //stack.pop(); //stack.push(new AssignNode(assignEnd - 1, assignEnd, assignEnd)); //Invert argument doesn't matter because begin == end Branch rtn = _helper_popSetCondition(stack, invert, assignEnd); return rtn; }
public virtual Branch popCondition(unluac.util.Stack<Branch> stack) { Branch branch = stack.pop(); if(backup != null) backup.push(branch); if(branch is TestSetNode) { throw new Exception(); } int begin = branch.begin; if(code.op(branch.begin) == Op.JMP) { begin += 1 + code.sBx(branch.begin); } while(stack.Count > 0) { Branch next = stack.peek(); if(next is TestSetNode) break; if(next.end == begin) { branch = new OrBranch(popCondition(stack).invert(), branch); } else if(next.end == branch.end) { branch = new AndBranch(popCondition(stack), branch); } else { break; } } return branch; }
private Branch _helper_popSetCondition(unluac.util.Stack<Branch> stack, bool invert, int assignEnd) { Branch branch = stack.pop(); int begin = branch.begin; int end = branch.end; //System.err.println(stack.size()); //System.err.println("_helper_popSetCondition; count: " + count); //System.err.println("_helper_popSetCondition; begin: " + begin); //System.err.println("_helper_popSetCondition; end: " + end); if(invert) { branch = branch.invert(); } if(code.op(begin) == Op.LOADBOOL) { if(code.C(begin) != 0) { begin += 2; } else { begin += 1; } } if(code.op(end) == Op.LOADBOOL) { if(code.C(end) != 0) { end += 2; } else { end += 1; } } //System.err.println("_helper_popSetCondition; begin_adj: " + begin); //System.err.println("_helper_popSetCondition; end_adj: " + end); //if(count >= 2) System.exit(1); int target = branch.setTarget; while(!stack.isEmpty()) { Branch next = stack.peek(); //System.err.println("_helper_popSetCondition; next begin: " + next.begin); //System.err.println("_helper_popSetCondition; next end: " + next.end); bool ninvert; int nend = next.end; if(code.op(next.end) == Op.LOADBOOL) { ninvert = code.B(next.end) != 0; if(code.C(next.end) != 0) { nend += 2; } else { nend += 1; } } else if(next is TestSetNode) { TestSetNode node = (TestSetNode) next; ninvert = node._invert; } else if(next is TestNode) { TestNode node = (TestNode) next; ninvert = node._invert; } else { ninvert = false; if(nend >= assignEnd) { //System.err.println("break"); break; } } int addr; if(ninvert == invert) { addr = end; } else { addr = begin; } //System.err.println(" addr: " + addr + "(" + begin + ", " + end + ")"); //System.err.println(" nend: " + nend); //System.err.println(" ninv: " + ninvert); //System.err.println("-------------"); //System.exit(0); if(addr == nend) { if(addr != nend) ninvert = !ninvert; if(ninvert) { branch = new OrBranch(_helper_popSetCondition(stack, ninvert, assignEnd), branch); } else { branch = new AndBranch(_helper_popSetCondition(stack, ninvert, assignEnd), branch); } branch.end = nend; } else { if(!(branch is TestSetNode)) { stack.push(branch); branch = popCondition(stack); } //System.out.println("--break"); break; } } branch.isSet = true; branch.setTarget = target; return branch; }