private void setByIndex(final String[] names, final int[] indexes) throws Exception { final CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_SET_BY_INDEX, null); e.load_this(); e.load_arg(1); e.load_arg(0); e.process_switch(indexes, new ProcessSwitchCallback() { public void processCase(int key, Label end) throws Exception { Type type = (Type)fields.get(names[key]); e.unbox(type); e.putfield(names[key]); e.return_value(); } public void processDefault() throws Exception { e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field index"); } }); e.end_method(); }
private void getByIndex(final String[] names, final int[] indexes) throws Exception { final CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_GET_BY_INDEX, null); e.load_this(); e.load_arg(0); e.process_switch(indexes, new ProcessSwitchCallback() { public void processCase(int key, Label end) throws Exception { Type type = (Type)fields.get(names[key]); e.getfield(names[key]); e.box(type); e.return_value(); } public void processDefault() throws Exception { e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field index"); } }); e.end_method(); }
private void getField(String[] names) throws Exception { final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, PROVIDER_GET, null); e.load_this(); e.load_arg(0); EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { public void processCase(Object key, Label end) { Type type = (Type)fields.get(key); e.getfield((String)key); e.box(type); e.return_value(); } public void processDefault() { e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field name"); } }); e.end_method(); }
private void setField(String[] names) throws Exception { final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, PROVIDER_SET, null); e.load_this(); e.load_arg(1); e.load_arg(0); EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { public void processCase(Object key, Label end) { Type type = (Type)fields.get(key); e.unbox(type); e.putfield((String)key); e.return_value(); } public void processDefault() { e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field name"); } }); e.end_method(); }
private void generateGet(Class type, final Map getters) { final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_GET, null); e.load_arg(0); e.checkcast(Type.getType(type)); e.load_arg(1); e.checkcast(Constants.TYPE_STRING); EmitUtils.string_switch(e, getNames(getters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { public void processCase(Object key, Label end) { PropertyDescriptor pd = (PropertyDescriptor)getters.get(key); MethodInfo method = ReflectUtils.getMethodInfo(pd.getReadMethod()); e.invoke(method); e.box(method.getSignature().getReturnType()); e.return_value(); } public void processDefault() { e.aconst_null(); e.return_value(); } }); e.end_method(); }
private void generateGetPropertyType(final Map allProps, String[] allNames) { final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_TYPE, null); e.load_arg(0); EmitUtils.string_switch(e, allNames, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { public void processCase(Object key, Label end) { PropertyDescriptor pd = (PropertyDescriptor)allProps.get(key); EmitUtils.load_class(e, Type.getType(pd.getPropertyType())); e.return_value(); } public void processDefault() { e.aconst_null(); e.return_value(); } }); e.end_method(); }
public void generateFindProxy(ClassEmitter ce, final Map sigMap) { final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_STATIC, FIND_PROXY, null); e.load_arg(0); e.invoke_virtual(Constants.TYPE_OBJECT, TO_STRING); ObjectSwitchCallback callback = new ObjectSwitchCallback() { public void processCase(Object key, Label end) { e.getfield((String)sigMap.get(key)); e.return_value(); } public void processDefault() { e.aconst_null(); e.return_value(); } }; EmitUtils.string_switch(e, (String[])sigMap.keySet().toArray(new String[0]), Constants.SWITCH_STYLE_HASH, callback); e.end_method(); }
private void emitGetCallback(ClassEmitter ce, int[] keys) { final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, GET_CALLBACK, null); e.load_this(); e.invoke_static_this(BIND_CALLBACKS); e.load_this(); e.load_arg(0); e.process_switch(keys, new ProcessSwitchCallback() { public void processCase(int key, Label end) { e.getfield(getCallbackField(key)); e.goTo(end); } public void processDefault() { e.pop(); // stack height e.aconst_null(); } }); e.return_value(); e.end_method(); }
private void emitSetCallback(ClassEmitter ce, int[] keys) { final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, SET_CALLBACK, null); e.load_arg(0); e.process_switch(keys, new ProcessSwitchCallback() { public void processCase(int key, Label end) { e.load_this(); e.load_arg(1); e.checkcast(callbackTypes[key]); e.putfield(getCallbackField(key)); e.goTo(end); } public void processDefault() { // TODO: error? } }); e.return_value(); e.end_method(); }
private void signatureSwitchHelper(final CodeEmitter e, final List signatures) { ObjectSwitchCallback callback = new ObjectSwitchCallback() { public void processCase(Object key, Label end) { // TODO: remove linear indexOf e.push(signatures.indexOf(key)); e.return_value(); } public void processDefault() { e.push(-1); e.return_value(); } }; EmitUtils.string_switch(e, (String[])signatures.toArray(new String[signatures.size()]), Constants.SWITCH_STYLE_HASH, callback); }
public void generateClass(ClassVisitor v) throws Exception { ClassEmitter ce = new ClassEmitter(v); ce.begin_class(Constants.V1_2, Constants.ACC_PUBLIC, getClassName(), STRING_SWITCHER, null, Constants.SOURCE_FILE); EmitUtils.null_constructor(ce); final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, INT_VALUE, null); e.load_arg(0); final List stringList = Arrays.asList(strings); int style = fixedInput ? Constants.SWITCH_STYLE_HASHONLY : Constants.SWITCH_STYLE_HASH; EmitUtils.string_switch(e, strings, style, new ObjectSwitchCallback() { public void processCase(Object key, Label end) { e.push(ints[stringList.indexOf(key)]); e.return_value(); } public void processDefault() { e.push(-1); e.return_value(); } }); e.end_method(); ce.end_class(); }
/** * Process an array on the stack. Assumes the top item on the stack * is an array of the specified type. For each element in the array, * puts the element on the stack and triggers the callback. * @param type the type of the array (type.isArray() must be true) * @param callback the callback triggered for each element */ public static void process_array(CodeEmitter e, Type type, ProcessArrayCallback callback) { Type componentType = TypeUtils.getComponentType(type); Local array = e.make_local(); Local loopvar = e.make_local(Type.INT_TYPE); Label loopbody = e.make_label(); Label checkloop = e.make_label(); e.store_local(array); e.push(0); e.store_local(loopvar); e.goTo(checkloop); e.mark(loopbody); e.load_local(array); e.load_local(loopvar); e.array_load(componentType); callback.processElement(componentType); e.iinc(loopvar, 1); e.mark(checkloop); e.load_local(loopvar); e.load_local(array); e.arraylength(); e.if_icmp(e.LT, loopbody); }
private static void hash_object(CodeEmitter e, Type type, Customizer customizer) { // (f == null) ? 0 : f.hashCode(); Label skip = e.make_label(); Label end = e.make_label(); e.dup(); e.ifnull(skip); if (customizer != null) { customizer.customize(e, type); } e.invoke_virtual(Constants.TYPE_OBJECT, HASH_CODE); e.goTo(end); e.mark(skip); e.pop(); e.push(0); e.mark(end); }
/** * If both objects on the top of the stack are non-null, does nothing. * If one is null, or both are null, both are popped off and execution * branches to the respective label. * @param oneNull label to branch to if only one of the objects is null * @param bothNull label to branch to if both of the objects are null */ private static void nullcmp(CodeEmitter e, Label oneNull, Label bothNull) { e.dup2(); Label nonNull = e.make_label(); Label oneNullHelper = e.make_label(); Label end = e.make_label(); e.ifnonnull(nonNull); e.ifnonnull(oneNullHelper); e.pop2(); e.goTo(bothNull); e.mark(nonNull); e.ifnull(oneNullHelper); e.goTo(end); e.mark(oneNullHelper); e.pop2(); e.goTo(oneNull); e.mark(end); }
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"); 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); } mv.visitTableSwitchInsn(min, max, dflt, labels); }
public void visitLookupSwitchInsn( final Label dflt, final int[] keys, final Label[] labels) { checkEndCode(); checkStartCode(); checkLabel(dflt, false, "default label"); 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); } mv.visitLookupSwitchInsn(dflt, keys, labels); }
public void visitLocalVariable( final String name, final String desc, final String signature, final Label start, final Label end, final int index) { checkStartCode(); checkEndCode(); checkIdentifier(name, "name"); checkDesc(desc, false); checkLabel(start, true, "start label"); checkLabel(end, true, "end label"); checkUnsignedShort(index, "Invalid variable index"); int s = ((Integer) labels.get(start)).intValue(); int e = ((Integer) labels.get(end)).intValue(); if (e < s) { throw new IllegalArgumentException("Invalid start and end labels (end must be greater than start)"); } mv.visitLocalVariable(name, desc, signature, start, end, index); }
/** * Checks a stack frame value. * * @param value the value to be checked. */ static 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); } }
public void visitTableSwitchInsn( final int min, final int max, final Label dflt, final Label[] labels) { buf.setLength(0); buf.append(tab2).append("TABLESWITCH\n"); for (int i = 0; i < labels.length; ++i) { buf.append(tab3).append(min + i).append(": "); appendLabel(labels[i]); buf.append('\n'); } buf.append(tab3).append("default: "); appendLabel(dflt); buf.append('\n'); text.add(buf.toString()); if (mv != null) { mv.visitTableSwitchInsn(min, max, dflt, labels); } }
public void visitLookupSwitchInsn( final Label dflt, final int[] keys, final Label[] labels) { buf.setLength(0); buf.append(tab2).append("LOOKUPSWITCH\n"); for (int i = 0; i < labels.length; ++i) { buf.append(tab3).append(keys[i]).append(": "); appendLabel(labels[i]); buf.append('\n'); } buf.append(tab3).append("default: "); appendLabel(dflt); buf.append('\n'); text.add(buf.toString()); if (mv != null) { mv.visitLookupSwitchInsn(dflt, keys, labels); } }
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()); if (mv != null) { mv.visitTryCatchBlock(start, end, handler, type); } }
public void visitTableSwitchInsn( final int min, final int max, final Label dflt, final Label[] labels) { buf.setLength(0); for (int i = 0; i < labels.length; ++i) { declareLabel(labels[i]); } declareLabel(dflt); buf.append("mv.visitTableSwitchInsn(") .append(min) .append(", ") .append(max) .append(", "); appendLabel(dflt); buf.append(", new Label[] {"); for (int i = 0; i < labels.length; ++i) { buf.append(i == 0 ? " " : ", "); appendLabel(labels[i]); } buf.append(" });\n"); text.add(buf.toString()); }
public void visitLookupSwitchInsn( final Label dflt, final int[] keys, final Label[] labels) { buf.setLength(0); for (int i = 0; i < labels.length; ++i) { declareLabel(labels[i]); } declareLabel(dflt); buf.append("mv.visitLookupSwitchInsn("); appendLabel(dflt); buf.append(", new int[] {"); for (int i = 0; i < keys.length; ++i) { buf.append(i == 0 ? " " : ", ").append(keys[i]); } buf.append(" }, new Label[] {"); for (int i = 0; i < labels.length; ++i) { buf.append(i == 0 ? " " : ", "); appendLabel(labels[i]); } buf.append(" });\n"); text.add(buf.toString()); }
public void visitTryCatchBlock( final Label start, final Label end, final Label handler, final String type) { buf.setLength(0); declareLabel(start); declareLabel(end); declareLabel(handler); buf.append("mv.visitTryCatchBlock("); appendLabel(start); buf.append(", "); appendLabel(end); buf.append(", "); appendLabel(handler); buf.append(", "); appendConstant(type); buf.append(");\n"); text.add(buf.toString()); }
public void visitLocalVariable( final String name, final String desc, final String signature, final Label start, final Label end, final int index) { buf.setLength(0); buf.append("mv.visitLocalVariable("); appendConstant(name); buf.append(", "); appendConstant(desc); buf.append(", "); appendConstant(signature); buf.append(", "); appendLabel(start); buf.append(", "); appendLabel(end); buf.append(", ").append(index).append(");\n"); text.add(buf.toString()); }