public void visitEnd() { if (!methodDone && methodStartLabel != null && constructor) { methodDone = true; Label methodEndLabel = super.mark(); super.catchException(methodStartLabel, methodEndLabel, Type .getType(RuntimeException.class)); super.visitMethodInsn(Opcodes.INVOKESTATIC, name, LOG_INTERNAL_ALLOC_DEC, VOID_SIGNATURE); super.visitInsn(Opcodes.ATHROW); if (exceptions != null) { for (String ex : exceptions) { super.catchException(methodStartLabel, methodEndLabel, Type.getObjectType(ex)); super.visitMethodInsn(Opcodes.INVOKESTATIC, name, LOG_INTERNAL_ALLOC_DEC, VOID_SIGNATURE); super.visitInsn(Opcodes.ATHROW); } } } super.visitEnd(); }
/** * Checks a stack frame value. * * @param value * the value to be checked. */ void checkFrameValue(final Object value) { if (value == Opcodes.TOP || value == Opcodes.INTEGER || value == Opcodes.FLOAT || value == Opcodes.LONG || value == Opcodes.DOUBLE || value == Opcodes.NULL || value == Opcodes.UNINITIALIZED_THIS) { return; } if (value instanceof String) { checkInternalName((String) value, "Invalid stack frame value"); return; } if (!(value instanceof Label)) { throw new IllegalArgumentException("Invalid stack frame value: " + value); } else { usedLabels.add((Label) value); } }
private void visitx(GeneratorAdapter mv, List<String> strings) { if (strings.size() == 1) { visitCase(strings.get(0)); return; } for (String string : strings) { Label label = new Label(); visitString(); mv.visitLdcInsn(string); mv.invokeVirtual(STRING_TYPE, Method.getMethod("boolean equals(Object)")); mv.visitJumpInsn(Opcodes.IFEQ, label); visitCase(string); mv.visitLabel(label); } visitDefault(); }
@Override public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { checkEndCode(); checkStartCode(); checkLabel(dflt, false, "default label"); checkNonDebugLabel(dflt); if (keys == null || labels == null || keys.length != labels.length) { throw new IllegalArgumentException( "There must be the same number of keys and labels"); } for (int i = 0; i < labels.length; ++i) { checkLabel(labels[i], false, "label at index " + i); checkNonDebugLabel(labels[i]); } super.visitLookupSwitchInsn(dflt, keys, labels); usedLabels.add(dflt); for (int i = 0; i < labels.length; ++i) { usedLabels.add(labels[i]); } ++insnCount; }
@Override public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) { checkStartCode(); checkEndCode(); if (max < min) { throw new IllegalArgumentException("Max = " + max + " must be greater than or equal to min = " + min); } checkLabel(dflt, false, "default label"); checkNonDebugLabel(dflt); if (labels == null || labels.length != max - min + 1) { throw new IllegalArgumentException( "There must be max - min + 1 labels"); } for (int i = 0; i < labels.length; ++i) { checkLabel(labels[i], false, "label at index " + i); checkNonDebugLabel(labels[i]); } super.visitTableSwitchInsn(min, max, dflt, labels); for (int i = 0; i < labels.length; ++i) { usedLabels.add(labels[i]); } ++insnCount; }
private static void generateUpdateMethod(ClassWriter cw, String selfClassInternalName, String selfClassDescriptor, String argsClassInternalName, String constDesc, Parameter[] parameters) { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "update", "()Lio/primeval/reflex/arguments/Arguments;", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitTypeInsn(NEW, argsClassInternalName); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, selfClassInternalName, "parameters", "Ljava/util/List;"); for (int i = 0; i < parameters.length; i++) { Parameter parameter = parameters[i]; mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, selfClassInternalName, parameter.getName(), Type.getDescriptor(parameter.getType())); } mv.visitMethodInsn(INVOKESPECIAL, argsClassInternalName, "<init>", constDesc, false); mv.visitInsn(ARETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", selfClassDescriptor, null, l0, l1, 0); mv.visitMaxs(-1, -1); mv.visitEnd(); }
@Override public Container smaller(Container lval, Container rvalue, OpInfo opinfo) throws CompileException { Label not_smaller_label = new Label(); Label end_label = new Label(); opinfo.mv.visitInsn(Opcodes.DCMPG); opinfo.mv.visitJumpInsn(Opcodes.IFGE, not_smaller_label); opinfo.mv.visitInsn(Opcodes.ICONST_1); opinfo.mv.visitJumpInsn(Opcodes.GOTO, end_label); opinfo.mv.visitLabel(not_smaller_label); opinfo.mv.visitInsn(Opcodes.ICONST_0); opinfo.mv.visitLabel(end_label); Container anony_bool = new Container("anonymous", Container.FORM_OPSTACK_VAR, true, false); anony_bool.initializeType((AbsType) cpLoader.findClassFull(TPrimitiveClass.NAME_BOOL)); anony_bool.setAssigned(true); return anony_bool; }
@Override public Container bigger(Container lval, Container rvalue, OpInfo opinfo) throws CompileException { Label not_bigger_label = new Label(); Label end_label = new Label(); opinfo.mv.visitInsn(Opcodes.DCMPL); opinfo.mv.visitJumpInsn(Opcodes.IFLE, not_bigger_label); opinfo.mv.visitInsn(Opcodes.ICONST_1); opinfo.mv.visitJumpInsn(Opcodes.GOTO, end_label); opinfo.mv.visitLabel(not_bigger_label); opinfo.mv.visitInsn(Opcodes.ICONST_0); opinfo.mv.visitLabel(end_label); Container anony_bool = new Container("anonymous", Container.FORM_OPSTACK_VAR, true, false); anony_bool.initializeType((AbsType) cpLoader.findClassFull(TPrimitiveClass.NAME_BOOL)); anony_bool.setAssigned(true); return anony_bool; }
@Override public Container not_equal(Container lval, Container rvalue, OpInfo opinfo) throws CompileException { Label not_eq_label = new Label(); Label end_label = new Label(); opinfo.mv.visitInsn(Opcodes.DCMPL); opinfo.mv.visitJumpInsn(Opcodes.IFNE, not_eq_label); opinfo.mv.visitInsn(Opcodes.ICONST_0); opinfo.mv.visitJumpInsn(Opcodes.GOTO, end_label); opinfo.mv.visitLabel(not_eq_label); opinfo.mv.visitInsn(Opcodes.ICONST_1); opinfo.mv.visitLabel(end_label); Container anony_bool = new Container("anonymous", Container.FORM_OPSTACK_VAR, true, false); anony_bool.initializeType((AbsType) cpLoader.findClassFull(TPrimitiveClass.NAME_BOOL)); anony_bool.setAssigned(true); return anony_bool; }
private void visitAccessGetterLastPart(String memberType, Label firstLabel) { mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitLdcInsn("No " + memberType + " with index: "); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); Label lastLabel = new Label(); mv.visitLabel(lastLabel); mv.visitLocalVariable("this", classAccessTypeDescriptor, null, firstLabel, lastLabel, 0); mv.visitLocalVariable("obj", classTypeDescriptor, null, firstLabel, lastLabel, 1); mv.visitLocalVariable(memberType + "Index", "I", null, firstLabel, lastLabel, 2); mv.visitMaxs(5, 3); mv.visitEnd(); }
@Override public Container equal(Container lval, Container rvalue, OpInfo opinfo) throws CompileException { Label not_eq_label = new Label(); Label end_label = new Label(); opinfo.mv.visitInsn(Opcodes.LCMP); opinfo.mv.visitJumpInsn(Opcodes.IFNE, not_eq_label); opinfo.mv.visitInsn(Opcodes.ICONST_1); opinfo.mv.visitJumpInsn(Opcodes.GOTO, end_label); opinfo.mv.visitLabel(not_eq_label); opinfo.mv.visitInsn(Opcodes.ICONST_0); opinfo.mv.visitLabel(end_label); Container anony_bool = new Container("anonymous", Container.FORM_OPSTACK_VAR, true, false); anony_bool.initializeType((AbsType) cpLoader.findClassFull(TPrimitiveClass.NAME_BOOL)); anony_bool.setAssigned(true); return anony_bool; }
@Override public Container smaller(Container lval, Container rvalue, OpInfo opinfo) throws CompileException { Label greater_equal_label = new Label(); Label end_label = new Label(); opinfo.mv.visitJumpInsn(Opcodes.IF_ICMPGE, greater_equal_label); opinfo.mv.visitInsn(Opcodes.ICONST_1); opinfo.mv.visitJumpInsn(Opcodes.GOTO, end_label); opinfo.mv.visitLabel(greater_equal_label); opinfo.mv.visitInsn(Opcodes.ICONST_0); opinfo.mv.visitLabel(end_label); Container anony_bool = new Container("anonymous", Container.FORM_OPSTACK_VAR, true, false); anony_bool.initializeType((AbsType) cpLoader.findClassFull(TPrimitiveClass.NAME_BOOL)); anony_bool.setAssigned(true); return anony_bool; }
@Override public final void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) { AttributesImpl attrs = new AttributesImpl(); attrs.addAttribute("", "min", "min", "", Integer.toString(min)); attrs.addAttribute("", "max", "max", "", Integer.toString(max)); attrs.addAttribute("", "dflt", "dflt", "", getLabel(dflt)); String o = Printer.OPCODES[Opcodes.TABLESWITCH]; sa.addStart(o, attrs); for (int i = 0; i < labels.length; i++) { AttributesImpl att2 = new AttributesImpl(); att2.addAttribute("", "name", "name", "", getLabel(labels[i])); sa.addElement("label", att2); } sa.addEnd(o); }
private void writeNonAbstractMethodWrapper(ClassVisitor visitor, Type generatedType, Class<?> managedTypeClass, Method method) { Label start = new Label(); Label end = new Label(); Label handler = new Label(); MethodVisitor methodVisitor = declareMethod(visitor, method); methodVisitor.visitTryCatchBlock(start, end, handler, null); setCanCallSettersField(methodVisitor, generatedType, false); methodVisitor.visitLabel(start); invokeSuperMethod(methodVisitor, managedTypeClass, method); methodVisitor.visitLabel(end); setCanCallSettersField(methodVisitor, generatedType, true); methodVisitor.visitInsn(ARETURN); methodVisitor.visitLabel(handler); setCanCallSettersField(methodVisitor, generatedType, true); methodVisitor.visitInsn(ATHROW); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
private void appendFrameTypes(final int n, final Object[] o) { for (int i = 0; i < n; ++i) { if (i > 0) { buf.append(", "); } if (o[i] instanceof String) { appendConstant(o[i]); } else if (o[i] instanceof Integer) { switch (((Integer) o[i]).intValue()) { case 0: buf.append("Opcodes.TOP"); break; case 1: buf.append("Opcodes.INTEGER"); break; case 2: buf.append("Opcodes.FLOAT"); break; case 3: buf.append("Opcodes.DOUBLE"); break; case 4: buf.append("Opcodes.LONG"); break; case 5: buf.append("Opcodes.NULL"); break; case 6: buf.append("Opcodes.UNINITIALIZED_THIS"); break; } } else { appendLabel((Label) o[i]); } } }
@Override public void visitJumpInsn(final int opcode, final Label label) { minSize += 3; if (opcode == GOTO || opcode == JSR) { maxSize += 5; } else { maxSize += 8; } if (mv != null) { mv.visitJumpInsn(opcode, label); } }
@Override public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String desc, boolean visible) { checkStartCode(); checkEndCode(); int sort = typeRef >>> 24; if (sort != TypeReference.LOCAL_VARIABLE && sort != TypeReference.RESOURCE_VARIABLE) { throw new IllegalArgumentException("Invalid type reference sort 0x" + Integer.toHexString(sort)); } CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath); checkDesc(desc, false); if (start == null || end == null || index == null || end.length != start.length || index.length != start.length) { throw new IllegalArgumentException( "Invalid start, end and index arrays (must be non null and of identical length"); } for (int i = 0; i < start.length; ++i) { checkLabel(start[i], true, "start label"); checkLabel(end[i], true, "end label"); checkUnsignedShort(index[i], "Invalid variable index"); int s = labels.get(start[i]).intValue(); int e = labels.get(end[i]).intValue(); if (e < s) { throw new IllegalArgumentException( "Invalid start and end labels (end must be greater than start)"); } } return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible); }
@Override public void visitLineNumber(final int line, final Label start) { buf.setLength(0); buf.append(tab2).append("LINENUMBER ").append(line).append(' '); appendLabel(start); buf.append('\n'); text.add(buf.toString()); }
@Override public void injectAtMethodEnter() { startFinally = new Label(); aa.visitLabel(startFinally); aa.visitFieldInsn(GETSTATIC, className, staticFinalFieldName(metric), Type.getDescriptor(Gauged.getCoreType())); injectLabelsToStack(metric); aa.visitMethodInsn(INVOKESTATIC, METRIC_REPORTER_CLASSNAME, INC_METHOD, SIGNATURE, false); }
@Override public void visitLineNumber(final int line, final Label start) { checkStartCode(); checkEndCode(); checkUnsignedShort(line, "Invalid line number"); checkLabel(start, true, "start label"); super.visitLineNumber(line, start); }
public Label[] getLabelList() { int size = this.size(); Label[] label_arr = new Label[size]; MatchCaseEntry entry = null; for (int i = 0; i < size; i++) { entry = this.get(i); label_arr[i] = entry.label; } return label_arr; }
private LabelNode[] getLabelNodes(final Label[] l) { LabelNode[] nodes = new LabelNode[l.length]; for (int i = 0; i < l.length; ++i) { nodes[i] = getLabelNode(l[i]); } return nodes; }
@Override public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) { checkState(); insnIndex++; super.visitTableSwitchInsn(min, max, dflt, labels); }
@Override public void injectAtVisitMaxs(int maxStack, int maxLocals) { Label endFinally = new Label(); aa.visitTryCatchBlock(startFinally, endFinally, endFinally, null); aa.visitLabel(endFinally); aa.visitFieldInsn(GETSTATIC, className, staticFinalFieldName(exceptionMetric), Type.getDescriptor(Counted.getCoreType())); injectLabelsToStack(exceptionMetric); aa.visitMethodInsn(INVOKESTATIC, METRIC_REPORTER_CLASSNAME, EXCEPTION_COUNT_METHOD, EXCEPTION_COUNT_SIGNATURE, false); onFinally(ATHROW); aa.visitInsn(ATHROW); }
@Override public Object visit(ASTForCondition node, Object data) throws CompileException { LangUnitNode parent = (LangUnitNode) node.jjtGetParent(); Debug.assertion(parent != null, "parent should not be invalid"); Debug.assertion(parent.isNodeId(JJTCSTYLELOOPEXPR), "parent should be c style loop"); Label loop_body_label = parent.getLoopBodyLabel(); Debug.assertion(loop_body_label != null, "loop action label should not be invalid"); OpInfo opinfo = new OpInfo(getTopContext()); if (node.jjtGetNumChildren() == 0) { opinfo.mv.visitJumpInsn(Opcodes.GOTO, loop_body_label); } else if (node.jjtGetNumChildren() == 1) { Reduction reduce = popReduction(); Debug.assertion(reduce != null, "Reductin should not be invalid"); opinfo.mv.visitJumpInsn(Opcodes.IFNE, loop_body_label); } else { throw new CompileException("This case is not considered"); } Label loop_end_label = parent.getLoopEndLabel(); Debug.assertion(loop_end_label != null, "loop end label should not be invalid"); opinfo.mv.visitLabel(loop_end_label); if (node.hasDefinitionRefernce()) { // this loop does not reduce instance pushReduction(new Control(Control.FORM_LOOP)); } else { // this loop reduces list instance AbsType stream_type = langstream_finish(opinfo); Container stream_obj = new Container("anonymous stream", Container.FORM_OPSTACK_VAR, true, false); stream_obj.initializeType(stream_type); pushReduction(stream_obj); // reduced as a object } return null; }
private static Label[] getTableSwitchLabelsForAccess( Label defaultCaseLabel, List<? extends MemberInfo> members) { return AsmUtils.getTableSwitchLabels(defaultCaseLabel, members.stream() .mapToInt(m -> m.memberIndex) .toArray()); }
@Override public void injectAtVisitMaxs(int maxStack, int maxLocals) { Label endFinally = new Label(); aa.visitTryCatchBlock(startFinally, endFinally, endFinally, null); aa.visitLabel(endFinally); onFinally(ATHROW); aa.visitInsn(ATHROW); }
@Override public void accept(final MethodVisitor mv) { Label[] labels = new Label[this.labels.size()]; for (int i = 0; i < labels.length; ++i) { labels[i] = this.labels.get(i).getLabel(); } mv.visitTableSwitchInsn(min, max, dflt.getLabel(), labels); acceptAnnotations(mv); }
@Override public void visitJumpInsn(final int opcode, final Label label) { mv.visitJumpInsn(opcode, label); if (constructor) { switch (opcode) { case IFEQ: case IFNE: case IFLT: case IFGE: case IFGT: case IFLE: case IFNULL: case IFNONNULL: popValue(); break; case IF_ICMPEQ: case IF_ICMPNE: case IF_ICMPLT: case IF_ICMPGE: case IF_ICMPGT: case IF_ICMPLE: case IF_ACMPEQ: case IF_ACMPNE: popValue(); popValue(); break; case JSR: pushValue(OTHER); break; } addBranch(label); } }
/** * Writes the opcodes to flip a negative array index (meaning slots from the end of the array) into a 0-based one (meaning slots from * the start of the array). */ static void writeIndexFlip(MethodWriter writer, Consumer<MethodWriter> writeGetLength) { Label noFlip = new Label(); // Everywhere when it says 'array' below that could also be a list // The stack after each instruction: array, unnormalized_index writer.dup(); // array, unnormalized_index, unnormalized_index writer.ifZCmp(Opcodes.IFGE, noFlip); // array, unnormalized_index writer.swap(); // negative_index, array writer.dupX1(); // array, negative_index, array writeGetLength.accept(writer); // array, negative_index, length writer.visitInsn(Opcodes.IADD); // array, noralized_index writer.mark(noFlip); // array, noralized_index }
/** * Marks the start of an exception handler. * * @param start * beginning of the exception handler's scope (inclusive). * @param end * end of the exception handler's scope (exclusive). * @param exception * internal name of the type of exceptions handled by the * handler. */ public void catchException(final Label start, final Label end, final Type exception) { Label doCatch = new Label(); if (exception == null) { mv.visitTryCatchBlock(start, end, doCatch, null); } else { mv.visitTryCatchBlock(start, end, doCatch, exception.getInternalName()); } mark(doCatch); }
@Override public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) { minSize += 13 + labels.length * 4; maxSize += 16 + labels.length * 4; if (mv != null) { mv.visitTableSwitchInsn(min, max, dflt, labels); } }
@Override public void visitLabel(final Label label) { mv.visitLabel(label); if (constructor && branches != null) { List<Object> frame = branches.get(label); if (frame != null) { stackFrame = frame; branches.remove(label); } } }
@Override public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { buf.setLength(0); buf.append(tab2).append("TRYCATCHBLOCK "); appendLabel(start); buf.append(' '); appendLabel(end); buf.append(' '); appendLabel(handler); buf.append(' '); appendDescriptor(INTERNAL_NAME, type); buf.append('\n'); text.add(buf.toString()); }
@Override public void visitJumpInsn(final int opcode, final Label label) { buf.setLength(0); buf.append(tab2).append(OPCODES[opcode]).append(' '); appendLabel(label); buf.append('\n'); text.add(buf.toString()); }
@Override public final void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { AttributesImpl att = new AttributesImpl(); att.addAttribute("", "dflt", "dflt", "", getLabel(dflt)); String o = Printer.OPCODES[Opcodes.LOOKUPSWITCH]; sa.addStart(o, att); for (int i = 0; i < labels.length; i++) { AttributesImpl att2 = new AttributesImpl(); att2.addAttribute("", "name", "name", "", getLabel(labels[i])); att2.addAttribute("", "key", "key", "", Integer.toString(keys[i])); sa.addElement("label", att2); } sa.addEnd(o); }
@Override public void visitCode() { mv.visitCode(); if (constructor) { stackFrame = new ArrayList<Object>(); branches = new HashMap<Label, List<Object>>(); } else { superInitialized = true; onMethodEnter(); } }
@Override public final void end(final String name) { HashMap<?, ?> vals = (HashMap<?, ?>) pop(); Label dflt = getLabel(vals.get("dflt")); @SuppressWarnings("unchecked") ArrayList<String> keyList = (ArrayList<String>) vals.get("keys"); ArrayList<?> lbls = (ArrayList<?>) vals.get("labels"); Label[] labels = lbls.toArray(new Label[lbls.size()]); int[] keys = new int[keyList.size()]; for (int i = 0; i < keys.length; i++) { keys[i] = Integer.parseInt(keyList.get(i)); } getCodeVisitor().visitLookupSwitchInsn(dflt, keys, labels); }