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

Alkis Evlogimenos alkis at cs.uiuc.edu
Tue Jul 6 08:33:05 PDT 2004


Changes in directory llvm-java/lib/ClassFile:

ClassFile.cpp updated: 1.12 -> 1.13

---
Log message:

Implement class lookup by name given the CLASSPATH environment
variable. Classfile now includes a getClassFile() API that looks up a
class specified by its fully qualified name, in the directories
specified by CLASSPATH and caches the parsed ClassFile object for
later queries.


---
Diffs of the changes:  (+59 -1)

Index: llvm-java/lib/ClassFile/ClassFile.cpp
diff -u llvm-java/lib/ClassFile/ClassFile.cpp:1.12 llvm-java/lib/ClassFile/ClassFile.cpp:1.13
--- llvm-java/lib/ClassFile/ClassFile.cpp:1.12	Tue Jun 29 15:26:06 2004
+++ llvm-java/lib/ClassFile/ClassFile.cpp	Tue Jul  6 08:31:34 2004
@@ -12,13 +12,19 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "classfile"
+
 #include <llvm/Java/ClassFile.h>
+#include <Support/Debug.h>
+#include <Support/FileUtilities.h>
 #include <Support/STLExtras.h>
 
 #include <cassert>
+#include <fstream>
 #include <functional>
 #include <iostream>
 #include <iterator>
+#include <map>
 
 using namespace llvm::Java;
 
@@ -135,7 +141,7 @@
 
 //===----------------------------------------------------------------------===//
 // ClassFile implementation
-ClassFile* ClassFile::readClassFile(std::istream& is)
+const ClassFile* ClassFile::readClassFile(std::istream& is)
 {
     if (readU1(is) != 0xCA) throw ClassFileParseError("bad magic");
     if (readU1(is) != 0xFE) throw ClassFileParseError("bad magic");
@@ -145,6 +151,58 @@
     return new ClassFile(is);
 }
 
+std::vector<std::string> ClassFile::getClassPath()
+{
+    std::string classpath = getenv("CLASSPATH");
+    DEBUG(std::cerr << "CLASSPATH=" << classpath << '\n');
+
+    std::vector<std::string> result;
+    unsigned b = 0, e = 0;
+    do {
+        e = classpath.find(':', b);
+        result.push_back(classpath.substr(b, e));
+        b = e + 1;
+    } while (e != std::string::npos);
+
+    return result;
+}
+
+std::string ClassFile::getFileForClass(const std::string& classname)
+{
+    static const std::vector<std::string> classpath = getClassPath();
+    DEBUG(std::cerr << "Looking up class: " << classname << '\n');
+
+    std::string clazz = classname;
+    // replace '.' with '/'
+    for (unsigned i = 0, e = clazz.size(); i != e; ++i)
+        if (clazz[i] == '.')
+            clazz[i] = '/';
+    clazz += ".class";
+
+    for (unsigned i = 0, e = classpath.size(); i != e; ++i) {
+        std::string filename = classpath[i] + '/' + clazz;
+        DEBUG(std::cerr << "Trying file: " << filename << '\n');
+        if (FileOpenable(filename))
+            return filename;
+    }
+
+    throw ClassFileSemanticError("Class " + classname + " not found");
+}
+
+const ClassFile* ClassFile::getClassFile(const std::string& classname)
+{
+    typedef std::map<std::string, const ClassFile*> Name2ClassMap;
+    static Name2ClassMap n2cMap_;
+
+    Name2ClassMap::iterator it = n2cMap_.upper_bound(classname);
+    if (it == n2cMap_.end() || it->first != classname) {
+        std::ifstream in(getFileForClass(classname).c_str());
+        it = n2cMap_.insert(it, std::make_pair(classname, readClassFile(in)));
+    }
+
+    return it->second;
+}
+
 ClassFile::ClassFile(std::istream& is)
 {
     minorV_ = readU2(is);





More information about the llvm-commits mailing list