Package org.jakstab.analysis.explicit

Source Code of org.jakstab.analysis.explicit.NumberElement

/*
* NumberElement.java - This file is part of the Jakstab project.
* Copyright 2007-2012 Johannes Kinder <jk@jakstab.org>
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, see <http://www.gnu.org/licenses/>.
*/
package org.jakstab.analysis.explicit;

import java.util.Collections;
import java.util.Set;

import org.jakstab.analysis.AbstractValue;
import org.jakstab.analysis.LatticeElement;
import org.jakstab.rtl.BitVectorType;
import org.jakstab.rtl.expressions.ExpressionFactory;
import org.jakstab.rtl.expressions.RTLNumber;
import org.jakstab.util.*;

/**
* @author Johannes Kinder
*/
public class NumberElement implements AbstractValue, BitVectorType {

  @SuppressWarnings("unused")
  private static final Logger logger = Logger.getLogger(NumberElement.class);
 
  public static final NumberElement TRUE = new NumberElement(ExpressionFactory.TRUE);
  public static final NumberElement FALSE = new NumberElement(ExpressionFactory.FALSE);
 
  private static NumberElement[] TOPS = new NumberElement[128];
  static {
    for (int bitWidth = 1; bitWidth <= 128; bitWidth++) {
      TOPS[bitWidth - 1] = new NumberElement(ExpressionFactory.createNumber(bitWidth - 1, bitWidth));
    }
  }
 
  public static NumberElement getTop(int bitWidth) {
    return TOPS[bitWidth - 1];
  }

  private final RTLNumber value;
 
  public NumberElement(RTLNumber v) {
    this.value = v;
    assert v.getBitWidth() > 0 : "Cannot create number element for " + v + " with unknown bitwidth!";
    assert value != null;
  }
 
  public RTLNumber getNumber() {
    assert !isTop() : "Attempting to get value of a TOP NumberElement!";
    return value;
  }
 
  @Override
  public Set<RTLNumber> concretize() {
    if (isTop()) {
      // Enumerate small bitwidths
      if (getBitWidth() == 1) {
        Set<RTLNumber> result = new FastSet<RTLNumber>();
        result.add(ExpressionFactory.TRUE);
        result.add(ExpressionFactory.FALSE);
        return result;
      } else {
        return RTLNumber.ALL_NUMBERS;
      }
    }
    return Collections.singleton(value);
  }

  @Override
  public boolean isBot() {
    return false;
  }

  @Override
  public boolean isTop() {
    return this == getTop(getBitWidth());
  }
 
  @Override
  public int getBitWidth() {
    return value.getBitWidth();
  }

  @Override
  public NumberElement join(LatticeElement l) {
    NumberElement other = (NumberElement)l;

    // Can happen for memory cells at same offset but of different size
    //assert other.getBitWidth() == this.getBitWidth() : "Trying to join numberelements of different bitwidth: " + other + " and " + this;
    if (other.getBitWidth() > this.getBitWidth()) return getTop(other.getBitWidth());
    if (this.getBitWidth() > other.getBitWidth()) return getTop(this.getBitWidth());
    if (l.isTop() || isTop()) return getTop(getBitWidth());
   
    RTLNumber c = other.value;
    if (c.equals(value)) return this;
    else return getTop(getBitWidth());
  }

  @Override
  public boolean lessOrEqual(LatticeElement l) {
    return l.isTop() || equals(l);
  }
 
  @Override
  public boolean equals(Object obj) {
    if (obj == this) return true;
    if (!(obj instanceof NumberElement)) return false;
    NumberElement other = (NumberElement)obj;
    if (getBitWidth() != other.getBitWidth()) return false;
    if (isTop()) return other.isTop();
    return other.value.equals(this.value);
  }

  @Override
  public int hashCode() {
    return value.intValue();
    // intValue is slightly faster than hashCode - and this is a hotspot
    //return value.hashCode();
  }

  @Override
  public String toString() {
    if (isTop()) return Characters.TOP + "<" + getBitWidth() + ">";
    else return value.toString();
  }

  @Override
  public boolean hasUniqueConcretization() {
    return !isTop() && !isBot();
  }
}
TOP

Related Classes of org.jakstab.analysis.explicit.NumberElement

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.