/** * Remove the mapping from the name of the specified * {@link LocalVariableGen} to itself. * See also {@link #registerByName(LocalVariableGen)} and * {@link #lookUpByName(String)} * @param lvg a <code>LocalVariableGen</code> */ protected void removeByNameTracking(LocalVariableGen lvg) { Object duplicateNameEntry = _nameToLVGMap.get(lvg.getName()); if (duplicateNameEntry instanceof ArrayList) { ArrayList sameNameList = (ArrayList) duplicateNameEntry; for (int i = 0; i < sameNameList.size(); i++) { if (sameNameList.get(i) == lvg) { sameNameList.remove(i); break; } } } else { _nameToLVGMap.remove(lvg); } }
public void setMaxLocals() { // Get the current number of local variable slots int maxLocals = super.getMaxLocals(); int prevLocals = maxLocals; // Get numer of actual variables final LocalVariableGen[] localVars = super.getLocalVariables(); if (localVars != null) { if (localVars.length > maxLocals) maxLocals = localVars.length; } // We want at least 5 local variable slots (for parameters) if (maxLocals < 5) maxLocals = 5; super.setMaxLocals(maxLocals); }
public void releaseSlot(LocalVariableGen lvg) { final int size = lvg.getType().getSize(); final int slot = lvg.getIndex(); final int limit = _free; for (int i = 0; i < limit; i++) { if (_slotsTaken[i] == slot) { int j = i + size; while (j < limit) { _slotsTaken[i++] = _slotsTaken[j++]; } _free -= size; return; } } String state = "Variable slot allocation error"+ "(size="+size+", slot="+slot+", limit="+limit+")"; ErrorMsg err = new ErrorMsg(ErrorMsg.INTERNAL_ERR, state); throw new Error(err.toString()); }
public CompareGenerator(int access_flags, Type return_type, Type[] arg_types, String[] arg_names, String method_name, String class_name, InstructionList il, ConstantPoolGen cp) { super(access_flags, return_type, arg_types, arg_names, method_name, class_name, il, cp); _iloadCurrent = new ILOAD(CURRENT_INDEX); _istoreCurrent = new ISTORE(CURRENT_INDEX); _aloadDom = new ALOAD(DOM_INDEX); _iloadLast = new ILOAD(LAST_INDEX); LocalVariableGen iterator = addLocalVariable("iterator", Util.getJCRefType(Constants.NODE_ITERATOR_SIG), null, null); ITERATOR_INDEX = iterator.getIndex(); _aloadIterator = new ALOAD(ITERATOR_INDEX); _astoreIterator = new ASTORE(ITERATOR_INDEX); il.append(new ACONST_NULL()); il.append(storeIterator()); }
/** * <p>Set up a mapping of the name of the specified * {@link LocalVariableGen} object to the <code>LocalVariableGen</code> * itself.</p> * <p>This is a bit of a hack. XSLTC is relying on the fact that the * name that is being looked up won't be duplicated, which isn't * guaranteed. It replaces code which used to call * {@link MethodGen#getLocalVariables()} and looped through the * <code>LocalVariableGen</code> objects it contained to find the one * with the specified name. However, <code>getLocalVariables()</code> * has the side effect of setting the start and end for any * <code>LocalVariableGen</code> which did not already have them * set, which causes problems for outlining..</p> * <p>See also {@link #lookUpByName(String)} and * {@link #removeByNameTracking(LocalVariableGen)}</P * @param lvg a <code>LocalVariableGen</code> */ protected void registerByName(LocalVariableGen lvg) { Object duplicateNameEntry = _nameToLVGMap.get(lvg.getName()); if (duplicateNameEntry == null) { _nameToLVGMap.put(lvg.getName(), lvg); } else { ArrayList sameNameList; if (duplicateNameEntry instanceof ArrayList) { sameNameList = (ArrayList) duplicateNameEntry; sameNameList.add(lvg); } else { sameNameList = new ArrayList(); sameNameList.add(duplicateNameEntry); sameNameList.add(lvg); } _nameToLVGMap.put(lvg.getName(), sameNameList); } }
/** * Translates a real into a non-synthesized boolean. It does not push a * 0 or a 1 but instead returns branchhandle list to be appended to the * false list. A NaN must be converted to "false". * * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateToDesynthesized */ public FlowList translateToDesynthesized(ClassGenerator classGen, MethodGenerator methodGen, BooleanType type) { LocalVariableGen local; final FlowList flowlist = new FlowList(); final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); // Store real into a local variable il.append(DUP2); local = methodGen.addLocalVariable("real_to_boolean_tmp", com.sun.org.apache.bcel.internal.generic.Type.DOUBLE, null, null); local.setStart(il.append(new DSTORE(local.getIndex()))); // Compare it to 0.0 il.append(DCONST_0); il.append(DCMPG); flowlist.add(il.append(new IFEQ(null))); //!!! call isNaN // Compare it to itself to see if NaN il.append(new DLOAD(local.getIndex())); local.setEnd(il.append(new DLOAD(local.getIndex()))); il.append(DCMPG); flowlist.add(il.append(new IFNE(null))); // NaN != NaN return flowlist; }
/** * Allocates a local variable. If the slot allocator has already been * initialized, then call addLocalVariable2() so that the new variable * is known to the allocator. Failing to do this may cause the allocator * to return a slot that is already in use. */ public LocalVariableGen addLocalVariable(String name, Type type, InstructionHandle start, InstructionHandle end) { LocalVariableGen lvg; if (_allocatorInit) { lvg = addLocalVariable2(name, type, start); } else { lvg = super.addLocalVariable(name, type, start, end); getLocalVariableRegistry().registerLocalVariable(lvg); } return lvg; }
public LocalVariableGen addLocalVariable2(String name, Type type, InstructionHandle start) { LocalVariableGen lvg = super.addLocalVariable(name, type, _slotAllocator.allocateSlot(type), start, null); getLocalVariableRegistry().registerLocalVariable(lvg); return lvg; }
/** * Registers a {@link org.apache.bcel.generic.LocalVariableGen} * for this method. * <p><b>Preconditions:</b> * <ul> * <li>The range of instructions for <code>lvg</code> does not * overlap with the range of instructions for any * <code>LocalVariableGen</code> with the same slot index previously * registered for this method. <b><em>(Unchecked.)</em></b></li> * </ul></p> * @param lvg The variable to be registered */ protected void registerLocalVariable(LocalVariableGen lvg) { int slot = lvg.getIndex(); int registrySize = _variables.size(); // If the LocalVariableGen uses a slot index beyond any previously // encountered, expand the _variables, padding with intervening null // entries as required. if (slot >= registrySize) { for (int i = registrySize; i < slot; i++) { _variables.add(null); } _variables.add(lvg); } else { // If the LocalVariableGen reuses a slot, make sure the entry // in _variables contains an ArrayList and add the newly // registered LocalVariableGen to the list. If the entry in // _variables just contains null padding, store the // LocalVariableGen directly. Object localsInSlot = _variables.get(slot); if (localsInSlot != null) { if (localsInSlot instanceof LocalVariableGen) { ArrayList listOfLocalsInSlot = new ArrayList(); listOfLocalsInSlot.add(localsInSlot); listOfLocalsInSlot.add(lvg); _variables.set(slot, listOfLocalsInSlot); } else { ((ArrayList) localsInSlot).add(lvg); } } else { _variables.set(slot, lvg); } } registerByName(lvg); }
/** * Determines whether a particular variable is in use at a particular offset * in the byte code for this method. * <p><b>Preconditions:</b> * <ul> * <li>The {@link InstructionList#setPositions()} has been called for the * {@link InstructionList} associated with this {@link MethodGenerator}. * </li></ul></p> * @param lvg the {@link LocalVariableGen} for the variable * @param offset the position in the byte code * @return <code>true</code> if and only if the specified variable is in * use at the particular byte code offset. */ boolean offsetInLocalVariableGenRange(LocalVariableGen lvg, int offset) { InstructionHandle lvgStart = lvg.getStart(); InstructionHandle lvgEnd = lvg.getEnd(); // If no start handle is recorded for the LocalVariableGen, it is // assumed to be in use from the beginning of the method. if (lvgStart == null) { lvgStart = getInstructionList().getStart(); } // If no end handle is recorded for the LocalVariableGen, it is assumed // to be in use to the end of the method. if (lvgEnd == null) { lvgEnd = getInstructionList().getEnd(); } // Does the range of the instruction include the specified offset? // Note that the InstructionHandle.getPosition method returns the // offset of the beginning of an instruction. A LocalVariableGen's // range includes the end instruction itself, so that instruction's // length must be taken into consideration in computing whether the // varible is in range at a particular offset. return ((lvgStart.getPosition() <= offset) && (lvgEnd.getPosition() + lvgEnd.getInstruction().getLength() >= offset)); }
public void initialize(LocalVariableGen[] vars) { final int length = vars.length; int slot = 0, size, index; for (int i = 0; i < length; i++) { size = vars[i].getType().getSize(); index = vars[i].getIndex(); slot = Math.max(slot, index + size); } _firstAvailableSlot = slot; }