001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: FlowList.java 468650 2006-10-28 07:03:30Z minchau $
020 */
021
022 package org.apache.xalan.xsltc.compiler;
023
024 import java.util.Iterator;
025 import java.util.Vector;
026
027 import org.apache.bcel.generic.BranchHandle;
028 import org.apache.bcel.generic.InstructionHandle;
029 import org.apache.bcel.generic.InstructionList;
030
031 /**
032 * @author Jacek Ambroziak
033 * @author Santiago Pericas-Geertsen
034 */
035 public final class FlowList {
036 private Vector _elements;
037
038 public FlowList() {
039 _elements = null;
040 }
041
042 public FlowList(InstructionHandle bh) {
043 _elements = new Vector();
044 _elements.addElement(bh);
045 }
046
047 public FlowList(FlowList list) {
048 _elements = list._elements;
049 }
050
051 public FlowList add(InstructionHandle bh) {
052 if (_elements == null) {
053 _elements = new Vector();
054 }
055 _elements.addElement(bh);
056 return this;
057 }
058
059 public FlowList append(FlowList right) {
060 if (_elements == null) {
061 _elements = right._elements;
062 }
063 else {
064 final Vector temp = right._elements;
065 if (temp != null) {
066 final int n = temp.size();
067 for (int i = 0; i < n; i++) {
068 _elements.addElement(temp.elementAt(i));
069 }
070 }
071 }
072 return this;
073 }
074
075 /**
076 * Back patch a flow list. All instruction handles must be branch handles.
077 */
078 public void backPatch(InstructionHandle target) {
079 if (_elements != null) {
080 final int n = _elements.size();
081 for (int i = 0; i < n; i++) {
082 BranchHandle bh = (BranchHandle)_elements.elementAt(i);
083 bh.setTarget(target);
084 }
085 _elements.clear(); // avoid backpatching more than once
086 }
087 }
088
089 /**
090 * Redirect the handles from oldList to newList. "This" flow list
091 * is assumed to be relative to oldList.
092 */
093 public FlowList copyAndRedirect(InstructionList oldList,
094 InstructionList newList)
095 {
096 final FlowList result = new FlowList();
097 if (_elements == null) {
098 return result;
099 }
100
101 final int n = _elements.size();
102 final Iterator oldIter = oldList.iterator();
103 final Iterator newIter = newList.iterator();
104
105 while (oldIter.hasNext()) {
106 final InstructionHandle oldIh = (InstructionHandle) oldIter.next();
107 final InstructionHandle newIh = (InstructionHandle) newIter.next();
108
109 for (int i = 0; i < n; i++) {
110 if (_elements.elementAt(i) == oldIh) {
111 result.add(newIh);
112 }
113 }
114 }
115 return result;
116 }
117 }