1 package edu.berkeley.fleet.interpreter;
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 import edu.berkeley.fleet.interpreter.ships.*;
13 public class Interpreter extends Fleet {
15 /** some "halt ship" can turn this on to stop the interpreter */
16 public boolean halt = false;
17 public ArrayList<InterpreterShip> shiplist = new ArrayList<InterpreterShip>();
18 public HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
19 private BlockingQueue<Long> debugStream = new LinkedBlockingQueue<Long>();
20 public int[] mem = new int[0];
23 public void debug(long data) {
25 if (debugStream != null) {
26 debugStream.put(data);
28 Log.println(ANSI.invert(" DEBUG: got a datum: " + data+ANSI.clreol()));
30 } catch (Exception e) {
31 throw new RuntimeException(e);
35 public static class DynamicInterpreter extends Interpreter implements Fleet.WithDynamicShips {
38 public void expand(ShipDescription sd) {
40 String filename = (sd.name.charAt(0)+"").toUpperCase() + sd.name.substring(1).toLowerCase();
41 File outf = new File("build/java/edu/berkeley/fleet/interpreter/ships/"+filename+".java");
42 new File(outf.getParent()).mkdirs();
43 System.err.println("writing to " + outf);
44 FileOutputStream out = new FileOutputStream(outf);
45 PrintWriter pw = new PrintWriter(out);
47 pw.println("package edu.berkeley.fleet.interpreter.ships;");
48 pw.println("import edu.berkeley.sbp.util.ANSI;");
49 pw.println("import edu.berkeley.fleet.interpreter.*;");
50 pw.println("import edu.berkeley.fleet.api.*;");
51 pw.println("import edu.berkeley.fleet.*;");
52 pw.println("import java.util.*;");
53 pw.println("import java.io.*;");
55 pw.println("public class "+filename+" extends InterpreterShip {");
57 for(ShipDescription.BenkoBox b : sd.benkoBoxes) {
58 if (b.ports.length != 1)
59 throw new RuntimeException("multiple ports not supported");
60 String name = b.ports[0];
62 if (!b.tokenOnly && b.inbox) pw.print("DataInbox");
63 if ( b.tokenOnly && b.inbox) pw.print("TokenInbox");
64 if (!b.tokenOnly && !b.inbox) pw.print("DataOutbox");
65 if ( b.tokenOnly && !b.inbox) pw.print("TokenOutbox");
69 if (!b.tokenOnly && b.inbox) pw.print("DataInbox");
70 if ( b.tokenOnly && b.inbox) pw.print("TokenInbox");
71 if (!b.tokenOnly && !b.inbox) pw.print("DataOutbox");
72 if ( b.tokenOnly && !b.inbox) pw.print("TokenOutbox");
73 pw.println("(this, \""+name+"\");");
76 pw.println(" public "+filename+"(Interpreter fleet, String name) { super(fleet, name); }");
78 //pw.println(" public void service() {");
79 pw.println(sd.sections.get("fleeterpreter"));
84 } catch (Exception e) { throw new RuntimeException(e); }
87 public FleetProcess run(final byte[] instructions) {
89 final FleetProcess fp = new FleetProcess() {
90 public void invokeInstruction(Instruction i) { throw new RuntimeException("not supported"); }
91 public long readWord() {
93 return debugStream.take();
94 } catch (Exception e) {
95 throw new RuntimeException(e);
97 protected void _terminate() {
98 shiplist = new ArrayList<InterpreterShip>();
99 ships = new HashMap<String,InterpreterShip>();
100 debugStream = new LinkedBlockingQueue<Long>();
107 go(fp, instructions);
108 } catch (Exception e) {
109 if (fp.isTerminated()) return;
110 throw new RuntimeException(e);
115 } catch (Exception e) {
116 throw new RuntimeException(e);
120 public void go(FleetProcess fp, byte[] instructions) {
122 // find the first icache
123 InterpreterShip iscratch = null;
124 for(Ship ship : this)
125 if (ship.getClass().getSimpleName().equals("Iscratch")) {
126 iscratch = (InterpreterShip)ship;
130 iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.ships.Iscratch")
131 .getConstructor(new Class[] { Interpreter.class, String.class })
132 .newInstance(new Object[] { this, "iscratch" });
135 .getMethod("boot", new Class[] { byte[].class })
136 .invoke(iscratch, new Object[] { instructions });
138 while(!halt && !fp.isTerminated())
139 for(InterpreterShip ship : ships.values())
140 for(int j=0; j<10; j++)
143 // run the ships a bit longer for good measure
144 for(int i=0; i<100; i++)
145 for(InterpreterShip ship : ships.values())
146 for(int j=0; j<10; j++)
149 // check the state of the ships
150 for(InterpreterShip ship : ships.values())
153 Log.println(ANSI.yellow(" DONE: ====== FLEET is halted. Have a nice day. ======"));
154 } catch (Exception e) {
155 throw new RuntimeException(e);
159 public void dispatch(Instruction i, long address) {
161 if (i instanceof Instruction.Executable) {
162 InterpreterBenkoBox sourceBenkoBox = (InterpreterBenkoBox)(((Instruction.Executable)i).benkoBox);
163 ((InstructionPort)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
165 } else if (i instanceof Instruction.Literal.CodeBagDescriptor) {
166 Instruction.Literal.CodeBagDescriptor cbd = (Instruction.Literal.CodeBagDescriptor)i;
167 InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(cbd.dest);
168 long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
169 destBenkoBox.addDataFromFabric((int)absolute_cbd);
171 } else if (i instanceof Instruction.Literal.Absolute) {
172 InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(((Instruction.Literal.Absolute)i).dest);
173 Log.data(((Instruction.Literal.Absolute)i).value+"", null, destBenkoBox);
174 destBenkoBox.addDataFromFabric((int)((Instruction.Literal.Absolute)i).value);
176 } else if (i instanceof Instruction.Kill) {
177 InterpreterBenkoBox benkoBox = (InterpreterBenkoBox)(((Instruction.Kill)i).benkoBox);
178 ((InstructionPort)benkoBox).kill(((Instruction.Kill)i).count,
179 ((Instruction.Kill)i).killOnlyStandingInstructions);
182 throw new Error("unsupported: " + i.getClass().getName());
186 public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) {
187 Log.token(source, dest);
188 dest.addTokenFromFabric();
191 public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) {
192 Log.data(data+"", source, dest);
193 dest.addDataFromFabric(data);
197 // Implementation of the Fleet class abstract methods /////////////////////////////////////////////////////////
199 public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)shiplist.iterator(); }
201 public int computeOffset(int origin, int target) { return (target - origin)/6; }
202 public int computeTarget(int origin, int offset) { return origin + (offset*6); }
204 private InterpreterInstructionEncoder iie = new InterpreterInstructionEncoder();
205 public Instruction readInstruction(DataInputStream is) throws IOException { return iie.readInstruction(is); }
206 public Instruction readInstruction(long instr) { return iie.readInstruction(instr); }
207 public long writeInstruction(Instruction d) { return writeInstruction(d); }
208 public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { iie.writeInstruction(os, d); }
210 private class InterpreterInstructionEncoder extends InstructionEncoder {
211 public long getBoxAddr(Destination box) { return ((InterpreterBenkoBox)box).addr; }
212 public long getBoxInstAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).instr_addr; }
213 public BenkoBox getBoxByAddr(long dest) {
214 for(Ship ship : Interpreter.this)
215 for(BenkoBox bb : ship.getBenkoBoxes())
216 if (((InterpreterBenkoBox)bb).addr == dest)
220 public BenkoBox getBoxByInstAddr(long dest) {
221 for(Ship ship : Interpreter.this)
222 for(BenkoBox bb : ship.getBenkoBoxes())
223 if (((InterpreterBenkoBox)bb).instr_addr == dest)
229 public Ship createShip(String shipType, String shipname) {
231 Class c = Class.forName("edu.berkeley.fleet.interpreter.ships."+shipType);
232 Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
233 InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
234 ships.put(shipname, ret);
237 } catch (Exception e) {