Subzero: Switch file reading to be based on a DataStreamer and MemoryObject.
This makes it compatible with the current browser interface,
which pushes bytes to a DataStreamer.
In the browser-integration mode, there will be a push-based
DataStreamer (vs a file-based one).
BUG= https://code.google.com/p/nativeclient/issues/detail?id=4091
R=dschuff@chromium.org, kschimpf@google.com, stichnot@chromium.org
Review URL: https://codereview.chromium.org/982403002
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index d0b099d..2ff57c1 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -2992,43 +2992,27 @@
namespace Ice {
-void PNaClTranslator::translate(const std::string &IRFilename) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> ErrOrFile =
- MemoryBuffer::getFileOrSTDIN(IRFilename);
- if (std::error_code EC = ErrOrFile.getError()) {
- errs() << "Error reading '" << IRFilename << "': " << EC.message() << "\n";
- ErrorStatus.assign(EC.value());
- return;
- }
-
- std::unique_ptr<MemoryBuffer> MemBuf(ErrOrFile.get().release());
- translateBuffer(IRFilename, MemBuf.get());
-}
-
void PNaClTranslator::translateBuffer(const std::string &IRFilename,
MemoryBuffer *MemBuf) {
- if (MemBuf->getBufferSize() % 4 != 0) {
- errs() << IRFilename
- << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
- ErrorStatus.assign(EC_Bitcode);
- return;
- }
+ std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject(
+ reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()),
+ reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd())));
+ translate(IRFilename, std::move(MemObj));
+}
- const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart();
- const unsigned char *HeaderPtr = BufPtr;
- const unsigned char *EndBufPtr = BufPtr + MemBuf->getBufferSize();
+void PNaClTranslator::translate(const std::string &IRFilename,
+ std::unique_ptr<MemoryObject> &&MemObj) {
// Read header and verify it is good.
NaClBitcodeHeader Header;
- if (Header.Read(HeaderPtr, EndBufPtr) || !Header.IsSupported()) {
+ if (Header.Read(MemObj.get()) || !Header.IsSupported()) {
errs() << "Invalid PNaCl bitcode header.\n";
ErrorStatus.assign(EC_Bitcode);
return;
}
// Create a bitstream reader to read the bitcode file.
- NaClBitstreamReader InputStreamFile(BufPtr, EndBufPtr,
- Header.getHeaderSize());
+ NaClBitstreamReader InputStreamFile(MemObj.release(), Header.getHeaderSize());
NaClBitstreamCursor InputStream(InputStreamFile);
TopLevelParser Parser(*this, InputStream, ErrorStatus);
@@ -3047,6 +3031,12 @@
<< "\n";
ErrorStatus.assign(EC_Bitcode);
}
+ if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) {
+ errs() << IRFilename
+ << ": Bitcode stream should be a multiple of 4 bytes in length.\n";
+ ErrorStatus.assign(EC_Bitcode);
+ return;
+ }
}
} // end of namespace Ice
diff --git a/src/PNaClTranslator.h b/src/PNaClTranslator.h
index 9162d59..e2d423a 100644
--- a/src/PNaClTranslator.h
+++ b/src/PNaClTranslator.h
@@ -21,6 +21,7 @@
namespace llvm {
class MemoryBuffer;
+class MemoryObject;
} // end of namespace llvm
namespace Ice {
@@ -35,8 +36,9 @@
// Reads the PNaCl bitcode file and translates to ICE, which is then
// converted to machine code. Sets ErrorStatus to 1 if any errors
- // occurred.
- void translate(const std::string &IRFilename);
+ // occurred. Takes ownership of the MemoryObject.
+ void translate(const std::string &IRFilename,
+ std::unique_ptr<llvm::MemoryObject> &&MemoryObject);
// Reads MemBuf, assuming it is the PNaCl bitcode contents of IRFilename.
void translateBuffer(const std::string &IRFilename,
diff --git a/src/main.cpp b/src/main.cpp
index 8ced212..22ab0a1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -26,6 +26,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/StreamingMemoryObject.h"
#include "IceCfg.h"
#include "IceClFlags.h"
@@ -379,7 +380,17 @@
if (BuildOnRead) {
std::unique_ptr<Ice::PNaClTranslator> PTranslator(
new Ice::PNaClTranslator(&Ctx));
- PTranslator->translate(IRFilename);
+ std::string StrError;
+ std::unique_ptr<DataStreamer> FileStreamer(
+ getDataFileStreamer(IRFilename, &StrError));
+ if (!StrError.empty() || !FileStreamer) {
+ SMDiagnostic Err(IRFilename, SourceMgr::DK_Error, StrError);
+ Err.print(argv[0], errs());
+ return GetReturnValue(Ice::EC_Bitcode);
+ }
+ std::unique_ptr<StreamingMemoryObject> MemObj(
+ new StreamingMemoryObjectImpl(FileStreamer.release()));
+ PTranslator->translate(IRFilename, std::move(MemObj));
Translator.reset(PTranslator.release());
} else if (ALLOW_LLVM_IR) {
// Parse the input LLVM IR file into a module.