IRReaderFile.java

  1. /*
  2.  * To change this license header, choose License Headers in Project Properties.
  3.  * To change this template file, choose Tools | Templates
  4.  * and open the template in the editor.
  5.  */

  6. package org.jruby.ir.persistence;

  7. import org.jruby.RubyInstanceConfig;
  8. import org.jruby.ir.IRManager;
  9. import org.jruby.ir.IRScope;
  10. import org.jruby.ir.IRScopeType;
  11. import org.jruby.ir.Operation;
  12. import org.jruby.ir.instructions.Instr;
  13. import org.jruby.ir.operands.Operand;
  14. import org.jruby.ir.operands.OperandType;
  15. import org.jruby.ir.operands.TemporaryVariableType;
  16. import org.jruby.ir.operands.Variable;
  17. import org.jruby.parser.StaticScope;

  18. import java.io.File;
  19. import java.io.FileInputStream;
  20. import java.io.IOException;
  21. import java.nio.ByteBuffer;
  22. import java.nio.channels.FileChannel;
  23. import java.util.ArrayList;
  24. import java.util.HashMap;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.logging.Level;
  28. import java.util.logging.Logger;

  29. /**
  30.  *
  31.  * @author enebo
  32.  */
  33. public class IRReaderFile implements IRReaderDecoder, IRPersistenceValues {
  34.     private ByteBuffer buf;
  35.     private final InstrDecoderMap instrDecoderMap;
  36.     private final OperandDecoderMap operandDecoderMap;
  37.     private final List<IRScope> scopes = new ArrayList<IRScope>();
  38.     private IRScope currentScope = null; // FIXME: This is not thread-safe and more than a little gross

  39.     public IRReaderFile(IRManager manager, File file) {
  40.         try {
  41.             byte[] bytes = new byte[(int)file.length()];
  42.             if (RubyInstanceConfig.IR_READING_DEBUG) System.out.println("READING IN " + bytes.length + " BYTES OF DATA FROM " + file);
  43.             ByteBuffer buffer = ByteBuffer.wrap(bytes);
  44.             FileInputStream fis = new FileInputStream(file);
  45.             FileChannel fc = fis.getChannel();
  46.             fc.read(buffer);
  47.             fis.close();
  48.             buf = ByteBuffer.wrap(bytes);
  49.         } catch (IOException ex) {
  50.             Logger.getLogger(IRReaderFile.class.getName()).log(Level.SEVERE, null, ex);

  51.         }

  52.         instrDecoderMap = new InstrDecoderMap(manager, this);
  53.         operandDecoderMap = new OperandDecoderMap(manager, this);
  54.     }

  55.     @Override
  56.     public String decodeString() {
  57.         int strLength = decodeInt();
  58.         byte[] bytes = new byte[strLength]; // FIXME: This seems really innefficient
  59.         buf.get(bytes);

  60.         String newString = new String(bytes).intern();

  61.         if (RubyInstanceConfig.IR_READING_DEBUG) System.out.println("STR<" + newString + ">");

  62.         return newString;
  63.     }

  64.     @Override
  65.     public void addScope(IRScope scope) {
  66.         scopes.add(scope);
  67.     }

  68.     @Override
  69.     public IRScope getCurrentScope() {
  70.         return currentScope;
  71.     }

  72.     @Override
  73.     public String[] decodeStringArray() {
  74.         int arrayLength = decodeInt();
  75.         String[] array = new String[arrayLength];
  76.         for (int i = 0; i < arrayLength; i++) {
  77.             array[i] = decodeString();
  78.         }
  79.         return array;
  80.     }

  81.     private Map<String, Operand> vars = null;

  82.     @Override
  83.     public Map<String, Operand> getVars() {
  84.         return vars;
  85.     }

  86.     @Override
  87.     public List<Instr> decodeInstructionsAt(IRScope scope, int offset) {
  88.         currentScope = scope;
  89.         vars = new HashMap<String, Operand>();
  90.         buf.position(offset);

  91.         int numberOfInstructions = decodeInt();
  92.         if (RubyInstanceConfig.IR_READING_DEBUG) System.out.println("Number of Instructions: " + numberOfInstructions);
  93.         List<Instr> instrs = new ArrayList(numberOfInstructions);

  94.         for (int i = 0; i < numberOfInstructions; i++) {
  95.             Instr decodedInstr = decodeInstr();

  96.             if (RubyInstanceConfig.IR_READING_DEBUG) System.out.println(">INSTR = " + decodedInstr);

  97.             instrs.add(decodedInstr);
  98.         }

  99.         return instrs;
  100.     }

  101.     @Override
  102.     public Instr decodeInstr() {
  103.         return instrDecoderMap.decode(decodeOperation());
  104.     }

  105.     @Override
  106.     public IRScopeType decodeIRScopeType() {
  107.         return IRScopeType.fromOrdinal(decodeInt());
  108.     }

  109.     @Override
  110.     public TemporaryVariableType decodeTemporaryVariableType() {
  111.         return TemporaryVariableType.fromOrdinal(decodeInt());
  112.     }

  113.     @Override
  114.     public StaticScope.Type decodeStaticScopeType() {
  115.         return StaticScope.Type.fromOrdinal(decodeInt());
  116.     }

  117.     @Override
  118.     public Operation decodeOperation() {
  119.         Operation operation = Operation.fromOrdinal(decodeInt());
  120.         if (RubyInstanceConfig.IR_READING_DEBUG) System.out.println("INSTR<" + operation);
  121.         return operation;
  122.     }

  123.     @Override
  124.     public Operand decodeOperand() {
  125.         OperandType operandType = decodeOperandType();

  126.         if (RubyInstanceConfig.IR_READING_DEBUG) System.out.println("OP<" + operandType);

  127.         Operand decodedOperand = operandDecoderMap.decode(operandType);

  128.         if (RubyInstanceConfig.IR_READING_DEBUG) System.out.println(">OP = " + decodedOperand);

  129.         return decodedOperand;
  130.     }

  131.     @Override
  132.     public Variable decodeVariable() {
  133.         return (Variable) decodeOperand();
  134.     }

  135.     @Override
  136.     public Operand[] decodeOperandArray() {
  137.         int size = decodeInt();
  138.         Operand[] list = new Operand[size];

  139.         for (int i = 0; i < size; i++) {
  140.             list[i] = decodeOperand();
  141.         }

  142.         return list;
  143.     }

  144.     @Override
  145.     public List<Operand> decodeOperandList() {
  146.         int size = decodeInt();
  147.         if (RubyInstanceConfig.IR_READING_DEBUG) System.out.println("OPERAND LIST of size: " + size);
  148.         List<Operand> list = new ArrayList<Operand>(size);

  149.         for (int i = 0; i < size; i++) {
  150.             if (RubyInstanceConfig.IR_READING_DEBUG) System.out.println("OPERAND #" + i);
  151.             list.add(decodeOperand());
  152.         }

  153.         return list;
  154.     }

  155.     @Override
  156.     public OperandType decodeOperandType() {
  157.         return OperandType.fromCoded(decodeByte());
  158.     }

  159.     @Override
  160.     public boolean decodeBoolean() {
  161.         byte value = buf.get();
  162.         if (value == TRUE) return true;
  163.         if (value == FALSE) return false;

  164.         throw new IllegalArgumentException("Value (" + ((int) value) + ", " + (char) value + ") is not a boolean.");
  165.     }

  166.     @Override
  167.     public byte decodeByte() {
  168.         return buf.get();
  169.     }

  170.     @Override
  171.     public char decodeChar() {
  172.         return buf.getChar();
  173.     }

  174.     @Override
  175.     public int decodeInt() {
  176.         byte b = buf.get();
  177.         return b == FULL ? buf.getInt() : (int) b;
  178.     }

  179.     @Override
  180.     public int decodeIntRaw() {
  181.         return buf.getInt();
  182.     }

  183.     @Override
  184.     public long decodeLong() {
  185.         byte b = buf.get();
  186.         return b == FULL ? buf.getLong() : (int) b;
  187.     }

  188.     @Override
  189.     public double decodeDouble() {
  190.         return buf.getDouble();
  191.     }

  192.     @Override
  193.     public float decodeFloat() {
  194.         return buf.getFloat();
  195.     }

  196.     @Override
  197.     public IRScope decodeScope() {
  198.         return scopes.get(decodeInt());
  199.     }

  200.     @Override
  201.     public void seek(int headersOffset) {
  202.         buf.position(headersOffset);
  203.     }
  204. }