private void build() { ClassWriter cw = new ClassWriter(0); final ClassLoader cl = getClass().getClassLoader(); for (SVDBItemType t : SVDBItemType.values()) { Class cls = null; for (String pkg : fTargetPkgList) { try { cls = cl.loadClass(pkg + ".SVDB" + t.name()); } catch (Exception e) { } if (cls != null) { break; } } if (cls != null) { // Found a class to process fTypeClassMap.put(t, cls); } else { System.out.println("Error: Failed to find item " + t.name()); } } // long start = System.currentTimeMillis(); build_boilerplate(cw); for (SVDBItemType t : fTypeClassMap.keySet()) { Class cls = fTypeClassMap.get(t); buildItemAccessor(cw, t, cls); } for (Class c : fClassList) { buildObjectAccessor(cw, c); } cw.visitEnd(); JITClassLoader jit_cl = new JITClassLoader(cl, cw.toByteArray()); try { fDelegateCls = (Class<JITPersistenceDelegateBase>) jit_cl.loadClass(fTargetPkg + ".SVDBPersistenceDelegate"); } catch (Exception e) { e.printStackTrace(); } /* long end = System.currentTimeMillis(); System.out.println("Class-build time: " + (end-start)); System.out.println("Size: " + cw.toByteArray().length); */ }
private void buildItemAccessor(ClassWriter cw, SVDBItemType t, Class cls) { MethodVisitor mv; if (fDebugEn) { debug("--> buildAccessor t=" + t.name() + " cls=" + cls.getName()); } // Constructor String item_name = t.name(); String tgt_clsname = getClassName(cls); // Read method // // 0 - this // 1 - parent // 2 - object mv = cw.visitMethod( ACC_PRIVATE, "read" + item_name, "(L" + fChildItem + ";)L" + tgt_clsname + ";", null, new String[] {fDBFormatException}); mv.visitCode(); mv.visitTypeInsn(NEW, tgt_clsname); // Create a new class instance mv.visitInsn(DUP); // Duplicate handle. One will be consumed by the init call mv.visitMethodInsn(INVOKESPECIAL, tgt_clsname, "<init>", "()V"); // mv.visitInsn(DUP); // Duplicate. One will be consumed by store to obj-var mv.visitVarInsn(ASTORE, READ_OBJ_VAR); // Store handle to obj-var // mv.visitVarInsn(ALOAD, THIS_VAR); // mv.visitVarInsn(ALOAD, READ_OBJ_VAR); // mv.visitMethodInsn(INVOKESPECIAL, tgt_clsname, "<init>", "()V"); // mv.visit // mv.visitInsn(ACONST_NULL); // mv.visitVarInsn(ASTORE, READ_OBJ_VAR); // Initialize return visit(false, tgt_clsname, mv, cls); mv.visitVarInsn(ALOAD, READ_OBJ_VAR); // Setup for return of var0 mv.visitInsn(ARETURN); mv.visitMaxs(3, 3); mv.visitEnd(); // Write method // // 0 - this // 1 - object mv = cw.visitMethod( ACC_PRIVATE, "write" + item_name, // "(L" + tgt_clsname + ";)V", "(L" + tgt_clsname + ";)V", null, new String[] {fDBWriteException}); mv.visitCode(); visit(true, tgt_clsname, mv, cls); mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); if (fDebugEn) { debug("<-- buildAccessor t=" + t + " cls=" + cls.getName()); } }
private void buildItemDispatchMethods(ClassWriter cw) { String classname = "SVDBPersistenceDelegate"; String full_classname = transform_cls(fTargetPkg) + "/" + classname; Label labels[] = new Label[SVDBItemType.values().length]; int indexes[] = new int[SVDBItemType.values().length]; Label dflt, endcase; for (int i = 0; i < SVDBItemType.values().length; i++) { indexes[i] = i; } // writeItem Dispatch method MethodVisitor mv = cw.visitMethod( ACC_PUBLIC, "writeSVDBItem", "(L" + getClassName(ISVDBItemBase.class) + ";)V", null, new String[] {fDBWriteException}); for (int i = 0; i < SVDBItemType.values().length; i++) { labels[i] = new Label(); } dflt = new Label(); endcase = new Label(); // Retrieve the object type mv.visitVarInsn(ALOAD, WRITE_OBJ_VAR); mv.visitMethodInsn( INVOKEINTERFACE, getClassName(ISVDBItemBase.class), "getType", "()L" + getClassName(SVDBItemType.class) + ";"); mv.visitMethodInsn(INVOKEVIRTUAL, getClassName(SVDBItemType.class), "ordinal", "()I"); mv.visitLookupSwitchInsn(dflt, indexes, labels); for (SVDBItemType t : SVDBItemType.values()) { Class c = fTypeClassMap.get(t); mv.visitLabel(labels[t.ordinal()]); mv.visitVarInsn(ALOAD, THIS_VAR); mv.visitVarInsn(ALOAD, WRITE_OBJ_VAR); mv.visitTypeInsn(CHECKCAST, getClassName(c)); mv.visitMethodInsn( INVOKESPECIAL, full_classname, "write" + t.name(), "(L" + getClassName(c) + ";)V"); mv.visitJumpInsn(GOTO, endcase); } mv.visitLabel(dflt); mv.visitLabel(endcase); mv.visitInsn(RETURN); mv.visitMaxs(16, 16); mv.visitEnd(); // readItem dispatch method mv = cw.visitMethod( ACC_PUBLIC, "readSVDBItem", "(L" + getClassName(SVDBItemType.class) + ";L" + getClassName(ISVDBChildItem.class) + ";)L" + getClassName(ISVDBItemBase.class) + ";", null, new String[] {fDBWriteException}); for (int i = 0; i < SVDBItemType.values().length; i++) { labels[i] = new Label(); } dflt = new Label(); endcase = new Label(); mv.visitVarInsn(ALOAD, 1); // object type mv.visitMethodInsn(INVOKEVIRTUAL, getClassName(SVDBItemType.class), "ordinal", "()I"); mv.visitLookupSwitchInsn(dflt, indexes, labels); for (SVDBItemType t : SVDBItemType.values()) { Class c = fTypeClassMap.get(t); mv.visitLabel(labels[t.ordinal()]); mv.visitVarInsn(ALOAD, THIS_VAR); mv.visitVarInsn(ALOAD, 2); // parent mv.visitMethodInsn( INVOKESPECIAL, full_classname, "read" + t.name(), "(L" + getClassName(ISVDBChildItem.class) + ";)" + "L" + getClassName(c) + ";"); mv.visitJumpInsn(GOTO, endcase); } mv.visitLabel(dflt); mv.visitInsn(ACONST_NULL); mv.visitLabel(endcase); mv.visitInsn(ARETURN); mv.visitMaxs(16, 16); mv.visitEnd(); }