blob: 5b619b8b04039f02c187a7751a91f10359d208bd [file] [log] [blame]
//===-- ClassFile.h - ClassFile support library -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the ClassFile and subordinate
// classes, which represent a parsed class file.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_JAVA_CLASSFILE_H
#define LLVM_JAVA_CLASSFILE_H
#include <iosfwd>
#include <map>
#include <stdexcept>
#include <vector>
#include <stdint.h>
namespace llvm { namespace Java {
// Forward declarations
class Attribute;
class ConstantValueAttribute;
class CodeAttribute;
class ExceptionsAttribute;
class Constant;
class ConstantClass;
class ConstantFieldRef;
class ConstantInterfaceMethodRef;
class ConstantMethodRef;
class ConstantNameAndType;
class ConstantUtf8;
class ClassFile;
class Field;
class Method;
enum AccessFlag {
ACC_PUBLIC = 0x0001,
ACC_PRIVATE = 0x0002,
ACC_PROTECTED = 0x0004,
ACC_STATIC = 0x0008,
ACC_FINAL = 0x0010,
ACC_SUPER = 0x0020,
ACC_SYNCHRONIZED = 0x0020,
ACC_VOLATILE = 0x0040,
ACC_TRANSIENT = 0x0080,
ACC_NATIVE = 0x0100,
ACC_INTERFACE = 0x0200,
ACC_ABSTRACT = 0x0400,
ACC_STRICT = 0x0800,
};
typedef std::vector<Constant*> ConstantPool;
typedef std::vector<ConstantClass*> Classes;
typedef std::vector<Field*> Fields;
typedef std::vector<Method*> Methods;
typedef std::vector<Attribute*> Attributes;
Attribute* getAttribute(const Attributes& attrs,
const std::string& name);
class ClassFile {
static ClassFile* readClassFile(std::istream& is);
static std::vector<std::string> getClassPath();
static std::string getFileForClass(const std::string& classname);
typedef std::map<std::string, Method*> Name2MethodMap;
public:
static ClassFile* get(const std::string& classname);
~ClassFile();
uint16_t getMinorVersion() const { return minorV_; }
uint16_t getMajorVersion() const { return majorV_; }
Constant* getConstant(unsigned index) const { return cPool_[index]; }
ConstantClass* getConstantClass(unsigned index) const;
ConstantFieldRef* getConstantFieldRef(unsigned index) const;
ConstantMethodRef* getConstantMethodRef(unsigned index) const;
ConstantInterfaceMethodRef*
getConstantInterfaceMethodRef(unsigned index) const;
bool isPublic() const { return accessFlags_ & ACC_PUBLIC; }
bool isFinal() const { return accessFlags_ & ACC_FINAL; }
bool isSuper() const { return accessFlags_ & ACC_SUPER; }
bool isInterface() const { return accessFlags_ & ACC_INTERFACE; }
bool isAbstract() const { return accessFlags_ & ACC_ABSTRACT; }
ConstantClass* getThisClass() const { return thisClass_; }
ConstantClass* getSuperClass() const { return superClass_; }
const Classes& getInterfaces() const { return interfaces_; }
const Fields& getFields() const { return fields_; }
const Methods& getMethods() const { return methods_; }
const Attributes& getAttributes() const { return attributes_; }
Method* getMethod(const std::string& nameAndDescr) const;
std::ostream& dump(std::ostream& os) const;
private:
uint16_t majorV_;
uint16_t minorV_;
ConstantPool cPool_;
uint16_t accessFlags_;
ConstantClass* thisClass_;
ConstantClass* superClass_;
Classes interfaces_;
Fields fields_;
Methods methods_;
Attributes attributes_;
Name2MethodMap n2mMap_;
ClassFile(std::istream& is);
};
inline std::ostream& operator<<(std::ostream& os, const ClassFile& c) {
return c.dump(os);
}
class Constant {
protected:
const ConstantPool& cPool_;
Constant(const ConstantPool& cp)
: cPool_(cp) { }
public:
enum Tag {
CLASS = 7,
FIELD_REF = 9,
METHOD_REF = 10,
INTERFACE_METHOD_REF = 11,
STRING = 8,
INTEGER = 3,
FLOAT = 4,
LONG = 5,
DOUBLE = 6,
NAME_AND_TYPE = 12,
UTF8 = 1
};
static Constant* readConstant(const ConstantPool& cp,
std::istream& is);
virtual bool isSingleSlot() { return true; }
bool isDoubleSlot() { return !isSingleSlot(); }
virtual ~Constant();
virtual std::ostream& dump(std::ostream& os) const = 0;
};
inline std::ostream& operator<<(std::ostream& os, const Constant& c) {
return c.dump(os);
}
class ConstantClass : public Constant {
uint16_t nameIdx_;
public:
ConstantClass(const ConstantPool& cp, std::istream& is);
ConstantUtf8* getName() const {
return (ConstantUtf8*) cPool_[nameIdx_];
}
std::ostream& dump(std::ostream& os) const;
};
class ConstantMemberRef : public Constant {
uint16_t classIdx_;
uint16_t nameAndTypeIdx_;
protected:
ConstantMemberRef(const ConstantPool& cp, std::istream& is);
public:
ConstantClass* getClass() const {
return (ConstantClass*) cPool_[classIdx_];
}
ConstantNameAndType* getNameAndType() const {
return (ConstantNameAndType*) cPool_[nameAndTypeIdx_];
}
std::ostream& dump(std::ostream& os) const;
};
struct ConstantFieldRef : public ConstantMemberRef {
ConstantFieldRef(const ConstantPool& cp, std::istream& is)
: ConstantMemberRef(cp, is) { }
};
struct ConstantMethodRef : public ConstantMemberRef {
ConstantMethodRef(const ConstantPool& cp, std::istream& is)
: ConstantMemberRef(cp, is) { }
};
struct ConstantInterfaceMethodRef : public ConstantMemberRef {
ConstantInterfaceMethodRef(const ConstantPool& cp, std::istream& is)
: ConstantMemberRef(cp, is) { }
};
class ConstantString : public Constant {
uint16_t stringIdx_;
public:
ConstantString(const ConstantPool& cp, std::istream& is);
ConstantUtf8* getValue() const {
return (ConstantUtf8*) cPool_[stringIdx_];
}
std::ostream& dump(std::ostream& os) const;
};
class ConstantInteger : public Constant {
int32_t value_;
public:
ConstantInteger(const ConstantPool& cp, std::istream& is);
int32_t getValue() const { return value_; }
std::ostream& dump(std::ostream& os) const;
};
class ConstantFloat : public Constant {
float value_;
public:
ConstantFloat(const ConstantPool& cp, std::istream& is);
float getValue() const { return value_; }
std::ostream& dump(std::ostream& os) const;
};
class ConstantLong : public Constant {
int64_t value_;
public:
ConstantLong(const ConstantPool& cp, std::istream& is);
virtual bool isSingleSlot() { return false; }
int64_t getValue() const { return value_; }
std::ostream& dump(std::ostream& os) const;
};
class ConstantDouble : public Constant {
double value_;
public:
ConstantDouble(const ConstantPool& cp, std::istream& is);
virtual bool isSingleSlot() { return false; }
double getValue() const { return value_; }
std::ostream& dump(std::ostream& os) const;
};
class ConstantNameAndType : public Constant {
uint16_t nameIdx_;
uint16_t descriptorIdx_;
public:
ConstantNameAndType(const ConstantPool& cp, std::istream& is);
ConstantUtf8* getName() const {
return (ConstantUtf8*) cPool_[nameIdx_];
}
ConstantUtf8* getDescriptor() const {
return (ConstantUtf8*) cPool_[descriptorIdx_];
}
std::ostream& dump(std::ostream& os) const;
};
class ConstantUtf8 : public Constant {
std::string utf8_;
public:
ConstantUtf8(const ConstantPool& cp, std::istream& is);
const std::string& str() const { return utf8_; }
std::ostream& dump(std::ostream& os) const;
};
class Field {
private:
ConstantClass* parent_;
uint16_t accessFlags_;
ConstantUtf8* name_;
ConstantUtf8* descriptor_;
Attributes attributes_;
Field(ConstantClass* parent, const ConstantPool& cp, std::istream& is);
public:
static Field* readField(ConstantClass* parent,
const ConstantPool& cp,
std::istream& is) {
return new Field(parent, cp, is);
}
~Field();
bool isPublic() const { return accessFlags_ & ACC_PUBLIC; }
bool isPrivate() const { return accessFlags_ & ACC_PRIVATE; }
bool isProtected() const { return accessFlags_ & ACC_PROTECTED; }
bool isStatic() const { return accessFlags_ & ACC_STATIC; }
bool isFinal() const { return accessFlags_ & ACC_FINAL; }
bool isVolatile() const { return accessFlags_ & ACC_VOLATILE; }
bool isTransient() const { return accessFlags_ & ACC_TRANSIENT; }
ConstantClass* getParent() const { return parent_; }
ConstantUtf8* getName() const { return name_; }
ConstantUtf8* getDescriptor() const { return descriptor_; }
const Attributes& getAttributes() const { return attributes_; }
ConstantValueAttribute* getConstantValueAttribute() const;
std::ostream& dump(std::ostream& os) const;
};
inline std::ostream& operator<<(std::ostream& os, const Field& f) {
return f.dump(os);
}
class Method {
ConstantClass* parent_;
uint16_t accessFlags_;
ConstantUtf8* name_;
ConstantUtf8* descriptor_;
Attributes attributes_;
Method(ConstantClass* parent, const ConstantPool& cp, std::istream& is);
public:
static Method* readMethod(ConstantClass* parent,
const ConstantPool& cp,
std::istream& is) {
return new Method(parent, cp, is);
}
~Method();
bool isPublic() const { return accessFlags_ & ACC_PUBLIC; }
bool isPrivate() const { return accessFlags_ & ACC_PRIVATE; }
bool isProtected() const { return accessFlags_ & ACC_PROTECTED; }
bool isStatic() const { return accessFlags_ & ACC_STATIC; }
bool isFinal() const { return accessFlags_ & ACC_FINAL; }
bool isSynchronized() const { return accessFlags_ & ACC_SYNCHRONIZED; }
bool isNative() const { return accessFlags_ & ACC_NATIVE; }
bool isAbstract() const { return accessFlags_ & ACC_ABSTRACT; }
bool isStrict() const { return accessFlags_ & ACC_STRICT; }
ConstantClass* getParent() const { return parent_; }
ConstantUtf8* getName() const { return name_; }
ConstantUtf8* getDescriptor() const { return descriptor_; }
const Attributes& getAttributes() const { return attributes_; }
CodeAttribute* getCodeAttribute() const;
ExceptionsAttribute* getExceptionsAttribute() const;
std::ostream& dump(std::ostream& os) const;
};
inline std::ostream& operator<<(std::ostream& os, const Method& m) {
return m.dump(os);
}
class Attribute {
ConstantUtf8* name_;
protected:
Attribute(ConstantUtf8* name,
const ConstantPool& cp,
std::istream& is);
public:
static Attribute* readAttribute(const ConstantPool& cp,
std::istream& is);
virtual ~Attribute();
ConstantUtf8* getName() const { return name_; }
virtual std::ostream& dump(std::ostream& os) const;
static const std::string CONSTANT_VALUE;
static const std::string CODE;
static const std::string EXCEPTIONS;
static const std::string INNER_CLASSES;
static const std::string SYNTHETIC;
static const std::string SOURCE_FILE;
static const std::string LINE_NUMBER_TABLE;
static const std::string LOCAL_VARIABLE_TABLE;
static const std::string DEPRECATED;
};
inline std::ostream& operator<<(std::ostream& os, const Attribute& a) {
return a.dump(os);
}
class ConstantValueAttribute : public Attribute {
Constant* value_;
public:
ConstantValueAttribute(ConstantUtf8* name,
const ConstantPool& cp,
std::istream& is);
Constant* getValue() const { return value_; }
std::ostream& dump(std::ostream& os) const;
};
class CodeAttribute : public Attribute {
public:
class Exception {
uint16_t startPc_;
uint16_t endPc_;
uint16_t handlerPc_;
ConstantClass* catchType_;
public:
Exception(const ConstantPool& cp, std::istream& is);
uint16_t getStartPc() const { return startPc_; }
uint16_t getEndPc() const { return endPc_; }
uint16_t getHandlerPc() const { return handlerPc_; }
ConstantClass* getCatchType() const { return catchType_; }
std::ostream& dump(std::ostream& os) const;
};
typedef std::vector<Exception*> Exceptions;
private:
uint16_t maxStack_;
uint16_t maxLocals_;
uint32_t codeSize_;
uint8_t* code_;
Exceptions exceptions_;
Attributes attributes_;
public:
CodeAttribute(ConstantUtf8* name,
const ConstantPool& cp,
std::istream& is);
~CodeAttribute();
uint16_t getMaxStack() const { return maxStack_; }
uint16_t getMaxLocals() const { return maxLocals_; }
const uint8_t* getCode() const { return code_; }
uint32_t getCodeSize() const { return codeSize_; }
const Exceptions& getExceptions() const { return exceptions_; }
const Attributes& getAttributes() const { return attributes_; }
std::ostream& dump(std::ostream& os) const;
};
inline std::ostream& operator<<(std::ostream& os,
const CodeAttribute::Exception& e) {
return e.dump(os);
}
class ExceptionsAttribute : public Attribute {
private:
ConstantUtf8* name_;
Classes exceptions_;
public:
ExceptionsAttribute(ConstantUtf8* name,
const ConstantPool& cp,
std::istream& is);
const Classes& getExceptions() const { return exceptions_; }
std::ostream& dump(std::ostream& os) const;
};
class ClassFileParseError : public std::exception {
std::string msg_;
public:
explicit ClassFileParseError(const std::string& msg) : msg_(msg) { }
virtual ~ClassFileParseError() throw();
virtual const char* what() const throw() { return msg_.c_str(); }
};
class ClassFileSemanticError : public std::exception {
std::string msg_;
public:
explicit ClassFileSemanticError(const std::string& msg) : msg_(msg) { }
virtual ~ClassFileSemanticError() throw();
virtual const char* what() const throw() { return msg_.c_str(); }
};
class ClassNotFoundException : public std::exception {
std::string msg_;
public:
explicit ClassNotFoundException(const std::string& msg) : msg_(msg) { }
virtual ~ClassNotFoundException() throw();
virtual const char* what() const throw() { return msg_.c_str(); }
};
class InvocationTargetException : public std::exception {
std::string msg_;
public:
explicit InvocationTargetException(const std::string& msg) : msg_(msg) { }
virtual ~InvocationTargetException() throw();
virtual const char* what() const throw() { return msg_.c_str(); }
};
} } // namespace llvm::Java
#endif//LLVM_JAVA_CLASSFILE_H