(MethodInstance method, MethodNode asmNode)
| 123 | } |
| 124 | |
| 125 | private static MethodVarInstance[] gatherVars(MethodInstance method, MethodNode asmNode) { |
| 126 | if (asmNode == null) return emptyVars; |
| 127 | if (asmNode.localVariables == null) return emptyVars; // TODO: generate? |
| 128 | if (asmNode.localVariables.isEmpty()) return emptyVars; |
| 129 | |
| 130 | InsnList il = asmNode.instructions; |
| 131 | AbstractInsnNode firstInsn = il.getFirst(); |
| 132 | List<LocalVariableNode> vars = new ArrayList<>(); |
| 133 | |
| 134 | lvLoop: for (int i = 0; i < asmNode.localVariables.size(); i++) { |
| 135 | LocalVariableNode var = asmNode.localVariables.get(i); |
| 136 | |
| 137 | if (var.start == firstInsn) { // check if it's an arg |
| 138 | if (var.index == 0 && !method.isStatic) continue; |
| 139 | |
| 140 | for (MethodVarInstance arg : method.args) { |
| 141 | if (arg.asmIndex == i) { // var is an arg |
| 142 | continue lvLoop; |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | vars.add(var); |
| 148 | } |
| 149 | |
| 150 | if (vars.isEmpty()) return emptyVars; |
| 151 | |
| 152 | // stable sort by start bci |
| 153 | Collections.sort(vars, Comparator.comparingInt(var -> il.indexOf(var.start))); // Collections.sort is specified as stable, List.sort isn't (only implNote in OpenJDK 8) |
| 154 | |
| 155 | MethodVarInstance[] ret = new MethodVarInstance[vars.size()]; |
| 156 | |
| 157 | for (int i = 0; i < vars.size(); i++) { |
| 158 | LocalVariableNode var = vars.get(i); |
| 159 | |
| 160 | assert var.name != null; |
| 161 | assert method.args.length == 0 || var.index > method.args[method.args.length - 1].lvIndex; |
| 162 | |
| 163 | int startInsn = il.indexOf(var.start); |
| 164 | int endInsn = il.indexOf(var.end); |
| 165 | assert startInsn >= 0 && endInsn >= 0; |
| 166 | |
| 167 | AbstractInsnNode start = var.start; |
| 168 | int startOpIdx = 0; |
| 169 | |
| 170 | while ((start = start.getPrevious()) != null) { |
| 171 | if (start.getOpcode() >= 0) startOpIdx++; |
| 172 | } |
| 173 | |
| 174 | ret[i] = new MethodVarInstance(method, false, i, var.index, asmNode.localVariables.indexOf(var), |
| 175 | method.getEnv().getCreateClassInstance(var.desc), startInsn, endInsn, startOpIdx, |
| 176 | var.name, |
| 177 | var.name == null || method.nameObfuscatedLocal || method.cls.nameObfuscated || !Util.isValidJavaIdentifier(var.name)); |
| 178 | } |
| 179 | |
| 180 | return ret; |
| 181 | } |
| 182 |
no test coverage detected