private Frame firstFrame(MethodInfo method, int maxLocals, int maxStack) { int pos = 0; Frame first = new Frame(maxLocals, maxStack); if ((method.getAccessFlags() & AccessFlag.STATIC) == 0) { first.setLocal(pos++, Type.get(clazz)); } CtClass[] parameters; try { parameters = Descriptor.getParameterTypes(method.getDescriptor(), clazz.getClassPool()); } catch (NotFoundException e) { throw new RuntimeException(e); } for (int i = 0; i < parameters.length; i++) { Type type = zeroExtend(Type.get(parameters[i])); first.setLocal(pos++, type); if (type.getSize() == 2) first.setLocal(pos++, Type.TOP); } return first; }
private void mergeExceptionHandlers(IntQueue queue, MethodInfo method, int pos, Frame frame) { for (int i = 0; i < exceptions.length; i++) { ExceptionInfo exception = exceptions[i]; // Start is inclusive, while end is exclusive! if (pos >= exception.start && pos < exception.end) { Frame newFrame = frame.copy(); newFrame.clearStack(); newFrame.push(exception.type); merge(queue, newFrame, exception.handler); } } }
old = frames[returnLoc] = frame.copyStack(); changed = true; } else { changed = old.mergeStack(frame); Type oldType = old.getLocal(index); Type newType = frame.getLocal(index); if (oldType != newType) { old.setLocal(index, newType); changed = true; if (! old.isRetMerged()) { old.setRetMerged(true); changed = true; if (changed && old.isJsrMerged()) queue.add(returnLoc);
private Type simplePeek(Frame frame) { Type type = frame.peek(); return (type == Type.TOP) ? frame.getStack(frame.getTopIndex() - 1) : type; }
private void printStack(Frame frame) { stream.print("stack ["); int top = frame.getTopIndex(); for (int i = 0; i <= top; i++) { if (i > 0) stream.print(", "); Type type = frame.getStack(i); stream.print(type); } stream.println("]"); }
old = frames[next] = frame.copy(); changed = true; } else { for (int i = 0; i < frame.localsLength(); i++) { Type oldType = old.getLocal(i); Type newType = frame.getLocal(i); if (oldType == null) { old.setLocal(i, newType); changed = true; continue; old.setLocal(i, newType); if (!newType.equals(oldType) || newType.popChanged()) changed = true; if (! old.isJsrMerged()) { old.setJsrMerged(true); changed = true; if (changed && old.isRetMerged()) queue.add(next);
break; case ACONST_NULL: frame.push(Type.UNINIT); break; case ICONST_M1: case ICONST_4: case ICONST_5: frame.push(Type.INTEGER); break; case LCONST_0: case LCONST_1: frame.push(Type.LONG); frame.push(Type.TOP); break; case FCONST_0: case FCONST_1: case FCONST_2: frame.push(Type.FLOAT); break; case DCONST_0: case DCONST_1: frame.push(Type.DOUBLE); frame.push(Type.TOP); break; case BIPUSH: case SIPUSH: frame.push(Type.INTEGER); break;
private void printLocals(Frame frame) { stream.print("locals ["); int length = frame.localsLength(); for (int i = 0; i < length; i++) { if (i > 0) stream.print(", "); Type type = frame.getLocal(i); stream.print(type == null ? "empty" : type.toString()); } stream.println("]"); }
/** * Makes a shallow copy of the stack portion of this frame. The local * variable table size will be copied, but its contents will be empty. * * @return the shallow copy of the stack */ public Frame copyStack() { Frame frame = new Frame(locals.length, stack.length); System.arraycopy(stack, 0, frame.stack, 0, stack.length); frame.top = top; return frame; }
private void evalLoad(Type expected, int index, Frame frame, Subroutine subroutine) throws BadBytecode { Type type = frame.getLocal(index); verifyAssignable(expected, type); simplePush(type, frame); access(index, type, subroutine); }
iter.next(); Frame frame = frames[pos].copy(); Subroutine subroutine = subroutines[pos];
old = frames[next] = frame.copy(); changed = true; } else { for (int i = 0; i < frame.localsLength(); i++) { Type oldType = old.getLocal(i); Type newType = frame.getLocal(i); if (oldType == null) { old.setLocal(i, newType); changed = true; continue; old.setLocal(i, newType); if (!newType.equals(oldType) || newType.popChanged()) changed = true; if (! old.isJsrMerged()) { old.setJsrMerged(true); changed = true; if (changed && old.isRetMerged()) queue.add(next);
break; case ACONST_NULL: frame.push(Type.UNINIT); break; case ICONST_M1: case ICONST_4: case ICONST_5: frame.push(Type.INTEGER); break; case LCONST_0: case LCONST_1: frame.push(Type.LONG); frame.push(Type.TOP); break; case FCONST_0: case FCONST_1: case FCONST_2: frame.push(Type.FLOAT); break; case DCONST_0: case DCONST_1: frame.push(Type.DOUBLE); frame.push(Type.TOP); break; case BIPUSH: case SIPUSH: frame.push(Type.INTEGER); break;
private Type simplePeek(Frame frame) { Type type = frame.peek(); return (type == Type.TOP) ? frame.getStack(frame.getTopIndex() - 1) : type; }
private void printStack(Frame frame) { stream.print("stack ["); int top = frame.getTopIndex(); for (int i = 0; i <= top; i++) { if (i > 0) stream.print(", "); Type type = frame.getStack(i); stream.print(type); } stream.println("]"); }
private void printLocals(Frame frame) { stream.print("locals ["); int length = frame.localsLength(); for (int i = 0; i < length; i++) { if (i > 0) stream.print(", "); Type type = frame.getLocal(i); stream.print(type == null ? "empty" : type.toString()); } stream.println("]"); }
/** * Makes a shallow copy of this frame, i.e. the type instances will * remain the same. * * @return the shallow copy */ public Frame copy() { Frame frame = new Frame(locals.length, stack.length); System.arraycopy(locals, 0, frame.locals, 0, locals.length); System.arraycopy(stack, 0, frame.stack, 0, stack.length); frame.top = top; return frame; }
private void evalLoad(Type expected, int index, Frame frame, Subroutine subroutine) throws BadBytecode { Type type = frame.getLocal(index); verifyAssignable(expected, type); simplePush(type, frame); access(index, type, subroutine); }