{@inheritDoc}
(Frame frame, int offset, int opcode)
| 292 | |
| 293 | /** {@inheritDoc} */ |
| 294 | @Override |
| 295 | public void run(Frame frame, int offset, int opcode) { |
| 296 | /* |
| 297 | * This is the stack pointer after the opcode's arguments have been |
| 298 | * popped. |
| 299 | */ |
| 300 | int stackPointer = maxLocals + frame.getStack().size(); |
| 301 | |
| 302 | // The sources have to be retrieved before super.run() gets called. |
| 303 | RegisterSpecList sources = getSources(opcode, stackPointer); |
| 304 | int sourceCount = sources.size(); |
| 305 | |
| 306 | super.run(frame, offset, opcode); |
| 307 | |
| 308 | SourcePosition pos = method.makeSourcePosistion(offset); |
| 309 | RegisterSpec localTarget = getLocalTarget(opcode == ByteOps.ISTORE); |
| 310 | int destCount = resultCount(); |
| 311 | RegisterSpec dest; |
| 312 | |
| 313 | if (destCount == 0) { |
| 314 | dest = null; |
| 315 | switch (opcode) { |
| 316 | case ByteOps.POP: |
| 317 | case ByteOps.POP2: { |
| 318 | // These simply don't appear in the rop form. |
| 319 | return; |
| 320 | } |
| 321 | } |
| 322 | } else if (localTarget != null) { |
| 323 | dest = localTarget; |
| 324 | } else if (destCount == 1) { |
| 325 | dest = RegisterSpec.make(stackPointer, result(0)); |
| 326 | } else { |
| 327 | /* |
| 328 | * This clause only ever applies to the stack manipulation |
| 329 | * ops that have results (that is, dup* and swap but not |
| 330 | * pop*). |
| 331 | * |
| 332 | * What we do is first move all the source registers into |
| 333 | * the "temporary stack" area defined for the method, and |
| 334 | * then move stuff back down onto the main "stack" in the |
| 335 | * arrangement specified by the stack op pattern. |
| 336 | * |
| 337 | * Note: This code ends up emitting a lot of what will |
| 338 | * turn out to be superfluous moves (e.g., moving back and |
| 339 | * forth to the same local when doing a dup); however, |
| 340 | * that makes this code a bit easier (and goodness knows |
| 341 | * it doesn't need any extra complexity), and all the SSA |
| 342 | * stuff is going to want to deal with this sort of |
| 343 | * superfluous assignment anyway, so it should be a wash |
| 344 | * in the end. |
| 345 | */ |
| 346 | int scratchAt = ropper.getFirstTempStackReg(); |
| 347 | RegisterSpec[] scratchRegs = new RegisterSpec[sourceCount]; |
| 348 | |
| 349 | for (int i = 0; i < sourceCount; i++) { |
| 350 | RegisterSpec src = sources.get(i); |
| 351 | TypeBearer type = src.getTypeBearer(); |
nothing calls this directly
no test coverage detected