2e934a375a063b46f3d09782b6aac46ca6737486
[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.lang.reflect.*;
5 import edu.berkeley.fleet.*;
6 import edu.berkeley.fleet.api.*;
7 import edu.berkeley.fleet.ies44.*;
8 import edu.berkeley.fleet.ships.*;
9
10 public class Interpreter extends Fleet /*, Fleet.WithDynamicShips*/ {
11
12     /** some "halt ship" can turn this on to stop the interpreter */
13     public boolean       halt         = false;
14
15     public ArrayList<InterpreterShip> shiplist   = new ArrayList<InterpreterShip>();
16     public HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
17
18     public void go(byte[] instructions) {
19
20         // find the first icache
21         Icache icache = null;
22         for(Ship ship : this)
23             if (ship instanceof Icache) {
24                 icache = (Icache)ship;
25                 break;
26             }
27
28         // load the icache and take note of the 0-address CBD
29         long launch = 0;
30         for(int i=0; i<instructions.length; i+=6) {
31             long word = 0;
32             for(int j=0; j<6; j++)
33                 word = (word << 8) | (instructions[i+j] & 0xff);
34             icache.writeMem(i/6, word);
35             if (i==0) launch = word;
36         }
37
38         // dispatch the 0-address CBD
39         int base = (int)(launch >> 6);
40         base = base & ~(0xffffffff << 18);
41         int size = (int)launch;
42         size = size & ~(0xffffffff <<  6);
43         icache.dispatch(base, size);
44
45         while(!halt)
46             for(InterpreterShip ship : ships.values())
47                 for(int j=0; j<10; j++)
48                     ship._service();
49
50         // run the ships a bit longer for good measure
51         for(int i=0; i<100; i++)
52             for(InterpreterShip ship : ships.values())
53                 for(int j=0; j<10; j++)
54                     ship._service();
55
56         // check the state of the ships
57         for(InterpreterShip ship : ships.values())
58             ship.shutdown();
59
60         Log.println(Log.yellow("    DONE: ====== FLEET is halted.  Have a nice day.  ======"));
61     }
62
63     public void dispatch(Instruction i, long address) {
64         Log.dispatch(i);
65         if (i instanceof Instruction.Executable) {
66             InterpreterBenkoBox sourceBenkoBox = (InterpreterBenkoBox)(((Instruction.Executable)i).benkoBox);
67             ((InstructionPort)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
68
69         } else if (i instanceof Instruction.Literal.CodeBagDescriptor) {
70             Instruction.Literal.CodeBagDescriptor cbd = (Instruction.Literal.CodeBagDescriptor)i;
71             InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(cbd.dest);
72             long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
73             destBenkoBox.addDataFromFabric((int)absolute_cbd);
74             
75         } else if (i instanceof Instruction.Literal.Absolute) {
76             InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(((Instruction.Literal.Absolute)i).dest);
77             Log.data(((Instruction.Literal.Absolute)i).value+"", null, destBenkoBox);
78             destBenkoBox.addDataFromFabric((int)((Instruction.Literal.Absolute)i).value);
79
80         } else if (i instanceof Instruction.Kill) {
81             InterpreterBenkoBox benkoBox = (InterpreterBenkoBox)(((Instruction.Kill)i).benkoBox);
82             ((InstructionPort)benkoBox).kill(((Instruction.Kill)i).count);
83
84         } else {
85             throw new Error("unsupported: " + i.getClass().getName());
86         }
87     }
88
89     public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) {
90         Log.token(source, dest);
91         dest.addTokenFromFabric();
92     }
93
94     public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) {
95         Log.data(data+"", source, dest);
96         dest.addDataFromFabric(data);
97     }
98
99
100     // Implementation of the Fleet class abstract methods /////////////////////////////////////////////////////////
101
102     public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)shiplist.iterator(); }
103
104     public int computeOffset(int origin, int target) { return (target - origin)/6; }
105     public int computeTarget(int origin, int offset) { return origin + (offset*6); }
106
107     private InterpreterInstructionEncoder iie = new InterpreterInstructionEncoder();
108     public Instruction readInstruction(DataInputStream is) throws IOException { return iie.readInstruction(is); }
109     public Instruction readInstruction(long instr) { return iie.readInstruction(instr); }
110     public long writeInstruction(Instruction d) { return writeInstruction(d); }
111     public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { iie.writeInstruction(os, d); }
112
113     private class InterpreterInstructionEncoder extends InstructionEncoder {
114         public long getBoxAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).addr; }
115         public long getBoxInstAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).instr_addr; }
116         public BenkoBox getBoxByAddr(long dest) {
117             for(Ship ship : Interpreter.this)
118                 for(BenkoBox bb : ship.getBenkoBoxes())
119                     if (((InterpreterBenkoBox)bb).addr == dest)
120                         return bb;
121             return null;
122         }
123         public BenkoBox getBoxByInstAddr(long dest) {
124             for(Ship ship : Interpreter.this)
125                 for(BenkoBox bb : ship.getBenkoBoxes())
126                     if (((InterpreterBenkoBox)bb).instr_addr == dest)
127                         return bb;
128             return null;
129         }
130     }
131
132     public Ship createShip(String shipType, String shipname) {
133         try {
134             Class c = Class.forName("edu.berkeley.fleet.ships."+shipType);
135             Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
136             InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
137             ships.put(shipname, ret);
138             shiplist.add(ret);
139             return ret;
140         } catch (Exception e) {
141             return null;
142         }
143     }
144
145
146     // Memory //////////////////////////////////////////////////////////////////////////////
147
148     public int[] mem = new int[0];
149
150     public void dumpMem() {
151         Log.print(Log.cyan("  MEMORY: "));
152         for(int i=0; i<mem.length; i++) {
153             if ((i%10)==0 && i!=0) Log.print(Log.cyan("          "));
154             Log.print(Log.cyan(mem[i] + " "));
155             if ((i%10)==9 && i!=mem.length-1) Log.println("");
156         }
157         Log.println();
158     }
159
160     public int readMem(int addr) {
161         return addr >= mem.length ? 0 : mem[addr];
162     }
163     public void writeMem(int addr, int data) {
164         if (addr >= mem.length) {
165             int[] mem2 = new int[addr*2+1];
166             System.arraycopy(mem, 0, mem2, 0, mem2.length);
167             mem = mem2;
168         }
169         mem[addr] = data;
170     }
171
172
173 }
174