| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | package com.sun.fortress.compiler.phases; |
|---|
| 19 | |
|---|
| 20 | import java.util.Comparator; |
|---|
| 21 | import java.util.Map; |
|---|
| 22 | import java.util.Set; |
|---|
| 23 | |
|---|
| 24 | import edu.rice.cs.plt.collect.PredicateSet; |
|---|
| 25 | import edu.rice.cs.plt.collect.Relation; |
|---|
| 26 | import edu.rice.cs.plt.iter.IterUtil; |
|---|
| 27 | |
|---|
| 28 | import com.sun.fortress.compiler.AnalyzeResult; |
|---|
| 29 | import com.sun.fortress.compiler.codegen.*; |
|---|
| 30 | import com.sun.fortress.compiler.environments.TopLevelEnvGen; |
|---|
| 31 | import com.sun.fortress.compiler.index.ApiIndex; |
|---|
| 32 | import com.sun.fortress.compiler.index.ComponentIndex; |
|---|
| 33 | import com.sun.fortress.compiler.index.Function; |
|---|
| 34 | import com.sun.fortress.compiler.typechecker.TypeAnalyzer; |
|---|
| 35 | import com.sun.fortress.exceptions.MultipleStaticError; |
|---|
| 36 | import com.sun.fortress.exceptions.StaticError; |
|---|
| 37 | import com.sun.fortress.nodes.APIName; |
|---|
| 38 | import com.sun.fortress.nodes.Component; |
|---|
| 39 | import com.sun.fortress.nodes.IdOrOpOrAnonymousName; |
|---|
| 40 | import com.sun.fortress.repository.ForeignJava; |
|---|
| 41 | import com.sun.fortress.repository.FortressRepository; |
|---|
| 42 | import com.sun.fortress.scala_src.typechecker.TraitTable; |
|---|
| 43 | import com.sun.fortress.useful.BASet; |
|---|
| 44 | import com.sun.fortress.useful.Debug; |
|---|
| 45 | import com.sun.fortress.useful.DefaultComparator; |
|---|
| 46 | import com.sun.fortress.useful.MultiMap; |
|---|
| 47 | import com.sun.fortress.useful.Useful; |
|---|
| 48 | |
|---|
| 49 | public class CodeGenerationPhase extends Phase { |
|---|
| 50 | |
|---|
| 51 | public static Symbols symbolTable = new Symbols(); |
|---|
| 52 | public static final boolean debugOverloading = false; |
|---|
| 53 | |
|---|
| 54 | public CodeGenerationPhase(Phase parentPhase) { |
|---|
| 55 | super(parentPhase); |
|---|
| 56 | } |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | @Override |
|---|
| 60 | public AnalyzeResult execute() throws StaticError { |
|---|
| 61 | Debug.debug(Debug.Type.FORTRESS, 1, "Start phase CodeGeneration"); |
|---|
| 62 | AnalyzeResult previous = parentPhase.getResult(); |
|---|
| 63 | FortressRepository repository = getRepository(); |
|---|
| 64 | |
|---|
| 65 | |
|---|
| 66 | |
|---|
| 67 | Debug.debug(Debug.Type.CODEGEN, 1, |
|---|
| 68 | "CodeGenerationPhase: components " + previous.components() + |
|---|
| 69 | " apis = " + previous.apis().keySet()); |
|---|
| 70 | |
|---|
| 71 | |
|---|
| 72 | |
|---|
| 73 | |
|---|
| 74 | for (Map.Entry<APIName, ApiIndex> entry : repository.apis().entrySet()) { |
|---|
| 75 | symbolTable.addApi(entry.getKey(), entry.getValue()); |
|---|
| 76 | } |
|---|
| 77 | |
|---|
| 78 | for (Component component : previous.componentIterator()) { |
|---|
| 79 | APIName api = component.getName(); |
|---|
| 80 | symbolTable.addComponent(api, previous.components().get(api)); |
|---|
| 81 | } |
|---|
| 82 | |
|---|
| 83 | Debug.debug(Debug.Type.CODEGEN, 1, |
|---|
| 84 | "SymbolTable=" + symbolTable.toString()); |
|---|
| 85 | |
|---|
| 86 | for ( APIName api : previous.apis().keySet() ) { |
|---|
| 87 | if (ForeignJava.only.foreignApiNeedingCompilation(api)) { |
|---|
| 88 | ApiIndex ai = previous.apis().get(api); |
|---|
| 89 | TypeAnalyzer ta = new TypeAnalyzer(new TraitTable(ai, getEnv())); |
|---|
| 90 | |
|---|
| 91 | Relation<IdOrOpOrAnonymousName, Function> fns = ai.functions(); |
|---|
| 92 | |
|---|
| 93 | Set<OverloadSet> overloads = |
|---|
| 94 | new BASet<OverloadSet>(DefaultComparator.<OverloadSet>normal()); |
|---|
| 95 | |
|---|
| 96 | for (IdOrOpOrAnonymousName name : fns.firstSet()) { |
|---|
| 97 | PredicateSet<Function> defs = fns.matchFirst(name); |
|---|
| 98 | if (defs.size() > 1) { |
|---|
| 99 | foundAnOverLoadedForeignFunction(ai, ta, name, defs, overloads); |
|---|
| 100 | } |
|---|
| 101 | } |
|---|
| 102 | ForeignJava.only.generateWrappersForApi(api, overloads); |
|---|
| 103 | |
|---|
| 104 | } |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | for (Component component : previous.componentIterator()) { |
|---|
| 108 | Debug.debug(Debug.Type.CODEGEN, 1, |
|---|
| 109 | "CodeGenerationPhase: Compile(" + component.getName() + ")"); |
|---|
| 110 | ComponentIndex ci = previous.components().get(component.getName()); |
|---|
| 111 | Relation<IdOrOpOrAnonymousName, Function> fns = ci.functions(); |
|---|
| 112 | TypeAnalyzer ta = new TypeAnalyzer(new TraitTable(ci, getEnv())); |
|---|
| 113 | |
|---|
| 114 | |
|---|
| 115 | ParallelismAnalyzer pa = new ParallelismAnalyzer(); |
|---|
| 116 | component.accept(pa); |
|---|
| 117 | pa.printTable(); |
|---|
| 118 | |
|---|
| 119 | CodeGen c = new CodeGen(component, symbolTable, ta, ci); |
|---|
| 120 | component.accept(c); |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | return new AnalyzeResult(previous.apis(), previous.components(), |
|---|
| 124 | IterUtil.<StaticError> empty(), |
|---|
| 125 | previous.typeCheckerOutput()); |
|---|
| 126 | |
|---|
| 127 | } |
|---|
| 128 | |
|---|
| 129 | |
|---|
| 130 | |
|---|
| 131 | |
|---|
| 132 | |
|---|
| 133 | |
|---|
| 134 | |
|---|
| 135 | |
|---|
| 136 | private void foundAnOverLoadedForeignFunction(ApiIndex ai, TypeAnalyzer ta, |
|---|
| 137 | IdOrOpOrAnonymousName name, PredicateSet<Function> defs, Set<OverloadSet> overloads) { |
|---|
| 138 | |
|---|
| 139 | if (debugOverloading) |
|---|
| 140 | System.err.println("Found an overloaded function " + name); |
|---|
| 141 | |
|---|
| 142 | MultiMap<Integer, Function> partitionedByArgCount = new MultiMap<Integer, Function> (); |
|---|
| 143 | |
|---|
| 144 | for (Function d : defs) { |
|---|
| 145 | partitionedByArgCount.putItem(d.parameters().size(), d); |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | for(Map.Entry<Integer, Set<Function>> entry : partitionedByArgCount.entrySet()) { |
|---|
| 149 | int i = entry.getKey(); |
|---|
| 150 | Set<Function> fs = entry.getValue(); |
|---|
| 151 | if (fs.size() > 1) { |
|---|
| 152 | OverloadSet os = new OverloadSet.Local(ai.ast().getName(), name, ta, fs, |
|---|
| 153 | i); |
|---|
| 154 | |
|---|
| 155 | os.split(true); |
|---|
| 156 | String s = os.toString(); |
|---|
| 157 | overloads.add(os); |
|---|
| 158 | } |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | } |
|---|