1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xalan.internal.xsltc.compiler; 22 23 import com.sun.org.apache.bcel.internal.generic.BranchHandle; 24 import com.sun.org.apache.bcel.internal.generic.InstructionHandle; 25 import com.sun.org.apache.bcel.internal.generic.InstructionList; 26 import java.util.ArrayList; 27 import java.util.Iterator; 28 import java.util.List; 29 30 /** 31 * @author Jacek Ambroziak 32 * @author Santiago Pericas-Geertsen 33 * @LastModified: Oct 2017 34 */ 35 public final class FlowList { 36 private List<InstructionHandle> _elements; 37 38 public FlowList() { 39 _elements = null; 40 } 41 42 public FlowList(InstructionHandle bh) { 43 _elements = new ArrayList<>(); 44 _elements.add(bh); 45 } 46 47 public FlowList(FlowList list) { 48 _elements = list._elements; 49 } 50 51 public FlowList add(InstructionHandle bh) { 52 if (_elements == null) { 53 _elements = new ArrayList<>(); 54 } 55 _elements.add(bh); 56 return this; 57 } 58 59 public FlowList append(FlowList right) { 60 if (_elements == null) { 61 _elements = right._elements; 62 } 63 else { 64 final List<InstructionHandle> temp = right._elements; 65 if (temp != null) { 66 final int n = temp.size(); 67 for (int i = 0; i < n; i++) { 68 _elements.add(temp.get(i)); 69 } 70 } 71 } 72 return this; 73 } 74 75 /** 76 * Back patch a flow list. All instruction handles must be branch handles. 77 */ 78 public void backPatch(InstructionHandle target) { 79 if (_elements != null) { 80 final int n = _elements.size(); 81 for (int i = 0; i < n; i++) { 82 BranchHandle bh = (BranchHandle)_elements.get(i); 83 bh.setTarget(target); 84 } 85 _elements.clear(); // avoid backpatching more than once 86 } 87 } 88 89 /** 90 * Redirect the handles from oldList to newList. "This" flow list 91 * is assumed to be relative to oldList. 92 */ 93 public FlowList copyAndRedirect(InstructionList oldList, 94 InstructionList newList) 95 { 96 final FlowList result = new FlowList(); 97 if (_elements == null) { 98 return result; 99 } 100 101 final int n = _elements.size(); 102 final Iterator<InstructionHandle> oldIter = oldList.iterator(); 103 final Iterator<InstructionHandle> newIter = newList.iterator(); 104 105 while (oldIter.hasNext()) { 106 final InstructionHandle oldIh = oldIter.next(); 107 final InstructionHandle newIh = newIter.next(); 108 109 for (int i = 0; i < n; i++) { 110 if (_elements.get(i) == oldIh) { 111 result.add(newIh); 112 } 113 } 114 } 115 return result; 116 } 117 }