List of usage examples for org.objectweb.asm MethodVisitor visitLabel
public void visitLabel(final Label label)
From source file:org.eclipse.m2m.atl.emftvm.jit.CodeBlockJIT.java
License:Open Source License
/** * Generates an execute method for the {@link JITCodeBlock}. * @param execute the execute method visitor * @param cb the {@link CodeBlock} to JIT-compile * @param className the name of the generated class *///w w w . j a va 2 s. c o m protected void generateExecute(final MethodVisitor execute, final CodeBlock cb, final String className) { execute.visitCode(); // Generate labels final LabelSwitch ls = new LabelSwitch(); for (Instruction instr : cb.getCode()) { ls.doSwitch(instr); } // Default labels final Label start = new Label(); final Label end = new Label(); final Label tryStart = new Label(); final Label vmExceptionHandler = new Label(); final Label exceptionHandler = new Label(); final Label catchEnd = new Label(); // Create exception table execute.visitTryCatchBlock(tryStart, vmExceptionHandler, vmExceptionHandler, Type.getInternalName(VMException.class)); execute.visitTryCatchBlock(tryStart, vmExceptionHandler, exceptionHandler, Type.getInternalName(Exception.class)); // Generate bytecode execute.visitLabel(start); execute.visitVarInsn(ALOAD, 1); // frame execute.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(StackFrame.class), "getEnv", Type.getMethodDescriptor(Type.getType(ExecEnv.class), new Type[0])); execute.visitVarInsn(ASTORE, 2); execute.visitVarInsn(ALOAD, 2); // env execute.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(ExecEnv.class), "getMonitor", Type.getMethodDescriptor(Type.getType(VMMonitor.class), new Type[0])); execute.visitVarInsn(ASTORE, 3); // monitor execute.visitLabel(tryStart); final ByteCodeSwitch bs = new ByteCodeSwitch(this, execute, ls); final EList<Instruction> code = cb.getCode(); final boolean hasMonitor = getEnv().getMonitor() != null; for (Instruction instr : code) { if (hasMonitor) { // do checkMonitor() before each instruction generateCheckMonitor(execute, code.indexOf(instr) + 1); // pc } // generate instruction-specific code bs.doSwitch(instr); } execute.visitJumpInsn(GOTO, catchEnd); // catch (VMException e) execute.visitLabel(vmExceptionHandler); execute.visitVarInsn(ASTORE, 4); // e execute.visitVarInsn(ALOAD, 4); // e execute.visitInsn(ATHROW); // throw e // catch (Exception e) execute.visitLabel(exceptionHandler); execute.visitVarInsn(ASTORE, 4); // e execute.visitTypeInsn(NEW, Type.getInternalName(VMException.class)); // new VMException(): [vme, ...] execute.visitInsn(DUP); // [vme, vme, e, ...] execute.visitVarInsn(ALOAD, 1); // frame: [frame, vme, vme, ...] execute.visitVarInsn(ALOAD, 4); // e: [e, frame, vme, vme, ...] execute.visitMethodInsn(INVOKESPECIAL, // new VMException(frame, e): [vme, ...] Type.getInternalName(VMException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(StackFrame.class), Type.getType(Throwable.class) })); execute.visitInsn(ATHROW); // throw vme // Regular method return execute.visitLabel(catchEnd); if (cb.getStackLevel() == 0) { execute.visitInsn(ACONST_NULL); // push null } execute.visitInsn(ARETURN); // return result execute.visitLabel(end); // Create local variable table execute.visitLocalVariable("this", "L" + className + ";", null, start, end, 0); execute.visitLocalVariable("frame", Type.getDescriptor(StackFrame.class), null, start, end, 1); execute.visitLocalVariable("env", Type.getDescriptor(ExecEnv.class), null, start, end, 2); execute.visitLocalVariable("monitor", Type.getDescriptor(VMMonitor.class), null, start, end, 3); execute.visitLocalVariable("e", Type.getDescriptor(VMException.class), null, vmExceptionHandler, exceptionHandler, 4); execute.visitLocalVariable("e", Type.getDescriptor(Exception.class), null, exceptionHandler, catchEnd, 4); // Finalise execute.visitMaxs(0, 0); // recalculate execute.visitEnd(); }
From source file:org.eclipse.m2m.atl.emftvm.jit.CodeBlockJIT.java
License:Open Source License
/** * Generates bytecode for checking the VM monitor * @param mv the method visitor to generate code for * @param pc the current program counter *///from w ww .j av a 2s . c om protected static void generateCheckMonitor(final MethodVisitor mv, final int pc) { // Labels final Label notTerminated = new Label(); // Generate bytecode mv.visitVarInsn(ALOAD, 3); // monitor: [..., monitor] mv.visitMethodInsn(INVOKEINTERFACE, // monitor.isTerminated(): [..., boolean] Type.getInternalName(VMMonitor.class), "isTerminated", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[0])); mv.visitJumpInsn(IFEQ, notTerminated); // jump if isTerminated == false: [...] mv.visitTypeInsn(NEW, Type.getInternalName(VMException.class)); // new VMException: [..., vme] mv.visitInsn(DUP); // [..., vme, vme] mv.visitVarInsn(ALOAD, 1); // frame: [..., vme, vme, frame] mv.visitLdcInsn("Execution terminated."); // [..., vme, vme, frame, msg] mv.visitMethodInsn(INVOKESPECIAL, // vme.<init>(frame, msg): [..., vme] Type.getInternalName(VMException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(StackFrame.class), Type.getType(String.class) })); mv.visitInsn(ATHROW); // throw vme: [...] mv.visitLabel(notTerminated); mv.visitVarInsn(ALOAD, 1); // frame: [..., frame] generatePushInt(mv, pc); // [..., frame, pc] mv.visitMethodInsn(INVOKEVIRTUAL, // frame.setPc(pc): [...] Type.getInternalName(StackFrame.class), "setPc", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.INT_TYPE })); mv.visitVarInsn(ALOAD, 3); // monitor: [..., monitor] mv.visitVarInsn(ALOAD, 1); // frame: [..., monitor, frame] mv.visitMethodInsn(INVOKEINTERFACE, // monitor.step(frame): [...] Type.getInternalName(VMMonitor.class), "step", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(StackFrame.class) })); }
From source file:org.eclipse.objectteams.otredyn.bytecode.asm.AddGlobalTeamActivationAdapter.java
License:Open Source License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { synchronized (AddGlobalTeamActivationAdapter.class) { if (!done && isMainMethod(name, desc, access)) { done = true;//from w ww .j a v a 2 s . c om final MethodVisitor methodVisitor = cv.visitMethod(access, name, desc, null, null); return new AdviceAdapter(this.api, methodVisitor, access, name, desc) { @Override protected void onMethodEnter() { List<String> teams = getTeamsFromConfigFile(); for (String aTeam : teams) { Label start, end, typeHandler, ctorHandler, after; String aTeamSlash = aTeam.replace('.', '/'); // new SomeTeam(): methodVisitor.visitLabel(start = new Label()); methodVisitor.visitTypeInsn(Opcodes.NEW, aTeamSlash); // .activate(Team.ALL_THREADS): methodVisitor.visitInsn(Opcodes.DUP); methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, aTeamSlash, "<init>", "()V", false); methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, ClassNames.TEAM_SLASH, "ALL_THREADS", "Ljava/lang/Thread;"); methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, aTeamSlash, "activate", "(Ljava/lang/Thread;)V", false); methodVisitor.visitLabel(end = new Label()); methodVisitor.visitJumpInsn(Opcodes.GOTO, after = new Label()); // catch (ClassNotFoundException, NoClassDefFoundError): // System.err.println(...) methodVisitor.visitLabel(typeHandler = new Label()); methodVisitor.visitInsn(Opcodes.POP); // discard the exception methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;"); methodVisitor.visitLdcInsn("Config error: Team class '" + aTeam + "' in config file '" + TEAM_CONFIG_FILE + "' can not be found!"); methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); methodVisitor.visitJumpInsn(Opcodes.GOTO, after); methodVisitor.visitTryCatchBlock(start, end, typeHandler, "java/lang/ClassNotFoundException"); // dup to avoid stackmap errors (ASM bug at 1.8) methodVisitor.visitLabel(typeHandler = new Label()); methodVisitor.visitInsn(Opcodes.POP); // discard the exception methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;"); methodVisitor.visitLdcInsn("Config error: Team class '" + aTeam + "' in config file '" + TEAM_CONFIG_FILE + "' can not be found!"); methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); methodVisitor.visitJumpInsn(Opcodes.GOTO, after); // methodVisitor.visitTryCatchBlock(start, end, typeHandler, "java/lang/NoClassDefFoundError"); // catch (NoSuchMethodError): // System.err.println(...) methodVisitor.visitLabel(ctorHandler = new Label()); methodVisitor.visitInsn(Opcodes.POP); // discard the exception methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;"); methodVisitor.visitLdcInsn( "Activation failed: Team class '" + aTeam + "' has no default constuctor!"); methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); methodVisitor.visitTryCatchBlock(start, end, ctorHandler, "java/lang/NoSuchMethodError"); methodVisitor.visitLabel(after); } } @Override public void visitMaxs(int maxStack, int maxLocals) { super.visitMaxs(Math.max(maxStack, 3), maxLocals); } }; } return null; } }
From source file:org.eclipse.objectteams.otredyn.bytecode.asm.AddThreadNotificationAdapter.java
License:Open Source License
@Override public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) {/*from w ww . j a v a2s . co m*/ if (INIT.equals(methodName)) { // into each constructor ... final MethodVisitor methodVisitor = cv.visitMethod(access, methodName, desc, null, null); return new AdviceAdapter(this.api, methodVisitor, access, methodName, desc) { @Override public void invokeConstructor(Type type, Method method) { super.invokeConstructor(type, method); // ... that contains a super(..) call (rather than this(..)): if (type.getInternalName().equals(clazz.getInternalSuperClassName())) { // insert: // this._OT$creationThread = Thread.currentThread(); methodVisitor.visitIntInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, ClassNames.THREAD_SLASH, CURRENT_THREAD, CURRENT_THREAD_DESC, false); methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, clazz.getInternalName(), CREATION_THREAD, THREAD_DESC); } } }; } else if (RUN.equals(methodName) && RUN_DESC.equals(desc)) { final MethodVisitor methodVisitor = cv.visitMethod(access, methodName, desc, null, null); return new AdviceAdapter(this.api, methodVisitor, access, methodName, desc) { Label start = new Label(); // start of method (scope of new local) Label end = new Label(); // end of method int isThreadStartIdx; // new local: boolean _OT$isThreadStart @Override protected void onMethodEnter() { methodVisitor.visitLabel(start); isThreadStartIdx = newLocal(Type.BOOLEAN_TYPE); methodVisitor.visitLocalVariable("_OT$isThreadStart", "Z", null, start, end, isThreadStartIdx); // TeamThreadManager.newThreadStarted(false, this._OT$creationThread) methodVisitor.visitInsn(Opcodes.ICONST_0); methodVisitor.visitIntInsn(Opcodes.ALOAD, 0); methodVisitor.visitFieldInsn(Opcodes.GETFIELD, clazz.getInternalName(), CREATION_THREAD, THREAD_DESC); methodVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, ClassNames.TEAM_THREAD_MANAGER_SLASH, NEW_THREAD_STARTED, NEW_THREAD_STARTED_DESC, false); methodVisitor.visitIntInsn(Opcodes.ISTORE, isThreadStartIdx); // this._OT$creationThread = null; // avoid leak methodVisitor.visitIntInsn(Opcodes.ALOAD, 0); methodVisitor.visitInsn(Opcodes.ACONST_NULL); methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, clazz.getInternalName(), CREATION_THREAD, THREAD_DESC); } @Override protected void onMethodExit(int opcode) { insertThreadEndedNotification(); } @Override public void endMethod() { methodVisitor.visitLabel(end); // insert another threadEnded notification as a handler for Throwable Label handler = new Label(); methodVisitor.visitLabel(handler); insertThreadEndedNotification(); methodVisitor.visitInsn(Opcodes.ATHROW); // rethrow caught exception methodVisitor.visitTryCatchBlock(start, end, handler, ClassNames.THROWABLE_SLASH); methodVisitor.visitMaxs(0, 0); } void insertThreadEndedNotification() { Label skip = new Label(); // insert: // if (_OT$isThreadStart) TeamThreadManager.threadEnded(); methodVisitor.visitIntInsn(Opcodes.ILOAD, isThreadStartIdx); methodVisitor.visitJumpInsn(Opcodes.IFEQ, skip); methodVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, ClassNames.TEAM_THREAD_MANAGER_SLASH, THREAD_ENDED, THREAD_ENDED_DESC, false); methodVisitor.visitLabel(skip); } }; } return null; }
From source file:org.eclipse.sisu.peaberry.internal.ImportGlue.java
License:Open Source License
@SuppressWarnings("PMD.ExcessiveMethodLength") private static void wrap(final ClassWriter cw, final String proxyName, final Method method) { final String methodName = method.getName(); final String descriptor = getMethodDescriptor(method); final String[] exceptions = getInternalNames(method.getExceptionTypes()); // simple delegating proxy, so don't need synchronization on wrapper method final int modifiers = method.getModifiers() & ~(ABSTRACT | NATIVE | SYNCHRONIZED); final MethodVisitor v = cw.visitMethod(modifiers, methodName, descriptor, null, exceptions); final Label start = new Label(); final Label invoke = new Label(); final Label end = new Label(); final Label ungetR = new Label(); final Label finalR = new Label(); final Label catchX = new Label(); final Label ungetX = new Label(); final Label finalX = new Label(); v.visitCode();//from w w w . java 2 s . c o m // support try{ get(); } finally { unget(); } model v.visitTryCatchBlock(start, ungetR, catchX, null); v.visitTryCatchBlock(ungetR, finalR, finalR, EXCEPTION_NAME); v.visitTryCatchBlock(ungetX, finalX, finalX, EXCEPTION_NAME); // store handle as "this" v.visitVarInsn(ALOAD, 0); v.visitFieldInsn(GETFIELD, proxyName, PROXY_HANDLE, IMPORT_DESC); v.visitInsn(DUP); v.visitVarInsn(ASTORE, 0); v.visitLabel(start); // dereference handle to get actual service instance v.visitMethodInsn(INVOKEINTERFACE, IMPORT_NAME, "get", "()" + OBJECT_DESC); v.visitInsn(DUP); // null => ServiceUnavailableException v.visitJumpInsn(IFNONNULL, invoke); v.visitTypeInsn(NEW, UNAVAILABLE_NAME); v.visitInsn(DUP); v.visitMethodInsn(INVOKESPECIAL, UNAVAILABLE_NAME, "<init>", "()V"); v.visitInsn(ATHROW); v.visitLabel(invoke); final Class<?> clazz = method.getDeclaringClass(); final String subjectName = getInternalName(clazz); if (!clazz.isInterface()) { v.visitTypeInsn(CHECKCAST, subjectName); } int i = 1; for (final Type t : getArgumentTypes(method)) { v.visitVarInsn(t.getOpcode(ILOAD), i); i = i + t.getSize(); } // delegate to real method if (clazz.isInterface()) { v.visitMethodInsn(INVOKEINTERFACE, subjectName, methodName, descriptor); } else { v.visitMethodInsn(INVOKEVIRTUAL, subjectName, methodName, descriptor); } final Type returnType = getReturnType(method); if (VOID != returnType.getSort()) { v.visitVarInsn(returnType.getOpcode(ISTORE), 1); } v.visitLabel(ungetR); // unget on return v.visitVarInsn(ALOAD, 0); v.visitMethodInsn(INVOKEINTERFACE, IMPORT_NAME, "unget", VOID_DESC); v.visitInsn(ACONST_NULL); v.visitLabel(finalR); if (VOID != returnType.getSort()) { v.visitVarInsn(returnType.getOpcode(ILOAD), 1); } v.visitInsn(returnType.getOpcode(IRETURN)); // cache initial exception v.visitLabel(catchX); v.visitVarInsn(ASTORE, 1); v.visitLabel(ungetX); // unget on exception v.visitVarInsn(ALOAD, 0); v.visitMethodInsn(INVOKEINTERFACE, IMPORT_NAME, "unget", VOID_DESC); v.visitInsn(ACONST_NULL); v.visitLabel(finalX); // restore initial exception v.visitVarInsn(ALOAD, 1); v.visitInsn(ATHROW); v.visitLabel(end); v.visitMaxs(0, 0); v.visitEnd(); }
From source file:org.enerj.enhancer.ClassEnhancer.java
License:Open Source License
/** * Generate the getfield/putfield replacement methods (enerj_Get_* and enerj_Set_*) * for persistent fields.//from w w w . j a v a 2s.c o m * Parameters to the generated methods conveniently match the stack frame of * getfield and putfield. * * @param aField a Field for which the methods will be generated. */ private void emitPersistentFieldMediationMethods(Field aField) { int fieldScope = aField.getAccessModifiers() & (ACC_PRIVATE | ACC_PUBLIC | ACC_PROTECTED); String fieldName = aField.getName(); String methodNameSuffix = getFieldMethodNameSuffix(mClassName, fieldName); String fieldType = aField.getDescriptor(); int opcodeOffset = getOpcodeOffsetForDescriptor(fieldType); // TODO do we need to worry about fields with parameterized types? //String genericSignature = Type.getDescriptor( aField.getGenericType() ); MethodVisitor mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_ACCESSOR_PREFIX + methodNameSuffix, '(' + mThisClassDescr + ')' + fieldType, null, null); Label label0 = new Label(); mv.visitLabel(label0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, "enerj_mLoaded", "Z"); Label label1 = new Label(); mv.visitJumpInsn(IFNE, label1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, "enerj_mNew", "Z"); mv.visitJumpInsn(IFNE, label1); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); mv.visitMethodInsn(INVOKESTATIC, sPersistableHelperClassSlashed, "checkLoaded", "(Lorg/enerj/core/Persistable;Z)V"); mv.visitLabel(label1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType); mv.visitInsn(getReturnOpcodeForDescriptor(fieldType)); Label label3 = new Label(); mv.visitLabel(label3); mv.visitLocalVariable("anInstance", mThisClassDescr, null, label0, label3, 0); mv.visitMaxs(0, 0); ///-------------- // Mutator (Setter). Because of the == comparison, the method is a little different // for primitives, Strings (final class that implements equals() properly), and regular objects. mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_MUTATOR_PREFIX + methodNameSuffix, '(' + mThisClassDescr + fieldType + ")V", null, null); mv.visitCode(); // Check if checkLoaded needs to be called. Call if (!enerj_mLoaded && !enerj_mNew) Label mutatorStartLabel = new Label(); mv.visitLabel(mutatorStartLabel); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, "enerj_mLoaded", "Z"); Label mutatorLabel1 = new Label(); mv.visitJumpInsn(IFNE, mutatorLabel1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, "enerj_mNew", "Z"); mv.visitJumpInsn(IFNE, mutatorLabel1); // Call checkLoaded mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_1); mv.visitMethodInsn(INVOKESTATIC, sPersistableHelperClassSlashed, "checkLoaded", "(Lorg/enerj/core/Persistable;Z)V"); mv.visitLabel(mutatorLabel1); // Check if the field's value is actually changing. For primitives, we use ==; // for special classes declared final (e.g., String, Integer), we use equals(); // and for other objects we use == (identity). Label notModifiedLabel = new Label(); if (MetaData.isPrimitive(fieldType)) { // Push parameter 1 - the new value mv.visitVarInsn(ILOAD + opcodeOffset, 1); // This mv.visitVarInsn(ALOAD, 0); // Current value mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType); char type = fieldType.charAt(0); switch (type) { case 'B': case 'Z': case 'C': case 'S': case 'I': mv.visitJumpInsn(IF_ICMPEQ, notModifiedLabel); break; case 'F': mv.visitInsn(FCMPL); mv.visitJumpInsn(IFEQ, notModifiedLabel); break; case 'J': mv.visitInsn(LCMP); mv.visitJumpInsn(IFEQ, notModifiedLabel); break; case 'D': mv.visitInsn(DCMPL); mv.visitJumpInsn(IFEQ, notModifiedLabel); break; default: throw new RuntimeException("Unknown primitive type: " + type); } } else if (fieldType.equals("Ljava/lang/String;") || fieldType.equals("Ljava/lang/Integer;") || fieldType.equals("Ljava/lang/Long;") || fieldType.equals("Ljava/lang/Byte;") || fieldType.equals("Ljava/lang/Boolean;") || fieldType.equals("Ljava/lang/Character;") || fieldType.equals("Ljava/lang/Short;") || fieldType.equals("Ljava/lang/Float;") || fieldType.equals("Ljava/lang/Double;")) { // One of the core final immutable types. Use equals() to compare values, like this: // "if ((aValue == null{1} && anInstance.mString != null{2}) || (aValue != null{3} && !aValue.equals(anInstance.mString){4})" ... // {1}: aValue == null mv.visitVarInsn(ALOAD, 1); Label imEqualsLabel = new Label(); mv.visitJumpInsn(IFNONNULL, imEqualsLabel); // {2}: anInstance.mString != null mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType); Label imStoreLabel = new Label(); mv.visitJumpInsn(IFNONNULL, imStoreLabel); // {3}: aValue != null mv.visitLabel(imEqualsLabel); mv.visitVarInsn(ALOAD, 1); mv.visitJumpInsn(IFNULL, notModifiedLabel); // {4}: equals()... // Push parameter 1 - the new value mv.visitVarInsn(ALOAD, 1); // Current Value mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType); // Compare !equals() mv.visitMethodInsn(INVOKEVIRTUAL, aField.getInternalName(), "equals", "(Ljava/lang/Object;)Z"); mv.visitJumpInsn(IFNE, notModifiedLabel); mv.visitLabel(imStoreLabel); } else { // Some other Object -- use identity == // Push parameter 1 - the new value mv.visitVarInsn(ALOAD, 1); // This mv.visitVarInsn(ALOAD, 0); // Current value mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType); mv.visitJumpInsn(IF_ACMPEQ, notModifiedLabel); } // Store the value // Mark owner object as modified - short circuit if already marked modified mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, "enerj_mModified", "Z"); Label mutatorLabel2 = new Label(); mv.visitJumpInsn(IFNE, mutatorLabel2); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESTATIC, sPersistableHelperClassSlashed, "addModified", sPersistableVoidSignature); mv.visitLabel(mutatorLabel2); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD + opcodeOffset, 1); mv.visitFieldInsn(PUTFIELD, mThisClassNameSlashed, fieldName, fieldType); mv.visitLabel(notModifiedLabel); mv.visitInsn(RETURN); Label mutatorEndlabel = new Label(); mv.visitLabel(mutatorEndlabel); mv.visitLocalVariable("anInstance", mThisClassDescr, null, mutatorStartLabel, mutatorEndlabel, 0); mv.visitLocalVariable("aValue", fieldType, null, mutatorStartLabel, mutatorEndlabel, 1); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:org.enerj.enhancer.ClassEnhancer.java
License:Open Source License
/** * Generate the getfield/putfield replacement methods (enerj_Get_* and enerj_Set_*) * for non-static transient fields./* w w w .ja v a2 s .c om*/ * Parameters to the generated methods conveniently match the stack frame of * getfield and putfield. * * @param aField a Field for which the methods will be generated. */ private void emitTransientFieldMediationMethods(Field aField) { int fieldScope = aField.getAccessModifiers() & (ACC_PRIVATE | ACC_PUBLIC | ACC_PROTECTED); String fieldName = aField.getName(); String methodNameSuffix = getFieldMethodNameSuffix(mClassName, fieldName); String fieldType = aField.getDescriptor(); // Accessor (Getter). MethodVisitor mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_ACCESSOR_PREFIX + methodNameSuffix, '(' + mThisClassDescr + ')' + fieldType, null, null); mv.visitCode(); Label startLabel = new Label(); mv.visitLabel(startLabel); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType); mv.visitInsn(getReturnOpcodeForDescriptor(fieldType)); Label endLabel = new Label(); mv.visitLabel(endLabel); mv.visitLocalVariable("anInstance", mThisClassDescr, null, startLabel, endLabel, 0); mv.visitMaxs(0, 0); mv.visitEnd(); // Mutator (Setter). mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_MUTATOR_PREFIX + methodNameSuffix, '(' + mThisClassDescr + fieldType + ")V", null, null); mv.visitCode(); startLabel = new Label(); mv.visitLabel(startLabel); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(getLoadOpcodeForDescriptor(fieldType), 1); mv.visitFieldInsn(PUTFIELD, mThisClassNameSlashed, fieldName, fieldType); mv.visitInsn(RETURN); endLabel = new Label(); mv.visitLabel(endLabel); mv.visitLocalVariable("anInstance", mThisClassDescr, null, startLabel, endLabel, 0); mv.visitLocalVariable("aValue", fieldType, null, startLabel, endLabel, 1); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:org.enerj.enhancer.ClassEnhancer.java
License:Open Source License
/** * Generate the getstatic/putstatic replacement methods (enerj_Get_* and enerj_Set_*) * for static transient fields. //from w w w . j a v a 2 s .c o m * Parameters to the generated methods conveniently match the stack frame of * getstatic and putstatic. * * @param aField a Field for which the methods will be generated. */ private void emitStaticFieldMediationMethods(Field aField) { int fieldScope = aField.getAccessModifiers() & (ACC_PRIVATE | ACC_PUBLIC | ACC_PROTECTED); String fieldName = aField.getName(); String methodNameSuffix = getFieldMethodNameSuffix(mClassName, fieldName); String fieldType = aField.getDescriptor(); // Accessor (Getter). MethodVisitor mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_ACCESSOR_PREFIX + methodNameSuffix, "()" + fieldType, null, null); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, mThisClassNameSlashed, fieldName, fieldType); mv.visitInsn(getReturnOpcodeForDescriptor(fieldType)); mv.visitMaxs(0, 0); mv.visitEnd(); // Mutator (Setter). mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_MUTATOR_PREFIX + methodNameSuffix, '(' + fieldType + ")V", null, null); mv.visitCode(); Label startLabel = new Label(); mv.visitLabel(startLabel); mv.visitVarInsn(getLoadOpcodeForDescriptor(fieldType), 0); mv.visitFieldInsn(PUTSTATIC, mThisClassNameSlashed, fieldName, fieldType); mv.visitInsn(RETURN); Label endLabel = new Label(); mv.visitLabel(endLabel); mv.visitLocalVariable("aValue", fieldType, null, startLabel, endLabel, 0); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:org.enerj.enhancer.ClassEnhancer.java
License:Open Source License
/** * Emit the special clone() method on a top-level persistable. This is * generated when a top-level Persistable doesn't have a clone method. * It ensures initPersistableClone is called if a sub-class implements clone(). *//*from w ww . ja v a 2 s. c om*/ private void emitClone() { // TODO Only add this exception if superclass throws it. Object does, while java.util.Date does not. // TODO Either that or never throw it and wrap the super.clone() in a try/catch. // TODO catch part should never happen. If it does, return null. String[] exceptions = new String[] { "java/lang/CloneNotSupportedException" }; MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "clone", "()Ljava/lang/Object;", null, exceptions); mv.visitCode(); Label startLabel = new Label(); mv.visitLabel(startLabel); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, mSuperClassNameSlashed, "clone", "()Ljava/lang/Object;"); mv.visitInsn(DUP); mv.visitTypeInsn(CHECKCAST, sPersistableClassSlashed); mv.visitMethodInsn(INVOKESTATIC, sPersistableHelperClassSlashed, "initPersistableClone", sPersistableVoidSignature); mv.visitInsn(ARETURN); Label endLabel = new Label(); mv.visitLabel(endLabel); mv.visitLocalVariable("this", mThisClassDescr, null, startLabel, endLabel, 0); mv.visitMaxs(0, 0); mv.visitEnd(); }