From d7321b5b0d38c575e54c770f7aa18dacbacab3c8 Mon Sep 17 00:00:00 2001 From: jeff Date: Sun, 27 Jul 2014 22:33:21 -0400 Subject: added identifier renaming capability copied some code over from M3L to handle the heavy bytecode magic. It's ok... M3L will eventually depend on Enigma. Completely restructured the mappings though. This way is better. =) --- .../bytecode/accessors/ClassInfoAccessor.java | 69 +++++++ .../bytecode/accessors/ConstInfoAccessor.java | 199 +++++++++++++++++++++ .../accessors/InvokeDynamicInfoAccessor.java | 96 ++++++++++ .../bytecode/accessors/MemberRefInfoAccessor.java | 96 ++++++++++ .../accessors/MethodHandleInfoAccessor.java | 96 ++++++++++ .../bytecode/accessors/MethodTypeInfoAccessor.java | 69 +++++++ .../accessors/NameAndTypeInfoAccessor.java | 96 ++++++++++ .../bytecode/accessors/StringInfoAccessor.java | 69 +++++++ .../bytecode/accessors/Utf8InfoAccessor.java | 33 ++++ 9 files changed, 823 insertions(+) create mode 100644 src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java create mode 100644 src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java create mode 100644 src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java create mode 100644 src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java create mode 100644 src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java create mode 100644 src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java create mode 100644 src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java create mode 100644 src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java create mode 100644 src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java (limited to 'src/cuchaz/enigma/bytecode/accessors') diff --git a/src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java new file mode 100644 index 0000000..41e1d04 --- /dev/null +++ b/src/cuchaz/enigma/bytecode/accessors/ClassInfoAccessor.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.bytecode.accessors; + +import java.lang.reflect.Field; + +public class ClassInfoAccessor +{ + private static Class m_class; + private static Field m_nameIndex; + + static + { + try + { + m_class = Class.forName( "javassist.bytecode.ClassInfo" ); + m_nameIndex = m_class.getDeclaredField( "name" ); + m_nameIndex.setAccessible( true ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public static boolean isType( ConstInfoAccessor accessor ) + { + return m_class.isAssignableFrom( accessor.getItem().getClass() ); + } + + private Object m_item; + + public ClassInfoAccessor( Object item ) + { + m_item = item; + } + + public int getNameIndex( ) + { + try + { + return (Integer)m_nameIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setNameIndex( int val ) + { + try + { + m_nameIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } +} diff --git a/src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java new file mode 100644 index 0000000..3c3d3fa --- /dev/null +++ b/src/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.bytecode.accessors; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import cuchaz.enigma.bytecode.InfoType; + +public class ConstInfoAccessor +{ + private static Class m_class; + private static Field m_index; + private static Method m_getTag; + + static + { + try + { + m_class = Class.forName( "javassist.bytecode.ConstInfo" ); + m_index = m_class.getDeclaredField( "index" ); + m_index.setAccessible( true ); + m_getTag = m_class.getMethod( "getTag" ); + m_getTag.setAccessible( true ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + private Object m_item; + + public ConstInfoAccessor( Object item ) + { + if( item == null ) + { + throw new IllegalArgumentException( "item cannot be null!" ); + } + m_item = item; + } + + public ConstInfoAccessor( DataInputStream in ) + throws IOException + { + try + { + // read the entry + String className = in.readUTF(); + int oldIndex = in.readInt(); + + // NOTE: ConstInfo instances write a type id (a "tag"), but they don't read it back + // so we have to read it here + in.readByte(); + + Constructor constructor = Class.forName( className ).getConstructor( DataInputStream.class, int.class ); + constructor.setAccessible( true ); + m_item = constructor.newInstance( in, oldIndex ); + } + catch( IOException ex ) + { + throw ex; + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public Object getItem( ) + { + return m_item; + } + + public int getIndex( ) + { + try + { + return (Integer)m_index.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setIndex( int val ) + { + try + { + m_index.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public int getTag( ) + { + try + { + return (Integer)m_getTag.invoke( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public ConstInfoAccessor copy( ) + { + return new ConstInfoAccessor( copyItem() ); + } + + public Object copyItem( ) + { + // I don't know of a simpler way to copy one of these silly things... + try + { + // serialize the item + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream( buf ); + write( out ); + + // deserialize the item + DataInputStream in = new DataInputStream( new ByteArrayInputStream( buf.toByteArray() ) ); + Object item = new ConstInfoAccessor( in ).getItem(); + in.close(); + + return item; + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void write( DataOutputStream out ) + throws IOException + { + try + { + out.writeUTF( m_item.getClass().getName() ); + out.writeInt( getIndex() ); + + Method method = m_item.getClass().getMethod( "write", DataOutputStream.class ); + method.setAccessible( true ); + method.invoke( m_item, out ); + } + catch( IOException ex ) + { + throw ex; + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + @Override + public String toString( ) + { + try + { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + PrintWriter out = new PrintWriter( buf ); + Method print = m_item.getClass().getMethod( "print", PrintWriter.class ); + print.setAccessible( true ); + print.invoke( m_item, out ); + out.close(); + return buf.toString().replace( "\n", "" ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public InfoType getType( ) + { + return InfoType.getByTag( getTag() ); + } +} diff --git a/src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java new file mode 100644 index 0000000..169306a --- /dev/null +++ b/src/cuchaz/enigma/bytecode/accessors/InvokeDynamicInfoAccessor.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.bytecode.accessors; + +import java.lang.reflect.Field; + +public class InvokeDynamicInfoAccessor +{ + private static Class m_class; + private static Field m_bootstrapIndex; + private static Field m_nameAndTypeIndex; + + static + { + try + { + m_class = Class.forName( "javassist.bytecode.InvokeDynamicInfo" ); + m_bootstrapIndex = m_class.getDeclaredField( "bootstrap" ); + m_bootstrapIndex.setAccessible( true ); + m_nameAndTypeIndex = m_class.getDeclaredField( "nameAndType" ); + m_nameAndTypeIndex.setAccessible( true ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public static boolean isType( ConstInfoAccessor accessor ) + { + return m_class.isAssignableFrom( accessor.getItem().getClass() ); + } + + private Object m_item; + + public InvokeDynamicInfoAccessor( Object item ) + { + m_item = item; + } + + public int getBootstrapIndex( ) + { + try + { + return (Integer)m_bootstrapIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setBootstrapIndex( int val ) + { + try + { + m_bootstrapIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public int getNameAndTypeIndex( ) + { + try + { + return (Integer)m_nameAndTypeIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setNameAndTypeIndex( int val ) + { + try + { + m_nameAndTypeIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } +} diff --git a/src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java new file mode 100644 index 0000000..2ee3aff --- /dev/null +++ b/src/cuchaz/enigma/bytecode/accessors/MemberRefInfoAccessor.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.bytecode.accessors; + +import java.lang.reflect.Field; + +public class MemberRefInfoAccessor +{ + private static Class m_class; + private static Field m_classIndex; + private static Field m_nameAndTypeIndex; + + static + { + try + { + m_class = Class.forName( "javassist.bytecode.MemberrefInfo" ); + m_classIndex = m_class.getDeclaredField( "classIndex" ); + m_classIndex.setAccessible( true ); + m_nameAndTypeIndex = m_class.getDeclaredField( "nameAndTypeIndex" ); + m_nameAndTypeIndex.setAccessible( true ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public static boolean isType( ConstInfoAccessor accessor ) + { + return m_class.isAssignableFrom( accessor.getItem().getClass() ); + } + + private Object m_item; + + public MemberRefInfoAccessor( Object item ) + { + m_item = item; + } + + public int getClassIndex( ) + { + try + { + return (Integer)m_classIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setClassIndex( int val ) + { + try + { + m_classIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public int getNameAndTypeIndex( ) + { + try + { + return (Integer)m_nameAndTypeIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setNameAndTypeIndex( int val ) + { + try + { + m_nameAndTypeIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } +} diff --git a/src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java new file mode 100644 index 0000000..27b7aee --- /dev/null +++ b/src/cuchaz/enigma/bytecode/accessors/MethodHandleInfoAccessor.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.bytecode.accessors; + +import java.lang.reflect.Field; + +public class MethodHandleInfoAccessor +{ + private static Class m_class; + private static Field m_kindIndex; + private static Field m_indexIndex; + + static + { + try + { + m_class = Class.forName( "javassist.bytecode.MethodHandleInfo" ); + m_kindIndex = m_class.getDeclaredField( "refKind" ); + m_kindIndex.setAccessible( true ); + m_indexIndex = m_class.getDeclaredField( "refIndex" ); + m_indexIndex.setAccessible( true ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public static boolean isType( ConstInfoAccessor accessor ) + { + return m_class.isAssignableFrom( accessor.getItem().getClass() ); + } + + private Object m_item; + + public MethodHandleInfoAccessor( Object item ) + { + m_item = item; + } + + public int getTypeIndex( ) + { + try + { + return (Integer)m_kindIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setTypeIndex( int val ) + { + try + { + m_kindIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public int getMethodRefIndex( ) + { + try + { + return (Integer)m_indexIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setMethodRefIndex( int val ) + { + try + { + m_indexIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } +} diff --git a/src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java new file mode 100644 index 0000000..4cba6a2 --- /dev/null +++ b/src/cuchaz/enigma/bytecode/accessors/MethodTypeInfoAccessor.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.bytecode.accessors; + +import java.lang.reflect.Field; + +public class MethodTypeInfoAccessor +{ + private static Class m_class; + private static Field m_descriptorIndex; + + static + { + try + { + m_class = Class.forName( "javassist.bytecode.MethodTypeInfo" ); + m_descriptorIndex = m_class.getDeclaredField( "descriptor" ); + m_descriptorIndex.setAccessible( true ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public static boolean isType( ConstInfoAccessor accessor ) + { + return m_class.isAssignableFrom( accessor.getItem().getClass() ); + } + + private Object m_item; + + public MethodTypeInfoAccessor( Object item ) + { + m_item = item; + } + + public int getTypeIndex( ) + { + try + { + return (Integer)m_descriptorIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setTypeIndex( int val ) + { + try + { + m_descriptorIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } +} diff --git a/src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java new file mode 100644 index 0000000..03b4de3 --- /dev/null +++ b/src/cuchaz/enigma/bytecode/accessors/NameAndTypeInfoAccessor.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.bytecode.accessors; + +import java.lang.reflect.Field; + +public class NameAndTypeInfoAccessor +{ + private static Class m_class; + private static Field m_nameIndex; + private static Field m_typeIndex; + + static + { + try + { + m_class = Class.forName( "javassist.bytecode.NameAndTypeInfo" ); + m_nameIndex = m_class.getDeclaredField( "memberName" ); + m_nameIndex.setAccessible( true ); + m_typeIndex = m_class.getDeclaredField( "typeDescriptor" ); + m_typeIndex.setAccessible( true ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public static boolean isType( ConstInfoAccessor accessor ) + { + return m_class.isAssignableFrom( accessor.getItem().getClass() ); + } + + private Object m_item; + + public NameAndTypeInfoAccessor( Object item ) + { + m_item = item; + } + + public int getNameIndex( ) + { + try + { + return (Integer)m_nameIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setNameIndex( int val ) + { + try + { + m_nameIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public int getTypeIndex( ) + { + try + { + return (Integer)m_typeIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setTypeIndex( int val ) + { + try + { + m_typeIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } +} diff --git a/src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java new file mode 100644 index 0000000..5cdfce4 --- /dev/null +++ b/src/cuchaz/enigma/bytecode/accessors/StringInfoAccessor.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.bytecode.accessors; + +import java.lang.reflect.Field; + +public class StringInfoAccessor +{ + private static Class m_class; + private static Field m_stringIndex; + + static + { + try + { + m_class = Class.forName( "javassist.bytecode.StringInfo" ); + m_stringIndex = m_class.getDeclaredField( "string" ); + m_stringIndex.setAccessible( true ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public static boolean isType( ConstInfoAccessor accessor ) + { + return m_class.isAssignableFrom( accessor.getItem().getClass() ); + } + + private Object m_item; + + public StringInfoAccessor( Object item ) + { + m_item = item; + } + + public int getStringIndex( ) + { + try + { + return (Integer)m_stringIndex.get( m_item ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public void setStringIndex( int val ) + { + try + { + m_stringIndex.set( m_item, val ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } +} diff --git a/src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java b/src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java new file mode 100644 index 0000000..1cadd83 --- /dev/null +++ b/src/cuchaz/enigma/bytecode/accessors/Utf8InfoAccessor.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.bytecode.accessors; + +public class Utf8InfoAccessor +{ + private static Class m_class; + + static + { + try + { + m_class = Class.forName( "javassist.bytecode.Utf8Info" ); + } + catch( Exception ex ) + { + throw new Error( ex ); + } + } + + public static boolean isType( ConstInfoAccessor accessor ) + { + return m_class.isAssignableFrom( accessor.getItem().getClass() ); + } +} -- cgit v1.2.3