Chromium Code Reviews| Index: lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeReader.cpp |
| diff --git a/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeReader.cpp b/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeReader.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..cf6df18dfd39a96b4e0d72154ce47e0a0bd3cb06 |
| --- /dev/null |
| +++ b/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeReader.cpp |
| @@ -0,0 +1,157 @@ |
| +//===- NaClBitcodeMungeReader.cpp - Read bitcode record list ----*- C++ -*-===// |
| +// |
| +// The LLVM Compiler Infrastructure |
| +// |
| +// This file is distributed under the University of Illinois Open Source |
| +// License. See LICENSE.TXT for details. |
| +// |
| +//===----------------------------------------------------------------------===// |
| +// |
| +// Implements bitcode reader for NaClBitcodeRecordList and NaClMungedBitcode. |
|
jvoung (off chromium)
2015/05/05 00:27:23
extra space in " NaClMungedBitcode"
Karl
2015/05/05 22:38:03
Done.
|
| + |
| +#include "llvm/Bitcode/NaCl/NaClBitcodeMungeUtils.h" |
| + |
| +#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
| +#include "llvm/Support/MemoryBuffer.h" |
| + |
| +using namespace llvm; |
| + |
| +namespace { |
| + |
| +class BitcodeParser; |
| + |
| +// \brief The state associated with parsing a bitcode buffer. |
| +class BitcodeParseState { |
| + BitcodeParseState(const BitcodeParseState&) = delete; |
| + BitcodeParseState &operator=(const BitcodeParseState&) = delete; |
| +public: |
| + // \brief Construct the bitcode parse state. |
| + // |
| + // \param Parser The parser used to parse the bitcode. |
| + // \param[out] Records Filled with parsed records. |
| + BitcodeParseState(BitcodeParser *Parser, |
| + NaClBitcodeRecordList &Records); |
| + |
| + // List to read records into. |
| + NaClBitcodeRecordList &Records; |
| + // Listener use to get abbreviations as they are read. |
|
jvoung (off chromium)
2015/05/05 00:27:23
"use to get" -> "used to get" ?
Karl
2015/05/05 22:38:04
Done.
|
| + NaClBitcodeParserListener AbbrevListener; |
| + // |
|
jvoung (off chromium)
2015/05/05 00:27:23
Dangling "//"
Karl
2015/05/05 22:38:03
Done.
|
| +}; |
| + |
| +// \brief The bitcode parser to extract bitcode records. |
| +class BitcodeParser : public NaClBitcodeParser { |
| + BitcodeParser(const BitcodeParser &) = delete; |
| + BitcodeParser &operator=(const BitcodeParser&) = delete; |
| +public: |
| + // \brief Top-level constructor for a bitcode parser. |
| + // |
| + // \param Cursor The beginning position of the bitcode to parse. |
| + // \param[out] Records Filled with parsed records. |
| + BitcodeParser(NaClBitstreamCursor &Cursor, |
| + NaClBitcodeRecordList &Records) |
| + : NaClBitcodeParser(Cursor), |
| + State(new BitcodeParseState(this, Records)) { |
| + SetListener(&State->AbbrevListener); |
| + } |
| + |
| + virtual ~BitcodeParser() override { |
|
jvoung (off chromium)
2015/05/05 00:27:23
Only need one "override" and don't need "virtual"
Karl
2015/05/05 22:38:03
Done.
|
| + if (EnclosingParser == nullptr) |
| + delete State; |
| + } |
| + |
| + bool ParseBlock(unsigned BlockID) override { |
| + BitcodeParser NestedParser(BlockID, this); |
| + return NestedParser.ParseThisBlock(); |
| + } |
| + |
| + void EnterBlock(unsigned NumWords) override { |
| + NaClRecordVector Values; |
| + Values.push_back(GetBlockID()); |
| + Values.push_back(Record.GetCursor().getAbbrevIDWidth()); |
| + std::unique_ptr<NaClBitcodeAbbrevRecord> AbbrevRec( |
| + new NaClBitcodeAbbrevRecord(naclbitc::ENTER_SUBBLOCK, |
| + naclbitc::BLK_CODE_ENTER, |
| + Values)); |
| + State->Records.push_back(std::move(AbbrevRec)); |
| + } |
| + |
| + void ExitBlock() override { |
| + NaClRecordVector Values; |
| + std::unique_ptr<NaClBitcodeAbbrevRecord> AbbrevRec( |
| + new NaClBitcodeAbbrevRecord(naclbitc::END_BLOCK, |
| + naclbitc::BLK_CODE_EXIT, |
| + Values)); |
| + State->Records.push_back(std::move(AbbrevRec)); |
| + } |
| + |
| + void ProcessRecord() override { |
| + std::unique_ptr<NaClBitcodeAbbrevRecord> AbbrevRec( |
| + new NaClBitcodeAbbrevRecord(Record.GetAbbreviationIndex(), |
| + Record.GetCode(), |
| + Record.GetValues())); |
| + State->Records.push_back(std::move(AbbrevRec)); |
| + } |
| + |
| + void SetBID() override { |
| + ProcessRecord(); |
| + } |
| + |
| + void ProcessAbbreviation(unsigned BlockID, |
| + NaClBitCodeAbbrev *Abbrev, |
| + bool IsLocal) override { |
| + ProcessRecord(); |
| + } |
| + |
| +private: |
| + // \brief Nested constructor for blocks within the bitcode buffer. |
| + // |
| + // \param BlockID The identifying constant associated with the block. |
| + // \param EnclosingParser The bitcode parser parsing the enclosing block. |
| + BitcodeParser(unsigned BlockID, BitcodeParser *EnclosingParser) |
| + : NaClBitcodeParser(BlockID, EnclosingParser), |
| + State(EnclosingParser->State) {} |
| + |
| + // The state of the bitcode parser. |
| + BitcodeParseState* State; |
| +}; |
| + |
| +BitcodeParseState::BitcodeParseState(BitcodeParser *Parser, |
| + NaClBitcodeRecordList &Records) |
| + : Records(Records), AbbrevListener(Parser) {} |
| + |
| +} // end of anonymous namespace |
| + |
| +void llvm::readNaClBitcodeRecordList( |
| + NaClBitcodeRecordList &RecordList, |
| + std::unique_ptr<MemoryBuffer> InputBuffer) { |
| + if (InputBuffer->getBufferSize() % 4 != 0) |
| + report_fatal_error("Bitcode stream must be a multiple of 4 bytes in length"); |
|
jvoung (off chromium)
2015/05/05 00:27:23
just a little too long for 80 cols
Karl
2015/05/05 22:38:03
Done.
|
| + |
| + const unsigned char *BufPtr = |
| + (const unsigned char *) InputBuffer->getBufferStart(); |
| + const unsigned char *EndBufPtr = BufPtr + InputBuffer->getBufferSize(); |
| + const unsigned char *HeaderPtr = BufPtr; |
| + |
| + // Read header and verify it is good. |
| + NaClBitcodeHeader Header; |
| + if (Header.Read(HeaderPtr, EndBufPtr) || !Header.IsSupported()) |
| + report_fatal_error("Invalid PNaCl bitcode header.\n"); |
| + |
| + NaClBitstreamReader Reader(BufPtr, EndBufPtr, Header.getHeaderSize()); |
| + NaClBitstreamCursor Cursor(Reader); |
| + |
| + // Parse the bitcode buffer. |
| + BitcodeParser Parser(Cursor, RecordList); |
| + |
| + while (!Parser.AtEndOfStream()) { |
|
jvoung (off chromium)
2015/05/05 00:27:22
There are a couple of instances of code that are v
Karl
2015/05/05 22:38:03
The problem I discovered was that this pattern was
|
| + if (Parser.Parse()) |
| + report_fatal_error("Malformed records founds, unable to continue"); |
| + } |
| +} |
| + |
| + |
| +NaClMungedBitcode::NaClMungedBitcode(std::unique_ptr<MemoryBuffer> InputBuffer) |
| + : BaseRecords(new NaClBitcodeRecordList()) { |
| + readNaClBitcodeRecordList(*BaseRecords, std::move(InputBuffer)); |
| +} |