implement am26 support for constants
[fleet.git] / src / edu / berkeley / fleet / interpreter / Interpreter.java
1 package edu.berkeley.fleet.interpreter;
2 import java.io.*;
3 import java.util.*;
4 import java.util.concurrent.*;
5 import java.lang.reflect.*;
6 import edu.berkeley.fleet.*;
7 import edu.berkeley.sbp.util.ANSI;
8 import edu.berkeley.fleet.doc.*;
9 import edu.berkeley.fleet.api.*;
10 import edu.berkeley.fleet.ies44.*;
11
12 public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
13
14     /** some "halt ship" can turn this on to stop the interpreter */
15     private HashMap<String,InterpreterShip> ships       = new HashMap<String,InterpreterShip>();
16     private BlockingQueue<Long>             debugStream = new LinkedBlockingQueue<Long>();
17
18     public FleetProcess run(final byte[] instructions) {
19         try {
20             final FleetProcess fp = new FleetProcess() {
21                     public void invokeInstruction(Instruction i) { throw new RuntimeException("not supported"); }
22                     public long readWord() {
23                         try {
24                             return debugStream.take();
25                         } catch (Exception e) {
26                             throw new RuntimeException(e);
27                         } }
28                     protected void _terminate() {
29                         // FIXME: hack
30                         ships = new HashMap<String,InterpreterShip>();
31                         debugStream = new LinkedBlockingQueue<Long>();
32                     }
33                 };
34             new Thread() {
35                 public void run() {
36                     try {
37                         // find the first icache
38                         InterpreterShip iscratch = null;
39                         for(Ship ship : Interpreter.this)
40                             if (ship.getClass().getSimpleName().equals("Memory")) {
41                                 iscratch = (InterpreterShip)ship;
42                                 break;
43                             }
44                         if (iscratch==null)
45                             iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.Memory")
46                                 .getConstructor(new Class[] { Interpreter.class, String.class })
47                                 .newInstance(new Object[] { Interpreter.this, "memory" });
48                         iscratch
49                             .getClass()
50                             .getMethod("boot", new Class[] { byte[].class })
51                             .invoke(iscratch, new Object[] { instructions });
52                         
53                         while(!fp.isTerminated())
54                             for(InterpreterShip ship : ships.values())
55                                 for(int j=0; j<10; j++)
56                                     ship._service();
57                         
58                         // run the ships a bit longer for good measure
59                         for(int i=0; i<100; i++)
60                             for(InterpreterShip ship : ships.values())
61                                 for(int j=0; j<10; j++)
62                                     ship._service();
63                         
64                         // check the state of the ships
65                         for(InterpreterShip ship : ships.values())
66                             ship.shutdown();
67                         
68                         Log.println(ANSI.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
69                         
70                     } catch (Exception e) {
71                         if (fp.isTerminated()) return;
72                         throw new RuntimeException(e);
73                     }
74                 }
75             }.start();
76             return fp;
77         } catch (Exception e) {
78             throw new RuntimeException(e);
79         }
80     }
81
82     public void dispatch(Instruction i, long address) {
83         Log.dispatch(i);
84         if (i instanceof Instruction.Executable) {
85             InterpreterBenkoBox sourceBenkoBox = (InterpreterBenkoBox)(((Instruction.Executable)i).benkoBox);
86             ((InstructionBenkoBox)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
87
88         } else if (i instanceof Instruction.Literal.CodeBagDescriptor) {
89             Instruction.Literal.CodeBagDescriptor cbd = (Instruction.Literal.CodeBagDescriptor)i;
90             long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
91             new Packet(this, null, (int)absolute_cbd, (InterpreterDestination)cbd.dest).send();
92             
93         } else if (i instanceof Instruction.Literal.Absolute) {
94             new Packet(this, null,
95                        (int)((Instruction.Literal.Absolute)i).value,
96                        (InterpreterDestination)(((Instruction.Literal.Absolute)i).dest)).send();
97
98         } else if (i instanceof Instruction.Kill) {
99             InterpreterBenkoBox benkoBox = (InterpreterBenkoBox)(((Instruction.Kill)i).benkoBox);
100             ((InstructionBenkoBox)benkoBox).kill(((Instruction.Kill)i).count,
101                                              ((Instruction.Kill)i).killOnlyStandingInstructions);
102
103         } else {
104             throw new Error("unsupported: " + i.getClass().getName());
105         }
106     }
107
108     public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
109
110     public Ship createShip(String shipType, String shipname) {
111         try {
112             Class c = Class.forName("edu.berkeley.fleet.interpreter."+shipType);
113             Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
114             InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
115             BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+shipType+".ship")));
116             ShipDescription sd = new ShipDescription(shipname, br);
117             ret.setShipDescription(sd);
118             ships.put(shipname, ret);
119             return ret;
120         } catch (Exception e) {
121             return null;
122         }
123     }
124
125     public void debug(long data) {
126         try {
127             if (debugStream != null) debugStream.put(data);
128             else Log.println(ANSI.invert("   DEBUG: got a datum: " +  data+ANSI.clreol()));
129         } catch (Exception e) {
130             throw new RuntimeException(e);
131         }
132     }
133
134     // Instruction Encoding /////////////////////////////////////////////////////////////////////////
135
136     public final InterpreterInstructionEncoder iie = new InterpreterInstructionEncoder();
137     public Instruction readInstruction(DataInputStream is) throws IOException { return iie.readInstruction(is); }
138     public Instruction readInstruction(long instr) { return iie.readInstruction(instr); }
139     public long writeInstruction(Instruction d) { return writeInstruction(d); }
140     public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { iie.writeInstruction(os, d); }
141     public class InterpreterInstructionEncoder extends InstructionEncoder {
142         public long getDestAddr(Destination box) { return ((InterpreterDestination)box).getDestAddr(); }
143         public long getBoxInstAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).getDestAddr(); }
144         public Destination getDestByAddr(long dest) {
145             for(Ship ship : Interpreter.this)
146                 for(BenkoBox bb : ship.getBenkoBoxes())
147                     for(Destination d : bb.getDestinations())
148                         if (getDestAddr(d)==dest)
149                             return d;
150             return null;
151         }
152         public BenkoBox getBoxByInstAddr(long dest) {
153             for(Ship ship : Interpreter.this)
154                 for(BenkoBox bb : ship.getBenkoBoxes())
155                     if (getBoxInstAddr(bb) == dest)
156                         return bb;
157             return null;
158         }
159     }
160
161     // ShipDescription //////////////////////////////////////////////////////////////////////////////
162
163     public void expand(ShipDescription sd) {
164         try {
165             String filename = sd.getName();
166             //String filename = (sd.getName().charAt(0)+"").toUpperCase() + sd.getName().substring(1).toLowerCase();
167             File outf = new File("build/java/edu/berkeley/fleet/interpreter/"+filename+".java");
168             new File(outf.getParent()).mkdirs();
169             System.err.println("writing to " + outf);
170             FileOutputStream out = new FileOutputStream(outf);
171             PrintWriter pw = new PrintWriter(out);
172
173             pw.println("package edu.berkeley.fleet.interpreter;");
174             pw.println("import edu.berkeley.sbp.util.ANSI;");
175             pw.println("import edu.berkeley.fleet.api.*;");
176             pw.println("import edu.berkeley.fleet.*;");
177             pw.println("import java.util.*;");
178             pw.println("import java.io.*;");
179             pw.println("");
180             pw.println("public class "+filename+" extends InterpreterShip {");
181             pw.println("");
182             for(BenkoBoxDescription b : sd) {
183                 String name = b.getName();
184                 pw.print("    ");
185                 if ( b.isInbox()) pw.print("Inbox");
186                 if (!b.isInbox()) pw.print("Outbox");
187                 pw.print(" box_");
188                 pw.print(name);
189                 pw.print(" = new ");
190                 if ( b.isInbox()) pw.print("Inbox");
191                 if (!b.isInbox()) pw.print("Outbox");
192                 pw.print("(this, \""+name+"\", new String[] { ");
193                 boolean first = true;
194                 for(String destination : b) {
195                     if (!first) pw.print(", ");
196                     first = false;
197                     pw.print("\""+destination+"\"");
198                 }
199                 pw.println("});");
200             }
201             pw.println("");
202             pw.println("    public "+filename+"(Interpreter fleet, String name) {");
203             pw.println("       super(fleet, name, \""+filename+"\");");
204             for(BenkoBoxDescription b : sd)
205                 pw.println("       addBenkoBox(\""+b.getName()+"\", box_"+b.getName()+");");
206             pw.println("    }");
207             pw.println("");
208             pw.println(sd.getSection("fleeterpreter"));
209             pw.println("}");
210             pw.flush();
211             pw.close();
212         } catch (Exception e) { throw new RuntimeException(e); }
213     }
214
215 }
216