- Finally nailed: test/Regression/Assembler/2002-08-16-ConstExprInlined.llx

- ParseConstantPool was resolving reference to value using the function
      slot # instead of the global slot #.
  - Bytecode reader changes:
    - Remove the failure<> template from Bytecode Reader
    - Remove extraneous #includes
    - s/method/function/ a bit
    - Eliminate the fwdRefs class that just added abstraction where it was not
      needed, making things more complex.
    - Use a vector instead of a list for function signatures.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3366 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2002-08-17 22:01:27 +00:00
parent 8e28a70044
commit 7473413072
4 changed files with 292 additions and 378 deletions

View File

@ -5,7 +5,7 @@
// Note that this library should be as fast as possible, reentrant, and
// threadsafe!!
//
// TODO: Make error message outputs be configurable depending on an option?
// TODO: Return error messages to caller instead of printing them out directly.
// TODO: Allow passing in an option to ignore the symbol table
//
//===----------------------------------------------------------------------===//
@ -13,7 +13,6 @@
#include "ReaderInternals.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Bytecode/Format.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/iPHINode.h"
@ -24,7 +23,6 @@
#include <fcntl.h>
#include <unistd.h>
#include <algorithm>
#include <iostream>
using std::cerr;
using std::pair;
using std::make_pair;
@ -56,14 +54,14 @@ const Type *BytecodeParser::getType(unsigned ID) {
//cerr << "Looking up Type ID: " << ID << "\n";
const Value *D = getValue(Type::TypeTy, ID, false);
if (D == 0) return failure<const Type*>(0);
if (D == 0) return 0;
return cast<Type>(D);
}
int BytecodeParser::insertValue(Value *Val, std::vector<ValueList> &ValueTab) {
unsigned type;
if (getTypeSlot(Val->getType(), type)) return failure<int>(-1);
if (getTypeSlot(Val->getType(), type)) return -1;
assert(type != Type::TypeTyID && "Types should never be insertValue'd!");
if (ValueTab.size() <= type)
@ -80,7 +78,7 @@ Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) {
unsigned Num = oNum;
unsigned type; // The type plane it lives in...
if (getTypeSlot(Ty, type)) return failure<Value*>(0); // TODO: true
if (getTypeSlot(Ty, type)) return 0;
if (type == Type::TypeTyID) { // The 'type' plane has implicit values
assert(Create == false);
@ -111,22 +109,26 @@ Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) {
if (Values.size() > type && Values[type].size() > Num)
return Values[type][Num];
if (!Create) return failure<Value*>(0); // Do not create a placeholder?
if (!Create) return 0; // Do not create a placeholder?
Value *d = 0;
switch (Ty->getPrimitiveID()) {
case Type::LabelTyID: d = new BBPHolder(Ty, oNum); break;
case Type::FunctionTyID:
cerr << "Creating method pholder! : " << type << ":" << oNum << " "
<< Ty->getName() << "\n";
d = new MethPHolder(Ty, oNum);
if (insertValue(d, LateResolveModuleValues) ==-1) return failure<Value*>(0);
d = new FunctionPHolder(Ty, oNum);
if (insertValue(d, LateResolveModuleValues) == -1) return 0;
return d;
default: d = new DefPHolder(Ty, oNum); break;
case Type::LabelTyID:
d = new BBPHolder(Ty, oNum);
break;
default:
d = new ValPHolder(Ty, oNum);
break;
}
assert(d != 0 && "How did we not make something?");
if (insertValue(d, LateResolveValues) == -1) return failure<Value*>(0);
if (insertValue(d, LateResolveValues) == -1) return 0;
return d;
}
@ -168,11 +170,11 @@ bool BytecodeParser::ParseBasicBlock(const uchar *&Buf, const uchar *EndBuf,
Instruction *Inst;
if (ParseInstruction(Buf, EndBuf, Inst)) {
delete BB;
return failure(true);
return true;
}
if (Inst == 0) { delete BB; return failure(true); }
if (insertValue(Inst, Values) == -1) { delete BB; return failure(true); }
if (Inst == 0) { delete BB; return true; }
if (insertValue(Inst, Values) == -1) { delete BB; return true; }
BB->getInstList().push_back(Inst);
@ -188,9 +190,9 @@ bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf,
// Symtab block header: [num entries][type id number]
unsigned NumEntries, Typ;
if (read_vbr(Buf, EndBuf, NumEntries) ||
read_vbr(Buf, EndBuf, Typ)) return failure(true);
read_vbr(Buf, EndBuf, Typ)) return true;
const Type *Ty = getType(Typ);
if (Ty == 0) return failure(true);
if (Ty == 0) return true;
BCR_TRACE(3, "Plane Type: '" << Ty << "' with " << NumEntries <<
" entries\n");
@ -198,15 +200,15 @@ bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf,
for (unsigned i = 0; i < NumEntries; ++i) {
// Symtab entry: [def slot #][name]
unsigned slot;
if (read_vbr(Buf, EndBuf, slot)) return failure(true);
if (read_vbr(Buf, EndBuf, slot)) return true;
std::string Name;
if (read(Buf, EndBuf, Name, false)) // Not aligned...
return failure(true);
return true;
Value *D = getValue(Ty, slot, false); // Find mapping...
if (D == 0) {
BCR_TRACE(3, "FAILED LOOKUP: Slot #" << slot << "\n");
return failure(true);
return true;
}
BCR_TRACE(4, "Map: '" << Name << "' to #" << slot << ":" << D;
if (!isa<Instruction>(D)) cerr << "\n");
@ -215,141 +217,53 @@ bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf,
}
}
if (Buf > EndBuf) return failure(true);
if (Buf > EndBuf) return true;
return false;
}
Value*
ConstantFwdRefs::find(const Type* Ty, unsigned Slot) {
GlobalRefsType::iterator I = GlobalRefs.find(make_pair(Ty, Slot));
if (I != GlobalRefs.end()) {
return I->second;
} else {
return failure<Value*>(0);
}
}
void BytecodeParser::ResolveReferencesToValue(Value *NewV, unsigned Slot) {
GlobalRefsType::iterator I = GlobalRefs.find(make_pair(NewV->getType(),Slot));
if (I == GlobalRefs.end()) return; // Never forward referenced?
void
ConstantFwdRefs::insert(const Type* Ty, unsigned Slot, Value* V) {
// Keep track of the fact that we have a forward ref to recycle it
const pair<GlobalRefsType::iterator, bool>& result =
GlobalRefs.insert(make_pair(make_pair(Ty, Slot), V));
assert(result.second == true && "Entry already exists for this slot?");
}
BCR_TRACE(3, "Mutating forward refs!\n");
Value *VPH = I->second; // Get the placeholder...
void
ConstantFwdRefs::erase(const Type* Ty, unsigned Slot) {
GlobalRefsType::iterator I = GlobalRefs.find(make_pair(Ty, Slot));
if (I != GlobalRefs.end())
GlobalRefs.erase(I);
}
// GetFwdRefToConstant - Get a forward reference to a constant value.
// Create a unique one if it does not exist already.
//
Constant*
ConstantFwdRefs::GetFwdRefToConstant(const Type* Ty, unsigned Slot) {
Constant* C = cast_or_null<Constant>(find(Ty, Slot));
if (C) {
BCR_TRACE(5, "Previous forward ref found!\n");
} else {
// Create a placeholder for the constant reference and
// keep track of the fact that we have a forward ref to recycle it
BCR_TRACE(5, "Creating new forward ref to a constant!\n");
C = new ConstPHolder(Ty, Slot);
insert(Ty, Slot, C);
}
return C;
}
// GetFwdRefToGlobal - Get a forward reference to a global value.
// Create a unique one if it does not exist already.
//
GlobalValue*
ConstantFwdRefs::GetFwdRefToGlobal(const PointerType* PT, unsigned Slot) {
GlobalValue* GV = cast_or_null<GlobalValue>(find(PT, Slot));
if (GV) {
BCR_TRACE(5, "Previous forward ref found!\n");
} else {
BCR_TRACE(5, "Creating new forward ref to a global variable!\n");
// Create a placeholder for the global variable reference...
GlobalVariable *GVar =
new GlobalVariable(PT->getElementType(), false, true);
// Keep track of the fact that we have a forward ref to recycle it
insert(PT, Slot, GVar);
// Must temporarily push this value into the module table...
TheModule->getGlobalList().push_back(GVar);
GV = GVar;
}
return GV;
}
void
ConstantFwdRefs::ResolveRefsToValue(Value* NewV, unsigned Slot) {
if (Value* vph = find(NewV->getType(), Slot)) {
BCR_TRACE(3, "Mutating forward refs!\n");
// Loop over all of the uses of the Value. What they are depends
// on what NewV is. Replacing a use of the old reference takes the
// use off the use list, so loop with !use_empty(), not the use_iterator.
while (!vph->use_empty()) {
Constant *C = cast<Constant>(vph->use_back());
unsigned numReplaced = C->mutateReferences(vph, NewV);
assert(numReplaced > 0 && "Supposed user wasn't really a user?");
// Loop over all of the uses of the Value. What they are depends
// on what NewV is. Replacing a use of the old reference takes the
// use off the use list, so loop with !use_empty(), not the use_iterator.
while (!VPH->use_empty()) {
Constant *C = cast<Constant>(VPH->use_back());
unsigned numReplaced = C->mutateReferences(VPH, NewV);
assert(numReplaced > 0 && "Supposed user wasn't really a user?");
if (GlobalValue* GVal = dyn_cast<GlobalValue>(NewV)) {
// Remove the placeholder GlobalValue from the module...
GVal->getParent()->getGlobalList().remove(cast<GlobalVariable>(vph));
}
if (GlobalValue* GVal = dyn_cast<GlobalValue>(NewV)) {
// Remove the placeholder GlobalValue from the module...
GVal->getParent()->getGlobalList().remove(cast<GlobalVariable>(VPH));
}
delete vph; // Delete the old placeholder
erase(NewV->getType(), Slot); // Remove the map entry for it
}
}
// resolveRefsToGlobal - Patch up forward references to global values in the
// form of ConstantPointerRef.
//
void BytecodeParser::resolveRefsToGlobal(GlobalValue *GV, unsigned Slot) {
fwdRefs.ResolveRefsToValue(GV, Slot);
delete VPH; // Delete the old placeholder
GlobalRefs.erase(I); // Remove the map entry for it
}
// resolveRefsToConstant - Patch up forward references to constants
//
void BytecodeParser::resolveRefsToConstant(Constant *C, unsigned Slot) {
fwdRefs.ResolveRefsToValue(C, Slot);
}
bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
Module *C) {
// Clear out the local values table...
Values.clear();
if (MethodSignatureList.empty()) {
if (FunctionSignatureList.empty()) {
Error = "Function found, but FunctionSignatureList empty!";
return failure(true); // Unexpected method!
return true; // Unexpected method!
}
const PointerType *PMTy = MethodSignatureList.front().first; // PtrMeth
const PointerType *PMTy = FunctionSignatureList.back().first; // PtrMeth
const FunctionType *MTy = dyn_cast<FunctionType>(PMTy->getElementType());
if (MTy == 0) return failure(true); // Not ptr to method!
if (MTy == 0) return true; // Not ptr to method!
unsigned isInternal;
if (read_vbr(Buf, EndBuf, isInternal)) return failure(true);
if (read_vbr(Buf, EndBuf, isInternal)) return true;
unsigned MethSlot = MethodSignatureList.front().second;
MethodSignatureList.pop_front();
unsigned MethSlot = FunctionSignatureList.back().second;
FunctionSignatureList.pop_back();
Function *M = new Function(MTy, isInternal != 0);
BCR_TRACE(2, "METHOD TYPE: " << MTy << "\n");
@ -360,7 +274,7 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
Argument *FA = new Argument(*It);
if (insertValue(FA, Values) == -1) {
Error = "Error reading method arguments!\n";
delete M; return failure(true);
delete M; return true;
}
M->getArgumentList().push_back(FA);
}
@ -370,14 +284,14 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
const uchar *OldBuf = Buf;
if (readBlock(Buf, EndBuf, Type, Size)) {
Error = "Error reading Function level block!";
delete M; return failure(true);
delete M; return true;
}
switch (Type) {
case BytecodeFormat::ConstantPool:
BCR_TRACE(2, "BLOCK BytecodeFormat::ConstantPool: {\n");
if (ParseConstantPool(Buf, Buf+Size, Values, MethodTypeValues)) {
delete M; return failure(true);
delete M; return true;
}
break;
@ -386,7 +300,7 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
BasicBlock *BB;
if (ParseBasicBlock(Buf, Buf+Size, BB) ||
insertValue(BB, Values) == -1) {
delete M; return failure(true); // Parse error... :(
delete M; return true; // Parse error... :(
}
M->getBasicBlockList().push_back(BB);
@ -396,14 +310,14 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
case BytecodeFormat::SymbolTable:
BCR_TRACE(2, "BLOCK BytecodeFormat::SymbolTable: {\n");
if (ParseSymbolTable(Buf, Buf+Size, M->getSymbolTableSure())) {
delete M; return failure(true);
delete M; return true;
}
break;
default:
BCR_TRACE(2, "BLOCK <unknown>:ignored! {\n");
Buf += Size;
if (OldBuf > Buf) return failure(true); // Wrap around!
if (OldBuf > Buf) return true; // Wrap around!
break;
}
BCR_TRACE(2, "} end block\n");
@ -411,19 +325,19 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
if (align32(Buf, EndBuf)) {
Error = "Error aligning Function level block!";
delete M; // Malformed bc file, read past end of block.
return failure(true);
return true;
}
}
if (postResolveValues(LateResolveValues) ||
postResolveValues(LateResolveModuleValues)) {
Error = "Error resolving method values!";
delete M; return failure(true); // Unresolvable references!
delete M; return true; // Unresolvable references!
}
Value *MethPHolder = getValue(PMTy, MethSlot, false);
assert(MethPHolder && "Something is broken no placeholder found!");
assert(isa<Function>(MethPHolder) && "Not a function?");
Value *FunctionPHolder = getValue(PMTy, MethSlot, false);
assert(FunctionPHolder && "Something is broken no placeholder found!");
assert(isa<Function>(FunctionPHolder) && "Not a function?");
unsigned type; // Type slot
assert(!getTypeSlot(MTy, type) && "How can meth type not exist?");
@ -438,37 +352,37 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
MethodTypeValues.clear();
// If anyone is using the placeholder make them use the real method instead
MethPHolder->replaceAllUsesWith(M);
FunctionPHolder->replaceAllUsesWith(M);
// We don't need the placeholder anymore!
delete MethPHolder;
delete FunctionPHolder;
// If the method is empty, we don't need the method argument entries...
if (M->isExternal())
M->getArgumentList().clear();
resolveRefsToGlobal(M, MethSlot);
ResolveReferencesToValue(M, MethSlot);
return false;
}
bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
Module *Mod) {
if (!MethodSignatureList.empty()) {
if (!FunctionSignatureList.empty()) {
Error = "Two ModuleGlobalInfo packets found!";
return failure(true); // Two ModuleGlobal blocks?
return true; // Two ModuleGlobal blocks?
}
// Read global variables...
unsigned VarType;
if (read_vbr(Buf, End, VarType)) return failure(true);
if (read_vbr(Buf, End, VarType)) return true;
while (VarType != Type::VoidTyID) { // List is terminated by Void
// VarType Fields: bit0 = isConstant, bit1 = hasInitializer,
// bit2 = isInternal, bit3+ = slot#
const Type *Ty = getType(VarType >> 3);
if (!Ty || !isa<PointerType>(Ty)) {
Error = "Global not pointer type! Ty = " + Ty->getDescription();
return failure(true);
return true;
}
const PointerType *PTy = cast<const PointerType>(Ty);
@ -480,10 +394,10 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
// which should have been read before now.
//
unsigned InitSlot;
if (read_vbr(Buf, End, InitSlot)) return failure(true);
if (read_vbr(Buf, End, InitSlot)) return true;
Value *V = getValue(ElTy, InitSlot, false);
if (V == 0) return failure(true);
if (V == 0) return true;
Initializer = cast<Constant>(V);
}
@ -491,28 +405,28 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, VarType & 4,
Initializer);
int DestSlot = insertValue(GV, ModuleValues);
if (DestSlot == -1) return failure(true);
if (DestSlot == -1) return true;
Mod->getGlobalList().push_back(GV);
resolveRefsToGlobal(GV, unsigned(DestSlot));
ResolveReferencesToValue(GV, (unsigned)DestSlot);
BCR_TRACE(2, "Global Variable of type: " << PTy->getDescription()
<< " into slot #" << DestSlot << "\n");
if (read_vbr(Buf, End, VarType)) return failure(true);
if (read_vbr(Buf, End, VarType)) return true;
}
// Read the method signatures for all of the methods that are coming, and
// create fillers in the Value tables.
unsigned MethSignature;
if (read_vbr(Buf, End, MethSignature)) return failure(true);
while (MethSignature != Type::VoidTyID) { // List is terminated by Void
const Type *Ty = getType(MethSignature);
unsigned FnSignature;
if (read_vbr(Buf, End, FnSignature)) return true;
while (FnSignature != Type::VoidTyID) { // List is terminated by Void
const Type *Ty = getType(FnSignature);
if (!Ty || !isa<PointerType>(Ty) ||
!isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) {
Error = "Function not ptr to func type! Ty = " + Ty->getDescription();
return failure(true);
return true;
}
// We create methods by passing the underlying FunctionType to create...
@ -524,25 +438,29 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
// placeholder is replaced.
// Insert the placeholder...
Value *Val = new MethPHolder(Ty, 0);
if (insertValue(Val, ModuleValues) == -1) return failure(true);
Value *Val = new FunctionPHolder(Ty, 0);
if (insertValue(Val, ModuleValues) == -1) return true;
// Figure out which entry of its typeslot it went into...
unsigned TypeSlot;
if (getTypeSlot(Val->getType(), TypeSlot)) return failure(true);
if (getTypeSlot(Val->getType(), TypeSlot)) return true;
unsigned SlotNo = ModuleValues[TypeSlot].size()-1;
// Keep track of this information in a linked list that is emptied as
// methods are loaded...
//
MethodSignatureList.push_back(
FunctionSignatureList.push_back(
make_pair(cast<const PointerType>(Val->getType()), SlotNo));
if (read_vbr(Buf, End, MethSignature)) return failure(true);
if (read_vbr(Buf, End, FnSignature)) return true;
BCR_TRACE(2, "Function of type: " << Ty << "\n");
}
if (align32(Buf, End)) return failure(true);
if (align32(Buf, End)) return true;
// Now that the function signature list is set up, reverse it so that we can
// remove elements efficiently from the back of the vector.
std::reverse(FunctionSignatureList.begin(), FunctionSignatureList.end());
// This is for future proofing... in the future extra fields may be added that
// we don't understand, so we transparently ignore them.
@ -552,73 +470,72 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
}
bool BytecodeParser::ParseModule(const uchar *Buf, const uchar *EndBuf,
Module *&C) {
Module *&Mod) {
unsigned Type, Size;
if (readBlock(Buf, EndBuf, Type, Size)) return failure(true);
if (readBlock(Buf, EndBuf, Type, Size)) return true;
if (Type != BytecodeFormat::Module || Buf+Size != EndBuf) {
Error = "Expected Module packet!";
return failure(true); // Hrm, not a class?
return true; // Hrm, not a class?
}
BCR_TRACE(0, "BLOCK BytecodeFormat::Module: {\n");
MethodSignatureList.clear(); // Just in case...
FunctionSignatureList.clear(); // Just in case...
// Read into instance variables...
if (read_vbr(Buf, EndBuf, FirstDerivedTyID)) return failure(true);
if (align32(Buf, EndBuf)) return failure(true);
if (read_vbr(Buf, EndBuf, FirstDerivedTyID)) return true;
if (align32(Buf, EndBuf)) return true;
BCR_TRACE(1, "FirstDerivedTyID = " << FirstDerivedTyID << "\n");
TheModule = C = new Module();
fwdRefs.VisitingModule(TheModule);
TheModule = Mod = new Module();
while (Buf < EndBuf) {
const uchar *OldBuf = Buf;
if (readBlock(Buf, EndBuf, Type, Size)) { delete C; return failure(true); }
if (readBlock(Buf, EndBuf, Type, Size)) { delete Mod; return true;}
switch (Type) {
case BytecodeFormat::ConstantPool:
BCR_TRACE(1, "BLOCK BytecodeFormat::ConstantPool: {\n");
if (ParseConstantPool(Buf, Buf+Size, ModuleValues, ModuleTypeValues)) {
delete C; return failure(true);
delete Mod; return true;
}
break;
case BytecodeFormat::ModuleGlobalInfo:
BCR_TRACE(1, "BLOCK BytecodeFormat::ModuleGlobalInfo: {\n");
if (ParseModuleGlobalInfo(Buf, Buf+Size, C)) {
delete C; return failure(true);
if (ParseModuleGlobalInfo(Buf, Buf+Size, Mod)) {
delete Mod; return true;
}
break;
case BytecodeFormat::Function: {
BCR_TRACE(1, "BLOCK BytecodeFormat::Function: {\n");
if (ParseMethod(Buf, Buf+Size, C)) {
delete C; return failure(true); // Error parsing method
if (ParseMethod(Buf, Buf+Size, Mod)) {
delete Mod; return true; // Error parsing function
}
break;
}
case BytecodeFormat::SymbolTable:
BCR_TRACE(1, "BLOCK BytecodeFormat::SymbolTable: {\n");
if (ParseSymbolTable(Buf, Buf+Size, C->getSymbolTableSure())) {
delete C; return failure(true);
if (ParseSymbolTable(Buf, Buf+Size, Mod->getSymbolTableSure())) {
delete Mod; return true;
}
break;
default:
Error = "Expected Module Block!";
Buf += Size;
if (OldBuf > Buf) return failure(true); // Wrap around!
if (OldBuf > Buf) return true; // Wrap around!
break;
}
BCR_TRACE(1, "} end block\n");
if (align32(Buf, EndBuf)) { delete C; return failure(true); }
if (align32(Buf, EndBuf)) { delete Mod; return true; }
}
if (!MethodSignatureList.empty()) { // Expected more methods!
if (!FunctionSignatureList.empty()) { // Expected more methods!
Error = "Function expected, but bytecode stream at end!";
return failure(true);
return true;
}
BCR_TRACE(0, "} end block\n\n");
@ -632,7 +549,7 @@ Module *BytecodeParser::ParseBytecode(const uchar *Buf, const uchar *EndBuf) {
if (read(Buf, EndBuf, Sig) ||
Sig != ('l' | ('l' << 8) | ('v' << 16) | 'm' << 24)) {
Error = "Invalid bytecode signature!";
return failure<Module*>(0); // Invalid signature!
return 0; // Invalid signature!
}
Module *Result;
@ -656,21 +573,21 @@ Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) {
int FD = open(Filename.c_str(), O_RDONLY);
if (FD == -1) {
if (ErrorStr) *ErrorStr = "Error opening file!";
return failure<Module*>(0);
return 0;
}
if (fstat(FD, &StatBuf) == -1) { close(FD); return failure<Module*>(0); }
if (fstat(FD, &StatBuf) == -1) { close(FD); return 0; }
int Length = StatBuf.st_size;
if (Length == 0) {
if (ErrorStr) *ErrorStr = "Error stat'ing file!";
close(FD); return failure<Module*>(0);
close(FD); return 0;
}
uchar *Buffer = (uchar*)mmap(0, Length, PROT_READ,
MAP_PRIVATE, FD, 0);
if (Buffer == (uchar*)-1) {
if (ErrorStr) *ErrorStr = "Error mmapping file!";
close(FD); return failure<Module*>(0);
close(FD); return 0;
}
BytecodeParser Parser;
@ -684,7 +601,7 @@ Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) {
int BlockSize;
uchar Buffer[4096], *FileData = 0;
while ((BlockSize = read(0, Buffer, 4))) {
if (BlockSize == -1) { free(FileData); return failure<Module*>(0); }
if (BlockSize == -1) { free(FileData); return 0; }
FileData = (uchar*)realloc(FileData, FileSize+BlockSize);
memcpy(FileData+FileSize, Buffer, BlockSize);
@ -693,7 +610,7 @@ Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) {
if (FileSize == 0) {
if (ErrorStr) *ErrorStr = "Standard Input empty!";
free(FileData); return failure<Module*>(0);
free(FileData); return 0;
}
#define ALIGN_PTRS 1