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 |