Major refactoring of the bytecode reader. This includes the following
[oota-llvm.git] / lib / Bytecode / Reader / Reader.cpp
index c8be36845a26656a0ecac62158dbfb01a9162741..e649cdc08f142e6e14d4c6b23d1fdb0981a413aa 100644 (file)
@@ -5,7 +5,7 @@
 // Note that this library should be as fast as possible, reentrant, and 
 // threadsafe!!
 //
-// TODO: Make error message outputs be configurable depending on an option?
+// TODO: Return error messages to caller instead of printing them out directly.
 // TODO: Allow passing in an option to ignore the symbol table
 //
 //===----------------------------------------------------------------------===//
 #include "ReaderInternals.h"
 #include "llvm/Bytecode/Reader.h"
 #include "llvm/Bytecode/Format.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Module.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/ConstantVals.h"
+#include "llvm/Constants.h"
 #include "llvm/iPHINode.h"
 #include "llvm/iOther.h"
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
+#include "llvm/Module.h"
+#include "Support/StringExtras.h"
+#include "Config/unistd.h"
+#include "Config/sys/mman.h"
+#include "Config/sys/stat.h"
+#include "Config/sys/types.h"
 #include <algorithm>
+#include <memory>
 
-bool BytecodeParser::getTypeSlot(const Type *Ty, unsigned &Slot) {
-  if (Ty->isPrimitiveType()) {
-    Slot = Ty->getPrimitiveID();
-  } else {
-    // Check the method level types first...
-    TypeValuesListTy::iterator I = find(MethodTypeValues.begin(),
-                                       MethodTypeValues.end(), Ty);
-    if (I != MethodTypeValues.end()) {
-      Slot = FirstDerivedTyID+ModuleTypeValues.size()+
-             (&*I - &MethodTypeValues[0]);
-    } else {
-      I = find(ModuleTypeValues.begin(), ModuleTypeValues.end(), Ty);
-      if (I == ModuleTypeValues.end()) return true;   // Didn't find type!
-      Slot = FirstDerivedTyID + (&*I - &ModuleTypeValues[0]);
-    }
-  }
-  //cerr << "getTypeSlot '" << Ty->getName() << "' = " << Slot << endl;
-  return false;
+static inline void ALIGN32(const unsigned char *&begin,
+                           const unsigned char *end) {
+  if (align32(begin, end))
+    throw std::string("Alignment error in buffer: read past end of block.");
+}
+
+unsigned BytecodeParser::getTypeSlot(const Type *Ty) {
+  if (Ty->isPrimitiveType())
+    return Ty->getPrimitiveID();
+
+  // Check the function level types first...
+  TypeValuesListTy::iterator I = find(FunctionTypeValues.begin(),
+                                      FunctionTypeValues.end(), Ty);
+  if (I != FunctionTypeValues.end())
+    return FirstDerivedTyID + ModuleTypeValues.size() +
+             (&*I - &FunctionTypeValues[0]);
+
+  I = find(ModuleTypeValues.begin(), ModuleTypeValues.end(), Ty);
+  if (I == ModuleTypeValues.end())
+    throw std::string("Didn't find type in ModuleTypeValues.");
+  return FirstDerivedTyID + (&*I - &ModuleTypeValues[0]);
 }
 
 const Type *BytecodeParser::getType(unsigned ID) {
-  const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID);
-  if (T) return T;
+  if (ID < Type::NumPrimitiveIDs)
+    if (const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID))
+      return T;
   
-  //cerr << "Looking up Type ID: " << ID << endl;
+  //cerr << "Looking up Type ID: " << ID << "\n";
 
-  const Value *D = getValue(Type::TypeTy, ID, false);
-  if (D == 0) return failure<const Type*>(0);
+  if (ID < Type::NumPrimitiveIDs)
+    if (const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID))
+      return T;   // Asked for a primitive type...
 
-  return cast<Type>(D);
+  // Otherwise, derived types need offset...
+  ID -= FirstDerivedTyID;
+
+  // Is it a module-level type?
+  if (ID < ModuleTypeValues.size())
+    return ModuleTypeValues[ID].get();
+
+  // Nope, is it a function-level type?
+  ID -= ModuleTypeValues.size();
+  if (ID < FunctionTypeValues.size())
+    return FunctionTypeValues[ID].get();
+
+  throw std::string("Illegal type reference!");
 }
 
-int BytecodeParser::insertValue(Value *Val, vector<ValueList> &ValueTab) {
-  unsigned type;
-  if (getTypeSlot(Val->getType(), type)) return failure<int>(-1);
+unsigned BytecodeParser::insertValue(Value *Val, ValueTable &ValueTab) {
+  assert((!HasImplicitZeroInitializer || !isa<Constant>(Val) ||
+          Val->getType()->isPrimitiveType() ||
+          !cast<Constant>(Val)->isNullValue()) &&
+         "Cannot read null values from bytecode!");
+  unsigned type = getTypeSlot(Val->getType());
   assert(type != Type::TypeTyID && "Types should never be insertValue'd!");
  
-  if (ValueTab.size() <= type)
-    ValueTab.resize(type+1, ValueList());
+  if (ValueTab.size() <= type) {
+    unsigned OldSize = ValueTab.size();
+    ValueTab.resize(type+1);
+    while (OldSize != type+1)
+      ValueTab[OldSize++] = new ValueList();
+  }
 
   //cerr << "insertValue Values[" << type << "][" << ValueTab[type].size() 
-  //     << "] = " << Val << endl;
-  ValueTab[type].push_back(Val);
+  //   << "] = " << Val << "\n";
+  ValueTab[type]->push_back(Val);
 
-  return ValueTab[type].size()-1;
-}
-
-Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) {
-  unsigned Num = oNum;
-  unsigned type;   // The type plane it lives in...
+  bool HasOffset = HasImplicitZeroInitializer &&
+    !Val->getType()->isPrimitiveType();
 
-  if (getTypeSlot(Ty, type)) return failure<Value*>(0); // TODO: true
-
-  if (type == Type::TypeTyID) {  // The 'type' plane has implicit values
-    assert(Create == false);
-    const Type *T = Type::getPrimitiveType((Type::PrimitiveID)Num);
-    if (T) return (Value*)T;   // Asked for a primitive type...
+  return ValueTab[type]->size()-1 + HasOffset;
+}
 
-    // Otherwise, derived types need offset...
-    Num -= FirstDerivedTyID;
 
-    // Is it a module level type?
-    if (Num < ModuleTypeValues.size())
-      return (Value*)ModuleTypeValues[Num].get();
+Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) {
+  return getValue(getTypeSlot(Ty), oNum, Create);
+}
 
-    // Nope, is it a method level type?
-    Num -= ModuleTypeValues.size();
-    if (Num < MethodTypeValues.size())
-      return (Value*)MethodTypeValues[Num].get();
+Value *BytecodeParser::getValue(unsigned type, unsigned oNum, bool Create) {
+  assert(type != Type::TypeTyID && "getValue() cannot get types!");
+  assert(type != Type::LabelTyID && "getValue() cannot get blocks!");
+  unsigned Num = oNum;
 
-    return 0;
+  if (HasImplicitZeroInitializer && type >= FirstDerivedTyID) {
+    if (Num == 0)
+      return Constant::getNullValue(getType(type));
+    --Num;
   }
 
   if (type < ModuleValues.size()) {
-    if (Num < ModuleValues[type].size())
-      return ModuleValues[type][Num];
-    Num -= ModuleValues[type].size();
+    if (Num < ModuleValues[type]->size())
+      return ModuleValues[type]->getOperand(Num);
+    Num -= ModuleValues[type]->size();
   }
 
-  if (Values.size() > type && Values[type].size() > Num)
-    return Values[type][Num];
-
-  if (!Create) return failure<Value*>(0);  // Do not create a placeholder?
-
-  Value *d = 0;
-  switch (Ty->getPrimitiveID()) {
-  case Type::LabelTyID: d = new    BBPHolder(Ty, oNum); break;
-  case Type::MethodTyID:
-    cerr << "Creating method pholder! : " << type << ":" << oNum << " " 
-        << Ty->getName() << endl;
-    d = new MethPHolder(Ty, oNum);
-    if (insertValue(d, LateResolveModuleValues) ==-1) return failure<Value*>(0);
-    return d;
-  default:                   d = new   DefPHolder(Ty, oNum); break;
-  }
+  if (Values.size() > type && Values[type]->size() > Num)
+    return Values[type]->getOperand(Num);
 
-  assert(d != 0 && "How did we not make something?");
-  if (insertValue(d, LateResolveValues) == -1) return failure<Value*>(0);
-  return d;
-}
+  if (!Create) return 0;  // Do not create a placeholder?
 
-bool BytecodeParser::postResolveValues(ValueTable &ValTab) {
-  bool Error = false;
-  for (unsigned ty = 0; ty < ValTab.size(); ++ty) {
-    ValueList &DL = ValTab[ty];
-    unsigned Size;
-    while ((Size = DL.size())) {
-      unsigned IDNumber = getValueIDNumberFromPlaceHolder(DL[Size-1]);
-
-      Value *D = DL[Size-1];
-      DL.pop_back();
-
-      Value *NewDef = getValue(D->getType(), IDNumber, false);
-      if (NewDef == 0) {
-       Error = true;  // Unresolved thinger
-       cerr << "Unresolvable reference found: <"
-             << D->getType()->getDescription() << ">:" << IDNumber << "!\n";
-      } else {
-       // Fixup all of the uses of this placeholder def...
-        D->replaceAllUsesWith(NewDef);
-
-        // Now that all the uses are gone, delete the placeholder...
-        // If we couldn't find a def (error case), then leak a little
-       delete D;  // memory, 'cause otherwise we can't remove all uses!
-      }
-    }
-  }
+  std::pair<unsigned,unsigned> KeyValue(type, oNum);
+  std::map<std::pair<unsigned,unsigned>, Value*>::iterator I = 
+    ForwardReferences.lower_bound(KeyValue);
+  if (I != ForwardReferences.end() && I->first == KeyValue)
+    return I->second;   // We have already created this placeholder
 
-  return Error;
+  Value *Val = new Argument(getType(type));
+  ForwardReferences.insert(I, std::make_pair(KeyValue, Val));
+  return Val;
 }
 
-bool BytecodeParser::ParseBasicBlock(const uchar *&Buf, const uchar *EndBuf, 
-                                    BasicBlock *&BB) {
-  BB = new BasicBlock();
+/// getBasicBlock - Get a particular numbered basic block, which might be a
+/// forward reference.  This works together with ParseBasicBlock to handle these
+/// forward references in a clean manner.
+///
+BasicBlock *BytecodeParser::getBasicBlock(unsigned ID) {
+  // Make sure there is room in the table...
+  if (ParsedBasicBlocks.size() <= ID) ParsedBasicBlocks.resize(ID+1);
+
+  // First check to see if this is a backwards reference, i.e., ParseBasicBlock
+  // has already created this block, or if the forward reference has already
+  // been created.
+  if (ParsedBasicBlocks[ID])
+    return ParsedBasicBlocks[ID];
+
+  // Otherwise, the basic block has not yet been created.  Do so and add it to
+  // the ParsedBasicBlocks list.
+  return ParsedBasicBlocks[ID] = new BasicBlock();
+}
 
-  while (Buf < EndBuf) {
-    Instruction *Inst;
-    if (ParseInstruction(Buf, EndBuf, Inst)) {
-      delete BB;
-      return failure(true);
-    }
+/// getConstantValue - Just like getValue, except that it returns a null pointer
+/// only on error.  It always returns a constant (meaning that if the value is
+/// defined, but is not a constant, that is an error).  If the specified
+/// constant hasn't been parsed yet, a placeholder is defined and used.  Later,
+/// after the real value is parsed, the placeholder is eliminated.
+///
+Constant *BytecodeParser::getConstantValue(const Type *Ty, unsigned Slot) {
+  if (Value *V = getValue(Ty, Slot, false))
+    return dyn_cast<Constant>(V);      // If we already have the value parsed...
+
+  std::pair<const Type*, unsigned> Key(Ty, Slot);
+  GlobalRefsType::iterator I = GlobalRefs.lower_bound(Key);
+
+  if (I != GlobalRefs.end() && I->first == Key) {
+    BCR_TRACE(5, "Previous forward ref found!\n");
+    return cast<Constant>(I->second);
+  } else {
+    // Create a placeholder for the constant reference and
+    // keep track of the fact that we have a forward ref to recycle it
+    BCR_TRACE(5, "Creating new forward ref to a constant!\n");
+    Constant *C = new ConstPHolder(Ty, Slot);
+    
+    // Keep track of the fact that we have a forward ref to recycle it
+    GlobalRefs.insert(I, std::make_pair(Key, C));
+    return C;
+  }
+}
 
-    if (Inst == 0) { delete BB; return failure(true); }
-    if (insertValue(Inst, Values) == -1) { delete BB; return failure(true); }
 
-    BB->getInstList().push_back(Inst);
+BasicBlock *BytecodeParser::ParseBasicBlock(const unsigned char *&Buf,
+                                            const unsigned char *EndBuf,
+                                            unsigned BlockNo) {
+  BasicBlock *BB;
+  if (ParsedBasicBlocks.size() == BlockNo)
+    ParsedBasicBlocks.push_back(BB = new BasicBlock());
+  else if (ParsedBasicBlocks[BlockNo] == 0)
+    BB = ParsedBasicBlocks[BlockNo] = new BasicBlock();
+  else
+    BB = ParsedBasicBlocks[BlockNo];
 
+  while (Buf < EndBuf) {
+    Instruction *Inst = ParseInstruction(Buf, EndBuf);
+    insertValue(Inst, Values);
+    BB->getInstList().push_back(Inst);
     BCR_TRACE(4, Inst);
   }
 
-  return false;
+  return BB;
 }
 
-bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf,
-                                     SymbolTable *ST) {
+void BytecodeParser::ParseSymbolTable(const unsigned char *&Buf,
+                                      const unsigned char *EndBuf,
+                                      SymbolTable *ST,
+                                      Function *CurrentFunction) {
   while (Buf < EndBuf) {
     // Symtab block header: [num entries][type id number]
     unsigned NumEntries, Typ;
     if (read_vbr(Buf, EndBuf, NumEntries) ||
-        read_vbr(Buf, EndBuf, Typ)) return failure(true);
+        read_vbr(Buf, EndBuf, Typ)) throw Error_readvbr;
     const Type *Ty = getType(Typ);
-    if (Ty == 0) return failure(true);
-
-    BCR_TRACE(3, "Plane Type: '" << Ty << "' with " << NumEntries <<
-             " entries\n");
+    BCR_TRACE(3, "Plane Type: '" << *Ty << "' with " << NumEntries <<
+                 " entries\n");
 
     for (unsigned i = 0; i < NumEntries; ++i) {
       // Symtab entry: [def slot #][name]
       unsigned slot;
-      if (read_vbr(Buf, EndBuf, slot)) return failure(true);
-      string Name;
+      if (read_vbr(Buf, EndBuf, slot)) throw Error_readvbr;
+      std::string Name;
       if (read(Buf, EndBuf, Name, false))  // Not aligned...
-       return failure(true);
-
-      Value *D = getValue(Ty, slot, false); // Find mapping...
-      if (D == 0) {
-       BCR_TRACE(3, "FAILED LOOKUP: Slot #" << slot << endl);
-       return failure(true);
-      }
-      BCR_TRACE(4, "Map: '" << Name << "' to #" << slot << ":" << D;
-               if (!isa<Instruction>(D)) cerr << endl);
-
-      D->setName(Name, ST);
+        throw std::string("Buffer not aligned.");
+
+      Value *V = 0;
+      if (Typ == Type::TypeTyID)
+        V = (Value*)getType(slot);
+      else if (Typ == Type::LabelTyID) {
+        if (CurrentFunction) {
+          // FIXME: THIS IS N^2!!!
+          Function::iterator BlockIterator = CurrentFunction->begin();
+          std::advance(BlockIterator, slot);
+          V = BlockIterator;
+        }
+      } else
+        V = getValue(Typ, slot, false); // Find mapping...
+      if (V == 0) throw std::string("Failed value look-up.");
+      BCR_TRACE(4, "Map: '" << Name << "' to #" << slot << ":" << *V;
+                if (!isa<Instruction>(V)) std::cerr << "\n");
+
+      V->setName(Name, ST);
     }
   }
 
-  if (Buf > EndBuf) return failure(true);
-  return false;
+  if (Buf > EndBuf) throw std::string("Tried to read past end of buffer.");
 }
 
-// DeclareNewGlobalValue - Patch up forward references to global values in the
-// form of ConstantPointerRef.
-//
-void BytecodeParser::DeclareNewGlobalValue(GlobalValue *GV, unsigned Slot) {
-  // Check to see if there is a forward reference to this global variable...
-  // if there is, eliminate it and patch the reference to use the new def'n.
-  GlobalRefsType::iterator I = GlobalRefs.find(make_pair(GV->getType(), Slot));
-
-  if (I != GlobalRefs.end()) {
-    GlobalVariable *OldGV = I->second;   // Get the placeholder...
-    BCR_TRACE(3, "Mutating CPPR Forward Ref!\n");
-      
-    // Loop over all of the uses of the GlobalValue.  The only thing they are
-    // allowed to be at this point is ConstantPointerRef's.
-    assert(OldGV->use_size() == 1 && "Only one reference should exist!");
-    while (!OldGV->use_empty()) {
-      User *U = OldGV->use_back();  // Must be a ConstantPointerRef...
-      ConstantPointerRef *CPPR = cast<ConstantPointerRef>(U);
-      assert(CPPR->getValue() == OldGV && "Something isn't happy");
-      
-      BCR_TRACE(4, "Mutating Forward Ref!\n");
-      
-      // Change the const pool reference to point to the real global variable
-      // now.  This should drop a use from the OldGV.
-      CPPR->mutateReference(GV);
-    }
-    
-    // Remove GV from the module...
-    GV->getParent()->getGlobalList().remove(OldGV);
-    delete OldGV;                        // Delete the old placeholder
-    
-    // Remove the map entry for the global now that it has been created...
-    GlobalRefs.erase(I);
-  }
-}
+void BytecodeParser::ResolveReferencesToValue(Value *NewV, unsigned Slot) {
+  GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(NewV->getType(),
+                                                              Slot));
+  if (I == GlobalRefs.end()) return;   // Never forward referenced?
 
-bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf, 
-                                Module *C) {
-  // Clear out the local values table...
-  Values.clear();
-  if (MethodSignatureList.empty()) {
-    Error = "Method found, but MethodSignatureList empty!";
-    return failure(true);  // Unexpected method!
-  }
+  BCR_TRACE(3, "Mutating forward refs!\n");
+  Value *VPH = I->second;   // Get the placeholder...
 
-  const PointerType *PMTy = MethodSignatureList.front().first; // PtrMeth
-  const MethodType  *MTy  = dyn_cast<const MethodType>(PMTy->getElementType());
-  if (MTy == 0) return failure(true);  // Not ptr to method!
+  VPH->replaceAllUsesWith(NewV);
 
-  unsigned isInternal;
-  if (read_vbr(Buf, EndBuf, isInternal)) return failure(true);
+  // If this is a global variable being resolved, remove the placeholder from
+  // the module...
+  if (GlobalValue* GVal = dyn_cast<GlobalValue>(NewV))
+    GVal->getParent()->getGlobalList().remove(cast<GlobalVariable>(VPH));
 
-  unsigned MethSlot = MethodSignatureList.front().second;
-  MethodSignatureList.pop_front();
-  Method *M = new Method(MTy, isInternal != 0);
+  delete VPH;                         // Delete the old placeholder
+  GlobalRefs.erase(I);                // Remove the map entry for it
+}
 
-  BCR_TRACE(2, "METHOD TYPE: " << MTy << endl);
+void BytecodeParser::ParseFunction(const unsigned char *&Buf,
+                                   const unsigned char *EndBuf) {
+  if (FunctionSignatureList.empty())
+    throw std::string("FunctionSignatureList empty!");
+
+  Function *F = FunctionSignatureList.back().first;
+  unsigned FunctionSlot = FunctionSignatureList.back().second;
+  FunctionSignatureList.pop_back();
+
+  // Save the information for future reading of the function
+  LazyFunctionInfo *LFI = new LazyFunctionInfo();
+  LFI->Buf = Buf; LFI->EndBuf = EndBuf; LFI->FunctionSlot = FunctionSlot;
+  LazyFunctionLoadMap[F] = LFI;
+  // Pretend we've `parsed' this function
+  Buf = EndBuf;
+}
 
-  const MethodType::ParamTypes &Params = MTy->getParamTypes();
-  for (MethodType::ParamTypes::const_iterator It = Params.begin();
-       It != Params.end(); ++It) {
-    MethodArgument *MA = new MethodArgument(*It);
-    if (insertValue(MA, Values) == -1) {
-      Error = "Error reading method arguments!\n";
-      delete M; return failure(true); 
-    }
-    M->getArgumentList().push_back(MA);
+void BytecodeParser::materializeFunction(Function* F) {
+  // Find {start, end} pointers and slot in the map. If not there, we're done.
+  std::map<Function*, LazyFunctionInfo*>::iterator Fi =
+    LazyFunctionLoadMap.find(F);
+  if (Fi == LazyFunctionLoadMap.end()) return;
+  
+  LazyFunctionInfo *LFI = Fi->second;
+  const unsigned char *Buf = LFI->Buf;
+  const unsigned char *EndBuf = LFI->EndBuf;
+  unsigned FunctionSlot = LFI->FunctionSlot;
+  LazyFunctionLoadMap.erase(Fi);
+  delete LFI;
+
+  GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage;
+
+  if (!hasInternalMarkerOnly) {
+    unsigned LinkageType;
+    if (read_vbr(Buf, EndBuf, LinkageType)) 
+      throw std::string("ParseFunction: Error reading from buffer.");
+    if (LinkageType & ~0x3) 
+      throw std::string("Invalid linkage type for Function.");
+    Linkage = (GlobalValue::LinkageTypes)LinkageType;
+  } else {
+    // We used to only support two linkage models: internal and external
+    unsigned isInternal;
+    if (read_vbr(Buf, EndBuf, isInternal)) 
+      throw std::string("ParseFunction: Error reading from buffer.");
+    if (isInternal) Linkage = GlobalValue::InternalLinkage;
   }
 
+  F->setLinkage(Linkage);
+
+  const FunctionType::ParamTypes &Params =F->getFunctionType()->getParamTypes();
+  Function::aiterator AI = F->abegin();
+  for (FunctionType::ParamTypes::const_iterator It = Params.begin();
+       It != Params.end(); ++It, ++AI)
+    insertValue(AI, Values);
+
+  // Keep track of how many basic blocks we have read in...
+  unsigned BlockNum = 0;
+
   while (Buf < EndBuf) {
     unsigned Type, Size;
-    const uchar *OldBuf = Buf;
-    if (readBlock(Buf, EndBuf, Type, Size)) {
-      Error = "Error reading Method level block!";
-      delete M; return failure(true); 
-    }
+    const unsigned char *OldBuf = Buf;
+    readBlock(Buf, EndBuf, Type, Size);
 
     switch (Type) {
-    case BytecodeFormat::ConstantPool:
+    case BytecodeFormat::ConstantPool: {
       BCR_TRACE(2, "BLOCK BytecodeFormat::ConstantPool: {\n");
-      if (ParseConstantPool(Buf, Buf+Size, Values, MethodTypeValues)) {
-       delete M; return failure(true);
-      }
+      ParseConstantPool(Buf, Buf+Size, Values, FunctionTypeValues);
       break;
+    }
 
     case BytecodeFormat::BasicBlock: {
       BCR_TRACE(2, "BLOCK BytecodeFormat::BasicBlock: {\n");
-      BasicBlock *BB;
-      if (ParseBasicBlock(Buf, Buf+Size, BB) ||
-         insertValue(BB, Values) == -1) {
-       delete M; return failure(true);                // Parse error... :(
-      }
-
-      M->getBasicBlocks().push_back(BB);
+      BasicBlock *BB = ParseBasicBlock(Buf, Buf+Size, BlockNum++);
+      F->getBasicBlockList().push_back(BB);
       break;
     }
 
-    case BytecodeFormat::SymbolTable:
+    case BytecodeFormat::SymbolTable: {
       BCR_TRACE(2, "BLOCK BytecodeFormat::SymbolTable: {\n");
-      if (ParseSymbolTable(Buf, Buf+Size, M->getSymbolTableSure())) {
-       delete M; return failure(true);
-      }
+      ParseSymbolTable(Buf, Buf+Size, &F->getSymbolTable(), F);
       break;
+    }
 
     default:
       BCR_TRACE(2, "BLOCK <unknown>:ignored! {\n");
       Buf += Size;
-      if (OldBuf > Buf) return failure(true); // Wrap around!
+      if (OldBuf > Buf) 
+        throw std::string("Wrapped around reading bytecode.");
       break;
     }
     BCR_TRACE(2, "} end block\n");
 
-    if (align32(Buf, EndBuf)) {
-      Error = "Error aligning Method level block!";
-      delete M;    // Malformed bc file, read past end of block.
-      return failure(true);
-    }
-  }
-
-  if (postResolveValues(LateResolveValues) ||
-      postResolveValues(LateResolveModuleValues)) {
-    Error = "Error resolving method values!";
-    delete M; return failure(true);     // Unresolvable references!
+    // Malformed bc file if read past end of block.
+    ALIGN32(Buf, EndBuf);
   }
 
-  Value *MethPHolder = getValue(PMTy, MethSlot, false);
-  assert(MethPHolder && "Something is broken no placeholder found!");
-  assert(isa<Method>(MethPHolder) && "Not a method?");
-
-  unsigned type;  // Type slot
-  assert(!getTypeSlot(MTy, type) && "How can meth type not exist?");
-  getTypeSlot(PMTy, type);
+  // Make sure there were no references to non-existant basic blocks.
+  if (BlockNum != ParsedBasicBlocks.size())
+    throw std::string("Illegal basic block operand reference");
+  ParsedBasicBlocks.clear();
 
-  C->getMethodList().push_back(M);
 
-  // Replace placeholder with the real method pointer...
-  ModuleValues[type][MethSlot] = M;
+  // Resolve forward references
+  while (!ForwardReferences.empty()) {
+    std::map<std::pair<unsigned,unsigned>, Value*>::iterator I = ForwardReferences.begin();
+    unsigned type = I->first.first;
+    unsigned Slot = I->first.second;
+    Value *PlaceHolder = I->second;
+    ForwardReferences.erase(I);
 
-  // Clear out method level types...
-  MethodTypeValues.clear();
+    Value *NewVal = getValue(type, Slot, false);
+    if (NewVal == 0)
+      throw std::string("Unresolvable reference found: <" +
+                        PlaceHolder->getType()->getDescription() + ">:" + 
+                        utostr(Slot) + ".");
 
-  // If anyone is using the placeholder make them use the real method instead
-  MethPHolder->replaceAllUsesWith(M);
-
-  // We don't need the placeholder anymore!
-  delete MethPHolder;
-
-  // If the method is empty, we don't need the method argument entries...
-  if (M->isExternal())
-    M->getArgumentList().delete_all();
+    // Fixup all of the uses of this placeholder def...
+    PlaceHolder->replaceAllUsesWith(NewVal);
+      
+    // Now that all the uses are gone, delete the placeholder...
+    // If we couldn't find a def (error case), then leak a little
+    // memory, because otherwise we can't remove all uses!
+    delete PlaceHolder;
+  }
 
-  DeclareNewGlobalValue(M, MethSlot);
+  // Clear out function-level types...
+  FunctionTypeValues.clear();
 
-  return false;
+  freeTable(Values);
 }
 
-bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
-                                          Module *Mod) {
-  if (!MethodSignatureList.empty()) {
-    Error = "Two ModuleGlobalInfo packets found!";
-    return failure(true);  // Two ModuleGlobal blocks?
-  }
+void BytecodeParser::ParseModuleGlobalInfo(const unsigned char *&Buf,
+                                           const unsigned char *End) {
+  if (!FunctionSignatureList.empty())
+    throw std::string("Two ModuleGlobalInfo packets found!");
 
   // Read global variables...
   unsigned VarType;
-  if (read_vbr(Buf, End, VarType)) return failure(true);
+  if (read_vbr(Buf, End, VarType)) throw Error_readvbr;
   while (VarType != Type::VoidTyID) { // List is terminated by Void
-    // VarType Fields: bit0 = isConstant, bit1 = hasInitializer,
-    // bit2 = isInternal, bit3+ = slot#
-    const Type *Ty = getType(VarType >> 3);
-    if (!Ty || !Ty->isPointerType()) { 
-      Error = "Global not pointer type!  Ty = " + Ty->getDescription();
-      return failure(true); 
+    unsigned SlotNo;
+    GlobalValue::LinkageTypes Linkage;
+
+    if (!hasInternalMarkerOnly) {
+      // VarType Fields: bit0 = isConstant, bit1 = hasInitializer,
+      // bit2,3 = Linkage, bit4+ = slot#
+      SlotNo = VarType >> 4;
+      Linkage = (GlobalValue::LinkageTypes)((VarType >> 2) & 3);
+    } else {
+      // VarType Fields: bit0 = isConstant, bit1 = hasInitializer,
+      // bit2 = isInternal, bit3+ = slot#
+      SlotNo = VarType >> 3;
+      Linkage = (VarType & 4) ? GlobalValue::InternalLinkage :
+        GlobalValue::ExternalLinkage;
     }
 
-    const PointerType *PTy = cast<const PointerType>(Ty);
-    const Type *ElTy = PTy->getElementType();
+    const Type *Ty = getType(SlotNo);
+    if (!isa<PointerType>(Ty))
+      throw std::string("Global not pointer type!  Ty = " + 
+                        Ty->getDescription());
 
-    Constant *Initializer = 0;
-    if (VarType & 2) { // Does it have an initalizer?
-      // Do not improvise... values must have been stored in the constant pool,
-      // which should have been read before now.
-      //
-      unsigned InitSlot;
-      if (read_vbr(Buf, End, InitSlot)) return failure(true);
-      
-      Value *V = getValue(ElTy, InitSlot, false);
-      if (V == 0) return failure(true);
-      Initializer = cast<Constant>(V);
-    }
+    const Type *ElTy = cast<PointerType>(Ty)->getElementType();
 
     // Create the global variable...
-    GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, VarType & 4,
-                                           Initializer);
-    int DestSlot = insertValue(GV, ModuleValues);
-    if (DestSlot == -1) return failure(true);
-
-    Mod->getGlobalList().push_back(GV);
-
-    DeclareNewGlobalValue(GV, unsigned(DestSlot));
-
-    BCR_TRACE(2, "Global Variable of type: " << PTy->getDescription() 
-             << " into slot #" << DestSlot << endl);
+    GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, Linkage,
+                                            0, "", TheModule);
+    BCR_TRACE(2, "Global Variable of type: " << *Ty << "\n");
+    ResolveReferencesToValue(GV, insertValue(GV, ModuleValues));
 
-    if (read_vbr(Buf, End, VarType)) return failure(true);
+    if (VarType & 2) { // Does it have an initializer?
+      unsigned InitSlot;
+      if (read_vbr(Buf, End, InitSlot)) throw Error_readvbr;
+      GlobalInits.push_back(std::make_pair(GV, InitSlot));
+    }
+    if (read_vbr(Buf, End, VarType)) throw Error_readvbr;
   }
 
-  // Read the method signatures for all of the methods that are coming, and 
-  // create fillers in the Value tables.
-  unsigned MethSignature;
-  if (read_vbr(Buf, End, MethSignature)) return failure(true);
-  while (MethSignature != Type::VoidTyID) { // List is terminated by Void
-    const Type *Ty = getType(MethSignature);
-    if (!Ty || !isa<PointerType>(Ty) ||
-        !isa<MethodType>(cast<PointerType>(Ty)->getElementType())) { 
-      Error = "Method not ptr to meth type!  Ty = " + Ty->getDescription();
-      return failure(true); 
-    }
-    
-    // We create methods by passing the underlying MethodType to create...
+  // Read the function objects for all of the functions that are coming
+  unsigned FnSignature;
+  if (read_vbr(Buf, End, FnSignature)) throw Error_readvbr;
+  while (FnSignature != Type::VoidTyID) { // List is terminated by Void
+    const Type *Ty = getType(FnSignature);
+    if (!isa<PointerType>(Ty) ||
+        !isa<FunctionType>(cast<PointerType>(Ty)->getElementType()))
+      throw std::string("Function not ptr to func type!  Ty = " +
+                        Ty->getDescription());
+
+    // We create functions by passing the underlying FunctionType to create...
     Ty = cast<PointerType>(Ty)->getElementType();
 
-    // When the ModuleGlobalInfo section is read, we load the type of each 
-    // method and the 'ModuleValues' slot that it lands in.  We then load a 
-    // placeholder into its slot to reserve it.  When the method is loaded, this
-    // placeholder is replaced.
+    // When the ModuleGlobalInfo section is read, we load the type of each
+    // function and the 'ModuleValues' slot that it lands in.  We then load a
+    // placeholder into its slot to reserve it.  When the function is loaded,
+    // this placeholder is replaced.
 
     // Insert the placeholder...
-    Value *Val = new MethPHolder(Ty, 0);
-    if (insertValue(Val, ModuleValues) == -1) return failure(true);
+    Function *Func = new Function(cast<FunctionType>(Ty),
+                                  GlobalValue::InternalLinkage, "", TheModule);
+    unsigned DestSlot = insertValue(Func, ModuleValues);
+    ResolveReferencesToValue(Func, DestSlot);
 
-    // Figure out which entry of its typeslot it went into...
-    unsigned TypeSlot;
-    if (getTypeSlot(Val->getType(), TypeSlot)) return failure(true);
-
-    unsigned SlotNo = ModuleValues[TypeSlot].size()-1;
-    
-    // Keep track of this information in a linked list that is emptied as 
-    // methods are loaded...
+    // Keep track of this information in a list that is emptied as functions are
+    // loaded...
     //
-    MethodSignatureList.push_back(
-           make_pair(cast<const PointerType>(Val->getType()), SlotNo));
-    if (read_vbr(Buf, End, MethSignature)) return failure(true);
-    BCR_TRACE(2, "Method of type: " << Ty << endl);
+    FunctionSignatureList.push_back(std::make_pair(Func, DestSlot));
+
+    if (read_vbr(Buf, End, FnSignature)) throw Error_readvbr;
+    BCR_TRACE(2, "Function of type: " << Ty << "\n");
   }
 
-  if (align32(Buf, End)) return failure(true);
+  ALIGN32(Buf, End);
+
+  // Now that the function signature list is set up, reverse it so that we can 
+  // remove elements efficiently from the back of the vector.
+  std::reverse(FunctionSignatureList.begin(), FunctionSignatureList.end());
 
   // This is for future proofing... in the future extra fields may be added that
   // we don't understand, so we transparently ignore them.
   //
   Buf = End;
-  return false;
 }
 
-bool BytecodeParser::ParseModule(const uchar *Buf, const uchar *EndBuf, 
-                               Module *&C) {
+void BytecodeParser::ParseVersionInfo(const unsigned char *&Buf,
+                                      const unsigned char *EndBuf) {
+  unsigned Version;
+  if (read_vbr(Buf, EndBuf, Version)) throw Error_readvbr;
 
-  unsigned Type, Size;
-  if (readBlock(Buf, EndBuf, Type, Size)) return failure(true);
-  if (Type != BytecodeFormat::Module || Buf+Size != EndBuf) {
-    Error = "Expected Module packet!";
-    return failure(true);                      // Hrm, not a class?
+  // Unpack version number: low four bits are for flags, top bits = version
+  Module::Endianness  Endianness;
+  Module::PointerSize PointerSize;
+  Endianness  = (Version & 1) ? Module::BigEndian : Module::LittleEndian;
+  PointerSize = (Version & 2) ? Module::Pointer64 : Module::Pointer32;
+
+  bool hasNoEndianness = Version & 4;
+  bool hasNoPointerSize = Version & 8;
+  
+  RevisionNum = Version >> 4;
+
+  // Default values for the current bytecode version
+  HasImplicitZeroInitializer = true;
+  hasInternalMarkerOnly = false;
+  FirstDerivedTyID = 14;
+
+  switch (RevisionNum) {
+  case 0:                  // Initial revision
+    // Version #0 didn't have any of the flags stored correctly, and in fact as
+    // only valid with a 14 in the flags values.  Also, it does not support
+    // encoding zero initializers for arrays compactly.
+    //
+    if (Version != 14) throw std::string("Unknown revision 0 flags?");
+    HasImplicitZeroInitializer = false;
+    Endianness  = Module::BigEndian;
+    PointerSize = Module::Pointer64;
+    hasInternalMarkerOnly = true;
+    hasNoEndianness = hasNoPointerSize = false;
+    break;
+  case 1:
+    // Version #1 has four bit fields: isBigEndian, hasLongPointers,
+    // hasNoEndianness, and hasNoPointerSize.
+    hasInternalMarkerOnly = true;
+    break;
+  case 2:
+    // Version #2 added information about all 4 linkage types instead of just
+    // having internal and external.
+    break;
+  default:
+    throw std::string("Unknown bytecode version number!");
   }
 
+  if (hasNoEndianness) Endianness  = Module::AnyEndianness;
+  if (hasNoPointerSize) PointerSize = Module::AnyPointerSize;
+
+  TheModule->setEndianness(Endianness);
+  TheModule->setPointerSize(PointerSize);
+  BCR_TRACE(1, "Bytecode Rev = " << (unsigned)RevisionNum << "\n");
+  BCR_TRACE(1, "Endianness/PointerSize = " << Endianness << ","
+               << PointerSize << "\n");
+  BCR_TRACE(1, "HasImplicitZeroInit = " << HasImplicitZeroInitializer << "\n");
+}
+
+void BytecodeParser::ParseModule(const unsigned char *Buf,
+                                 const unsigned char *EndBuf) {
+  unsigned Type, Size;
+  readBlock(Buf, EndBuf, Type, Size);
+  if (Type != BytecodeFormat::Module || Buf+Size != EndBuf)
+    throw std::string("Expected Module packet! B: "+
+        utostr((unsigned)(intptr_t)Buf) + ", S: "+utostr(Size)+
+        " E: "+utostr((unsigned)(intptr_t)EndBuf)); // Hrm, not a class?
+
   BCR_TRACE(0, "BLOCK BytecodeFormat::Module: {\n");
-  MethodSignatureList.clear();                 // Just in case...
+  FunctionSignatureList.clear();                 // Just in case...
 
   // Read into instance variables...
-  if (read_vbr(Buf, EndBuf, FirstDerivedTyID)) return failure(true);
-  if (align32(Buf, EndBuf)) return failure(true);
-  BCR_TRACE(1, "FirstDerivedTyID = " << FirstDerivedTyID << "\n");
+  ParseVersionInfo(Buf, EndBuf);
+  ALIGN32(Buf, EndBuf);
 
-  TheModule = C = new Module();
   while (Buf < EndBuf) {
-    const uchar *OldBuf = Buf;
-    if (readBlock(Buf, EndBuf, Type, Size)) { delete C; return failure(true); }
+    const unsigned char *OldBuf = Buf;
+    readBlock(Buf, EndBuf, Type, Size);
     switch (Type) {
-    case BytecodeFormat::ConstantPool:
-      BCR_TRACE(1, "BLOCK BytecodeFormat::ConstantPool: {\n");
-      if (ParseConstantPool(Buf, Buf+Size, ModuleValues, ModuleTypeValues)) {
-       delete C; return failure(true);
-      }
+    case BytecodeFormat::GlobalTypePlane:
+      BCR_TRACE(1, "BLOCK BytecodeFormat::GlobalTypePlane: {\n");
+      ParseGlobalTypes(Buf, Buf+Size);
       break;
 
     case BytecodeFormat::ModuleGlobalInfo:
       BCR_TRACE(1, "BLOCK BytecodeFormat::ModuleGlobalInfo: {\n");
+      ParseModuleGlobalInfo(Buf, Buf+Size);
+      break;
 
-      if (ParseModuleGlobalInfo(Buf, Buf+Size, C)) {
-       delete C; return failure(true);
-      }
+    case BytecodeFormat::ConstantPool:
+      BCR_TRACE(1, "BLOCK BytecodeFormat::ConstantPool: {\n");
+      ParseConstantPool(Buf, Buf+Size, ModuleValues, ModuleTypeValues);
       break;
 
-    case BytecodeFormat::Method: {
-      BCR_TRACE(1, "BLOCK BytecodeFormat::Method: {\n");
-      if (ParseMethod(Buf, Buf+Size, C)) {
-       delete C; return failure(true);               // Error parsing method
-      }
+    case BytecodeFormat::Function: {
+      BCR_TRACE(1, "BLOCK BytecodeFormat::Function: {\n");
+      ParseFunction(Buf, Buf+Size);
       break;
     }
 
     case BytecodeFormat::SymbolTable:
       BCR_TRACE(1, "BLOCK BytecodeFormat::SymbolTable: {\n");
-      if (ParseSymbolTable(Buf, Buf+Size, C->getSymbolTableSure())) {
-       delete C; return failure(true);
-      }
+      ParseSymbolTable(Buf, Buf+Size, &TheModule->getSymbolTable(), 0);
       break;
 
     default:
-      Error = "Expected Module Block!";
       Buf += Size;
-      if (OldBuf > Buf) return failure(true); // Wrap around!
+      if (OldBuf > Buf) throw std::string("Expected Module Block!");
       break;
     }
     BCR_TRACE(1, "} end block\n");
-    if (align32(Buf, EndBuf)) { delete C; return failure(true); }
-  }
-
-  if (!MethodSignatureList.empty()) {     // Expected more methods!
-    Error = "Method expected, but bytecode stream at end!";
-    return failure(true);
+    ALIGN32(Buf, EndBuf);
   }
 
-  BCR_TRACE(0, "} end block\n\n");
-  return false;
-}
-
-Module *BytecodeParser::ParseBytecode(const uchar *Buf, const uchar *EndBuf) {
-  LateResolveValues.clear();
-  unsigned Sig;
-  // Read and check signature...
-  if (read(Buf, EndBuf, Sig) ||
-      Sig != ('l' | ('l' << 8) | ('v' << 16) | 'm' << 24)) {
-    Error = "Invalid bytecode signature!";
-    return failure<Module*>(0);                          // Invalid signature!
+  // After the module constant pool has been read, we can safely initialize
+  // global variables...
+  while (!GlobalInits.empty()) {
+    GlobalVariable *GV = GlobalInits.back().first;
+    unsigned Slot = GlobalInits.back().second;
+    GlobalInits.pop_back();
+
+    // Look up the initializer value...
+    if (Value *V = getValue(GV->getType()->getElementType(), Slot, false)) {
+      if (GV->hasInitializer()) 
+        throw std::string("Global *already* has an initializer?!");
+      GV->setInitializer(cast<Constant>(V));
+    } else
+      throw std::string("Cannot find initializer value.");
   }
 
-  Module *Result;
-  if (ParseModule(Buf, EndBuf, Result)) return 0;
-  return Result;
-}
+  if (!FunctionSignatureList.empty())
+    throw std::string("Function expected, but bytecode stream ended!");
 
-
-Module *ParseBytecodeBuffer(const uchar *Buffer, unsigned Length) {
-  BytecodeParser Parser;
-  return Parser.ParseBytecode(Buffer, Buffer+Length);
+  BCR_TRACE(0, "} end block\n\n");
 }
 
-// Parse and return a class file...
-//
-Module *ParseBytecodeFile(const string &Filename, string *ErrorStr) {
-  struct stat StatBuf;
-  Module *Result = 0;
-
-  if (Filename != string("-")) {        // Read from a file...
-    int FD = open(Filename.c_str(), O_RDONLY);
-    if (FD == -1) {
-      if (ErrorStr) *ErrorStr = "Error opening file!";
-      return failure<Module*>(0);
-    }
-
-    if (fstat(FD, &StatBuf) == -1) { close(FD); return failure<Module*>(0); }
+void
+BytecodeParser::ParseBytecode(const unsigned char *Buf, unsigned Length,
+                              const std::string &ModuleID) {
 
-    int Length = StatBuf.st_size;
-    if (Length == 0) { 
-      if (ErrorStr) *ErrorStr = "Error stat'ing file!";
-      close(FD); return failure<Module*>(0); 
-    }
-    uchar *Buffer = (uchar*)mmap(0, Length, PROT_READ, 
-                               MAP_PRIVATE, FD, 0);
-    if (Buffer == (uchar*)-1) {
-      if (ErrorStr) *ErrorStr = "Error mmapping file!";
-      close(FD); return failure<Module*>(0);
-    }
+  unsigned char *EndBuf = (unsigned char*)(Buf + Length);
 
-    BytecodeParser Parser;
-    Result  = Parser.ParseBytecode(Buffer, Buffer+Length);
-
-    munmap((char*)Buffer, Length);
-    close(FD);
-    if (ErrorStr) *ErrorStr = Parser.getError();
-  } else {                              // Read from stdin
-    size_t FileSize = 0;
-    int BlockSize;
-    uchar Buffer[4096], *FileData = 0;
-    while ((BlockSize = read(0, Buffer, 4))) {
-      if (BlockSize == -1) { free(FileData); return failure<Module*>(0); }
-
-      FileData = (uchar*)realloc(FileData, FileSize+BlockSize);
-      memcpy(FileData+FileSize, Buffer, BlockSize);
-      FileSize += BlockSize;
-    }
-
-    if (FileSize == 0) {
-      if (ErrorStr) *ErrorStr = "Standard Input empty!";
-      free(FileData); return failure<Module*>(0);
-    }
-
-#define ALIGN_PTRS 1
-#if ALIGN_PTRS
-    uchar *Buf = (uchar*)mmap(0, FileSize, PROT_READ|PROT_WRITE, 
-                             MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-    assert((Buf != (uchar*)-1) && "mmap returned error!");
-    memcpy(Buf, FileData, FileSize);
-    free(FileData);
-#else
-    uchar *Buf = FileData;
-#endif
-
-    BytecodeParser Parser;
-    Result = Parser.ParseBytecode(Buf, Buf+FileSize);
-
-#if ALIGN_PTRS
-    munmap((char*)Buf, FileSize);   // Free mmap'd data area
-#else
-    free(FileData);          // Free realloc'd block of memory
-#endif
-
-    if (ErrorStr) *ErrorStr = Parser.getError();
+  // Read and check signature...
+  unsigned Sig;
+  if (read(Buf, EndBuf, Sig) ||
+      Sig != ('l' | ('l' << 8) | ('v' << 16) | ('m' << 24)))
+    throw std::string("Invalid bytecode signature!");
+
+  TheModule = new Module(ModuleID);
+  try { 
+    ParseModule(Buf, EndBuf);
+  } catch (std::string &Error) {
+    freeState();       // Must destroy handles before deleting module!
+    delete TheModule;
+    TheModule = 0;
+    throw;
   }
-
-  return Result;
 }