List of usage examples for org.objectweb.asm MethodVisitor visitLocalVariable
public void visitLocalVariable(final String name, final String descriptor, final String signature, final Label start, final Label end, final int index)
From source file:org.boretti.drools.integration.drools5.DroolsClassVisitor.java
License:Open Source License
@Override public void visitEnd() { FieldVisitor fv = null;//w w w . j ava 2 s.com if (isNeedChangeForBoth()) { fv = super.visitField(Opcodes.ACC_PRIVATE, DROOLS_FIELD_NAME, Type.BOOLEAN_TYPE.getDescriptor(), null, null); if (fv != null) { AnnotationVisitor av = fv.visitAnnotation(Type.getType(Generated.class).getDescriptor(), true); AnnotationVisitor value = av.visitArray("value"); value.visit("", "Generated by Drools5IntegrationHelper Maven plugin"); value.visitEnd(); av.visit("date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz").format(current)); av.visitEnd(); fv.visitEnd(); } } if (isNeedChangeForField()) { fv = super.visitField(Opcodes.ACC_PRIVATE, DROOLS_FIELD_RULE, Type.getType(RuleBase.class).getDescriptor(), null, null); if (fv != null) { AnnotationVisitor av = fv.visitAnnotation(Type.getType(Generated.class).getDescriptor(), true); AnnotationVisitor value = av.visitArray("value"); value.visit("", "Generated by Drools5IntegrationHelper Maven plugin"); value.visitEnd(); av.visit("date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz").format(current)); av.visitEnd(); fv.visitEnd(); } MethodVisitor mv = super.visitMethod(Opcodes.ACC_PRIVATE, DROOLS_METHOD_RUN, "()V", null, null); AnnotationVisitor av = mv.visitAnnotation(Type.getType(Generated.class).getDescriptor(), true); AnnotationVisitor value = av.visitArray("value"); value.visit("", "Generated by Drools5IntegrationHelper Maven plugin"); value.visitEnd(); av.visit("date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz").format(current)); av.visitEnd(); mv.visitCode(); Label start = new Label(); mv.visitLabel(start); Label doIt = new Label(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, Type.getObjectType(me).getInternalName(), DROOLS_FIELD_NAME, Type.BOOLEAN_TYPE.getDescriptor()); mv.visitJumpInsn(Opcodes.IFEQ, doIt); mv.visitInsn(Opcodes.RETURN); mv.visitLabel(doIt); mv.visitFrame(Opcodes.F_SAME, 1, new Object[] { Type.getObjectType(me).getInternalName() }, 0, new Object[] {}); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, Type.getObjectType(me).getInternalName(), DROOLS_FIELD_RULE, Type.getType(RuleBase.class).getDescriptor()); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(RuleBase.class).getInternalName(), "newStatelessSession", "()Lorg/drools/StatelessSession;"); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn(FIELD_NAME_LOGGER); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getType(Object.class).getInternalName(), "getClass", "()Ljava/lang/Class;"); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getType(org.apache.log4j.Logger.class).getInternalName(), "getLogger", "(Ljava/lang/Class;)Lorg/apache/log4j/Logger;"); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(StatelessSession.class).getInternalName(), "setGlobal", "(Ljava/lang/String;Ljava/lang/Object;)V"); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(StatelessSession.class).getInternalName(), "execute", "(Ljava/lang/Object;)V"); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitInsn(Opcodes.ICONST_1); mv.visitFieldInsn(Opcodes.PUTFIELD, Type.getObjectType(me).getInternalName(), DROOLS_FIELD_NAME, Type.BOOLEAN_TYPE.getDescriptor()); mv.visitInsn(Opcodes.RETURN); Label end = new Label(); mv.visitLabel(end); mv.visitLocalVariable("this", Type.getObjectType(me).getDescriptor(), null, start, end, 0); mv.visitMaxs(4, 1); mv.visitEnd(); } super.visitEnd(); }
From source file:org.codehaus.groovy.classgen.asm.CompileStack.java
License:Apache License
/** * Clears the state of the class. This method should be called * after a MethodNode is visited. Note that a call to init will * fail if clear is not called before//from w ww.j a va2 s . c o m */ public void clear() { if (stateStack.size() > 1) { int size = stateStack.size() - 1; throw new GroovyBugError("the compile stack contains " + size + " more push instruction" + (size == 1 ? "" : "s") + " than pops."); } if (lhsStack.size() > 1) { int size = lhsStack.size() - 1; throw new GroovyBugError("lhs stack is supposed to be empty, but has " + size + " elements left."); } if (implicitThisStack.size() > 1) { int size = implicitThisStack.size() - 1; throw new GroovyBugError( "implicit 'this' stack is supposed to be empty, but has " + size + " elements left."); } clear = true; MethodVisitor mv = controller.getMethodVisitor(); // br experiment with local var table so debuggers can retrieve variable names if (true) {//AsmClassGenerator.CREATE_DEBUG_INFO) { if (thisEndLabel == null) setEndLabels(); if (!scope.isInStaticContext()) { // write "this" mv.visitLocalVariable("this", className, null, thisStartLabel, thisEndLabel, 0); } for (Object usedVariable : usedVariables) { BytecodeVariable v = (BytecodeVariable) usedVariable; ClassNode t = v.getType(); if (v.isHolder()) t = ClassHelper.REFERENCE_TYPE; String type = BytecodeHelper.getTypeDescription(t); Label start = v.getStartLabel(); Label end = v.getEndLabel(); mv.visitLocalVariable(v.getName(), type, null, start, end, v.getIndex()); } } //exception table writing for (ExceptionTableEntry ep : typedExceptions) { mv.visitTryCatchBlock(ep.start, ep.end, ep.goal, ep.sig); } //exception table writing for (ExceptionTableEntry ep : untypedExceptions) { mv.visitTryCatchBlock(ep.start, ep.end, ep.goal, ep.sig); } pop(); typedExceptions.clear(); untypedExceptions.clear(); stackVariables.clear(); usedVariables.clear(); scope = null; finallyBlocks.clear(); resetVariableIndex(false); superBlockNamedLabels.clear(); currentBlockNamedLabels.clear(); namedLoopBreakLabel.clear(); namedLoopContinueLabel.clear(); continueLabel = null; breakLabel = null; thisStartLabel = null; thisEndLabel = null; mv = null; }
From source file:org.eclipse.m2m.atl.emftvm.jit.CodeBlockJIT.java
License:Open Source License
/** * Generates a constructor for the {@link JITCodeBlock}. * @param init the constructor visitor/*from w w w . j a va 2s . co m*/ * @param className the name of the generated class */ protected static void generateConstructor(final MethodVisitor init, final String className) { init.visitCode(); // Generate labels final Label start = new Label(); final Label end = new Label(); // Generate bytecode init.visitLabel(start); init.visitVarInsn(ALOAD, 0); // this init.visitVarInsn(ALOAD, 1); // cb init.visitMethodInsn(INVOKESPECIAL, // super(cb) Type.getInternalName(JITCodeBlock.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(CodeBlock.class) })); init.visitInsn(RETURN); init.visitLabel(end); // Create local variable table init.visitLocalVariable("this", "L" + className + ";", null, start, end, 0); init.visitLocalVariable("cb", Type.getDescriptor(CodeBlock.class), null, start, end, 1); // Finalise init.visitMaxs(2, 2); init.visitEnd(); }
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 v a 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.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 ww w .j av a 2 s. c o 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.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 . ja v a 2s .co 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./*from w ww . 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 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 www . j a v a 2s.co 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 www .j a v a2 s. c o m 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(); }
From source file:org.enerj.enhancer.ClassEnhancer.java
License:Open Source License
/** * Emits the enerj_ReadObject method.// w ww . j a va2 s . c o m * * @param someFields a list of the persistent fields for this class (not including * super-class fields). */ private void emitReadObject(ArrayList<Field> someFields) { MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "enerj_ReadObject", sReadWriteObjectMethodSignature, null, new String[] { "java/io/IOException" }); mv.visitCode(); Label startLabel = new Label(); mv.visitLabel(startLabel); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, sObjectSerializerClassNameSlashed, "getDataInput", "()Ljava/io/DataInput;"); mv.visitVarInsn(ASTORE, 2); if (!mIsTopLevelPersistable) { // Call super read if not a top-level persistable mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, mSuperClassNameSlashed, "enerj_ReadObject", sReadWriteObjectMethodSignature); } for (Field field : someFields) { String fieldName = field.getName(); String fieldType = field.getDescriptor(); // This will return null if the type is not a primitive. String dataInOutSuffix = MetaData.getPrimitiveDataInOutSuffix(fieldType); if (dataInOutSuffix != null) { // Read instructions for primitive... // this - For putfield mv.visitVarInsn(ALOAD, 0); // DataInput "stream" mv.visitVarInsn(ALOAD, 2); // Invoke read method on DataInput mv.visitMethodInsn(INVOKEINTERFACE, sDataInputClassNameSlashed, "read" + dataInOutSuffix, "()" + fieldType); // Store the value mv.visitFieldInsn(PUTFIELD, mThisClassNameSlashed, fieldName, fieldType); } else { // Read instructions for a SCO or FCO... // this - For putfield mv.visitVarInsn(ALOAD, 0); // ReadContext - method param 1 mv.visitVarInsn(ALOAD, 1); // this - method param 2 mv.visitVarInsn(ALOAD, 0); // Invoke readObject - value to stack for putfield mv.visitMethodInsn(INVOKEVIRTUAL, sObjectSerializerClassNameSlashed, "readObject", "(" + sPersistableClassDescr + ")Ljava/lang/Object;"); // Cast Object result to proper type mv.visitTypeInsn(CHECKCAST, field.getInternalName()); // Store the value mv.visitFieldInsn(PUTFIELD, mThisClassNameSlashed, fieldName, fieldType); } } // Invoke enerjPostLoad if it exists if (mHasPostLoad) { // this mv.visitVarInsn(ALOAD, 0); // See comments on call to enerjPreStore for reason why INVOKESPECIAL is used. mv.visitMethodInsn(INVOKESPECIAL, mThisClassNameSlashed, sPostLoadMethodName, sNoArgMethodSignature); } mv.visitInsn(RETURN); Label endLabel = new Label(); mv.visitLabel(endLabel); mv.visitLocalVariable("this", mThisClassDescr, null, startLabel, endLabel, 0); mv.visitLocalVariable("aContext", "Lorg/enerj/core/ObjectSerializer;", null, startLabel, endLabel, 1); mv.visitLocalVariable("stream", "Ljava/io/DataInput;", null, startLabel, endLabel, 2); mv.visitMaxs(0, 0); mv.visitEnd(); }