[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