| Index: src/PNaClTranslator.cpp
|
| diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
|
| index 6ff9d97929ba5bc5d48ac61738786cd3e150bbc2..1eb1767dbf195f0c9afb9a9ccdb218d13665b708 100644
|
| --- a/src/PNaClTranslator.cpp
|
| +++ b/src/PNaClTranslator.cpp
|
| @@ -306,24 +306,11 @@ public:
|
| }
|
| }
|
|
|
| - /// Creates Count global variable declarations.
|
| - void createGlobalVariables(NaClBcIndexSize_t Count) {
|
| + /// Adds the given global declaration to the end of the list of global
|
| + /// declarations.
|
| + void addGlobalDeclaration(Ice::VariableDeclaration *Decl) {
|
| assert(VariableDeclarations);
|
| - assert(VariableDeclarations->empty());
|
| - for (size_t i = 0; i < Count; ++i) {
|
| - VariableDeclarations->push_back(
|
| - Ice::VariableDeclaration::create(getTranslator().getContext()));
|
| - }
|
| - }
|
| -
|
| - /// Returns the number of global variable declarations in the
|
| - /// bitcode file.
|
| - size_t getNumGlobalVariables() const {
|
| - if (VariableDeclarations) {
|
| - return VariableDeclarations->size();
|
| - } else {
|
| - return ValueIDConstants.size() - FunctionDeclarationList.size();
|
| - }
|
| + VariableDeclarations->push_back(Decl);
|
| }
|
|
|
| /// Returns the global variable declaration with the given index.
|
| @@ -955,6 +942,7 @@ public:
|
| GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser)
|
| : BlockParserBaseClass(BlockID, EnclosingParser),
|
| Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()),
|
| + NumFunctionIDs(Context->getNumFunctionIDs()),
|
| DummyGlobalVar(
|
| Ice::VariableDeclaration::create(getTranslator().getContext())),
|
| CurGlobalVar(DummyGlobalVar) {}
|
| @@ -964,7 +952,21 @@ public:
|
| const char *getBlockName() const override { return "globals"; }
|
|
|
| private:
|
| + typedef std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>
|
| + GlobalVarsMapType;
|
| +
|
| Ice::TimerMarker Timer;
|
| +
|
| + // Holds global variables generated/referenced in the global variables block.
|
| + GlobalVarsMapType GlobalVarsMap;
|
| +
|
| + // Holds the number of defined function IDs.
|
| + NaClBcIndexSize_t NumFunctionIDs;
|
| +
|
| + // Holds the specified number of global variables by the count record in
|
| + // the global variables block.
|
| + NaClBcIndexSize_t SpecifiedNumberVars = 0;
|
| +
|
| // Keeps track of how many initializers are expected for the global variable
|
| // declaration being built.
|
| NaClBcIndexSize_t InitializersNeeded = 0;
|
| @@ -980,16 +982,43 @@ private:
|
| // Holds the current global variable declaration being built.
|
| Ice::VariableDeclaration *CurGlobalVar;
|
|
|
| - void ExitBlock() override {
|
| - verifyNoMissingInitializers();
|
| - unsigned NumIDs = Context->getNumGlobalVariables();
|
| - if (NextGlobalID < NumIDs) {
|
| + // Returns the global variable associated with the given Index.
|
| + Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) {
|
| + Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index];
|
| + if (Decl == nullptr)
|
| + Decl = Ice::VariableDeclaration::create(getTranslator().getContext());
|
| + return Decl;
|
| + }
|
| +
|
| + // Returns the global declaration associated with the given index.
|
| + Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) {
|
| + if (Index < NumFunctionIDs)
|
| + return Context->getFunctionByID(Index);
|
| + return getGlobalVarByID(Index - NumFunctionIDs);
|
| + }
|
| +
|
| + // If global variables parsed correctly, install them into the top-level
|
| + // context.
|
| + void installGlobalVariables() {
|
| + // Verify specified number of globals matches number found.
|
| + size_t NumGlobals = GlobalVarsMap.size();
|
| + if (SpecifiedNumberVars != NumGlobals ||
|
| + SpecifiedNumberVars != NextGlobalID) {
|
| std::string Buffer;
|
| raw_string_ostream StrBuf(Buffer);
|
| - StrBuf << getBlockName() << " block expects " << NumIDs
|
| - << " global variable declarations. Found: " << NextGlobalID;
|
| + StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars
|
| + << " global variables. Found: " << GlobalVarsMap.size();
|
| Error(StrBuf.str());
|
| + return;
|
| }
|
| + // Install global variables into top-level context.
|
| + for (size_t I = 0; I < NumGlobals; ++I)
|
| + Context->addGlobalDeclaration(GlobalVarsMap[I]);
|
| + }
|
| +
|
| + void ExitBlock() override {
|
| + verifyNoMissingInitializers();
|
| + installGlobalVariables();
|
| BlockParserBaseClass::ExitBlock();
|
| }
|
|
|
| @@ -1022,20 +1051,23 @@ void GlobalsParser::ProcessRecord() {
|
| // COUNT: [n]
|
| if (!isValidRecordSize(1, "count"))
|
| return;
|
| - if (NextGlobalID != Context->getNumGlobalVariables()) {
|
| + if (SpecifiedNumberVars || NextGlobalID) {
|
| Error("Globals count record not first in block.");
|
| return;
|
| }
|
| - Context->createGlobalVariables(Values[0]);
|
| + SpecifiedNumberVars = Values[0];
|
| return;
|
| case naclbitc::GLOBALVAR_VAR: {
|
| // VAR: [align, isconst]
|
| if (!isValidRecordSize(2, "variable"))
|
| return;
|
| verifyNoMissingInitializers();
|
| + // Always build the global variable, even if IR generation is turned off.
|
| + // This is needed because we need a placeholder in the top-level context
|
| + // when no IR is generated.
|
| + CurGlobalVar = getGlobalVarByID(NextGlobalID);
|
| if (!isIRGenerationDisabled()) {
|
| InitializersNeeded = 1;
|
| - CurGlobalVar = Context->getGlobalVariableByID(NextGlobalID);
|
| CurGlobalVar->setAlignment((1 << Values[0]) >> 1);
|
| CurGlobalVar->setIsConstant(Values[1] != 0);
|
| }
|
| @@ -1088,7 +1120,15 @@ void GlobalsParser::ProcessRecord() {
|
| return;
|
| if (isIRGenerationDisabled())
|
| return;
|
| - unsigned Index = Values[0];
|
| + NaClBcIndexSize_t Index = Values[0];
|
| + NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs;
|
| + if (Index >= IndexLimit) {
|
| + std::string Buffer;
|
| + raw_string_ostream StrBuf(Buffer);
|
| + StrBuf << "Relocation index " << Index << " to big. Expect index < "
|
| + << IndexLimit;
|
| + Error(StrBuf.str());
|
| + }
|
| uint64_t Offset = 0;
|
| if (Values.size() == 2) {
|
| Offset = Values[1];
|
| @@ -1101,7 +1141,7 @@ void GlobalsParser::ProcessRecord() {
|
| }
|
| CurGlobalVar->addInitializer(
|
| Ice::VariableDeclaration::RelocInitializer::create(
|
| - Context->getGlobalDeclarationByID(Index), Offset));
|
| + getGlobalDeclByID(Index), Offset));
|
| return;
|
| }
|
| default:
|
|
|