Package erjang.beam.repr

Source Code of erjang.beam.repr.Operands$XReg

/** -*- tab-width: 4 -*-
* This file is part of Erjang - A JVM-based Erlang VM
*
* Copyright (c) 2010 by Trifork
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/

package erjang.beam.repr;

import erjang.EObject;
import erjang.EAtom;
import erjang.ESmall;
import erjang.EBig;
import erjang.EDouble;
import erjang.ETuple;
import erjang.ESeq;
import erjang.EString;
import erjang.EBitString;
import erjang.ERT;

import java.util.ArrayList;
import java.math.BigInteger;

import static erjang.beam.CodeAtoms.*;

public class Operands {

    public static abstract class Operand {
    public SourceOperand asSource() {
      throw new IllegalArgumentException("Not a source: "+this);
    }
    public DestinationOperand asDestination() {
      throw new IllegalArgumentException("Not a destination: "+this);
    }
    public Label asLabel() {
      throw new IllegalArgumentException("Not a label: "+this);
    }
    public Literal asLiteral() {
      throw new IllegalArgumentException("Not a literal: "+this);
    }
    public Atom asAtom() {
      throw new IllegalArgumentException("Not an atom: "+this);
    }
    public CodeInt asCodeInt() {
      throw new IllegalArgumentException("Not a code integer: "+this);
    }
    public SelectList asSelectList() {
      throw new IllegalArgumentException("Not a select list: "+this);
    }
    public AllocList asAllocList() {
      throw new IllegalArgumentException("Not an alloc list: "+this);
    }
    public YReg asYReg() {
      throw new IllegalArgumentException("Not a Y register: "+this);
    }

    public TableLiteral testTableLiteral() { return null; }
    public Atom testAtom() { return null; }
    public Int testInt() { return null; }
    public BigInt testBigInt() { return null; }
    public Float testFloat() { return null; }
    public SelectList testSelectList() { return null; }
    public AllocList testAllocList() { return null; }
    public DestinationOperand testDestination() {return null;}
    public XReg testXReg() { return null; }
    public YReg testYReg() { return null; }
    public FReg testFReg() { return null; }

    public abstract EObject toSymbolic();
    }

  public static ESeq toSymbolicList(Operand[] args) {
    ESeq res = ERT.NIL;
    for (int i = args.length-1; i >= 0; i--) {
      res = res.cons(args[i].toSymbolic());
    }
    return res;
  }

    public static abstract class SourceOperand extends Operand {
    @Override
    public SourceOperand asSource() {return this;}
    }
    public static abstract class DestinationOperand extends SourceOperand {
    @Override
    public DestinationOperand asDestination() {return this;}
    @Override
    public DestinationOperand testDestination() {return this;}
    }
    public static abstract class Literal extends SourceOperand {
    @Override
    public Literal asLiteral() {return this;}
    public abstract EObject literalValue();
    }

    public static Literal makeInt(byte[] d) {
    BigInteger tmp = new BigInteger(d);
    return (d.length<=4)
      ? new Int(tmp.intValue())
      : new BigInt(tmp);
    }

    /** CodeInt is present in jump-table-by-arity (select_arity). */
    public static class CodeInt extends Operand {
    public final int value;
    public CodeInt(int value) {this.value=value;}

    @Override
    public CodeInt asCodeInt() {return this;}

    public EObject toSymbolic() {
      return new ESmall(value);
    }
    }

    public static class Int extends Literal {
    public final int value;
    public Int(int value) {this.value=value;}

    public boolean equals(int val) { return value == val; }
   
    @Override
    public Int testInt() {return this;}

    @Override
    public EObject literalValue() {return new ESmall(value);}

    public EObject toSymbolic() {
      return ETuple.make(INTEGER_ATOM, new ESmall(value));
    }
    }

    public static class BigInt extends Literal {
    public final BigInteger value;
    public BigInt(BigInteger value) {this.value=value;}

    @Override
    public BigInt testBigInt() {return this;}

    @Override
    public EObject literalValue() {return new EBig(value);}

    public EObject toSymbolic() {
      return ETuple.make(INTEGER_ATOM, new EBig(value));
    }
    }

    public static class Float extends Literal {
    public final double value;
    public Float(double value) {this.value=value;}

    @Override
    public Float testFloat() {return this;}

    @Override
    public EObject literalValue() {return new EDouble(value);}

    public EObject toSymbolic() {
      return ETuple.make(FLOAT_ATOM, new EDouble(value));
    }
    }

    public static final Nil Nil = new Nil();
    public static class Nil extends Literal {
    private Nil() {}

    @Override
    public EObject literalValue() {return ERT.NIL;}

    public EObject toSymbolic() {return NIL_ATOM;}
    }

    public static class SelectList extends Operand {
    Operand[] list;
    public SelectList(Operand[] list) {this.list=list;}

    @Override
    public SelectList asSelectList() {return this;}

    public int size() {return list.length / 2;}
    public Operand getValue(int i) {return list[2*i];}
    public Label getLabel(int i)   {return (Label)list[2*i+1];}

    public EObject toSymbolic() {
      EObject[] elems = new EObject[list.length];
      for (int i=0; i<list.length; i++) {
        elems[i] = list[i].toSymbolic();
      }
      return ETuple.make(LIST_ATOM, ESeq.fromArray(elems));
    }
    }

    public static class AllocList extends Operand {
    static final int WORDS  = 0;
    static final int FLOATS = 1;

    int[] list;
    public AllocList(int[] list) {this.list=list;}
    public AllocList(int words) {
      list=new int[2];
      list[0] = WORDS;
      list[1] = words;
    }

    @Override
    public AllocList asAllocList() {return this;}
    public EObject toSymbolic() {
      int len = list.length/2;

      if (len==1 && list[0] == WORDS)
        return new ESmall(list[1]); // Just words.

      EObject[] elems = new EObject[len];
      for (int i=0; i<len; i++) {
        elems[i] = ETuple.make(kindToSymbolic(list[2*i]),
                     new ESmall(list[2*i+1]));
      }
      return ETuple.make(ALLOC_ATOM, ESeq.fromArray(elems));
    }
    protected EAtom kindToSymbolic(int kind) {
      switch (kind) {
      case WORDS:  return WORDS_ATOM;
      case FLOATS: return FLOATS_ATOM;
      default:
        throw new IllegalArgumentException("Unknown alloc kind: "+kind);
      } // switch
    }
    }


    public static class Atom extends Literal {
    private EAtom value;
    public Atom(EAtom value) {this.value=value;}

    @Override
    public Atom asAtom() {return this;}

    @Override
    public Atom testAtom() {return this;}

    @Override
    public EObject literalValue() {return value;}

    public EAtom getEAtom() {return value;}
    public EObject toSymbolic() {
      return ETuple.make(ATOM_ATOM, value);
    }
   
    @Override
    public String toString() {
      return "atom:" + value.toString();
    }
    }

    public static class BitString extends Literal {
    public  final EBitString value;
    public BitString(EBitString value) {
      this.value = value;
    }

    @Override
    public EObject literalValue() {return value;}

    public long bitLength() {return value.bitSize();}

    @Override
    public EObject toSymbolic() {
      return value; // OBS: beam_disasm round up to nearest byte.
    }
    }

    public static class ByteString extends Literal {
    public final EString value;
    public ByteString(EString value) {
      this.value = value;
    }

    @Override
    public EObject literalValue() {return value;}

    public int byteLength() {return value.length();}

    @Override
    public EObject toSymbolic() {
      return ETuple.make(STRING_ATOM, value);
    }
    }

    public static class TableLiteral extends Literal {
    public final EObject value;
    public TableLiteral(EObject value) {this.value=value;}

    @Override
    public EObject literalValue() {return value;}

    @Override
    public TableLiteral testTableLiteral() {return this;}

    public EObject toSymbolic() {
      return ETuple.make(LITERAL_ATOM, value);
    }
    }

    public static class Label extends Operand {
    public final int nr;
    public Label(int nr) {this.nr=nr;}
    @Override
    public Label asLabel() {return this;}

    public EObject toSymbolic() {
      return ETuple.make(F_ATOM, new ESmall(nr));
    }
   
    @Override
    public int hashCode() {
      return nr;
    }
   
    @Override
    public boolean equals(Object obj) {
      if (obj instanceof Label) {
        Label lab = (Label) obj;
        return lab.nr == nr;
      } else {
        return false;
      }
    }
    }

    public static class XReg extends DestinationOperand {
    public final int nr;
    public XReg(int nr) {this.nr=nr;}

    @Override
    public XReg testXReg() {return this;}

    private static ArrayList<XReg> cache = new ArrayList<XReg>();
    public static XReg get(int nr) {
      while (cache.size() <= nr) {
        cache.add(new XReg(cache.size()));
      }
      return cache.get(nr);
    }

    public EObject toSymbolic() {
      return ETuple.make(X_ATOM, new ESmall(nr));
    }
    }

    public static class YReg extends DestinationOperand {
    public final int nr;
    public YReg(int nr) {this.nr=nr;}

    @Override
    public YReg asYReg() {return this;}
    @Override
    public YReg testYReg() {return this;}

    private static ArrayList<YReg> cache = new ArrayList<YReg>();
    public static YReg get(int nr) {
      while (cache.size() <= nr) {
        cache.add(new YReg(cache.size()));
      }
      return cache.get(nr);
    }

    public EObject toSymbolic() {
      return ETuple.make(Y_ATOM, new ESmall(nr));
    }
    }

    public static class FReg extends DestinationOperand {
    public final int nr;
    public FReg(int nr) {this.nr=nr;}

    @Override
    public FReg testFReg() {return this;}

    private static ArrayList<FReg> cache = new ArrayList<FReg>();
    public static FReg get(int nr) {
      while (cache.size() <= nr) {
        cache.add(new FReg(cache.size()));
      }
      return cache.get(nr);
    }

    public EObject toSymbolic() {
      return ETuple.make(FR_ATOM, new ESmall(nr));
    }
    }

}
TOP

Related Classes of erjang.beam.repr.Operands$XReg

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.