Chromium Code Reviews| Index: lib/Bitcode/Reader/BitcodeReader.cpp |
| diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp |
| index 46565f36af16117244097a77de3dc314a82fdd51..5dc2c69b1dbe23143bb4b98b1d065683100ccc7f 100644 |
| --- a/lib/Bitcode/Reader/BitcodeReader.cpp |
| +++ b/lib/Bitcode/Reader/BitcodeReader.cpp |
| @@ -13,6 +13,7 @@ |
| #include "llvm/Bitcode/ReaderWriter.h" |
| #include "BitcodeReader.h" |
| +#include "llvm/Bitcode/BitcodeStream.h" |
| #include "llvm/Constants.h" |
| #include "llvm/DerivedTypes.h" |
| #include "llvm/InlineAsm.h" |
| @@ -1823,25 +1824,8 @@ bool BitcodeReader::ParseModule() { |
| bool BitcodeReader::ParseBitcodeInto(Module *M) { |
| TheModule = 0; |
| - |
| - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); |
| - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); |
| - |
| - if (Buffer->getBufferSize() & 3) { |
| - if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd)) |
| - return Error("Invalid bitcode signature"); |
| - else |
| - return Error("Bitcode stream should be a multiple of 4 bytes in length"); |
| - } |
| - |
| - // If we have a wrapper header, parse it and ignore the non-bc file contents. |
| - // The magic number is 0x0B17C0DE stored in little endian. |
| - if (isBitcodeWrapper(BufPtr, BufEnd)) |
| - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) |
| - return Error("Invalid bitcode wrapper header"); |
| - |
| - StreamFile.init(BufPtr, BufEnd); |
| - Stream.init(StreamFile); |
| + bool err; |
| + if ((err = InitStream())) return err; |
|
nlewycky
2011/11/05 00:45:06
if (InitStream()) return true;
(google.com) Derek Schuff
2011/11/07 22:33:50
Done.
|
| // Sniff for the signature. |
| if (Stream.Read(8) != 'B' || |
| @@ -1952,20 +1936,8 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) { |
| } |
| bool BitcodeReader::ParseTriple(std::string &Triple) { |
| - if (Buffer->getBufferSize() & 3) |
| - return Error("Bitcode stream should be a multiple of 4 bytes in length"); |
| - |
| - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); |
| - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); |
| - |
| - // If we have a wrapper header, parse it and ignore the non-bc file contents. |
| - // The magic number is 0x0B17C0DE stored in little endian. |
| - if (isBitcodeWrapper(BufPtr, BufEnd)) |
| - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) |
| - return Error("Invalid bitcode wrapper header"); |
| - |
| - StreamFile.init(BufPtr, BufEnd); |
| - Stream.init(StreamFile); |
| + bool err; |
| + if ((err = InitStream())) return err; |
|
nlewycky
2011/11/05 00:45:06
again
(google.com) Derek Schuff
2011/11/07 22:33:50
Done.
|
| // Sniff for the signature. |
| if (Stream.Read(8) != 'B' || |
| @@ -2948,6 +2920,56 @@ bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) { |
| return false; |
| } |
| +bool BitcodeReader::InitStream() { |
| + if (LazyStreamer) return InitLazyStream(); |
| + else return InitStreamFromBuffer(); |
|
nlewycky
2011/11/05 00:45:06
Delete the "else". See http://llvm.org/docs/Coding
|
| +} |
| + |
| +bool BitcodeReader::InitStreamFromBuffer() { |
| + const unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); |
| + const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); |
| + |
| + if (Buffer->getBufferSize() & 3) { |
| + if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd)) |
| + return Error("Invalid bitcode signature"); |
| + else |
| + return Error("Bitcode stream should be a multiple of 4 bytes in length"); |
| + } |
| + |
| + // If we have a wrapper header, parse it and ignore the non-bc file contents. |
| + // The magic number is 0x0B17C0DE stored in little endian. |
| + if (isBitcodeWrapper(BufPtr, BufEnd)) |
| + if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) |
| + return Error("Invalid bitcode wrapper header"); |
| + |
| + StreamFile.reset(new BitstreamReader(BufPtr, BufEnd)); |
| + Stream.init(*StreamFile); |
| + |
| + return false; |
| +} |
| + |
| +bool BitcodeReader::InitLazyStream() { |
| + // Check and strip off the bitcode wrapper; BitstreamReader expects never to |
| + // see it. |
| + LazyBitstreamVector *BSV = new LazyBitstreamVector(LazyStreamer); |
| + StreamFile.reset(new BitstreamReader(BSV)); |
| + Stream.init(*StreamFile); |
| + if (!BSV->canSkipToPos(15)) |
| + return Error("Bitcode stream must be at least 16 bytes in length"); |
| + unsigned char buf[16]; |
| + for (int i = 0; i < 16; i++) buf[i] = BSV->operator[](i); |
|
nlewycky
2011/11/05 00:45:06
(*BSV)[i]
(google.com) Derek Schuff
2011/11/07 22:33:50
Done.
|
| + if (!isBitcode(buf, buf + 16)) { |
| + return Error("Invalid bitcode signature"); |
| + } |
| + if (isBitcodeWrapper(buf, buf + 4)) { |
| + const unsigned char *bitcodeStart = buf; |
| + const unsigned char *bitcodeEnd = buf + 16; |
| + SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false); |
| + BSV->dropLeadingBytes(bitcodeStart - buf); |
| + BSV->setKnownBitcodeSize(bitcodeEnd - bitcodeStart); |
| + } |
| + return false; |
| +} |
| //===----------------------------------------------------------------------===// |
| // External interface |
| @@ -2973,6 +2995,24 @@ Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer, |
| return M; |
| } |
| + |
| +Module *llvm::getStreamedBitcodeModule(const std::string& name, |
| + BitcodeStreamer* streamer, |
| + LLVMContext& Context, |
| + std::string *ErrMsg) { |
| + Module *M = new Module(name, Context); |
| + BitcodeReader *R = new BitcodeReader(streamer, Context); |
| + M->setMaterializer(R); |
| + if (R->ParseBitcodeInto(M)) { |
| + if (ErrMsg) |
| + *ErrMsg = R->getErrorString(); |
| + delete M; //Also deletes R. |
|
nlewycky
2011/11/05 00:45:06
Space after //
(google.com) Derek Schuff
2011/11/07 22:33:50
Done.
|
| + return 0; |
| + } |
| + R->setBufferOwned(false); // no buffer to delete |
| + return M; |
| +} |
| + |
| /// ParseBitcodeFile - Read the specified bitcode file, returning the module. |
| /// If an error occurs, return null and fill in *ErrMsg if non-null. |
| Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, |