[llvm-commits] CVS: llvm-java/lib/ClassFile/ClassFile.cpp

Alkis Evlogimenos alkis at cs.uiuc.edu
Sat Apr 17 11:19:19 PDT 2004


Changes in directory llvm-java/lib/ClassFile:

ClassFile.cpp updated: 1.2 -> 1.3

---
Log message:

Fix memory leaks.
Add ConstantValue and Code attributes.


---
Diffs of the changes:  (+135 -12)

Index: llvm-java/lib/ClassFile/ClassFile.cpp
diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.2 llvm-java/lib/ClassFile/ClassFile.cpp:1.3
--- llvm-java/lib/ClassFile/ClassFile.cpp:1.2	Fri Apr 16 18:07:19 2004
+++ llvm-java/lib/ClassFile/ClassFile.cpp	Sat Apr 17 02:52:15 2004
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include <llvm/Java/ClassFile.h>
+#include <Support/STLExtras.h>
 
 #include <cassert>
 #include <functional>
@@ -126,7 +127,10 @@
         os << '\n' << name << "s:\n";
         for (typename Container::const_iterator
                  i = c.begin(), e = c.end(); i != e; ++i)
-            (*i)->dump(os << name << ' ') << '\n';
+            if (*i)
+                (*i)->dump(os << name << ' ') << '\n';
+            else
+                os << name << " NULL\n";
         return os;
     }
 
@@ -164,6 +168,14 @@
     readAttributes(attributes_, cPool_, is);
 }
 
+ClassFile::~ClassFile()
+{
+    for_each(cPool_.begin(), cPool_.end(), deleter<Constant>);
+    for_each(fields_.begin(), fields_.end(), deleter<Field>);
+    for_each(methods_.begin(), methods_.end(), deleter<Method>);
+    for_each(attributes_.begin(), attributes_.end(), deleter<Attribute>);
+}
+
 std::ostream& ClassFile::dump(std::ostream& os) const
 {
     os << "Minor version: " << getMinorVersion() << '\n'
@@ -351,8 +363,11 @@
 {
     uint16_t length = readU2(is);
     char buf[length];
-    is.read(buf, length);
-    utf8_ = std::string(buf, length);
+    std::streamsize s = is.rdbuf()->sgetn(buf, length);
+    if (s != length)
+        throw ClassFileParseError(
+            "Could not read string constant from input stream");
+    utf8_.assign(buf, length);
 }
 
 std::ostream& ConstantUtf8::dump(std::ostream& os) const
@@ -375,6 +390,11 @@
     readAttributes(attributes_, cp, is);
 }
 
+Field::~Field()
+{
+    for_each(attributes_.begin(), attributes_.end(), deleter<Attribute>);
+}
+
 std::ostream& Field::dump(std::ostream& os) const
 {
     os << *getName() << ' ' << *getDescriptor() << '\n'
@@ -408,6 +428,11 @@
     readAttributes(attributes_, cp, is);
 }
 
+Method::~Method()
+{
+    for_each(attributes_.begin(), attributes_.end(), deleter<Attribute>);
+}
+
 std::ostream& Method::dump(std::ostream& os) const
 {
     os << *getName() << ' ' << *getDescriptor() << '\n'
@@ -428,24 +453,122 @@
 
 //===----------------------------------------------------------------------===//
 // Attribute implementation
-Attribute::Attribute(const ClassFile::ConstantPool& cp, std::istream& is)
+Attribute* Attribute::readAttribute(const ClassFile::ConstantPool& cp,
+                                    std::istream& is)
 {
-    name_ = dynamic_cast<ConstantUtf8*>(cp[readU2(is)]);
-    if (!name_)
+    ConstantUtf8* name = dynamic_cast<ConstantUtf8*>(cp[readU2(is)]);
+    if (!name)
         throw ClassFileSemanticError(
             "Representation of attribute name is not of type ConstantUtf8");
-    uint32_t length = readU4(is);
-    is.ignore(length);
+
+    if (strcmp(*name, "ConstantValue") == 0)
+        return new AttributeConstantValue(name, cp, is);
+    else if (strcmp(*name, "Code") == 0)
+        return new AttributeCode(name, cp, is);
+    else {
+        uint32_t length = readU4(is);
+        is.ignore(length);
+        return new Attribute(name, cp, is);
+    }
 }
 
-Attribute* Attribute::readAttribute(const ClassFile::ConstantPool& cp,
-                                    std::istream& is)
+Attribute::Attribute(ConstantUtf8* name,
+                     const ClassFile::ConstantPool& cp,
+                     std::istream& is)
+    : name_(name)
+{
+
+}
+
+Attribute::~Attribute()
 {
-    return new Attribute(cp, is);
+
 }
 
 std::ostream& Attribute::dump(std::ostream& os) const
 {
-    os << *getName() << '\n';
+    return os << *getName();
+}
+
+//===----------------------------------------------------------------------===//
+// AttributeConstantValue implementation
+AttributeConstantValue::AttributeConstantValue(
+    ConstantUtf8* name,
+    const ClassFile::ConstantPool& cp,
+    std::istream& is)
+    : Attribute(name, cp, is)
+{
+    uint32_t length = readU4(is);
+    if (length != 2)
+        throw ClassFileSemanticError(
+            "Length of AttributeConstantValue is not 2");
+    value_ = cp[readU2(is)];
+}
+
+std::ostream& AttributeConstantValue::dump(std::ostream& os) const
+{
+    return Attribute::dump(os) << ": " << *value_;
+}
+
+//===----------------------------------------------------------------------===//
+// Attribute code
+AttributeCode::AttributeCode(ConstantUtf8* name,
+                             const ClassFile::ConstantPool& cp,
+                             std::istream& is)
+    : Attribute(name, cp, is)
+{
+    uint32_t length = readU4(is);
+    maxStack_ = readU2(is);
+    maxLocals_ = readU2(is);
+    codeSize_ = readU4(is);
+    code_ = new char[codeSize_];
+    std::streamsize s = is.rdbuf()->sgetn(code_, codeSize_);
+    if (s != (std::streamsize) codeSize_)
+        throw ClassFileParseError(
+            "Could not read code from input stream");
+    uint16_t exceptCount = readU2(is);
+    exceptions_.reserve(exceptCount);
+    while (exceptCount--)
+        exceptions_.push_back(new Exception(cp, is));
+    readAttributes(attributes_, cp, is);
+}
+
+AttributeCode::~AttributeCode()
+{
+    delete[] code_;
+    for_each(exceptions_.begin(), exceptions_.end(), deleter<Exception>);
+    for_each(attributes_.begin(), attributes_.end(), deleter<Attribute>);
+}
+
+std::ostream& AttributeCode::dump(std::ostream& os) const
+{
+    Attribute::dump(os)
+        << '\n'
+        << "Max stack: " << maxStack_ << '\n'
+        << "Max locals: " << maxLocals_ << '\n'
+        << "Code size: " << codeSize_ << '\n';
+    dumpCollection(exceptions_, "Exception", os);
+    dumpCollection(attributes_, "Attribute", os);
+
     return os;
+}
+
+AttributeCode::Exception::Exception(const ClassFile::ConstantPool& cp,
+                                    std::istream& is)
+{
+    startPc_ = readU2(is);
+    endPc_ = readU2(is);
+    handlerPc_ = readU2(is);
+    catchType_ = dynamic_cast<ConstantClass*>(cp[readU2(is)]);
+    if (!catchType_)
+        throw ClassFileSemanticError(
+            "Representation of catch type is not of type ConstantClass");
+}
+
+std::ostream& AttributeCode::Exception::dump(std::ostream& os) const
+{
+    return os << *getCatchType() << '\n'
+              << "Start PC: " << startPc_ << '\n'
+              << "End PC: " << endPc_ << '\n'
+              << "Handler PC: " << handlerPc_;
 }





More information about the llvm-commits mailing list