diff options
Diffstat (limited to 'lib/Bytecode')
-rw-r--r-- | lib/Bytecode/Reader/Reader.cpp | 55 | ||||
-rw-r--r-- | lib/Bytecode/Reader/ReaderInternals.h | 1 | ||||
-rw-r--r-- | lib/Bytecode/Writer/Writer.cpp | 12 |
3 files changed, 48 insertions, 20 deletions
diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index fb561aa16c..c8bf5af72e 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -301,14 +301,24 @@ bool BytecodeParser::ParseFunction(const uchar *&Buf, const uchar *EndBuf) { return true; // Unexpected function! } - unsigned isInternal; - if (read_vbr(Buf, EndBuf, isInternal)) return true; + GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage; + + if (!hasInternalMarkerOnly) { + unsigned LinkageType; + if (read_vbr(Buf, EndBuf, LinkageType)) return true; + if (LinkageType & 0x3) return true; + Linkage = (GlobalValue::LinkageTypes)LinkageType; + } else { + // We used to only support two linkage models: internal and external + unsigned isInternal; + if (read_vbr(Buf, EndBuf, isInternal)) return true; + if (isInternal) Linkage = GlobalValue::InternalLinkage; + } Function *F = FunctionSignatureList.back().first; unsigned FunctionSlot = FunctionSignatureList.back().second; FunctionSignatureList.pop_back(); - F->setLinkage(isInternal ? GlobalValue::InternalLinkage : - GlobalValue::ExternalLinkage); + F->setLinkage(Linkage); const FunctionType::ParamTypes &Params =F->getFunctionType()->getParamTypes(); Function::aiterator AI = F->abegin(); @@ -390,9 +400,23 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End){ unsigned VarType; if (read_vbr(Buf, End, VarType)) return true; 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); + 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 Type *Ty = getType(SlotNo); if (!Ty || !isa<PointerType>(Ty)) { Error = "Global not pointer type! Ty = " + Ty->getDescription(); return true; @@ -400,11 +424,6 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End){ const Type *ElTy = cast<PointerType>(Ty)->getElementType(); - - GlobalValue::LinkageTypes Linkage = - (VarType & 4) ? GlobalValue::InternalLinkage : - GlobalValue::ExternalLinkage; - // Create the global variable... GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, Linkage, 0, "", TheModule); @@ -477,7 +496,11 @@ bool BytecodeParser::ParseVersionInfo(const uchar *&Buf, const uchar *EndBuf) { isBigEndian = Version & 1; hasLongPointers = Version & 2; RevisionNum = Version >> 4; + + // Default values for the current bytecode version HasImplicitZeroInitializer = true; + hasInternalMarkerOnly = false; + FirstDerivedTyID = 14; switch (RevisionNum) { case 0: // Initial revision @@ -486,13 +509,17 @@ bool BytecodeParser::ParseVersionInfo(const uchar *&Buf, const uchar *EndBuf) { // encoding zero initializers for arrays compactly. // if (Version != 14) return true; // Unknown revision 0 flags? - FirstDerivedTyID = 14; HasImplicitZeroInitializer = false; isBigEndian = hasLongPointers = true; + hasInternalMarkerOnly = true; break; case 1: // Version #1 has two bit fields: isBigEndian and hasLongPointers - FirstDerivedTyID = 14; + hasInternalMarkerOnly = true; + break; + case 2: + // Version #2 added information about all 4 linkage types instead of just + // having internal and external. break; default: Error = "Unknown bytecode version number!"; diff --git a/lib/Bytecode/Reader/ReaderInternals.h b/lib/Bytecode/Reader/ReaderInternals.h index 3e571f2ee8..dd2a08fcdb 100644 --- a/lib/Bytecode/Reader/ReaderInternals.h +++ b/lib/Bytecode/Reader/ReaderInternals.h @@ -85,6 +85,7 @@ private: // All of this data is transient across calls to ParseBytecode unsigned char FirstDerivedTyID; // First variable index to use for type bool HasImplicitZeroInitializer; // Is entry 0 of every slot implicity zeros? bool isBigEndian, hasLongPointers;// Information about the target compiled for + bool hasInternalMarkerOnly; // Only types of linkage are intern/external typedef std::vector<ValueList*> ValueTable; ValueTable Values, LateResolveValues; diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index 8f4f785c4d..03a6c4668e 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -46,8 +46,8 @@ BytecodeWriter::BytecodeWriter(std::deque<unsigned char> &o, const Module *M) bool isBigEndian = true; bool hasLongPointers = true; - // Output the version identifier... we are currently on bytecode version #1 - unsigned Version = (1 << 4) | isBigEndian | (hasLongPointers << 1); + // Output the version identifier... we are currently on bytecode version #2 + unsigned Version = (2 << 4) | isBigEndian | (hasLongPointers << 1); output_vbr(Version, Out); align32(Out); @@ -154,9 +154,9 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { int Slot = Table.getValSlot(I->getType()); assert(Slot != -1 && "Module global vars is broken!"); - // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2=InternalLinkage, - // bit3+ = Slot # for type - unsigned oSlot = ((unsigned)Slot << 3) | (I->hasInternalLinkage() << 2) | + // Fields: bit0 = isConstant, bit1 = hasInitializer, bit2,3=Linkage, + // bit4+ = Slot # for type + unsigned oSlot = ((unsigned)Slot << 4) | ((unsigned)I->getLinkage() << 2) | (I->hasInitializer() << 1) | I->isConstant(); output_vbr(oSlot, Out); @@ -183,7 +183,7 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { void BytecodeWriter::outputFunction(const Function *F) { BytecodeBlock FunctionBlock(BytecodeFormat::Function, Out); - output_vbr((unsigned)F->hasInternalLinkage(), Out); + output_vbr((unsigned)F->getLinkage(), Out); // Only output the constant pool and other goodies if needed... if (!F->isExternal()) { |