/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
import java.nio.*;
import java.lang.reflect.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
{
// your code goes here
MyClass mc = new MyClass();
method_info mi_cnst = new method_info(
method_info.ACC_PUBLIC,
mc.addCP(new CONSTANT_Utf8_info("<init>")),
mc.addCP(new CONSTANT_Utf8_info("()V")));
mc.addMethod(mi_cnst);
Code_attribute ca_cnst = new Code_attribute(mc);
mi_cnst.add(ca_cnst);
ca_cnst.addCode(0x2A); // aload_0
ca_cnst.addCode(0xB7); // invokespecial
ca_cnst.addCodeShort(
mc.addCP(new CONSTANT_Methodref_info(
mc, "java/lang/Object",
"<init>", "()V")));
ca_cnst.addCode(0xB1); // return
method_info mi_main = new method_info(
method_info.ACC_PUBLIC | method_info.ACC_STATIC,
mc.addCP(new CONSTANT_Utf8_info("main")),
mc.addCP(new CONSTANT_Utf8_info("([Ljava/lang/String;)V")));
mc.addMethod(mi_main);
Code_attribute ca_main = new Code_attribute(mc);
mi_main.add(ca_main);
ca_main.max_stack = 2;
ca_main.addCode(0xB2); // getstatic
ca_main.addCodeShort(
mc.addCP(new CONSTANT_Fieldref_info(
mc, "java/lang/System",
"out", "Ljava/io/PrintStream;")));
ca_main.addCode(0x12); // ldc
ca_main.addCode(
mc.addCP(new CONSTANT_String_info(mc, "Hello World!")));
ca_main.addCode(0xB6); // invokevirtual
ca_main.addCodeShort(
mc.addCP(new CONSTANT_Methodref_info(
mc, "java/io/PrintStream",
"println", "(Ljava/lang/String;)V")));
ca_main.addCode(0xB1); // return
// バイトコード生成!
byte[] buf = mc.toBytes();
// 生成したバイトコードを試すとこ!
try {
MyClassLoader loader = new MyClassLoader();
Object hoge
= loader.
getHoge(buf
).
newInstance(); Method[] mm
= hoge.
getClass().
getMethods();
mm
[0].
invoke(null,
new String[1]); hoge.getClass().getMethod("main", ss.getClass()).invoke(null, ss);
System.
out.
println("ロード失敗!!"); System.
out.
println(e.
toString()); }
System.
out.
println("--生成したバイトコード--"); for (int i = 0; i < buf.length; i++) {
System.
out.
printf("%02X ", buf
[i
]); if ((i & 0x7) == 0x7) {
}
if ((i & 0xF) == 0xF) {
}
}
System.
out.
println("--Constant pool--"); int c = 1;
for (Iterator<cp_info> i = mc.constant_pool.iterator()
; i.hasNext(); c++) {
System.
out.
println(c
+ ":: " + i.
next().
toString()); }
}
MyClassLoader() {}
public Class<?> getHoge(byte[] b) {
// return defineClass(b, 0, b.length);
return defineClass("Hoge", b, 0, b.length);
}
}
static class MyClass {
public static final int ACC_PUBLIC = 0x01;
public static final int ACC_SUPER = 0x20;
byte[] magic;
int minor_version;
int major_version;
ArrayList<cp_info> constant_pool;
int access_flags;
int this_class;
int super_class;
int interfaces_count;
IntBuffer interfaces;
ArrayList<field_info> fields;
ArrayList<method_info> methods;
ArrayList<attribute_info> attributes;
{
magic = new byte[4];
magic[0] = (byte)0xCA;
magic[1] = (byte)0xFE;
magic[2] = (byte)0xBA;
magic[3] = (byte)0xBE;
access_flags = ACC_PUBLIC | ACC_SUPER;
minor_version = 0;
major_version = 0x31;
constant_pool = new ArrayList<cp_info>();
interfaces_count = 0;
interfaces = IntBuffer.allocate(5);
fields = null;
methods = null;
attributes = null;
}
MyClass() {
this_class = addCP(
new CONSTANT_Class_info(this, "Hoge"));
super_class = addCP(
new CONSTANT_Class_info(this, "java/lang/Object"));
/*
addAttribute(
new SourceFile_attribute(this, "Hoge.java"));
*/
}
int addCP(cp_info cp) {
int i = constant_pool.indexOf(cp);
if (i < 0) {
constant_pool.add(cp);
return constant_pool.size();
}
return i + 1;
}
void addMethod(method_info mt) {
if (methods == null) {
methods = new ArrayList<method_info>();
}
methods.add(mt);
}
void addAttribute(attribute_info ab) {
if (attributes == null) {
attributes = new ArrayList<attribute_info>();
}
attributes.add(ab);
}
try {
out.write(magic, 0, magic.length);
out.writeShort(minor_version);
out.writeShort(major_version);
out.writeShort(constant_pool.size() + 1);
for (Iterator<cp_info> i = constant_pool.iterator()
; i.hasNext(); ) {
i.next().write(out);
}
out.writeShort(access_flags);
out.writeShort(this_class);
out.writeShort(super_class);
out.writeShort(interfaces_count);
for (int i = 0; i < interfaces_count; i++) {
out.writeShort(interfaces.get(i));
}
if (fields == null) {
out.writeShort(0);
} else {
out.writeShort(fields.size());
for (Iterator<field_info> i = fields.iterator()
; i.hasNext(); ) {
i.next().write(out);
}
}
if (methods == null) {
out.writeShort(0);
} else {
out.writeShort(methods.size());
for (Iterator<method_info> i = methods.iterator()
; i.hasNext(); ) {
i.next().write(out);
}
}
if (attributes == null) {
out.writeShort(0);
} else {
out.writeShort(attributes.size());
for (Iterator<attribute_info> i = attributes.iterator()
; i.hasNext(); ) {
i.next().write(out);
}
}
return buf.toByteArray();
} finally {
if (out != null) out.close();
if (buf != null) buf.close();
}
}
}
static interface Icp_info {
byte CONSTANT_Class = 7;
byte CONSTANT_Fieldref = 9;
byte CONSTANT_Methodref = 10;
byte CONSTANT_InterfaceMethodref = 11;
byte CONSTANT_String = 8;
byte CONSTANT_Integer = 3;
byte CONSTANT_Float = 4;
byte CONSTANT_Long = 5;
byte CONSTANT_Double = 6;
byte CONSTANT_NameAndType = 12;
byte CONSTANT_Utf8 = 1;
}
static abstract class cp_info implements Icp_info {
public final byte tag;
protected cp_info(byte tag) { this.tag = tag; }
}
static class CONSTANT_Class_info extends cp_info {
public final int name_index;
CONSTANT_Class_info(int i) { super(CONSTANT_Class); name_index = i; }
CONSTANT_Class_info
(MyClass mc,
String c
) { super(CONSTANT_Class);
name_index = mc.addCP(new CONSTANT_Utf8_info(c));
}
out.writeByte(tag);
out.writeShort(name_index);
}
public boolean equals
(Object obj
) { if (obj == null) return false; if (this == obj) return true;
if (!(obj instanceof CONSTANT_Class_info)) return false;
CONSTANT_Class_info v = (CONSTANT_Class_info)obj;
return name_index == v.name_index;
}
return "Class " + name_index;
}
}
static class CONSTANT_ref_info extends cp_info {
public final int class_index;
public final int name_and_type_index;
protected CONSTANT_ref_info(byte tag, int a, int b) { super(tag);
class_index = a; name_and_type_index = b;}
this(t
, mc.addCP(new CONSTANT_Class_info(mc, c))
, mc.addCP(new CONSTANT_NameAndType_info(mc, m, d)));
}
out.writeByte(tag);
out.writeShort(class_index);
out.writeShort(name_and_type_index);
}
public boolean equals
(Object obj
) { if (obj == null) return false; if (this == obj) return true;
if (!(obj instanceof CONSTANT_ref_info)) return false;
CONSTANT_ref_info v = (CONSTANT_ref_info)obj;
return (class_index == v.class_index) &&
(name_and_type_index == v.name_and_type_index);
}
return "c:" + class_index + " nat:" + name_and_type_index;
}
}
static class CONSTANT_Fieldref_info extends CONSTANT_ref_info {
CONSTANT_Fieldref_info(int a, int b) { super(CONSTANT_Fieldref,a,b); }
super(CONSTANT_Fieldref, mc, c, m, d);
}
return "Field " + super.toString();
}
}
static class CONSTANT_Methodref_info extends CONSTANT_ref_info {
CONSTANT_Methodref_info(int a, int b) { super(CONSTANT_Methodref,a,b); }
super(CONSTANT_Methodref, mc, c, m, d);
}
return "Method " + super.toString();
}
}
static class CONSTANT_InterfaceMethodref_info extends CONSTANT_ref_info {
CONSTANT_InterfaceMethodref_info(int a, int b) { super(CONSTANT_InterfaceMethodref,a,b); }
}
static class CONSTANT_String_info extends cp_info {
public final int string_index;
CONSTANT_String_info(int i) { super(CONSTANT_String); string_index = i; }
CONSTANT_String_info
(MyClass mc,
String s
) { super(CONSTANT_String);
string_index = mc.addCP(new CONSTANT_Utf8_info(s));
}
out.writeByte(tag);
out.writeShort(string_index);
}
public boolean equals
(Object obj
) { if (obj == null) return false; if (this == obj) return true;
if (!(obj instanceof CONSTANT_String_info)) return false;
CONSTANT_String_info v = (CONSTANT_String_info)obj;
return string_index == v.string_index;
}
return "String " + string_index;
}
}
static class CONSTANT_Integer_info extends cp_info {
public final int bytes;
CONSTANT_Integer_info(int v) { super(CONSTANT_Integer); bytes = v; }
out.writeByte(tag);
out.writeInt(bytes);
}
public boolean equals
(Object obj
) { if (obj == null) return false; if (this == obj) return true;
if (!(obj instanceof CONSTANT_Integer_info)) return false;
CONSTANT_Integer_info v = (CONSTANT_Integer_info)obj;
return bytes == v.bytes;
}
}
static class CONSTANT_Float_info extends cp_info {
public final float bytes;
CONSTANT_Float_info(float v) { super(CONSTANT_Float); bytes = v; }
out.writeByte(tag);
out.writeFloat(bytes);
}
public boolean equals
(Object obj
) { if (obj == null) return false; if (this == obj) return true;
if (!(obj instanceof CONSTANT_Float_info)) return false;
CONSTANT_Float_info v = (CONSTANT_Float_info)obj;
return bytes == v.bytes;
}
}
static class CONSTANT_Long_info extends cp_info {
public final long bytes;
CONSTANT_Long_info(long v) { super(CONSTANT_Long); bytes = v; }
out.writeByte(tag);
out.writeLong(bytes);
}
public boolean equals
(Object obj
) { if (obj == null) return false; if (this == obj) return true;
if (!(obj instanceof CONSTANT_Long_info)) return false;
CONSTANT_Long_info v = (CONSTANT_Long_info)obj;
return bytes == v.bytes;
}
}
static class CONSTANT_Double_info extends cp_info {
public final double bytes;
CONSTANT_Double_info(double d) { super(CONSTANT_Double); bytes = d; }
out.writeByte(tag);
out.writeDouble(bytes);
}
public boolean equals
(Object obj
) { if (obj == null) return false; if (this == obj) return true;
if (!(obj instanceof CONSTANT_Double_info)) return false;
CONSTANT_Double_info v = (CONSTANT_Double_info)obj;
return bytes == v.bytes;
}
}
static class CONSTANT_NameAndType_info extends cp_info {
public int name_index = 0;
public int descriptor_index = 0;
CONSTANT_NameAndType_info(int n, int d) {
super(CONSTANT_NameAndType); name_index = n; descriptor_index=d; }
super(CONSTANT_NameAndType);
name_index = mc.addCP(new CONSTANT_Utf8_info(n));
descriptor_index = mc.addCP(new CONSTANT_Utf8_info(d));
}
out.writeByte(tag);
out.writeShort(name_index);
out.writeShort(descriptor_index);
}
public boolean equals
(Object obj
) { if (obj == null) return false; if (this == obj) return true;
if (!(obj instanceof CONSTANT_NameAndType_info)) return false;
CONSTANT_NameAndType_info v = (CONSTANT_NameAndType_info)obj;
return (name_index == v.name_index) &&
(descriptor_index == v.descriptor_index);
}
return "NameAndType n:" + name_index + " d:" + descriptor_index;
}
}
static class CONSTANT_Utf8_info extends cp_info {
CONSTANT_Utf8_info
(String str
) { super(CONSTANT_Utf8
); bytes
= str
; } out.writeByte(tag);
out.writeShort(bytes.length());
byte[] b = bytes.getBytes();
out.write(b, 0, b.length);
}
public boolean equals
(Object obj
) { if (obj == null) return false; if (this == obj) return true;
if (!(obj instanceof CONSTANT_Utf8_info)) return false;
CONSTANT_Utf8_info v = (CONSTANT_Utf8_info)obj;
if (bytes == null) return v.bytes == null;
return bytes.equals(v.bytes);
}
return "\"" + bytes + "\"";
}
}
static abstract class attribute_info {
public final int attribute_name_index;
protected attribute_info(int i) { attribute_name_index = i; }
}
static class exception_info {
public int start_pc = 0;
public int end_pc = 0;
public int handler_pc = 0;
public int catch_type = 0;
out.writeShort(start_pc);
out.writeShort(end_pc);
out.writeShort(handler_pc);
out.writeShort(catch_type);
}
}
static class SourceFile_attribute extends attribute_info {
public final int sourcefile_index;
SourceFile_attribute
(MyClass mc,
String s
) { super(mc.addCP(new CONSTANT_Utf8_info("SourceFile")));
sourcefile_index = mc.addCP(
new CONSTANT_Utf8_info(s));
}
out.writeShort(attribute_name_index);
out.writeInt(2);
out.writeShort(sourcefile_index);
}
}
static class Code_attribute extends attribute_info {
public int max_stack = 1;
public int max_locals = 1;
public ArrayList<exception_info> exception_table = null;
public ArrayList<attribute_info> attributes = null;
Code_attribute(MyClass mc) {
super(mc.addCP(new CONSTANT_Utf8_info("Code")));
}
data.write(c);
}
data.writeShort(c);
}
out.writeShort(attribute_name_index);
try {
tmp.writeShort(max_stack);
tmp.writeShort(max_locals);
tmp.writeInt(code.size());
tmp.write(code.toByteArray(), 0, code.size());
if (exception_table == null) {
tmp.writeShort(0);
} else {
tmp.writeShort(exception_table.size());
for (Iterator<exception_info>
i = exception_table.iterator()
; i.hasNext(); ) {
i.next().write(tmp);
}
}
if (attributes == null) {
tmp.writeShort(0);
} else {
tmp.writeShort(attributes.size());
for (Iterator<attribute_info>
i = attributes.iterator()
; i.hasNext(); ) {
i.next().write(tmp);
}
}
byte[] b = buf.toByteArray();
out.writeInt(b.length);
out.write(b, 0, b.length);
} finally {
if (tmp != null) tmp.close();
if (buf != null) buf.close();
}
}
}
static abstract class member_info {
public int access_flags;
public int name_index;
public int descriptor_index;
public ArrayList<attribute_info> attributes = null;
protected member_info(int ac, int n, int d) {
access_flags = ac;
name_index = n;
descriptor_index = d;
}
public void add(attribute_info a) {
if (attributes == null) {
attributes = new ArrayList<attribute_info>();
}
attributes.add(a);
}
out.writeShort(access_flags);
out.writeShort(name_index);
out.writeShort(descriptor_index);
if (attributes == null) {
out.writeShort(0);
} else {
out.writeShort(attributes.size());
for (Iterator<attribute_info> i = attributes.iterator()
; i.hasNext(); ) {
i.next().write(out);
}
}
}
}
static class field_info extends member_info {
public static final int ACC_PUBLIC = 0x01;
public static final int ACC_PRIVATE = 0x02;
public static final int ACC_PROTECTED = 0x04;
public static final int ACC_STATIC = 0x08;
public static final int ACC_FINAL = 0x10;
field_info(int ac, int n, int d) { super(ac, n, d); }
}
static class method_info extends member_info {
public static final int ACC_PUBLIC = 0x01;
public static final int ACC_PRIVATE = 0x02;
public static final int ACC_PROTECTED = 0x04;
public static final int ACC_STATIC = 0x08;
public static final int ACC_FINAL = 0x10;
method_info(int ac, int n, int d) { super(ac,n,d); }
}
}