List of usage examples for org.objectweb.asm Opcodes ATHROW
int ATHROW
To view the source code for org.objectweb.asm Opcodes ATHROW.
Click Source Link
From source file:org.testeoa.estatica.AdapterInstrum.java
License:Open Source License
@Override public void visitInsn(int opcode) { if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) { inserirRetorno();//from w w w.j a va 2 s . c om } if (opcode == Opcodes.ATHROW) { //TODO O ATHROW S PODE RETORNAR SE ESTIVER FORA DO TRY-CATCH //inserirRetorno(); } super.visitInsn(opcode); }
From source file:pku.sei.checkedcoverage.dependenceAnalysis.DependencesExtractor.java
License:Creative Commons License
/** * Go backwards through the execution trace of the given threadId and extract * all dependences. {@link DependencesVisitor}s should have been added before * by calling {@link #registerVisitor(DependencesVisitor, VisitorCapability...)}. * * @param threadId identifies the thread whose trace should be analyzed * @param multithreaded use an extra thread to traverse the trace * @throws InterruptedException if the thread was interrupted during traversal * @throws IllegalArgumentException if the trace contains no thread with this id *//*from w w w .j a v a 2s . com*/ public void processBackwardTrace(ThreadId threadId, boolean multithreaded) throws InterruptedException { final BackwardTraceIterator<InstanceType> backwardInsnItr = this.trace.getBackwardIterator(threadId, null, this.instanceFactory); if (backwardInsnItr == null) throw new IllegalArgumentException("No such thread"); // store the current set of visitors of each capability in an array for better // performance and faster empty-check (null reference if empty) final DependencesVisitor<? super InstanceType>[] dataDependenceVisitorsReadAfterWrite0 = this.dataDependenceVisitorsReadAfterWrite .isEmpty() ? null : this.dataDependenceVisitorsReadAfterWrite.toArray( newDependencesVisitorArray(this.dataDependenceVisitorsReadAfterWrite.size())); final DependencesVisitor<? super InstanceType>[] dataDependenceVisitorsWriteAfterRead0 = this.dataDependenceVisitorsWriteAfterRead .isEmpty() ? null : this.dataDependenceVisitorsWriteAfterRead.toArray( newDependencesVisitorArray(this.dataDependenceVisitorsWriteAfterRead.size())); final DependencesVisitor<? super InstanceType>[] controlDependenceVisitors0 = this.controlDependenceVisitors .isEmpty() ? null : this.controlDependenceVisitors .toArray(newDependencesVisitorArray(this.controlDependenceVisitors.size())); final DependencesVisitor<? super InstanceType>[] instructionVisitors0 = this.instructionVisitors.isEmpty() ? null : this.instructionVisitors.toArray(newDependencesVisitorArray(this.instructionVisitors.size())); final DependencesVisitor<? super InstanceType>[] pendingDataDependenceVisitorsReadAfterWrite0 = this.pendingDataDependenceVisitorsReadAfterWrite .isEmpty() ? null : this.pendingDataDependenceVisitorsReadAfterWrite.toArray(newDependencesVisitorArray( this.pendingDataDependenceVisitorsReadAfterWrite.size())); final DependencesVisitor<? super InstanceType>[] pendingDataDependenceVisitorsWriteAfterRead0 = this.pendingDataDependenceVisitorsWriteAfterRead .isEmpty() ? null : this.pendingDataDependenceVisitorsWriteAfterRead.toArray(newDependencesVisitorArray( this.pendingDataDependenceVisitorsWriteAfterRead.size())); final DependencesVisitor<? super InstanceType>[] pendingControlDependenceVisitors0 = this.pendingControlDependenceVisitors .isEmpty() ? null : this.pendingControlDependenceVisitors .toArray(newDependencesVisitorArray(this.pendingControlDependenceVisitors.size())); final DependencesVisitor<? super InstanceType>[] methodEntryLeaveVisitors0 = this.methodEntryLeaveVisitors .isEmpty() ? null : this.methodEntryLeaveVisitors .toArray(newDependencesVisitorArray(this.methodEntryLeaveVisitors.size())); final DependencesVisitor<? super InstanceType>[] objectCreationVisitors0 = this.objectCreationVisitors .isEmpty() ? null : this.objectCreationVisitors .toArray(newDependencesVisitorArray(this.objectCreationVisitors.size())); @SuppressWarnings("unchecked") DependencesVisitor<? super InstanceType>[] allVisitors = union(dataDependenceVisitorsReadAfterWrite0, dataDependenceVisitorsWriteAfterRead0, controlDependenceVisitors0, instructionVisitors0, pendingDataDependenceVisitorsReadAfterWrite0, pendingDataDependenceVisitorsWriteAfterRead0, pendingControlDependenceVisitors0, methodEntryLeaveVisitors0, objectCreationVisitors0); IntegerMap<Set<Instruction>> controlDependences = new IntegerMap<Set<Instruction>>(); Iterator<InstanceType> instanceIterator; ProgressInformationProvider progressInfoProv; Thread iteratorThread = null; final AtomicReference<Throwable> iteratorException = new AtomicReference<Throwable>(null); if (multithreaded) { final AtomicLong percentPerInstance = this.progressMonitors.isEmpty() ? null : new AtomicLong(Double.doubleToLongBits(0)); // this AtomicLong holds a double value!! final BlockwiseSynchronizedBuffer<InstanceType> buffer = new BlockwiseSynchronizedBuffer<InstanceType>( 1 << 16, 1 << 20); final InstanceType firstInstance = backwardInsnItr.hasNext() ? backwardInsnItr.next() : null; iteratorThread = new Thread("Trace iterator") { @Override public void run() { try { int num = 0; while (backwardInsnItr.hasNext()) { buffer.put(backwardInsnItr.next()); if ((++num & ((1 << 16) - 1)) == 0 && percentPerInstance != null) { double percentPerInstance0 = backwardInsnItr.getPercentageDone() / num; percentPerInstance.set(Double.doubleToLongBits(percentPerInstance0)); } } } catch (Throwable t) { iteratorException.compareAndSet(null, t); } finally { try { buffer.put(firstInstance); // to signal that this is the end of the trace buffer.flush(); } catch (InterruptedException e) { iteratorException.compareAndSet(null, e); } } } }; iteratorThread.start(); final AtomicLong numInstancesSeen = percentPerInstance == null ? null : new AtomicLong(0); instanceIterator = new Iterator<InstanceType>() { private InstanceType next = firstInstance; public boolean hasNext() { if (this.next == null) { while (true) { try { this.next = buffer.take(); if (this.next == firstInstance) { this.next = null; } break; } catch (InterruptedException e) { // this.next stays null assert this.next == null; Thread.currentThread().interrupt(); } } } return this.next != null; } public InstanceType next() { if (!hasNext()) throw new NoSuchElementException(); InstanceType ret = this.next; this.next = null; if (numInstancesSeen != null) numInstancesSeen.incrementAndGet(); return ret; } public void remove() { throw new UnsupportedOperationException(); } }; progressInfoProv = percentPerInstance == null ? null : new ProgressInformationProvider() { public double getPercentageDone() { return Double.longBitsToDouble(percentPerInstance.get()) * numInstancesSeen.get(); } }; } else { instanceIterator = backwardInsnItr; progressInfoProv = backwardInsnItr; } // the lastWriter is needed for WAR data dependences Map<Variable, InstanceType> lastWriter = new HashMap<Variable, InstanceType>(); // lastReaders are needed for RAW data dependences Map<Variable, List<InstanceType>> lastReaders = new HashMap<Variable, List<InstanceType>>(); /* HashSet<Long> createdObjects = new HashSet<Long>(); HashSet<Long> seenObjects = new HashSet<Long>(); */ InstanceType instance = null; Instruction instruction = null; for (ProgressMonitor mon : this.progressMonitors) mon.start(progressInfoProv); try { long nextFrameNr = 0; int stackDepth = 0; List<ReadMethod> initialStackMethods = backwardInsnItr.getInitialStackMethods(); int allocStack = initialStackMethods.size() + 1; allocStack = Integer.highestOneBit(allocStack) * 2; @SuppressWarnings("unchecked") InstanceType[] atCatchBlockStart = (InstanceType[]) (new InstructionInstance[allocStack]); boolean[] throwsException = new boolean[allocStack]; boolean[] interruptedControlFlow = new boolean[allocStack]; /** * <code>true</code> iff this frame was aborted abnormally (NOT by a RETURN * instruction) */ boolean[] abnormalTermination = new boolean[allocStack]; /** * is set to true if the methods entry label has been passed */ boolean[] finished = new boolean[allocStack]; int[] opStack = new int[allocStack]; int[] minOpStack = new int[allocStack]; long[] frames = new long[allocStack]; Instruction[] lastInstruction = new Instruction[allocStack]; @SuppressWarnings("unchecked") HashSet<InstanceType>[] interestingInstances = (HashSet<InstanceType>[]) new HashSet<?>[allocStack]; StackEntry[][] cachedStackEntries = new StackEntry[allocStack][]; LocalVariable[][] cachedLocalVariables = new LocalVariable[allocStack][]; ReadMethod[] method = new ReadMethod[allocStack]; for (ReadMethod method0 : initialStackMethods) { ++stackDepth; method[stackDepth] = method0; interruptedControlFlow[stackDepth] = true; frames[stackDepth] = nextFrameNr++; if (methodEntryLeaveVisitors0 != null) for (DependencesVisitor<? super InstanceType> vis : methodEntryLeaveVisitors0) vis.visitMethodLeave(method0, stackDepth); } for (int i = 1; i < allocStack; ++i) { interestingInstances[i] = new HashSet<InstanceType>(); cachedStackEntries[i] = new StackEntry[8]; cachedLocalVariables[i] = new LocalVariable[8]; } SimulationEnvironment simEnv = new SimulationEnvironment(frames, opStack, minOpStack, cachedStackEntries, cachedLocalVariables, throwsException, lastInstruction, method, interruptedControlFlow); while (instanceIterator.hasNext()) { instance = instanceIterator.next(); instruction = instance.getInstruction(); if ((instance.getInstanceNr() & ((1 << 16) - 1)) == 0 && Thread.interrupted()) throw new InterruptedException(); int newStackDepth = instance.getStackDepth(); assert newStackDepth > 0; simEnv.removedMethod = null; boolean reenter = false; if (newStackDepth != stackDepth || (reenter = finished[stackDepth] || method[stackDepth] != instruction.getMethod())) { if (newStackDepth >= stackDepth) { // in all steps, the stackDepth can change by at most 1 (except for the very first instruction) assert newStackDepth == stackDepth + 1 || stackDepth == 0 || reenter; if (newStackDepth >= atCatchBlockStart.length) { int oldLen = atCatchBlockStart.length; int newLen = oldLen == 0 ? 8 : 2 * oldLen; atCatchBlockStart = Arrays.copyOf(atCatchBlockStart, newLen); throwsException = Arrays.copyOf(throwsException, newLen); interruptedControlFlow = Arrays.copyOf(interruptedControlFlow, newLen); abnormalTermination = Arrays.copyOf(abnormalTermination, newLen); finished = Arrays.copyOf(finished, newLen); opStack = Arrays.copyOf(opStack, newLen); minOpStack = Arrays.copyOf(minOpStack, newLen); frames = Arrays.copyOf(frames, newLen); interestingInstances = Arrays.copyOf(interestingInstances, newLen); lastInstruction = Arrays.copyOf(lastInstruction, newLen); cachedStackEntries = Arrays.copyOf(cachedStackEntries, newLen); cachedLocalVariables = Arrays.copyOf(cachedLocalVariables, newLen); method = Arrays.copyOf(method, newLen); for (int i = oldLen; i < newLen; ++i) { interestingInstances[i] = new HashSet<InstanceType>(); cachedStackEntries[i] = new StackEntry[8]; cachedLocalVariables[i] = new LocalVariable[8]; } simEnv = new SimulationEnvironment(frames, opStack, minOpStack, cachedStackEntries, cachedLocalVariables, throwsException, lastInstruction, method, interruptedControlFlow); } frames[newStackDepth] = nextFrameNr++; ReadMethod oldMethod = method[newStackDepth]; method[newStackDepth] = instruction.getMethod(); if (methodEntryLeaveVisitors0 != null) { for (DependencesVisitor<? super InstanceType> vis : methodEntryLeaveVisitors0) { if (reenter) vis.visitMethodEntry(oldMethod, newStackDepth); vis.visitMethodLeave(method[newStackDepth], newStackDepth); } } if (reenter) { cleanUpExecutionFrame(simEnv, stackDepth, lastReaders, lastWriter, pendingDataDependenceVisitorsWriteAfterRead0, pendingDataDependenceVisitorsReadAfterWrite0, dataDependenceVisitorsWriteAfterRead0, dataDependenceVisitorsReadAfterWrite0); } atCatchBlockStart[newStackDepth] = null; if (instruction == method[newStackDepth].getAbnormalTerminationLabel()) { throwsException[newStackDepth] = interruptedControlFlow[newStackDepth] = abnormalTermination[newStackDepth] = true; interruptedControlFlow[stackDepth] = true; } else { throwsException[newStackDepth] = interruptedControlFlow[newStackDepth] = abnormalTermination[newStackDepth] = false; } finished[newStackDepth] = false; opStack[newStackDepth] = 0; minOpStack[newStackDepth] = 0; interestingInstances[newStackDepth].clear(); if (cachedLocalVariables[newStackDepth].length > 128) cachedLocalVariables[newStackDepth] = new LocalVariable[8]; else Arrays.fill(cachedLocalVariables[newStackDepth], null); if (cachedStackEntries[newStackDepth].length > 128) cachedStackEntries[newStackDepth] = new StackEntry[8]; else Arrays.fill(cachedStackEntries[newStackDepth], null); } else { assert newStackDepth == stackDepth - 1; if (methodEntryLeaveVisitors0 != null) { for (DependencesVisitor<? super InstanceType> vis : methodEntryLeaveVisitors0) { vis.visitMethodEntry(method[stackDepth], stackDepth); } } simEnv.removedMethod = method[stackDepth]; } } stackDepth = newStackDepth; if (simEnv.removedMethod == null && (this.untracedMethodsVisitors != null) && (instruction.getType() == InstructionType.METHODINVOCATION)) { for (DependencesVisitor<? super InstanceType> vis : this.untracedMethodsVisitors) vis.visitUntracedMethodCall(instance); } if (instruction == instruction.getMethod().getMethodEntryLabel()) finished[stackDepth] = true; lastInstruction[stackDepth] = instruction; if (atCatchBlockStart[stackDepth] != null) throwsException[stackDepth] = true; DynamicInformation dynInfo = this.simulator.simulateInstruction(instance, simEnv); if (instructionVisitors0 != null) for (DependencesVisitor<? super InstanceType> vis : instructionVisitors0) vis.visitInstructionExecution(instance); // the computation of control dependences only has to be performed // if there are any controlDependenceVisitors if (controlDependenceVisitors0 != null) { if (simEnv.removedMethod != null && !interestingInstances[stackDepth + 1].isEmpty()) { // ok, we have a control dependence since the method was called by (or for) this instruction // checking if this is the instr. that directly called the method is impossible for (InstanceType depend : interestingInstances[stackDepth + 1]) { for (DependencesVisitor<? super InstanceType> vis : controlDependenceVisitors0) { vis.visitControlDependence(depend, instance); } } interestingInstances[stackDepth].add(instance); } Set<Instruction> instrControlDependences = controlDependences.get(instruction.getIndex()); if (instrControlDependences == null) { computeControlDependences(instruction.getMethod(), controlDependences); instrControlDependences = controlDependences.get(instruction.getIndex()); assert instrControlDependences != null; } boolean isExceptionsThrowingInstruction = throwsException[stackDepth] && (instruction.getType() != InstructionType.LABEL || !((LabelMarker) instruction).isAdditionalLabel()) && (instruction.getOpcode() != Opcodes.GOTO); // assert: every ATHROW must be an exception throwing instance assert (instruction.getOpcode() != Opcodes.ATHROW || isExceptionsThrowingInstruction); // get all interesting instructions, that are dependent on the current one Set<InstanceType> dependantInterestingInstances = getInstanceIntersection( instrControlDependences, interestingInstances[stackDepth]); if (isExceptionsThrowingInstruction) { throwsException[stackDepth] = false; // in this case, we have an additional control dependence from the catching to // the throwing instruction, and a data dependence on the thrown instruction for (int i = stackDepth; i > 0; --i) { if (atCatchBlockStart[i] != null) { if (interestingInstances[i].contains(atCatchBlockStart[i])) { if (dependantInterestingInstances.isEmpty()) dependantInterestingInstances = Collections.singleton(atCatchBlockStart[i]); else dependantInterestingInstances.add(atCatchBlockStart[i]); } atCatchBlockStart[i] = null; // data dependence: // (the stack height has already been decremented when entering the catch block) Variable definedException = simEnv.getOpStackEntry(i, opStack[i]); dynInfo = AdditionalDataDependence.annotate(dynInfo, definedException, dynInfo.getUsedVariables()); break; } } } if (!dependantInterestingInstances.isEmpty()) { for (InstanceType depend : dependantInterestingInstances) { for (DependencesVisitor<? super InstanceType> vis : controlDependenceVisitors0) { vis.visitControlDependence(depend, instance); } } interestingInstances[stackDepth].removeAll(dependantInterestingInstances); } interestingInstances[stackDepth].add(instance); } // TODO check this: if (pendingControlDependenceVisitors0 != null) { interestingInstances[stackDepth].add(instance); for (DependencesVisitor<? super InstanceType> vis : pendingControlDependenceVisitors0) vis.visitPendingControlDependence(instance); } Collection<? extends Variable> definedVariables = dynInfo.getDefinedVariables(); if (!definedVariables.isEmpty()) { /* for (Variable definedVariable: dynInfo.getDefinedVariables()) { if (definedVariable instanceof ObjectField) { seenObjects.add(((ObjectField)definedVariable).getObjectId()); assert !createdObjects.contains(((ObjectField)definedVariable).getObjectId()); } if (definedVariable instanceof ArrayElement) { seenObjects.add(((ArrayElement)definedVariable).getArrayId()); assert !createdObjects.contains(((ArrayElement)definedVariable).getArrayId()); } } */ if (dataDependenceVisitorsReadAfterWrite0 != null || dataDependenceVisitorsWriteAfterRead0 != null || pendingDataDependenceVisitorsWriteAfterRead0 != null) { for (Variable definedVariable : definedVariables) { if (!(definedVariable instanceof StackEntry)) { // we ignore WAR dependences over the stack! if (pendingDataDependenceVisitorsWriteAfterRead0 != null) { // for each defined variable, we have a pending WAR dependence // if the lastWriter is not null, we first discard old pending dependences InstanceType varLastWriter = lastWriter.put(definedVariable, instance); for (DependencesVisitor<? super InstanceType> vis : pendingDataDependenceVisitorsWriteAfterRead0) { if (varLastWriter != null) vis.discardPendingDataDependence(varLastWriter, definedVariable, DataDependenceType.WRITE_AFTER_READ); vis.visitPendingDataDependence(instance, definedVariable, DataDependenceType.WRITE_AFTER_READ); } // otherwise, if there are WAR visitors, we only update the lastWriter } else if (dataDependenceVisitorsWriteAfterRead0 != null) { lastWriter.put(definedVariable, instance); } } // if we have RAW visitors, we need to analyse the lastReaders if (dataDependenceVisitorsReadAfterWrite0 != null || pendingDataDependenceVisitorsReadAfterWrite0 != null) { List<InstanceType> readers = lastReaders.remove(definedVariable); if (readers != null) { Collection<? extends Variable> usedVariables = dataDependenceVisitorsReadAfterWrite0 != null ? dynInfo.getUsedVariables(definedVariable) : null; for (InstanceType reader : readers) { if (dataDependenceVisitorsReadAfterWrite0 != null) { for (DependencesVisitor<? super InstanceType> vis : dataDependenceVisitorsReadAfterWrite0) vis.visitDataDependence(reader, instance, usedVariables, definedVariable, DataDependenceType.READ_AFTER_WRITE); } if (pendingDataDependenceVisitorsReadAfterWrite0 != null) for (DependencesVisitor<? super InstanceType> vis : pendingDataDependenceVisitorsReadAfterWrite0) vis.discardPendingDataDependence(reader, definedVariable, DataDependenceType.READ_AFTER_WRITE); } } } } } } Collection<? extends Variable> usedVariables = dynInfo.getUsedVariables(); if (!usedVariables.isEmpty()) { /* for (Variable usedVariable: dynInfo.getUsedVariables()) { if (usedVariable instanceof ObjectField) { seenObjects.add(((ObjectField)usedVariable).getObjectId()); assert !createdObjects.contains(((ObjectField)usedVariable).getObjectId()); } if (usedVariable instanceof ArrayElement) { seenObjects.add(((ArrayElement)usedVariable).getArrayId()); assert !createdObjects.contains(((ArrayElement)usedVariable).getArrayId()); } } */ if (dataDependenceVisitorsWriteAfterRead0 != null || dataDependenceVisitorsReadAfterWrite0 != null || pendingDataDependenceVisitorsReadAfterWrite0 != null) { for (Variable usedVariable : usedVariables) { // if we have WAR visitors, we inform them about a new dependence if (dataDependenceVisitorsWriteAfterRead0 != null && !(usedVariable instanceof StackEntry)) { InstanceType lastWriterInst = lastWriter.get(usedVariable); // avoid self-loops in the DDG (e.g. for IINC, which reads and writes to the same variable) if (lastWriterInst != null && lastWriterInst != instance) { for (DependencesVisitor<? super InstanceType> vis : dataDependenceVisitorsWriteAfterRead0) vis.visitDataDependence(lastWriterInst, instance, null, usedVariable, DataDependenceType.WRITE_AFTER_READ); } } // for RAW visitors, update the lastReaders if (dataDependenceVisitorsReadAfterWrite0 != null || pendingDataDependenceVisitorsReadAfterWrite0 != null) { List<InstanceType> readers = lastReaders.get(usedVariable); if (readers == null) { readers = new ArrayList<InstanceType>(4); lastReaders.put(usedVariable, readers); } readers.add(instance); // for each used variable, we have a pending RAW dependence if (pendingDataDependenceVisitorsReadAfterWrite0 != null) { for (DependencesVisitor<? super InstanceType> vis : pendingDataDependenceVisitorsReadAfterWrite0) vis.visitPendingDataDependence(instance, usedVariable, DataDependenceType.READ_AFTER_WRITE); } } } } } for (Entry<Long, Collection<? extends Variable>> e : dynInfo.getCreatedObjects().entrySet()) { /* boolean added = createdObjects.add(e.getKey()); assert added; */ for (Variable var : e.getValue()) { assert var instanceof ObjectField || var instanceof ArrayElement; // clean up lastWriter if we have any WAR visitors if (pendingDataDependenceVisitorsWriteAfterRead0 != null) { InstanceType inst; if ((inst = lastWriter.remove(var)) != null) for (DependencesVisitor<? super InstanceType> vis : pendingDataDependenceVisitorsWriteAfterRead0) vis.discardPendingDataDependence(inst, var, DataDependenceType.WRITE_AFTER_READ); } else if (dataDependenceVisitorsWriteAfterRead0 != null) lastWriter.remove(var); // clean up lastReaders if we have any RAW visitors if (dataDependenceVisitorsReadAfterWrite0 != null || pendingDataDependenceVisitorsReadAfterWrite0 != null) { List<InstanceType> instList; if ((instList = lastReaders.remove(var)) != null) { if (dataDependenceVisitorsReadAfterWrite0 != null) for (DependencesVisitor<? super InstanceType> vis : dataDependenceVisitorsReadAfterWrite0) for (InstanceType instrInst : instList) vis.visitDataDependence(instrInst, instance, Collections.<Variable>emptySet(), var, DataDependenceType.READ_AFTER_WRITE); if (pendingDataDependenceVisitorsReadAfterWrite0 != null) for (DependencesVisitor<? super InstanceType> vis : pendingDataDependenceVisitorsReadAfterWrite0) for (InstanceType instrInst : instList) vis.discardPendingDataDependence(instrInst, var, DataDependenceType.READ_AFTER_WRITE); } } } if (objectCreationVisitors0 != null) for (DependencesVisitor<? super InstanceType> vis : objectCreationVisitors0) vis.visitObjectCreation(e.getKey(), instance); } if (dynInfo.isCatchBlock()) { atCatchBlockStart[stackDepth] = instance; interruptedControlFlow[stackDepth] = true; } else if (atCatchBlockStart[stackDepth] != null) { atCatchBlockStart[stackDepth] = null; } if (simEnv.removedMethod != null) { cleanUpExecutionFrame(simEnv, stackDepth + 1, lastReaders, lastWriter, pendingDataDependenceVisitorsWriteAfterRead0, pendingDataDependenceVisitorsReadAfterWrite0, dataDependenceVisitorsWriteAfterRead0, dataDependenceVisitorsReadAfterWrite0); } /* if (instance.getInstanceNr() % 1000000 == 0) { for (Variable var: lastReaders.keySet()) { if (var instanceof ObjectField) { assert seenObjects.contains(((ObjectField)var).getObjectId()); assert !createdObjects.contains(((ObjectField)var).getObjectId()); } if (var instanceof ArrayElement) { assert seenObjects.contains(((ArrayElement)var).getArrayId()); assert !createdObjects.contains(((ArrayElement)var).getArrayId()); } if (var instanceof StackEntry) assert frames.contains(((StackEntry)var).getFrame()); if (var instanceof LocalVariable) { assert frames.contains(((LocalVariable)var).getFrame()); } } for (Variable var: lastWriter.keySet()) { if (var instanceof ObjectField) { assert seenObjects.contains(((ObjectField)var).getObjectId()); assert !createdObjects.contains(((ObjectField)var).getObjectId()); } if (var instanceof ArrayElement) { assert seenObjects.contains(((ArrayElement)var).getArrayId()); assert !createdObjects.contains(((ArrayElement)var).getArrayId()); } // we do not store the last writer of a stack entry assert !(var instanceof StackEntry); if (var instanceof LocalVariable) { assert frames.contains(((LocalVariable)var).getFrame()); } } } */ } Throwable t = iteratorException.get(); if (t != null) { if (t instanceof RuntimeException) throw (RuntimeException) t; if (t instanceof Error) throw (Error) t; if (t instanceof InterruptedException) throw (InterruptedException) t; throw new TracerException("Iterator should not throw anything but RuntimeExceptions", t); } if (Thread.interrupted()) throw new InterruptedException(); cleanUpMaps(lastWriter, lastReaders, pendingDataDependenceVisitorsWriteAfterRead0, pendingDataDependenceVisitorsReadAfterWrite0); for (DependencesVisitor<? super InstanceType> vis : allVisitors) vis.visitEnd(instance == null ? 0 : instance.getInstanceNr()); if (Thread.interrupted()) throw new InterruptedException(); } catch (InterruptedException e) { for (DependencesVisitor<? super InstanceType> vis : allVisitors) vis.interrupted(); throw e; } finally { if (iteratorThread != null) iteratorThread.interrupt(); for (ProgressMonitor mon : this.progressMonitors) mon.end(); } }
From source file:pt.minha.kernel.instrument.SyncToMonitorClassVisitor.java
License:Open Source License
public void makeStub(int access, String name, String desc, String signature, String[] exceptions) { Method m = new Method(name, desc); MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); mv.visitCode();// w ww . j a v a2s .c o m Label begin = new Label(); Label pre_invoke = new Label(); Label pos_leave = new Label(); Label in_catch = new Label(); Label pre_rethrow = new Label(); Label end = new Label(); mv.visitTryCatchBlock(pre_invoke, pos_leave, in_catch, null); mv.visitTryCatchBlock(in_catch, pre_rethrow, in_catch, null); mv.visitLabel(begin); int offset; if ((access & Opcodes.ACC_STATIC) == 0) { mv.visitVarInsn(Opcodes.ALOAD, 0); offset = 1; } else { mv.visitFieldInsn(Opcodes.GETSTATIC, clz, "_fake_class", "L" + ClassConfig.fake_prefix + "java/lang/Object;"); offset = 0; } int length = 0; for (Type t : m.getArgumentTypes()) length += t.getSize(); mv.visitInsn(Opcodes.DUP); mv.visitVarInsn(Opcodes.ASTORE, offset + length); mv.visitInsn(Opcodes.MONITORENTER); mv.visitLabel(pre_invoke); if ((access & Opcodes.ACC_STATIC) == 0) mv.visitVarInsn(Opcodes.ALOAD, 0); int i = offset; for (Type t : m.getArgumentTypes()) { // t.getOpcode() should work for long and double too... :-( if (t.getClassName().equals("long")) mv.visitVarInsn(Opcodes.LLOAD, i); else if (t.getClassName().equals("double")) mv.visitVarInsn(Opcodes.DLOAD, i); else mv.visitVarInsn(t.getOpcode(Opcodes.ILOAD), i); i += t.getSize(); } boolean itf = (access & Opcodes.ACC_INTERFACE) != 0; if ((access & Opcodes.ACC_STATIC) == 0) mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, clz, "_" + name, desc, itf); else mv.visitMethodInsn(Opcodes.INVOKESTATIC, clz, "_" + name, desc, itf); mv.visitVarInsn(Opcodes.ALOAD, offset + length); mv.visitInsn(Opcodes.MONITOREXIT); mv.visitLabel(pos_leave); if (m.getReturnType().equals(Type.VOID_TYPE)) mv.visitInsn(Opcodes.RETURN); else mv.visitInsn(m.getReturnType().getOpcode(Opcodes.IRETURN)); mv.visitLabel(in_catch); mv.visitVarInsn(Opcodes.ALOAD, offset + length); mv.visitInsn(Opcodes.MONITOREXIT); mv.visitLabel(pre_rethrow); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(end); i = 0; if ((access & Opcodes.ACC_STATIC) == 0) mv.visitLocalVariable("this", "L" + clz + ";", null, begin, end, i++); for (Type t : m.getArgumentTypes()) mv.visitLocalVariable("arg" + i, t.getDescriptor(), null, begin, end, i++); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:serianalyzer.JVMImpl.java
License:Open Source License
/** * @param opcode/*from w w w. java 2 s .c om*/ * @param s */ static void handleJVMInsn(int opcode, JVMStackState s) { BaseType o1; BaseType o2; BaseType o3; List<BaseType> l1; List<BaseType> l2; switch (opcode) { case Opcodes.NOP: break; case Opcodes.ARRAYLENGTH: o1 = s.pop(); s.push(new BasicConstant(Type.INT_TYPE, 0, !(o1 != null && !o1.isTainted()))); break; case Opcodes.ACONST_NULL: s.push(new BasicConstant(Type.VOID_TYPE, "<null>")); //$NON-NLS-1$ break; case Opcodes.ICONST_M1: case Opcodes.ICONST_0: case Opcodes.ICONST_1: case Opcodes.ICONST_2: case Opcodes.ICONST_3: case Opcodes.ICONST_4: case Opcodes.ICONST_5: s.push(new BasicConstant(Type.INT_TYPE, opcode - 3)); break; case Opcodes.LCONST_0: case Opcodes.LCONST_1: s.push(new BasicConstant(Type.LONG_TYPE, opcode - 9L)); break; case Opcodes.FCONST_0: case Opcodes.FCONST_1: case Opcodes.FCONST_2: s.push(new BasicConstant(Type.FLOAT_TYPE, opcode - 11f)); break; case Opcodes.DCONST_0: case Opcodes.DCONST_1: s.push(new BasicConstant(Type.DOUBLE_TYPE, opcode - 14d)); break; case Opcodes.IALOAD: case Opcodes.LALOAD: case Opcodes.FALOAD: case Opcodes.DALOAD: case Opcodes.BALOAD: case Opcodes.CALOAD: case Opcodes.SALOAD: o1 = s.pop(); o2 = s.pop(); s.push(new BasicVariable(toType(opcode), "primitive array elem", //$NON-NLS-1$ (o1 == null || o1.isTainted()) | (o2 == null || o2.isTainted()))); break; case Opcodes.AALOAD: o1 = s.pop(); o2 = s.pop(); if (o1 != null && o2 instanceof SimpleType && ((SimpleType) o2).getType().toString().startsWith("[")) { //$NON-NLS-1$ Type atype = Type.getType(((SimpleType) o2).getType().toString().substring(1)); if (o2.getAlternativeTypes() != null && !o2.getAlternativeTypes().isEmpty()) { s.clear(); break; } s.push(new BasicVariable(atype, "array elem " + atype, o1.isTainted() | o2.isTainted())); //$NON-NLS-1$ } else { s.clear(); } break; case Opcodes.IASTORE: case Opcodes.LASTORE: case Opcodes.FASTORE: case Opcodes.DASTORE: case Opcodes.AASTORE: case Opcodes.BASTORE: case Opcodes.CASTORE: case Opcodes.SASTORE: s.pop(3); break; case Opcodes.POP2: s.pop(); case Opcodes.MONITORENTER: case Opcodes.MONITOREXIT: case Opcodes.POP: s.pop(); break; case Opcodes.DUP: if (!s.isEmpty()) { o1 = s.pop(); s.push(o1); s.push(o1); } break; case Opcodes.DUP_X1: o1 = s.pop(); o2 = s.pop(); s.push(o1); s.push(o2); s.push(o1); break; case Opcodes.DUP_X2: o1 = s.pop(); o2 = s.pop(); o3 = s.pop(); s.push(o1); s.push(o3); s.push(o2); s.push(o1); break; case Opcodes.DUP2: l1 = s.popWord(); if (l1.isEmpty()) { log.trace("DUP2 with unknown operand"); //$NON-NLS-1$ s.clear(); } else { s.pushWord(l1); s.pushWord(l1); } break; case Opcodes.DUP2_X1: l1 = s.popWord(); o1 = s.pop(); if (l1.isEmpty()) { log.trace("DUP2 with unknown operand"); //$NON-NLS-1$ s.clear(); } else { s.pushWord(l1); s.push(o1); s.pushWord(l1); } break; case Opcodes.DUP2_X2: l1 = s.popWord(); l2 = s.popWord(); if (l1.isEmpty() || l2.isEmpty()) { log.trace("DUP2 with unknown operand"); //$NON-NLS-1$ s.clear(); } else { s.pushWord(l1); s.pushWord(l2); s.pushWord(l1); } break; case Opcodes.SWAP: o1 = s.pop(); o2 = s.pop(); s.push(o1); s.push(o2); break; case Opcodes.IADD: case Opcodes.LADD: case Opcodes.FADD: case Opcodes.DADD: case Opcodes.ISUB: case Opcodes.LSUB: case Opcodes.FSUB: case Opcodes.DSUB: case Opcodes.IMUL: case Opcodes.LMUL: case Opcodes.FMUL: case Opcodes.DMUL: case Opcodes.IDIV: case Opcodes.LDIV: case Opcodes.FDIV: case Opcodes.DDIV: case Opcodes.IREM: case Opcodes.LREM: case Opcodes.FREM: case Opcodes.DREM: case Opcodes.IAND: case Opcodes.LAND: case Opcodes.IOR: case Opcodes.LOR: case Opcodes.IXOR: case Opcodes.LXOR: case Opcodes.LCMP: case Opcodes.FCMPL: case Opcodes.FCMPG: case Opcodes.DCMPL: case Opcodes.DCMPG: s.merge(2); break; case Opcodes.ISHL: case Opcodes.LSHL: case Opcodes.ISHR: case Opcodes.LSHR: case Opcodes.IUSHR: case Opcodes.LUSHR: s.pop(); // amount // ignore value break; case Opcodes.INEG: case Opcodes.F2I: case Opcodes.D2I: case Opcodes.L2I: s.push(cast(s.pop(), Type.INT_TYPE)); break; case Opcodes.LNEG: case Opcodes.I2L: case Opcodes.F2L: case Opcodes.D2L: s.push(cast(s.pop(), Type.LONG_TYPE)); break; case Opcodes.FNEG: case Opcodes.I2F: case Opcodes.L2F: case Opcodes.D2F: s.push(cast(s.pop(), Type.FLOAT_TYPE)); case Opcodes.DNEG: case Opcodes.I2D: case Opcodes.L2D: case Opcodes.F2D: s.push(cast(s.pop(), Type.DOUBLE_TYPE)); case Opcodes.I2B: s.push(cast(s.pop(), Type.BYTE_TYPE)); break; case Opcodes.I2C: s.push(cast(s.pop(), Type.CHAR_TYPE)); break; case Opcodes.I2S: s.push(cast(s.pop(), Type.SHORT_TYPE)); break; case Opcodes.ARETURN: s.clear(); break; case Opcodes.IRETURN: case Opcodes.LRETURN: case Opcodes.FRETURN: case Opcodes.DRETURN: case Opcodes.RETURN: if (log.isTraceEnabled()) { log.trace("Found return " + s.pop()); //$NON-NLS-1$ } s.clear(); break; case Opcodes.ATHROW: Object thrw = s.pop(); log.trace("Found throw " + thrw); //$NON-NLS-1$ s.clear(); break; default: log.warn("Unsupported instruction code " + opcode); //$NON-NLS-1$ } }
From source file:serianalyzer.SerianalyzerMethodVisitor.java
License:Open Source License
/** * {@inheritDoc}// w w w . j av a 2s . co m * * @see org.objectweb.asm.MethodVisitor#visitInsn(int) */ @Override public void visitInsn(int opcode) { switch (opcode) { case Opcodes.ARETURN: Object ret = this.stack.pop(); Type sigType = Type.getReturnType(this.ref.getSignature()); Type retType = null; Set<Type> altTypes = null; if (ret != null) { if (ret instanceof SimpleType) { retType = ((SimpleType) ret).getType(); altTypes = ((SimpleType) ret).getAlternativeTypes(); } else if (ret instanceof MultiAlternatives) { retType = ((MultiAlternatives) ret).getCommonType(); } } if (retType != null) { this.returnTypes.add(retType); if (altTypes != null) { this.returnTypes.addAll(altTypes); } } else { this.returnTypes.add(sigType); } this.stack.clear(); break; case Opcodes.IRETURN: case Opcodes.LRETURN: case Opcodes.FRETURN: case Opcodes.DRETURN: case Opcodes.RETURN: if (this.log.isTraceEnabled()) { this.log.trace("Found return " + this.stack.pop()); //$NON-NLS-1$ } this.stack.clear(); break; case Opcodes.ATHROW: Object thrw = this.stack.pop(); this.log.trace("Found throw " + thrw); //$NON-NLS-1$ this.stack.clear(); break; default: JVMImpl.handleJVMInsn(opcode, this.stack); } super.visitInsn(opcode); }
From source file:sg.atom.core.actor.internal.codegenerator.ActorProxyCreator.java
License:Apache License
/** * Writes a proxy method for messages./*from www . j a v a 2 s .c o m*/ * * @param classNameInternal the internal class name * @param classNameDescriptor the class name descriptor * @param cw the ClassWriter * @param index the message index * @param type the ActorState type to use * @param concurrencyModel the concurrency model of the message * @param messageDescriptor the message's descriptor * @param method the method to override * @param simpleDescriptor a simple descriptor of the message * @param genericSignature the signature of the message */ private static void writeProxyMethod(String classNameInternal, String classNameDescriptor, ClassWriter cw, int index, Type actorState, ConcurrencyModel concurrencyModel, MessageImplDescriptor messageDescriptor, Method method, String simpleDescriptor, String genericSignature) throws NoSuchMethodException { MethodVisitor mv; { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), simpleDescriptor, genericSignature, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitIntInsn(Opcodes.BIPUSH, method.getParameterTypes().length); mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); for (int j = 0; j < method.getParameterTypes().length; j++) { mv.visitInsn(Opcodes.DUP); mv.visitIntInsn(Opcodes.BIPUSH, j); Class<?> paraType = method.getParameterTypes()[j]; if (paraType.isPrimitive()) { String wrapperClass = GenerationUtils.getWrapperInternalName(paraType); Type primType = Type.getType(paraType); mv.visitVarInsn(primType.getOpcode(Opcodes.ILOAD), j + 1); mv.visitMethodInsn(Opcodes.INVOKESTATIC, wrapperClass, "valueOf", "(" + primType.getDescriptor() + ")" + "L" + wrapperClass + ";"); } else if (isArgumentFreezingRequired(method, j, paraType)) { mv.visitVarInsn(Opcodes.ALOAD, j + 1); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(SerializableFreezer.class), "freeze", Type.getMethodDescriptor(SerializableFreezer.class.getMethod("freeze", Object.class))); } else if (paraType.isInterface()) { mv.visitVarInsn(Opcodes.ALOAD, j + 1); mv.visitInsn(Opcodes.DUP); mv.visitTypeInsn(Opcodes.INSTANCEOF, "org/actorsguildframework/Actor"); Label lEndif = new Label(); mv.visitJumpInsn(Opcodes.IFNE, lEndif); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(ActorRuntimeException.class)); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn(String.format( "Argument %d is an non-Serializable interface, but you did not give an Actor. If a message's argument type is an interface that does not extend Serializable, only Actors are acceptable as argument.", j)); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(ActorRuntimeException.class), "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(lEndif); } else { mv.visitVarInsn(Opcodes.ALOAD, j + 1); } mv.visitInsn(Opcodes.AASTORE); } Label l1 = new Label(); mv.visitLabel(l1); mv.visitVarInsn(Opcodes.ASTORE, method.getParameterTypes().length + 1); // method.getParameterTypes().length+1 ==> 'args' local variable mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, classNameInternal, "actorState__ACTORPROXY", actorState.getDescriptor()); mv.visitFieldInsn(Opcodes.GETSTATIC, classNameInternal, String.format(MESSAGE_CALLER_NAME_FORMAT, index), "Lorg/actorsguildframework/internal/MessageCaller;"); mv.visitFieldInsn(Opcodes.GETSTATIC, "org/actorsguildframework/annotations/ThreadUsage", messageDescriptor.getThreadUsage().name(), "Lorg/actorsguildframework/annotations/ThreadUsage;"); mv.visitVarInsn(Opcodes.ALOAD, method.getParameterTypes().length + 1); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, actorState.getInternalName(), "queueMessage", "(Lorg/actorsguildframework/internal/MessageCaller;Lorg/actorsguildframework/annotations/ThreadUsage;[Ljava/lang/Object;)Lorg/actorsguildframework/internal/AsyncResultImpl;"); mv.visitInsn(Opcodes.ARETURN); Label l4 = new Label(); mv.visitLabel(l4); mv.visitLocalVariable("this", classNameDescriptor, null, l0, l4, 0); for (int j = 0; j < method.getParameterTypes().length; j++) { mv.visitLocalVariable("arg" + j, Type.getDescriptor(method.getParameterTypes()[j]), GenericTypeHelper.getSignatureIfGeneric(method.getGenericParameterTypes()[j]), l0, l4, j + 1); } mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l1, l4, method.getParameterTypes().length + 1); mv.visitMaxs(0, 0); mv.visitEnd(); } }
From source file:sg.atom.core.actor.internal.codegenerator.BeanCreator.java
License:Apache License
/** * Writes the bean constructor to the given ClassWriter. * * @param beanClass the original bean class to extend * @param bcd the descriptor of the bean * @param classNameInternal the internal name of the new class * @param cw the ClassWriter to write to * @param snippetWriter if not null, this will be invoked to add a snippet * after the invocation of the super constructor *//* ww w . j a va2 s . c o m*/ public static void writeConstructor(Class<?> beanClass, BeanClassDescriptor bcd, String classNameInternal, ClassWriter cw, SnippetWriter snippetWriter) { String classNameDescriptor = "L" + classNameInternal + ";"; int localPropertySize = 0; ArrayList<PropertyDescriptor> localVarProperties = new ArrayList<PropertyDescriptor>(); for (int i = 0; i < bcd.getPropertyCount(); i++) { PropertyDescriptor pd = bcd.getProperty(i); if (pd.getPropertySource().isGenerating() || (pd.getDefaultValue() != null)) { localVarProperties.add(pd); localPropertySize += Type.getType(pd.getPropertyClass()).getSize(); } } final int locVarThis = 0; final int locVarController = 1; final int locVarProps = 2; final int locVarPropertiesOffset = 3; final int locVarP = 3 + localPropertySize; final int locVarK = 4 + localPropertySize; final int locVarV = 5 + localPropertySize; MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Lorg/actorsguildframework/internal/Controller;Lorg/actorsguildframework/Props;)V", null, null); mv.visitCode(); Label lTry = new Label(); Label lCatch = new Label(); mv.visitTryCatchBlock(lTry, lCatch, lCatch, "java/lang/ClassCastException"); Label lBegin = new Label(); mv.visitLabel(lBegin); mv.visitVarInsn(Opcodes.ALOAD, locVarThis); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(beanClass), "<init>", "()V"); if (snippetWriter != null) { snippetWriter.write(mv); } Label lPropertyInit = new Label(); mv.visitLabel(lPropertyInit); // load default values into the local variables for each property that must be set int varCount = 0; for (PropertyDescriptor pd : localVarProperties) { Type pt = Type.getType(pd.getPropertyClass()); if (pd.getDefaultValue() != null) { mv.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(pd.getDefaultValue().getDeclaringClass()), pd.getDefaultValue().getName(), Type.getDescriptor(pd.getDefaultValue().getType())); } else { GenerationUtils.generateLoadDefault(mv, pd.getPropertyClass()); } mv.visitVarInsn(pt.getOpcode(Opcodes.ISTORE), locVarPropertiesOffset + varCount); varCount += pt.getSize(); } // loop through the props argument's list mv.visitVarInsn(Opcodes.ALOAD, locVarProps); mv.visitVarInsn(Opcodes.ASTORE, locVarP); Label lWhile = new Label(); Label lEndWhile = new Label(); Label lWhileBody = new Label(); mv.visitLabel(lWhile); mv.visitJumpInsn(Opcodes.GOTO, lEndWhile); mv.visitLabel(lWhileBody); mv.visitVarInsn(Opcodes.ALOAD, locVarP); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/actorsguildframework/Props", "getKey", "()Ljava/lang/String;"); mv.visitVarInsn(Opcodes.ASTORE, locVarK); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/actorsguildframework/Props", "getValue", "()Ljava/lang/Object;"); mv.visitVarInsn(Opcodes.ASTORE, locVarV); mv.visitLabel(lTry); // write an if for each property Label lEndIf = new Label(); varCount = 0; int ifCount = 0; for (int i = 0; i < bcd.getPropertyCount(); i++) { PropertyDescriptor pd = bcd.getProperty(i); boolean usesLocal = pd.getPropertySource().isGenerating() || (pd.getDefaultValue() != null); Class<?> propClass = pd.getPropertyClass(); Type pt = Type.getType(propClass); mv.visitVarInsn(Opcodes.ALOAD, locVarK); mv.visitLdcInsn(pd.getName()); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z"); Label lElse = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, lElse); if (!usesLocal) { mv.visitVarInsn(Opcodes.ALOAD, locVarThis); // for setter invocation, load 'this' } if (propClass.isPrimitive()) { mv.visitLdcInsn(pd.getName()); mv.visitVarInsn(Opcodes.ALOAD, locVarV); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(BeanHelper.class), String.format("get%s%sFromPropValue", propClass.getName().substring(0, 1).toUpperCase(Locale.US), propClass.getName().substring(1)), "(Ljava/lang/String;Ljava/lang/Object;)" + pt.getDescriptor()); } else if (!propClass.equals(Object.class)) { mv.visitVarInsn(Opcodes.ALOAD, locVarV); mv.visitTypeInsn(Opcodes.CHECKCAST, pt.getInternalName()); } else { mv.visitVarInsn(Opcodes.ALOAD, locVarV); } if (!usesLocal) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classNameInternal, pd.getSetter().getName(), Type.getMethodDescriptor(pd.getSetter())); } else { mv.visitVarInsn(pt.getOpcode(Opcodes.ISTORE), varCount + locVarPropertiesOffset); } mv.visitJumpInsn(Opcodes.GOTO, lEndIf); mv.visitLabel(lElse); ifCount++; if (usesLocal) { varCount += pt.getSize(); } } // else (==> if not prop matched) throw IllegalArgumentException mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(IllegalArgumentException.class)); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn("Unknown property \"%s\"."); mv.visitInsn(Opcodes.ICONST_1); mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.ICONST_0); mv.visitVarInsn(Opcodes.ALOAD, locVarK); mv.visitInsn(Opcodes.AASTORE); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;"); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(IllegalArgumentException.class), "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(lCatch); mv.visitInsn(Opcodes.POP); // pop the exception object (not needed) mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(IllegalArgumentException.class)); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn("Incompatible type for property \"%s\". Got %s."); mv.visitInsn(Opcodes.ICONST_2); mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.ICONST_0); mv.visitVarInsn(Opcodes.ALOAD, locVarK); mv.visitInsn(Opcodes.AASTORE); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.ICONST_1); mv.visitVarInsn(Opcodes.ALOAD, locVarV); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;"); mv.visitInsn(Opcodes.AASTORE); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;"); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(IllegalArgumentException.class), "<init>", "(Ljava/lang/String;)V"); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(lEndIf); mv.visitVarInsn(Opcodes.ALOAD, locVarP); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/actorsguildframework/Props", "tail", "()Lorg/actorsguildframework/Props;"); mv.visitVarInsn(Opcodes.ASTORE, locVarP); mv.visitLabel(lEndWhile); mv.visitVarInsn(Opcodes.ALOAD, locVarP); mv.visitJumpInsn(Opcodes.IFNONNULL, lWhileBody); // write local variables back into properties varCount = 0; for (PropertyDescriptor pd : localVarProperties) { Type pt = Type.getType(pd.getPropertyClass()); mv.visitVarInsn(Opcodes.ALOAD, locVarThis); if (pd.getPropertySource() == PropertySource.ABSTRACT_METHOD) { mv.visitVarInsn(pt.getOpcode(Opcodes.ILOAD), locVarPropertiesOffset + varCount); mv.visitFieldInsn(Opcodes.PUTFIELD, classNameInternal, String.format(PROP_FIELD_NAME_TEMPLATE, pd.getName()), pt.getDescriptor()); } else if (pd.getPropertySource() == PropertySource.USER_WRITTEN) { mv.visitVarInsn(pt.getOpcode(Opcodes.ILOAD), locVarPropertiesOffset + varCount); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classNameInternal, pd.getSetter().getName(), Type.getMethodDescriptor(pd.getSetter())); } else { throw new RuntimeException("Internal error"); } varCount += pt.getSize(); } // if bean is thread-safe, publish all writes now if (bcd.isThreadSafe()) { mv.visitVarInsn(Opcodes.ALOAD, locVarThis); mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.MONITORENTER); mv.visitInsn(Opcodes.MONITOREXIT); } mv.visitInsn(Opcodes.RETURN); Label lEnd = new Label(); mv.visitLabel(lEnd); mv.visitLocalVariable("this", classNameDescriptor, null, lBegin, lEnd, locVarThis); mv.visitLocalVariable("controller", "Lorg/actorsguildframework/internal/Controller;", null, lBegin, lEnd, locVarController); mv.visitLocalVariable("props", "Lorg/actorsguildframework/Props;", null, lBegin, lEnd, locVarProps); varCount = 0; for (PropertyDescriptor pd : localVarProperties) { Type pt = Type.getType(pd.getPropertyClass()); mv.visitLocalVariable("__" + pd.getName(), pt.getDescriptor(), GenericTypeHelper.getSignature(pd.getPropertyType()), lPropertyInit, lEnd, locVarPropertiesOffset + varCount); varCount += pt.getSize(); } mv.visitLocalVariable("p", "Lorg/actorsguildframework/Props;", null, lPropertyInit, lEnd, locVarP); mv.visitLocalVariable("k", "Ljava/lang/String;", null, lWhile, lEndWhile, locVarK); mv.visitLocalVariable("v", "Ljava/lang/Object;", null, lWhile, lEndWhile, locVarV); mv.visitMaxs(0, 0); mv.visitEnd(); }