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