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; }