/* * $Id$ * * Copyright (C) 2003-2016 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.jnasm.util; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.InvocationHandler; import org.jnode.assembler.x86.X86Assembler; import org.jnode.assembler.x86.X86BinaryAssembler; import org.jnode.assembler.x86.X86TextAssembler; import org.jnode.util.NumberUtils; /** * X86Assembler factory for creating an composed assembler stream which dispatches to a {@code X86TextAssembler} and a * {@code X86BinaryAssembler} instance. * * @author Levente S\u00e1ntha (lsantha@users.sourceforge.net) */ public class X86DualAssemblerFactory implements InvocationHandler { private X86TextAssembler textAssembler; private X86BinaryAssembler binaryAssembler; private boolean listing = false; private X86DualAssemblerFactory(X86TextAssembler textAssembler, X86BinaryAssembler binaryAssembler) { this.textAssembler = textAssembler; this.binaryAssembler = binaryAssembler; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object ret; if (method.getName().startsWith("write")) { int pos1 = binaryAssembler.getLength(); ret = method.invoke(binaryAssembler, args); int pos2 = binaryAssembler.getLength(); if (listing) { textAssembler.print(NumberUtils.hex(pos1)); } textAssembler.print(" "); int ln = pos2 - pos1; String msg; if (ln < 8) { if (listing) { msg = NumberUtils.hexCompact(binaryAssembler.getBytes(), pos1, pos2 - pos1); textAssembler.print(msg); if (msg.length() < 18) { for (int i = 0; i < 17 - msg.length(); i++) { textAssembler.print(" "); } } else { textAssembler.print(" "); } } method.invoke(textAssembler, args); } else { if (listing) { msg = NumberUtils.hexCompact(binaryAssembler.getBytes(), pos1, 8); textAssembler.print(msg); } method.invoke(textAssembler, args); if (listing) { msg = " -" + NumberUtils.hexCompact(binaryAssembler.getBytes(), pos1 + 8, ln - 8); textAssembler.println(msg); } } } else { method.invoke(textAssembler, args); ret = method.invoke(binaryAssembler, args); } if (textAssembler.getLength() % 100000 > 80000) { textAssembler.flush(); } if (method.getName().equals("getBytes")) { textAssembler.flush(); } return ret; } public static X86Assembler create(X86TextAssembler textAssembler,X86BinaryAssembler binaryAssembler) { return (X86Assembler) Enhancer.create(X86Assembler.class, new X86DualAssemblerFactory(textAssembler, binaryAssembler)); } }