[llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp
Alkis Evlogimenos
alkis at cs.uiuc.edu
Fri Apr 16 18:08:15 PDT 2004
Changes in directory llvm-java/lib/ClassFile:
ClassFile.cpp updated: 1.1 -> 1.2
---
Log message:
Fix several parsing bugs.
Add ClassFileSemanticError exception class.
Add operator<< for all classes.
---
Diffs of the changes: (+223 -144)
Index: llvm-java/lib/ClassFile/ClassFile.cpp
diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.1 llvm-java/lib/ClassFile/ClassFile.cpp:1.2
--- llvm-java/lib/ClassFile/ClassFile.cpp:1.1 Thu Apr 15 16:00:50 2004
+++ llvm-java/lib/ClassFile/ClassFile.cpp Fri Apr 16 18:07:19 2004
@@ -25,11 +25,6 @@
// Utility functions
namespace {
- char bool2cross(bool v)
- {
- return v ? 'x' : ' ';
- }
-
uint8_t readU1(std::istream& is) {
char val;
if (!is.get(val))
@@ -38,11 +33,13 @@
}
uint16_t readU2(std::istream& is) {
- return (readU1(is) << 8) | readU1(is);
+ uint16_t val = readU1(is);
+ return (val << 8) | readU1(is);
}
uint32_t readU4(std::istream& is) {
- return (readU2(is) << 16) | readU2(is);
+ uint32_t val = readU2(is);
+ return (val << 16) | readU2(is);
}
uint64_t readU8(std::istream& is) {
@@ -62,7 +59,130 @@
return tmp.out;
}
-};
+ void readConstantPool(ClassFile::ConstantPool& cp, std::istream& is)
+ {
+ assert(cp.empty() && "Should not call with a non-empty constant pool");
+ uint16_t count = readU2(is);
+ cp.reserve(count);
+ cp.push_back(NULL);
+ --count;
+ while (count--)
+ cp.push_back(Constant::readConstant(cp, is));
+ }
+
+ void readInterfaces(ClassFile::Interfaces& i,
+ const ClassFile::ConstantPool& cp,
+ std::istream& is)
+ {
+ assert(i.empty() &&
+ "Should not call with a non-empty interfaces vector");
+ uint16_t count = readU2(is);
+ i.reserve(count);
+ while (count--) {
+ ConstantClass* c = dynamic_cast<ConstantClass*>(cp[readU2(is)]);
+ if (!c) throw "FIXME: give better error message";
+ i.push_back(c);
+ }
+ }
+
+ void readFields(ClassFile::Fields& f,
+ const ClassFile::ConstantPool& cp,
+ std::istream& is)
+ {
+ assert(f.empty() && "Should not call with a non-empty fields vector");
+ uint16_t count = readU2(is);
+ f.reserve(count);
+ while(count--)
+ f.push_back(Field::readField(cp, is));
+ }
+
+ void readMethods(ClassFile::Methods& m,
+ const ClassFile::ConstantPool& cp,
+ std::istream& is)
+ {
+ assert(m.empty() && "Should not call with a non-empty methods vector");
+ uint16_t count = readU2(is);
+ m.reserve(count);
+ while(count--)
+ m.push_back(Method::readMethod(cp, is));
+ }
+
+ void readAttributes(ClassFile::Attributes& a,
+ const ClassFile::ConstantPool& cp,
+ std::istream& is)
+ {
+ assert(a.empty() &&
+ "Should not call with a non-empty attributes vector");
+ uint16_t count = readU2(is);
+ a.reserve(count);
+ while(count--)
+ a.push_back(Attribute::readAttribute(cp, is));
+ }
+
+ template <typename Container>
+ std::ostream& dumpCollection(Container& c,
+ const char* const name,
+ std::ostream& os) {
+ os << '\n' << name << "s:\n";
+ for (typename Container::const_iterator
+ i = c.begin(), e = c.end(); i != e; ++i)
+ (*i)->dump(os << name << ' ') << '\n';
+ return os;
+ }
+
+}
+
+//===----------------------------------------------------------------------===//
+// ClassFile implementation
+ClassFile* ClassFile::readClassFile(std::istream& is)
+{
+ if (readU1(is) != 0xCA) throw ClassFileParseError("bad magic");
+ if (readU1(is) != 0xFE) throw ClassFileParseError("bad magic");
+ if (readU1(is) != 0xBA) throw ClassFileParseError("bad magic");
+ if (readU1(is) != 0xBE) throw ClassFileParseError("bad magic");
+
+ return new ClassFile(is);
+}
+
+ClassFile::ClassFile(std::istream& is)
+{
+ minorV_ = readU2(is);
+ majorV_ = readU2(is);
+ readConstantPool(cPool_, is);
+ accessFlags_ = readU2(is);
+ thisClass_ = dynamic_cast<ConstantClass*>(cPool_[readU2(is)]);
+ if (!thisClass_)
+ throw ClassFileSemanticError(
+ "Representation of this class is not of type ConstantClass");
+ superClass_ = dynamic_cast<ConstantClass*>(cPool_[readU2(is)]);
+ if (!superClass_)
+ throw ClassFileSemanticError(
+ "Representation of super class is not of type ConstantClass");
+ readInterfaces(interfaces_, cPool_, is);
+ readFields(fields_, cPool_, is);
+ readMethods(methods_, cPool_, is);
+ readAttributes(attributes_, cPool_, is);
+}
+
+std::ostream& ClassFile::dump(std::ostream& os) const
+{
+ os << "Minor version: " << getMinorVersion() << '\n'
+ << "Major version: " << getMajorVersion() << "\n\n"
+ << "class " << *getThisClass() << " (" << *getSuperClass() << ")\n"
+ << "Flags:";
+ if (isPublic()) os << " public";
+ if (isFinal()) os << " final";
+ if (isSuper()) os << " super";
+ if (isInterface()) os << " interface";
+ if (isAbstract()) os << " abstract";
+
+ dumpCollection(interfaces_, "Interface", os);
+ dumpCollection(fields_, "Field", os);
+ dumpCollection(methods_, "Method", os);
+ dumpCollection(attributes_, "Attribute", os);
+
+ return os;
+}
//===----------------------------------------------------------------------===//
// ClassFileParseError implementation
@@ -72,6 +192,13 @@
}
//===----------------------------------------------------------------------===//
+// ClassFileSemanticError implementation
+ClassFileSemanticError::~ClassFileSemanticError() throw()
+{
+
+}
+
+//===----------------------------------------------------------------------===//
// Constant implementation
Constant* Constant::readConstant(const ClassFile::ConstantPool& cp,
std::istream& is)
@@ -112,12 +239,6 @@
}
-std::ostream& Constant::dump(std::ostream& os) const
-{
- // FIXME
- return os;
-}
-
ConstantMemberRef::ConstantMemberRef(const ClassFile::ConstantPool&cp,
std::istream& is)
: Constant(cp),
@@ -127,6 +248,11 @@
}
+std::ostream& ConstantMemberRef::dump(std::ostream& os) const
+{
+ return os << *getNameAndType() << '(' << *getClass() << ')';
+}
+
ConstantClass::ConstantClass(const ClassFile::ConstantPool& cp,
std::istream& is)
: Constant(cp),
@@ -135,6 +261,11 @@
}
+std::ostream& ConstantClass::dump(std::ostream& os) const
+{
+ return os << *getName();
+}
+
ConstantString::ConstantString(const ClassFile::ConstantPool& cp,
std::istream& is)
: Constant(cp),
@@ -143,6 +274,11 @@
}
+std::ostream& ConstantString::dump(std::ostream& os) const
+{
+ return os << "string " << *getValue();
+}
+
ConstantInteger::ConstantInteger(const ClassFile::ConstantPool& cp,
std::istream& is)
: Constant(cp),
@@ -151,6 +287,11 @@
}
+std::ostream& ConstantInteger::dump(std::ostream& os) const
+{
+ return os << value_;
+}
+
ConstantFloat::ConstantFloat(const ClassFile::ConstantPool& cp,
std::istream& is)
: Constant(cp),
@@ -159,6 +300,11 @@
}
+std::ostream& ConstantFloat::dump(std::ostream& os) const
+{
+ return os << value_;
+}
+
ConstantLong::ConstantLong(const ClassFile::ConstantPool& cp,
std::istream& is)
: Constant(cp),
@@ -167,6 +313,11 @@
}
+std::ostream& ConstantLong::dump(std::ostream& os) const
+{
+ return os << value_;
+}
+
ConstantDouble::ConstantDouble(const ClassFile::ConstantPool& cp,
std::istream& is)
: Constant(cp),
@@ -175,6 +326,11 @@
}
+std::ostream& ConstantDouble::dump(std::ostream& os) const
+{
+ return os << value_;
+}
+
ConstantNameAndType::ConstantNameAndType(const ClassFile::ConstantPool& cp,
std::istream& is)
: Constant(cp),
@@ -184,6 +340,11 @@
}
+std::ostream& ConstantNameAndType::dump(std::ostream& os) const
+{
+ return os << *getDescriptor() << ' ' << *getName();
+}
+
ConstantUtf8::ConstantUtf8(const ClassFile::ConstantPool& cp,
std::istream& is)
: Constant(cp)
@@ -194,19 +355,40 @@
utf8_ = std::string(buf, length);
}
+std::ostream& ConstantUtf8::dump(std::ostream& os) const
+{
+ return os << utf8_;
+}
+
//===----------------------------------------------------------------------===//
// Field implementation
Field::Field(const ClassFile::ConstantPool& cp, std::istream& is)
{
accessFlags_ = readU2(is);
- name_ = dynamic_cast<ConstantUtf8*>(cp[readU2(is)]);
- if (!name_) throw "FIXME: better error message";
+ if (!name_)
+ throw ClassFileSemanticError(
+ "Representation of field name is not of type ConstantUtf8");
descriptor_ = dynamic_cast<ConstantUtf8*>(cp[readU2(is)]);
+ if (!descriptor_)
+ throw ClassFileSemanticError(
+ "Representation of field descriptor is not of type ConstantUtf8");
+ readAttributes(attributes_, cp, is);
}
std::ostream& Field::dump(std::ostream& os) const
{
- // FIXME
+ os << *getName() << ' ' << *getDescriptor() << '\n'
+ << "Flags:";
+ if (isPublic()) os << " public";
+ if (isPrivate()) os << " private";
+ if (isProtected()) os << " protected";
+ if (isStatic()) os << " static";
+ if (isFinal()) os << " final";
+ if (isVolatile()) os << " volatile";
+ if (isTransient()) os << " transient";
+
+ dumpCollection(attributes_, "Attribute", os);
+
return os;
}
@@ -216,13 +398,31 @@
{
accessFlags_ = readU2(is);
name_ = dynamic_cast<ConstantUtf8*>(cp[readU2(is)]);
- if (!name_) throw "FIXME: better error message";
+ if (!name_)
+ throw ClassFileSemanticError(
+ "Representation of method name is not of type ConstantUtf8");
descriptor_ = dynamic_cast<ConstantUtf8*>(cp[readU2(is)]);
+ if (!descriptor_)
+ throw ClassFileSemanticError(
+ "Representation of method descriptor is not of type ConstantUtf8");
+ readAttributes(attributes_, cp, is);
}
std::ostream& Method::dump(std::ostream& os) const
{
- // FIXME
+ os << *getName() << ' ' << *getDescriptor() << '\n'
+ << "Flags:";
+ if (isPublic()) os << " public";
+ if (isPrivate()) os << " private";
+ if (isProtected()) os << " protected";
+ if (isStatic()) os << " static";
+ if (isFinal()) os << " final";
+ if (isSynchronized()) os << " synchronized";
+ if (isNative()) os << " native";
+ if (isStrict()) os << " strict";
+
+ dumpCollection(attributes_, "Attribute", os);
+
return os;
}
@@ -231,7 +431,9 @@
Attribute::Attribute(const ClassFile::ConstantPool& cp, std::istream& is)
{
name_ = dynamic_cast<ConstantUtf8*>(cp[readU2(is)]);
- if (!name_) throw "FIXME: better error message";
+ if (!name_)
+ throw ClassFileSemanticError(
+ "Representation of attribute name is not of type ConstantUtf8");
uint32_t length = readU4(is);
is.ignore(length);
}
@@ -244,129 +446,6 @@
std::ostream& Attribute::dump(std::ostream& os) const
{
- // FIXME
- return os;
-}
-
-//===----------------------------------------------------------------------===//
-// ClassFile implementation
-ClassFile* ClassFile::readClassFile(std::istream& is)
-{
- if (readU1(is) != 0xCA) throw ClassFileParseError("bad magic");
- if (readU1(is) != 0xFE) throw ClassFileParseError("bad magic");
- if (readU1(is) != 0xBA) throw ClassFileParseError("bad magic");
- if (readU1(is) != 0xBE) throw ClassFileParseError("bad magic");
-
- return new ClassFile(is);
-}
-
-namespace {
-
- void readConstantPool(ClassFile::ConstantPool& cp, std::istream& is)
- {
- assert(cp.empty() && "Should not call with a non-empty constant pool");
- uint16_t count = readU2(is) - 1;
- cp.reserve(count);
- while (count--)
- cp.push_back(Constant::readConstant(cp, is));
- }
-
- void readInterfaces(ClassFile::Interfaces& i,
- const ClassFile::ConstantPool& cp,
- std::istream& is)
- {
- assert(i.empty() &&
- "Should not call with a non-empty interfaces vector");
- uint16_t count = readU2(is);
- i.reserve(count);
- while (count--) {
- ConstantClass* c = dynamic_cast<ConstantClass*>(cp[readU2(is)]);
- if (!c) throw "FIXME: give better error message";
- i.push_back(c);
- }
- }
-
- void readFields(ClassFile::Fields& f,
- const ClassFile::ConstantPool& cp,
- std::istream& is)
- {
- assert(f.empty() && "Should not call with a non-empty fields vector");
- uint16_t count = readU2(is);
- f.reserve(count);
- while(count--)
- f.push_back(Field::readField(cp, is));
- }
-
- void readMethods(ClassFile::Methods& m,
- const ClassFile::ConstantPool& cp,
- std::istream& is)
- {
- assert(m.empty() && "Should not call with a non-empty methods vector");
- uint16_t count = readU2(is);
- m.reserve(count);
- while(count--)
- m.push_back(Method::readMethod(cp, is));
- }
-
- void readAttributes(ClassFile::Attributes& a,
- const ClassFile::ConstantPool& cp,
- std::istream& is)
- {
- assert(a.empty() &&
- "Should not call with a non-empty attributes vector");
- uint16_t count = readU2(is);
- a.reserve(count);
- while(count--)
- a.push_back(Attribute::readAttribute(cp, is));
- }
-
-}
-
-ClassFile::ClassFile(std::istream& is)
-{
- minorV_ = readU2(is);
- majorV_ = readU2(is);
- readConstantPool(cPool_, is);
- accessFlags_ = readU2(is);
- thisClass_ = dynamic_cast<ConstantClass*>(cPool_[readU2(is)]);
- if (!thisClass_) throw "FIXME: better error message";
- superClass_ = dynamic_cast<ConstantClass*>(cPool_[readU2(is)]);
- if (!superClass_) throw "FIXME: better error message";
- readInterfaces(interfaces_, cPool_, is);
- readFields(fields_, cPool_, is);
- readMethods(methods_, cPool_, is);
- readAttributes(attributes_, cPool_, is);
-}
-
-std::ostream& ClassFile::dump(std::ostream& os) const
-{
- os << "Minor version: " << getMinorVersion() << '\n'
- << "Major version: " << getMajorVersion() << '\n'
- << "Access flags (PFSIA): "
- << bool2cross(isPublic())
- << bool2cross(isFinal())
-
- << bool2cross(isSuper())
- << bool2cross(isInterface())
- << bool2cross(isAbstract()) << '\n'
- << "This class: " << getThisClass() << '\n'
- << "Super class: " << getSuperClass() << '\n';
-
- for (Interfaces::const_iterator
- i = interfaces_.begin(), e = interfaces_.end(); i != e; ++i)
- (*i)->dump(os);
-
- for (Fields::const_iterator
- i = fields_.begin(), e = fields_.end(); i != e; ++i)
- (*i)->dump(os);
-
- for (Methods::const_iterator
- i = methods_.begin(), e = methods_.end(); i != e; ++i)
- (*i)->dump(os);
-
- for (Attributes::const_iterator
- i = attributes_.begin(), e = attributes_.end(); i != e; ++i)
- (*i)->dump(os);
-
+ os << *getName() << '\n';
return os;
}
More information about the llvm-commits
mailing list