1 salcianu 1.1 // CompilerState.java, created Wed Apr 2 13:26:51 2003 by salcianu 2 salcianu 1.1 // Copyright (C) 2003 Alexandru Salcianu <salcianu@MIT.EDU> 3 salcianu 1.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 salcianu 1.1 package harpoon.Main; 5 salcianu 1.1 6 salcianu 1.1 import harpoon.ClassFile.Linker; 7 salcianu 1.1 import harpoon.ClassFile.HMethod; 8 salcianu 1.1 import harpoon.ClassFile.HCodeFactory; 9 salcianu 1.1 import harpoon.Backend.Generic.Frame; 10 salcianu 1.1 import harpoon.Analysis.ClassHierarchy; 11 salcianu 1.1 12 cananian 1.7 import net.cscott.jutil.PersistentMap; 13 salcianu 1.5 14 salcianu 1.1 import java.util.Set; 15 salcianu 1.2 import java.io.Serializable; 16 salcianu 1.1 17 salcianu 1.1 /** 18 salcianu 1.1 * <code>CompilerState</code> is an immutable tuple that encapsulates 19 salcianu 1.1 * the date required while compiling a program. Ideally, each stage 20 salcianu 1.1 * of the compiler receives a <code>CompilerState</code>, does some 21 salcianu 1.1 * transformations and returns a new <code>CompilerState</code> 22 salcianu 1.1 * object. 23 salcianu 1.1 * 24 salcianu 1.1 * <p> Because this tuple has many fields, and their number is likely 25 salcianu 1.1 * to vary, the portable way of generating a new 26 salcianu 1.1 * <code>CompilerState</code> is by using one of the 27 salcianu 1.1 * "change*" methods. This is also supposed to be very 28 salcianu 1.1 * convenient: most of the compiler stages will modify only a small 29 salcianu 1.1 * part of the compiler state (most usually, only a new code factory). 30 salcianu 1.4 * Also, <code>CompilerState.EMPTY_STATE</code> contains the initial, 31 salcianu 1.4 * empty compiler state (initial meaning "at the beginning of the 32 salcianu 1.4 * compiler") 33 salcianu 1.1 * 34 salcianu 1.1 * @author Alexandru Salcianu <salcianu@MIT.EDU> 35 cananian 1.7 * @version $Id: CompilerState.java,v 1.7 2004/02/08 01:58:13 cananian Exp $ */ 36 salcianu 1.2 public class CompilerState implements Cloneable, Serializable { 37 salcianu 1.1 38 salcianu 1.5 private CompilerState() { 39 salcianu 1.5 attribs = new PersistentMap/*<String,Object>*/(); 40 salcianu 1.5 } 41 salcianu 1.5 42 salcianu 1.3 public static CompilerState EMPTY_STATE = new CompilerState(); 43 salcianu 1.1 44 salcianu 1.1 private HMethod main; 45 salcianu 1.1 private Set roots; 46 salcianu 1.1 private Linker linker; 47 salcianu 1.1 private HCodeFactory hcf; 48 salcianu 1.1 private ClassHierarchy classHierarchy; 49 salcianu 1.1 // TODO: [ALEX] It's unclear why frame should be here; the backend 50 salcianu 1.1 // should be only one compiler stage, instead of part of the 51 salcianu 1.1 // compiler state 52 cananian 1.6 // CSA: because some stages depend indirectly on which backend is 53 cananian 1.6 // selected? 54 salcianu 1.1 private Frame frame; 55 salcianu 1.5 // other attributes (that don't occcur that often and don't 56 salcianu 1.5 // deserve separate fields) 57 cananian 1.6 private PersistentMap<String,Object> attribs; 58 salcianu 1.1 59 salcianu 1.1 /** @return main method of the compiled program */ 60 salcianu 1.1 public HMethod getMain() { return main; } 61 salcianu 1.1 62 salcianu 1.1 /** @return set of roots for the compiled program */ 63 salcianu 1.1 public Set getRoots() { return roots; } 64 salcianu 1.1 65 salcianu 1.1 /** @return linker that loads the classes of the compiled program */ 66 salcianu 1.1 public Linker getLinker() { return linker; } 67 salcianu 1.1 68 salcianu 1.1 /** @return code factory that provides the code of the methods 69 salcianu 1.1 from the compiled program. */ 70 salcianu 1.1 public HCodeFactory getCodeFactory() { return hcf; } 71 salcianu 1.1 72 salcianu 1.1 /** @return class hierarchy for the compiled program; */ 73 salcianu 1.1 public ClassHierarchy getClassHierarchy() { return classHierarchy; } 74 salcianu 1.1 75 salcianu 1.1 /** @return backend specific details for the compiled program */ 76 salcianu 1.1 public Frame getFrame() { return frame; } 77 salcianu 1.1 78 salcianu 1.1 79 salcianu 1.5 /** @return (persistent) map from attribute names to attribute 80 salcianu 1.5 values */ 81 cananian 1.6 public PersistentMap<String,Object> getAttributes() { return attribs; } 82 salcianu 1.5 83 salcianu 1.5 84 salcianu 1.1 // helper method used by the change* methods: returns a clone of 85 salcianu 1.1 // this object and takes care of the possible exception). Using 86 salcianu 1.1 // this method in the implem. of change* methods protects them 87 salcianu 1.1 // from fields addition / deletion 88 salcianu 1.1 private CompilerState newCopy() { 89 salcianu 1.1 try { 90 salcianu 1.1 return (CompilerState) this.clone(); 91 salcianu 1.1 } catch (CloneNotSupportedException e) { 92 salcianu 1.1 throw new Error("Should not happen"); 93 salcianu 1.1 } 94 salcianu 1.1 } 95 salcianu 1.1 96 salcianu 1.1 /** @return identical copy of <code>this</code> compiler state, 97 salcianu 1.1 with the exception of the main method, which is now set to 98 salcianu 1.1 <code>main</code> */ 99 salcianu 1.1 public CompilerState changeMain(HMethod main) { 100 salcianu 1.1 CompilerState newCS = this.newCopy(); 101 salcianu 1.1 newCS.main = main; 102 salcianu 1.1 return newCS; 103 salcianu 1.1 } 104 salcianu 1.1 105 salcianu 1.1 /** @return identical copy of <code>this</code> compiler state, 106 salcianu 1.1 with the exception of the set of roots, which is now set to 107 salcianu 1.1 <code>roots</code> */ 108 salcianu 1.3 public CompilerState changeRoots(Set roots) { 109 salcianu 1.1 CompilerState newCS = this.newCopy(); 110 salcianu 1.1 newCS.roots = roots; 111 salcianu 1.1 return newCS; 112 salcianu 1.1 } 113 salcianu 1.1 114 salcianu 1.1 /** @return identical copy of <code>this</code> compiler state, 115 salcianu 1.1 with the exception of the linker, which is now set to 116 salcianu 1.1 <code>linker</code> */ 117 salcianu 1.1 public CompilerState changeLinker(Linker linker) { 118 salcianu 1.1 CompilerState newCS = this.newCopy(); 119 salcianu 1.1 newCS.linker = linker; 120 salcianu 1.1 return newCS; 121 salcianu 1.1 } 122 salcianu 1.1 123 salcianu 1.1 /** @return identical copy of <code>this</code> compiler state, 124 salcianu 1.1 with the exception of the code factory, which is now set to 125 salcianu 1.1 <code>hcf</code> */ 126 salcianu 1.1 public CompilerState changeCodeFactory(HCodeFactory hcf) { 127 salcianu 1.1 CompilerState newCS = this.newCopy(); 128 salcianu 1.1 newCS.hcf = hcf; 129 salcianu 1.1 return newCS; 130 salcianu 1.1 } 131 salcianu 1.1 132 salcianu 1.1 /** @return identical copy of <code>this</code> compiler state, 133 salcianu 1.1 with the exception of the class hierarchy, which is now set to 134 salcianu 1.1 <code>classHierarchy</code> */ 135 salcianu 1.3 public CompilerState changeClassHierarchy(ClassHierarchy classHierarchy) { 136 salcianu 1.1 CompilerState newCS = this.newCopy(); 137 salcianu 1.1 newCS.classHierarchy = classHierarchy; 138 salcianu 1.1 return newCS; 139 salcianu 1.1 } 140 salcianu 1.1 141 salcianu 1.1 /** @return identical copy of <code>this</code> compiler state, 142 salcianu 1.1 with the exception of the frame, which is now set to 143 salcianu 1.1 <code>frame</code> */ 144 salcianu 1.1 public CompilerState changeFrame(Frame frame) { 145 salcianu 1.1 CompilerState newCS = this.newCopy(); 146 salcianu 1.1 newCS.frame = frame; 147 salcianu 1.1 return newCS; 148 salcianu 1.5 } 149 salcianu 1.5 150 salcianu 1.5 151 salcianu 1.5 /** @return identical copy of <code>this</code> compiler state, 152 salcianu 1.5 with the exception of the attribute map, which is now set to 153 salcianu 1.5 <code>attribs</code> */ 154 cananian 1.6 public CompilerState changeAttributes(PersistentMap<String,Object> attribs) { 155 salcianu 1.5 CompilerState newCS = this.newCopy(); 156 salcianu 1.5 newCS.attribs = attribs; 157 salcianu 1.5 return newCS; 158 salcianu 1.5 } 159 salcianu 1.1 }