Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(509)

Unified Diff: lib/Bitcode/Reader/BitcodeReader.cpp

Issue 8393017: Bitcode streaming (Closed)
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/Bitcode/Reader/BitcodeReader.cpp
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 5aa6373dbb3473a5217820302f9827f8ec402fbf..5726d3b0aad1340976404b22323846309addbae6 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"
@@ -1836,25 +1837,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;
// Sniff for the signature.
if (Stream.Read(8) != 'B' ||
@@ -1965,20 +1949,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;
// Sniff for the signature.
if (Stream.Read(8) != 'B' ||
@@ -2961,6 +2933,54 @@ bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) {
return false;
}
+bool BitcodeReader::InitStream() {
+ if (StreamCallback) return InitLazyStream();
+ else return InitStreamFromBuffer();
+}
+
+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(StreamCallback);
+ StreamFile.reset(new BitstreamReader(BSV));
+ Stream.init(*StreamFile);
+ if (!BSV->canSkipToPos(15))
+ return Error("Bitcode stream must be at least 16 bytes in length");
+ if (!isBitcode(BSV->addressOf(0), BSV->addressOf(16))) {
+ return Error("Invalid bitcode signature");
+ }
+ if (isBitcodeWrapper(BSV->addressOf(0), BSV->addressOf(4))) {
+ const unsigned char *bitcodeStart = BSV->addressOf(0);
+ const unsigned char *bitcodeEnd = BSV->addressOf(16);
+ SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false);
+ BSV->dropLeadingBytes(bitcodeStart - BSV->addressOf(0));
+ BSV->setKnownBitcodeSize(bitcodeEnd - bitcodeStart);
+ }
+ return false;
+}
//===----------------------------------------------------------------------===//
// External interface
@@ -2986,6 +3006,24 @@ Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
return M;
}
+Module *llvm::getLazyBitcodeStreamModule(const std::string& name,
+ StreamChunkCallback cb,
+ LLVMContext& Context,
+ std::string *ErrMsg) {
+ Module *M = new Module(name, Context);
+ BitcodeReader *R = new BitcodeReader(cb, Context);
+ M->setMaterializer(R);
+ if (R->ParseBitcodeInto(M)) {
+ if (ErrMsg)
+ *ErrMsg = R->getErrorString();
+
+ delete M; //Also deletes R.
+ 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,

Powered by Google App Engine
This is Rietveld 408576698