| OLD | NEW |
| 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// | 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 /// Returns the global declaration (variable or function) with the given | 331 /// Returns the global declaration (variable or function) with the given |
| 332 /// Index. | 332 /// Index. |
| 333 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) { | 333 Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) { |
| 334 size_t NumFunctionIds = FunctionDeclarations.size(); | 334 size_t NumFunctionIds = FunctionDeclarations.size(); |
| 335 if (Index < NumFunctionIds) | 335 if (Index < NumFunctionIds) |
| 336 return getFunctionByID(Index); | 336 return getFunctionByID(Index); |
| 337 else | 337 else |
| 338 return getGlobalVariableByID(Index - NumFunctionIds); | 338 return getGlobalVariableByID(Index - NumFunctionIds); |
| 339 } | 339 } |
| 340 | 340 |
| 341 /// Returns true if a module block has been parsed. |
| 342 bool parsedModuleBlock() const { return ParsedModuleBlock; } |
| 343 |
| 341 /// Returns the list of parsed global variable declarations. Releases | 344 /// Returns the list of parsed global variable declarations. Releases |
| 342 /// ownership of the current list of global variables. Note: only returns | 345 /// ownership of the current list of global variables. Note: only returns |
| 343 /// non-null pointer on first call. All successive calls return a null | 346 /// non-null pointer on first call. All successive calls return a null |
| 344 /// pointer. | 347 /// pointer. |
| 345 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() { | 348 std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() { |
| 346 // Before returning, check that ValidIDConstants has already been built. | 349 // Before returning, check that ValidIDConstants has already been built. |
| 347 assert(!VariableDeclarations || | 350 assert(!VariableDeclarations || |
| 348 VariableDeclarations->size() <= ValueIDConstants.size()); | 351 VariableDeclarations->size() <= ValueIDConstants.size()); |
| 349 return std::move(VariableDeclarations); | 352 return std::move(VariableDeclarations); |
| 350 } | 353 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 367 // function. | 370 // function. |
| 368 size_t NextDefiningFunctionID = 0; | 371 size_t NextDefiningFunctionID = 0; |
| 369 // The set of global variables. | 372 // The set of global variables. |
| 370 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations; | 373 std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations; |
| 371 // Relocatable constants associated with global declarations. | 374 // Relocatable constants associated with global declarations. |
| 372 Ice::ConstantList ValueIDConstants; | 375 Ice::ConstantList ValueIDConstants; |
| 373 // Error recovery value to use when getFuncSigTypeByID fails. | 376 // Error recovery value to use when getFuncSigTypeByID fails. |
| 374 Ice::FuncSigType UndefinedFuncSigType; | 377 Ice::FuncSigType UndefinedFuncSigType; |
| 375 // The block parser currently being applied. Used for error reporting. | 378 // The block parser currently being applied. Used for error reporting. |
| 376 BlockParserBaseClass *BlockParser = nullptr; | 379 BlockParserBaseClass *BlockParser = nullptr; |
| 380 // Defines if a module block has already been parsed. |
| 381 bool ParsedModuleBlock = false; |
| 377 | 382 |
| 378 bool ParseBlock(unsigned BlockID) override; | 383 bool ParseBlock(unsigned BlockID) override; |
| 379 | 384 |
| 380 // Gets extended type associated with the given index, assuming the extended | 385 // Gets extended type associated with the given index, assuming the extended |
| 381 // type is of the WantedKind. Generates error message if corresponding | 386 // type is of the WantedKind. Generates error message if corresponding |
| 382 // extended type of WantedKind can't be found, and returns nullptr. | 387 // extended type of WantedKind can't be found, and returns nullptr. |
| 383 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID, | 388 ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID, |
| 384 ExtendedType::TypeKind WantedKind) { | 389 ExtendedType::TypeKind WantedKind) { |
| 385 ExtendedType *Ty = nullptr; | 390 ExtendedType *Ty = nullptr; |
| 386 if (ID < TypeIDValues.size()) { | 391 if (ID < TypeIDValues.size()) { |
| (...skipping 2826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3213 return; | 3218 return; |
| 3214 } | 3219 } |
| 3215 default: | 3220 default: |
| 3216 BlockParserBaseClass::ProcessRecord(); | 3221 BlockParserBaseClass::ProcessRecord(); |
| 3217 return; | 3222 return; |
| 3218 } | 3223 } |
| 3219 } | 3224 } |
| 3220 | 3225 |
| 3221 bool TopLevelParser::ParseBlock(unsigned BlockID) { | 3226 bool TopLevelParser::ParseBlock(unsigned BlockID) { |
| 3222 if (BlockID == naclbitc::MODULE_BLOCK_ID) { | 3227 if (BlockID == naclbitc::MODULE_BLOCK_ID) { |
| 3228 if (ParsedModuleBlock) |
| 3229 Fatal("Input can't contain more than one module"); |
| 3223 ModuleParser Parser(BlockID, this); | 3230 ModuleParser Parser(BlockID, this); |
| 3224 return Parser.ParseThisBlock(); | 3231 bool ParseFailed = Parser.ParseThisBlock(); |
| 3232 ParsedModuleBlock = true; |
| 3233 return ParseFailed; |
| 3225 } | 3234 } |
| 3226 // Generate error message by using default block implementation. | 3235 // Generate error message by using default block implementation. |
| 3227 BlockParserBaseClass Parser(BlockID, this); | 3236 BlockParserBaseClass Parser(BlockID, this); |
| 3228 return Parser.ParseThisBlock(); | 3237 return Parser.ParseThisBlock(); |
| 3229 } | 3238 } |
| 3230 | 3239 |
| 3231 } // end of anonymous namespace | 3240 } // end of anonymous namespace |
| 3232 | 3241 |
| 3233 namespace Ice { | 3242 namespace Ice { |
| 3234 | 3243 |
| 3235 void PNaClTranslator::translateBuffer(const std::string &IRFilename, | 3244 void PNaClTranslator::translateBuffer(const std::string &IRFilename, |
| 3236 MemoryBuffer *MemBuf) { | 3245 MemoryBuffer *MemBuf) { |
| 3237 std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject( | 3246 std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject( |
| 3238 reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()), | 3247 reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()), |
| 3239 reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd()))); | 3248 reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd()))); |
| 3240 translate(IRFilename, std::move(MemObj)); | 3249 translate(IRFilename, std::move(MemObj)); |
| 3241 } | 3250 } |
| 3242 | 3251 |
| 3243 void PNaClTranslator::translate(const std::string &IRFilename, | 3252 void PNaClTranslator::translate(const std::string &IRFilename, |
| 3244 std::unique_ptr<MemoryObject> &&MemObj) { | 3253 std::unique_ptr<MemoryObject> &&MemObj) { |
| 3245 // On error, we report_fatal_error to avoid destroying the MemObj. That may | 3254 // On error, we report_fatal_error to avoid destroying the MemObj. That may |
| 3246 // still be in use by IceBrowserCompileServer. Otherwise, we need to change | 3255 // still be in use by IceBrowserCompileServer. Otherwise, we need to change |
| 3247 // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also | 3256 // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also |
| 3248 // need a hook to tell the IceBrowserCompileServer to unblock its | 3257 // need a hook to tell the IceBrowserCompileServer to unblock its |
| 3249 // QueueStreamer. | 3258 // QueueStreamer. |
| 3250 // https://code.google.com/p/nativeclient/issues/detail?id=4163 | 3259 // https://code.google.com/p/nativeclient/issues/detail?id=4163 |
| 3251 Ostream &ErrStream = getContext()->getStrError(); | |
| 3252 // Read header and verify it is good. | 3260 // Read header and verify it is good. |
| 3253 NaClBitcodeHeader Header; | 3261 NaClBitcodeHeader Header; |
| 3254 if (Header.Read(MemObj.get())) { | 3262 if (Header.Read(MemObj.get())) { |
| 3255 llvm::report_fatal_error("Invalid PNaCl bitcode header"); | 3263 llvm::report_fatal_error("Invalid PNaCl bitcode header"); |
| 3256 } | 3264 } |
| 3257 if (!Header.IsSupported()) { | 3265 if (!Header.IsSupported()) { |
| 3258 ErrStream << Header.Unsupported(); | 3266 getContext()->getStrError() << Header.Unsupported(); |
| 3259 if (!Header.IsReadable()) { | 3267 if (!Header.IsReadable()) { |
| 3260 llvm::report_fatal_error("Invalid PNaCl bitcode header"); | 3268 llvm::report_fatal_error("Invalid PNaCl bitcode header"); |
| 3261 } | 3269 } |
| 3262 } | 3270 } |
| 3263 | 3271 |
| 3264 // Create a bitstream reader to read the bitcode file. | 3272 // Create a bitstream reader to read the bitcode file. |
| 3265 NaClBitstreamReader InputStreamFile(MemObj.release(), Header); | 3273 NaClBitstreamReader InputStreamFile(MemObj.release(), Header); |
| 3266 NaClBitstreamCursor InputStream(InputStreamFile); | 3274 NaClBitstreamCursor InputStream(InputStreamFile); |
| 3267 | 3275 |
| 3268 TopLevelParser Parser(*this, InputStream, ErrorStatus); | 3276 TopLevelParser Parser(*this, InputStream, ErrorStatus); |
| 3269 int TopLevelBlocks = 0; | |
| 3270 while (!InputStream.AtEndOfStream()) { | 3277 while (!InputStream.AtEndOfStream()) { |
| 3271 if (Parser.Parse()) { | 3278 if (Parser.Parse()) { |
| 3272 ErrorStatus.assign(EC_Bitcode); | 3279 ErrorStatus.assign(EC_Bitcode); |
| 3273 return; | 3280 return; |
| 3274 } | 3281 } |
| 3275 ++TopLevelBlocks; | |
| 3276 } | 3282 } |
| 3277 | 3283 |
| 3278 if (TopLevelBlocks != 1) { | 3284 if (!Parser.parsedModuleBlock()) { |
| 3279 ErrStream << IRFilename | 3285 std::string Buffer; |
| 3280 << ": Contains more than one module. Found: " << TopLevelBlocks | 3286 raw_string_ostream StrBuf(Buffer); |
| 3281 << "\n"; | 3287 StrBuf << IRFilename << ": Does not contain a module!"; |
| 3282 llvm::report_fatal_error("Bitcode has more than one module"); | 3288 llvm::report_fatal_error(StrBuf.str()); |
| 3283 } | 3289 } |
| 3284 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { | 3290 if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { |
| 3285 ErrStream | |
| 3286 << IRFilename | |
| 3287 << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; | |
| 3288 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); | 3291 llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); |
| 3289 } | 3292 } |
| 3290 } | 3293 } |
| 3291 | 3294 |
| 3292 } // end of namespace Ice | 3295 } // end of namespace Ice |
| OLD | NEW |