mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-15 22:28:18 +00:00
Major refactoring of the bytecode reader. This includes the following
changes: * BytecodeReader::getType(...) used to return a null pointer on error. This was only checked about half the time. Now we convert it to throw an exception, and delete the half that checked for error. This was checked in before, but psmith crashed and lost the change :( * insertValue no longer returns -1 on error, so callers don't need to check for it. * Substantial rewrite of InstructionReader.cpp, to use more efficient, simpler, data structures. This provides another 5% speedup. This also makes the code much easier to read and understand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8984 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -27,7 +27,6 @@ const Type *BytecodeParser::parseTypeConstant(const unsigned char *&Buf,
|
|||||||
unsigned Typ;
|
unsigned Typ;
|
||||||
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
||||||
const Type *RetType = getType(Typ);
|
const Type *RetType = getType(Typ);
|
||||||
if (RetType == 0) return Val;
|
|
||||||
|
|
||||||
unsigned NumParams;
|
unsigned NumParams;
|
||||||
if (read_vbr(Buf, EndBuf, NumParams)) return Val;
|
if (read_vbr(Buf, EndBuf, NumParams)) return Val;
|
||||||
@@ -35,9 +34,7 @@ const Type *BytecodeParser::parseTypeConstant(const unsigned char *&Buf,
|
|||||||
std::vector<const Type*> Params;
|
std::vector<const Type*> Params;
|
||||||
while (NumParams--) {
|
while (NumParams--) {
|
||||||
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
||||||
const Type *Ty = getType(Typ);
|
Params.push_back(getType(Typ));
|
||||||
if (Ty == 0) return Val;
|
|
||||||
Params.push_back(Ty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
||||||
@@ -49,7 +46,6 @@ const Type *BytecodeParser::parseTypeConstant(const unsigned char *&Buf,
|
|||||||
unsigned ElTyp;
|
unsigned ElTyp;
|
||||||
if (read_vbr(Buf, EndBuf, ElTyp)) return Val;
|
if (read_vbr(Buf, EndBuf, ElTyp)) return Val;
|
||||||
const Type *ElementType = getType(ElTyp);
|
const Type *ElementType = getType(ElTyp);
|
||||||
if (ElementType == 0) return Val;
|
|
||||||
|
|
||||||
unsigned NumElements;
|
unsigned NumElements;
|
||||||
if (read_vbr(Buf, EndBuf, NumElements)) return Val;
|
if (read_vbr(Buf, EndBuf, NumElements)) return Val;
|
||||||
@@ -64,10 +60,7 @@ const Type *BytecodeParser::parseTypeConstant(const unsigned char *&Buf,
|
|||||||
|
|
||||||
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
||||||
while (Typ) { // List is terminated by void/0 typeid
|
while (Typ) { // List is terminated by void/0 typeid
|
||||||
const Type *Ty = getType(Typ);
|
Elements.push_back(getType(Typ));
|
||||||
if (Ty == 0) return Val;
|
|
||||||
Elements.push_back(Ty);
|
|
||||||
|
|
||||||
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,9 +70,7 @@ const Type *BytecodeParser::parseTypeConstant(const unsigned char *&Buf,
|
|||||||
unsigned ElTyp;
|
unsigned ElTyp;
|
||||||
if (read_vbr(Buf, EndBuf, ElTyp)) return Val;
|
if (read_vbr(Buf, EndBuf, ElTyp)) return Val;
|
||||||
BCR_TRACE(5, "Pointer Type Constant #" << ElTyp << "\n");
|
BCR_TRACE(5, "Pointer Type Constant #" << ElTyp << "\n");
|
||||||
const Type *ElementType = getType(ElTyp);
|
return PointerType::get(getType(ElTyp));
|
||||||
if (ElementType == 0) return Val;
|
|
||||||
return PointerType::get(ElementType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::OpaqueTyID: {
|
case Type::OpaqueTyID: {
|
||||||
@@ -169,9 +160,8 @@ Constant *BytecodeParser::parseConstantValue(const unsigned char *&Buf,
|
|||||||
if (read_vbr(Buf, EndBuf, ArgValSlot)) throw Error_readvbr;
|
if (read_vbr(Buf, EndBuf, ArgValSlot)) throw Error_readvbr;
|
||||||
if (read_vbr(Buf, EndBuf, ArgTypeSlot)) throw Error_readvbr;
|
if (read_vbr(Buf, EndBuf, ArgTypeSlot)) throw Error_readvbr;
|
||||||
const Type *ArgTy = getType(ArgTypeSlot);
|
const Type *ArgTy = getType(ArgTypeSlot);
|
||||||
if (ArgTy == 0) throw std::string("Argument type slot not found.");
|
|
||||||
|
|
||||||
BCR_TRACE(4, "CE Arg " << i << ": Type: '" << ArgTy << "' slot: "
|
BCR_TRACE(4, "CE Arg " << i << ": Type: '" << *ArgTy << "' slot: "
|
||||||
<< ArgValSlot << "\n");
|
<< ArgValSlot << "\n");
|
||||||
|
|
||||||
// Get the arg value from its slot if it exists, otherwise a placeholder
|
// Get the arg value from its slot if it exists, otherwise a placeholder
|
||||||
@@ -355,27 +345,25 @@ void BytecodeParser::ParseConstantPool(const unsigned char *&Buf,
|
|||||||
|
|
||||||
if (read_vbr(Buf, EndBuf, NumEntries) ||
|
if (read_vbr(Buf, EndBuf, NumEntries) ||
|
||||||
read_vbr(Buf, EndBuf, Typ)) throw Error_readvbr;
|
read_vbr(Buf, EndBuf, Typ)) throw Error_readvbr;
|
||||||
const Type *Ty = getType(Typ);
|
|
||||||
if (Ty == 0) throw std::string("Invalid type read.");
|
|
||||||
BCR_TRACE(3, "Type: '" << Ty << "' NumEntries: " << NumEntries << "\n");
|
|
||||||
|
|
||||||
if (Typ == Type::TypeTyID) {
|
if (Typ == Type::TypeTyID) {
|
||||||
|
BCR_TRACE(3, "Type: 'type' NumEntries: " << NumEntries << "\n");
|
||||||
parseTypeConstants(Buf, EndBuf, TypeTab, NumEntries);
|
parseTypeConstants(Buf, EndBuf, TypeTab, NumEntries);
|
||||||
} else {
|
} else {
|
||||||
|
const Type *Ty = getType(Typ);
|
||||||
|
BCR_TRACE(3, "Type: '" << *Ty << "' NumEntries: " << NumEntries << "\n");
|
||||||
|
|
||||||
for (unsigned i = 0; i < NumEntries; ++i) {
|
for (unsigned i = 0; i < NumEntries; ++i) {
|
||||||
Constant *C = parseConstantValue(Buf, EndBuf, Ty);
|
Constant *C = parseConstantValue(Buf, EndBuf, Ty);
|
||||||
assert(C && "parseConstantValue returned NULL!");
|
assert(C && "parseConstantValue returned NULL!");
|
||||||
BCR_TRACE(4, "Read Constant: '" << *C << "'\n");
|
BCR_TRACE(4, "Read Constant: '" << *C << "'\n");
|
||||||
int Slot;
|
unsigned Slot = insertValue(C, Tab);
|
||||||
if ((Slot = insertValue(C, Tab)) == -1)
|
|
||||||
throw std::string("Could not insert value into ValueTable.");
|
|
||||||
|
|
||||||
// If we are reading a function constant table, make sure that we adjust
|
// If we are reading a function constant table, make sure that we adjust
|
||||||
// the slot number to be the real global constant number.
|
// the slot number to be the real global constant number.
|
||||||
//
|
//
|
||||||
if (&Tab != &ModuleValues && Typ < ModuleValues.size())
|
if (&Tab != &ModuleValues && Typ < ModuleValues.size())
|
||||||
Slot += ModuleValues[Typ]->size();
|
Slot += ModuleValues[Typ]->size();
|
||||||
ResolveReferencesToValue(C, (unsigned)Slot);
|
ResolveReferencesToValue(C, Slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,9 +6,6 @@
|
|||||||
// Note that this library should be as fast as possible, reentrant, and
|
// Note that this library should be as fast as possible, reentrant, and
|
||||||
// threadsafe!!
|
// threadsafe!!
|
||||||
//
|
//
|
||||||
// TODO: Change from getValue(Raw.Arg1) etc, to getArg(Raw, 1)
|
|
||||||
// Make it check type, so that casts are checked.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "ReaderInternals.h"
|
#include "ReaderInternals.h"
|
||||||
@@ -17,11 +14,21 @@
|
|||||||
#include "llvm/iPHINode.h"
|
#include "llvm/iPHINode.h"
|
||||||
#include "llvm/iOther.h"
|
#include "llvm/iOther.h"
|
||||||
|
|
||||||
std::auto_ptr<RawInst>
|
struct RawInst { // The raw fields out of the bytecode stream...
|
||||||
BytecodeParser::ParseRawInst(const unsigned char *&Buf,
|
unsigned NumOperands;
|
||||||
const unsigned char *EndBuf) {
|
unsigned Opcode;
|
||||||
|
unsigned Type;
|
||||||
|
|
||||||
|
RawInst(const unsigned char *&Buf, const unsigned char *EndBuf,
|
||||||
|
std::vector<unsigned> &Args);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RawInst::RawInst(const unsigned char *&Buf, const unsigned char *EndBuf,
|
||||||
|
std::vector<unsigned> &Args) {
|
||||||
unsigned Op, Typ;
|
unsigned Op, Typ;
|
||||||
std::auto_ptr<RawInst> Result = std::auto_ptr<RawInst>(new RawInst());
|
|
||||||
if (read(Buf, EndBuf, Op))
|
if (read(Buf, EndBuf, Op))
|
||||||
throw std::string("Error reading from buffer.");
|
throw std::string("Error reading from buffer.");
|
||||||
|
|
||||||
@@ -29,20 +36,20 @@ BytecodeParser::ParseRawInst(const unsigned char *&Buf,
|
|||||||
// --------------------------
|
// --------------------------
|
||||||
// 01-00: Opcode type, fixed to 1.
|
// 01-00: Opcode type, fixed to 1.
|
||||||
// 07-02: Opcode
|
// 07-02: Opcode
|
||||||
Result->NumOperands = (Op >> 0) & 03;
|
Opcode = (Op >> 2) & 63;
|
||||||
Result->Opcode = (Op >> 2) & 63;
|
Args.resize((Op >> 0) & 03);
|
||||||
|
|
||||||
switch (Result->NumOperands) {
|
switch (Args.size()) {
|
||||||
case 1:
|
case 1:
|
||||||
// bits Instruction format:
|
// bits Instruction format:
|
||||||
// --------------------------
|
// --------------------------
|
||||||
// 19-08: Resulting type plane
|
// 19-08: Resulting type plane
|
||||||
// 31-20: Operand #1 (if set to (2^12-1), then zero operands)
|
// 31-20: Operand #1 (if set to (2^12-1), then zero operands)
|
||||||
//
|
//
|
||||||
Result->Ty = getType((Op >> 8) & 4095);
|
Type = (Op >> 8) & 4095;
|
||||||
Result->Arg1 = (Op >> 20) & 4095;
|
Args[0] = (Op >> 20) & 4095;
|
||||||
if (Result->Arg1 == 4095) // Handle special encoding for 0 operands...
|
if (Args[0] == 4095) // Handle special encoding for 0 operands...
|
||||||
Result->NumOperands = 0;
|
Args.resize(0);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// bits Instruction format:
|
// bits Instruction format:
|
||||||
@@ -51,9 +58,9 @@ BytecodeParser::ParseRawInst(const unsigned char *&Buf,
|
|||||||
// 23-16: Operand #1
|
// 23-16: Operand #1
|
||||||
// 31-24: Operand #2
|
// 31-24: Operand #2
|
||||||
//
|
//
|
||||||
Result->Ty = getType((Op >> 8) & 255);
|
Type = (Op >> 8) & 255;
|
||||||
Result->Arg1 = (Op >> 16) & 255;
|
Args[0] = (Op >> 16) & 255;
|
||||||
Result->Arg2 = (Op >> 24) & 255;
|
Args[1] = (Op >> 24) & 255;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// bits Instruction format:
|
// bits Instruction format:
|
||||||
@@ -63,159 +70,101 @@ BytecodeParser::ParseRawInst(const unsigned char *&Buf,
|
|||||||
// 25-20: Operand #2
|
// 25-20: Operand #2
|
||||||
// 31-26: Operand #3
|
// 31-26: Operand #3
|
||||||
//
|
//
|
||||||
Result->Ty = getType((Op >> 8) & 63);
|
Type = (Op >> 8) & 63;
|
||||||
Result->Arg1 = (Op >> 14) & 63;
|
Args[0] = (Op >> 14) & 63;
|
||||||
Result->Arg2 = (Op >> 20) & 63;
|
Args[1] = (Op >> 20) & 63;
|
||||||
Result->Arg3 = (Op >> 26) & 63;
|
Args[2] = (Op >> 26) & 63;
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
Buf -= 4; // Hrm, try this again...
|
Buf -= 4; // Hrm, try this again...
|
||||||
if (read_vbr(Buf, EndBuf, Result->Opcode))
|
if (read_vbr(Buf, EndBuf, Opcode))
|
||||||
throw std::string("Error reading from buffer.");
|
throw std::string("Error reading from buffer.");
|
||||||
Result->Opcode >>= 2;
|
Opcode >>= 2;
|
||||||
if (read_vbr(Buf, EndBuf, Typ))
|
if (read_vbr(Buf, EndBuf, Type))
|
||||||
throw std::string("Error reading from buffer.");
|
|
||||||
Result->Ty = getType(Typ);
|
|
||||||
if (Result->Ty == 0)
|
|
||||||
throw std::string("Invalid type read in instruction.");
|
|
||||||
if (read_vbr(Buf, EndBuf, Result->NumOperands))
|
|
||||||
throw std::string("Error reading from buffer.");
|
throw std::string("Error reading from buffer.");
|
||||||
|
|
||||||
switch (Result->NumOperands) {
|
unsigned NumOperands;
|
||||||
case 0:
|
if (read_vbr(Buf, EndBuf, NumOperands))
|
||||||
|
throw std::string("Error reading from buffer.");
|
||||||
|
Args.resize(NumOperands);
|
||||||
|
|
||||||
|
if (NumOperands == 0)
|
||||||
throw std::string("Zero-argument instruction found; this is invalid.");
|
throw std::string("Zero-argument instruction found; this is invalid.");
|
||||||
case 1:
|
|
||||||
if (read_vbr(Buf, EndBuf, Result->Arg1))
|
|
||||||
throw std::string("Error reading from buffer");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (read_vbr(Buf, EndBuf, Result->Arg1) ||
|
|
||||||
read_vbr(Buf, EndBuf, Result->Arg2))
|
|
||||||
throw std::string("Error reading from buffer");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (read_vbr(Buf, EndBuf, Result->Arg1) ||
|
|
||||||
read_vbr(Buf, EndBuf, Result->Arg2) ||
|
|
||||||
read_vbr(Buf, EndBuf, Result->Arg3))
|
|
||||||
throw std::string("Error reading from buffer");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (read_vbr(Buf, EndBuf, Result->Arg1) ||
|
|
||||||
read_vbr(Buf, EndBuf, Result->Arg2))
|
|
||||||
throw std::string("Error reading from buffer");
|
|
||||||
|
|
||||||
// Allocate a vector to hold arguments 3, 4, 5, 6 ...
|
for (unsigned i = 0; i != NumOperands; ++i)
|
||||||
Result->VarArgs = new std::vector<unsigned>(Result->NumOperands-2);
|
if (read_vbr(Buf, EndBuf, Args[i]))
|
||||||
for (unsigned a = 0; a < Result->NumOperands-2; a++)
|
throw std::string("Error reading from buffer");
|
||||||
if (read_vbr(Buf, EndBuf, (*Result->VarArgs)[a]))
|
if (align32(Buf, EndBuf))
|
||||||
throw std::string("Error reading from buffer");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (align32(Buf, EndBuf))
|
|
||||||
throw std::string("Unaligned bytecode buffer.");
|
throw std::string("Unaligned bytecode buffer.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
std::cerr << "NO: " << Result->NumOperands << " opcode: " << Result->Opcode
|
|
||||||
<< " Ty: "<< Result->Ty->getDescription()<< " arg1: "<< Result->Arg1
|
|
||||||
<< " arg2: " << Result->Arg2 << " arg3: " << Result->Arg3 << "\n";
|
|
||||||
#endif
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Instruction *BytecodeParser::ParseInstruction(const unsigned char *&Buf,
|
Instruction *BytecodeParser::ParseInstruction(const unsigned char *&Buf,
|
||||||
const unsigned char *EndBuf) {
|
const unsigned char *EndBuf) {
|
||||||
std::auto_ptr<RawInst> Raw = ParseRawInst(Buf, EndBuf);
|
std::vector<unsigned> Args;
|
||||||
|
RawInst RI(Buf, EndBuf, Args);
|
||||||
|
const Type *InstTy = getType(RI.Type);
|
||||||
|
|
||||||
if (Raw->Opcode >= Instruction::BinaryOpsBegin &&
|
if (RI.Opcode >= Instruction::BinaryOpsBegin &&
|
||||||
Raw->Opcode < Instruction::BinaryOpsEnd && Raw->NumOperands == 2)
|
RI.Opcode < Instruction::BinaryOpsEnd && Args.size() == 2)
|
||||||
return BinaryOperator::create((Instruction::BinaryOps)Raw->Opcode,
|
return BinaryOperator::create((Instruction::BinaryOps)RI.Opcode,
|
||||||
getValue(Raw->Ty, Raw->Arg1),
|
getValue(InstTy, Args[0]),
|
||||||
getValue(Raw->Ty, Raw->Arg2));
|
getValue(InstTy, Args[1]));
|
||||||
|
|
||||||
switch (Raw->Opcode) {
|
switch (RI.Opcode) {
|
||||||
case Instruction::VarArg:
|
case Instruction::VarArg:
|
||||||
case Instruction::Cast: {
|
return new VarArgInst(getValue(InstTy, Args[0]), getType(Args[1]));
|
||||||
Value *V = getValue(Raw->Ty, Raw->Arg1);
|
case Instruction::Cast:
|
||||||
const Type *Ty = getType(Raw->Arg2);
|
return new CastInst(getValue(InstTy, Args[0]), getType(Args[1]));
|
||||||
if (Ty == 0) throw std::string("Invalid cast!\n");
|
|
||||||
if (Raw->Opcode == Instruction::Cast)
|
|
||||||
return new CastInst(V, Ty);
|
|
||||||
else
|
|
||||||
return new VarArgInst(V, Ty);
|
|
||||||
}
|
|
||||||
case Instruction::PHINode: {
|
case Instruction::PHINode: {
|
||||||
PHINode *PN = new PHINode(Raw->Ty);
|
if (Args.size() == 0 || (Args.size() & 1))
|
||||||
switch (Raw->NumOperands) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
case 3:
|
|
||||||
delete PN;
|
|
||||||
throw std::string("Invalid phi node encountered!\n");
|
throw std::string("Invalid phi node encountered!\n");
|
||||||
case 2:
|
|
||||||
PN->addIncoming(getValue(Raw->Ty, Raw->Arg1), getBasicBlock(Raw->Arg2));
|
PHINode *PN = new PHINode(InstTy);
|
||||||
break;
|
for (unsigned i = 0, e = Args.size(); i != e; i += 2)
|
||||||
default:
|
PN->addIncoming(getValue(InstTy, Args[i]), getBasicBlock(Args[i+1]));
|
||||||
PN->addIncoming(getValue(Raw->Ty, Raw->Arg1), getBasicBlock(Raw->Arg2));
|
|
||||||
if (Raw->VarArgs->size() & 1) {
|
|
||||||
delete PN;
|
|
||||||
throw std::string("PHI Node with ODD number of arguments!\n");
|
|
||||||
} else {
|
|
||||||
std::vector<unsigned> &args = *Raw->VarArgs;
|
|
||||||
for (unsigned i = 0; i < args.size(); i+=2)
|
|
||||||
PN->addIncoming(getValue(Raw->Ty, args[i]), getBasicBlock(args[i+1]));
|
|
||||||
}
|
|
||||||
delete Raw->VarArgs;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return PN;
|
return PN;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Instruction::Shl:
|
case Instruction::Shl:
|
||||||
case Instruction::Shr:
|
case Instruction::Shr:
|
||||||
return new ShiftInst((Instruction::OtherOps)Raw->Opcode,
|
return new ShiftInst((Instruction::OtherOps)RI.Opcode,
|
||||||
getValue(Raw->Ty, Raw->Arg1),
|
getValue(InstTy, Args[0]),
|
||||||
getValue(Type::UByteTyID, Raw->Arg2));
|
getValue(Type::UByteTyID, Args[1]));
|
||||||
case Instruction::Ret:
|
case Instruction::Ret:
|
||||||
if (Raw->NumOperands == 0)
|
if (Args.size() == 0)
|
||||||
return new ReturnInst();
|
return new ReturnInst();
|
||||||
else if (Raw->NumOperands == 1)
|
else if (Args.size() == 1)
|
||||||
return new ReturnInst(getValue(Raw->Ty, Raw->Arg1));
|
return new ReturnInst(getValue(InstTy, Args[0]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction::Br:
|
case Instruction::Br:
|
||||||
if (Raw->NumOperands == 1)
|
if (Args.size() == 1)
|
||||||
return new BranchInst(getBasicBlock(Raw->Arg1));
|
return new BranchInst(getBasicBlock(Args[0]));
|
||||||
else if (Raw->NumOperands == 3)
|
else if (Args.size() == 3)
|
||||||
return new BranchInst(getBasicBlock(Raw->Arg1), getBasicBlock(Raw->Arg2),
|
return new BranchInst(getBasicBlock(Args[0]), getBasicBlock(Args[1]),
|
||||||
getValue(Type::BoolTyID , Raw->Arg3));
|
getValue(Type::BoolTyID , Args[2]));
|
||||||
throw std::string("Invalid number of operands for a 'br' instruction!");
|
throw std::string("Invalid number of operands for a 'br' instruction!");
|
||||||
|
|
||||||
case Instruction::Switch: {
|
case Instruction::Switch: {
|
||||||
SwitchInst *I = new SwitchInst(getValue(Raw->Ty, Raw->Arg1),
|
if (Args.size() & 1)
|
||||||
getBasicBlock(Raw->Arg2));
|
|
||||||
if (Raw->NumOperands < 3)
|
|
||||||
return I;
|
|
||||||
|
|
||||||
if (Raw->NumOperands == 3 || Raw->VarArgs->size() & 1) {
|
|
||||||
delete I;
|
|
||||||
throw std::string("Switch statement with odd number of arguments!");
|
throw std::string("Switch statement with odd number of arguments!");
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<unsigned> &args = *Raw->VarArgs;
|
|
||||||
for (unsigned i = 0; i < args.size(); i += 2)
|
|
||||||
I->addCase(cast<Constant>(getValue(Raw->Ty, args[i])),
|
|
||||||
getBasicBlock(args[i+1]));
|
|
||||||
|
|
||||||
delete Raw->VarArgs;
|
SwitchInst *I = new SwitchInst(getValue(InstTy, Args[0]),
|
||||||
|
getBasicBlock(Args[1]));
|
||||||
|
for (unsigned i = 2, e = Args.size(); i != e; i += 2)
|
||||||
|
I->addCase(cast<Constant>(getValue(InstTy, Args[i])),
|
||||||
|
getBasicBlock(Args[i+1]));
|
||||||
return I;
|
return I;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Instruction::Call: {
|
case Instruction::Call: {
|
||||||
Value *F = getValue(Raw->Ty, Raw->Arg1);
|
if (Args.size() == 0)
|
||||||
|
throw std::string("Invalid call instruction encountered!");
|
||||||
|
|
||||||
|
Value *F = getValue(InstTy, Args[0]);
|
||||||
|
|
||||||
// Check to make sure we have a pointer to function type
|
// Check to make sure we have a pointer to function type
|
||||||
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
|
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
|
||||||
@@ -229,45 +178,26 @@ Instruction *BytecodeParser::ParseInstruction(const unsigned char *&Buf,
|
|||||||
if (!FTy->isVarArg()) {
|
if (!FTy->isVarArg()) {
|
||||||
FunctionType::ParamTypes::const_iterator It = PL.begin();
|
FunctionType::ParamTypes::const_iterator It = PL.begin();
|
||||||
|
|
||||||
switch (Raw->NumOperands) {
|
for (unsigned i = 1, e = Args.size(); i != e; ++i) {
|
||||||
case 0: throw std::string("Invalid call instruction encountered!");
|
if (It == PL.end()) throw std::string("Invalid call instruction!");
|
||||||
case 1: break;
|
Params.push_back(getValue(*It++, Args[i]));
|
||||||
case 2: Params.push_back(getValue(*It++, Raw->Arg2)); break;
|
|
||||||
case 3: Params.push_back(getValue(*It++, Raw->Arg2));
|
|
||||||
if (It == PL.end()) throw std::string("Invalid call instruction!");
|
|
||||||
Params.push_back(getValue(*It++, Raw->Arg3)); break;
|
|
||||||
default:
|
|
||||||
Params.push_back(getValue(*It++, Raw->Arg2));
|
|
||||||
{
|
|
||||||
std::vector<unsigned> &args = *Raw->VarArgs;
|
|
||||||
for (unsigned i = 0; i < args.size(); i++) {
|
|
||||||
if (It == PL.end()) throw std::string("Invalid call instruction!");
|
|
||||||
Params.push_back(getValue(*It++, args[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete Raw->VarArgs;
|
|
||||||
}
|
}
|
||||||
if (It != PL.end()) throw std::string("Invalid call instruction!");
|
if (It != PL.end()) throw std::string("Invalid call instruction!");
|
||||||
} else {
|
} else {
|
||||||
if (Raw->NumOperands > 2) {
|
// FIXME: Args[1] is currently just a dummy padding field!
|
||||||
std::vector<unsigned> &args = *Raw->VarArgs;
|
|
||||||
if (args.size() < 1) throw std::string("Invalid call instruction!");
|
|
||||||
|
|
||||||
if ((args.size() & 1) != 0) // Must be pairs of type/value
|
if (Args.size() & 1) // Must be pairs of type/value
|
||||||
throw std::string("Invalid call instruction!");
|
throw std::string("Invalid call instruction!");
|
||||||
for (unsigned i = 0; i < args.size(); i+=2) {
|
|
||||||
const Type *Ty = getType(args[i]);
|
for (unsigned i = 2, e = Args.size(); i != e; i += 2)
|
||||||
if (Ty == 0) throw std::string("Invalid call instruction!");
|
Params.push_back(getValue(getType(Args[i]), Args[i+1]));
|
||||||
Params.push_back(getValue(Ty, args[i+1]));
|
|
||||||
}
|
|
||||||
delete Raw->VarArgs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CallInst(F, Params);
|
return new CallInst(F, Params);
|
||||||
}
|
}
|
||||||
case Instruction::Invoke: {
|
case Instruction::Invoke: {
|
||||||
Value *F = getValue(Raw->Ty, Raw->Arg1);
|
if (Args.size() < 3) throw std::string("Invalid invoke instruction!");
|
||||||
|
Value *F = getValue(InstTy, Args[0]);
|
||||||
|
|
||||||
// Check to make sure we have a pointer to function type
|
// Check to make sure we have a pointer to function type
|
||||||
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
|
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
|
||||||
@@ -276,131 +206,99 @@ Instruction *BytecodeParser::ParseInstruction(const unsigned char *&Buf,
|
|||||||
if (FTy == 0) throw std::string("Invoke to non function pointer value!");
|
if (FTy == 0) throw std::string("Invoke to non function pointer value!");
|
||||||
|
|
||||||
std::vector<Value *> Params;
|
std::vector<Value *> Params;
|
||||||
const FunctionType::ParamTypes &PL = FTy->getParamTypes();
|
|
||||||
std::vector<unsigned> &args = *Raw->VarArgs;
|
|
||||||
|
|
||||||
BasicBlock *Normal, *Except;
|
BasicBlock *Normal, *Except;
|
||||||
|
|
||||||
|
const FunctionType::ParamTypes &PL = FTy->getParamTypes();
|
||||||
|
|
||||||
if (!FTy->isVarArg()) {
|
if (!FTy->isVarArg()) {
|
||||||
if (Raw->NumOperands < 3) throw std::string("Invalid call instruction!");
|
Normal = getBasicBlock(Args[1]);
|
||||||
|
Except = getBasicBlock(Args[2]);
|
||||||
|
|
||||||
Normal = getBasicBlock(Raw->Arg2);
|
FunctionType::ParamTypes::const_iterator It = PL.begin();
|
||||||
if (Raw->NumOperands == 3)
|
for (unsigned i = 3, e = Args.size(); i != e; ++i) {
|
||||||
Except = getBasicBlock(Raw->Arg3);
|
if (It == PL.end()) throw std::string("Invalid invoke instruction!");
|
||||||
else {
|
Params.push_back(getValue(*It++, Args[i]));
|
||||||
Except = getBasicBlock(args[0]);
|
|
||||||
|
|
||||||
FunctionType::ParamTypes::const_iterator It = PL.begin();
|
|
||||||
for (unsigned i = 1; i < args.size(); i++) {
|
|
||||||
if (It == PL.end()) throw std::string("Invalid invoke instruction!");
|
|
||||||
Params.push_back(getValue(*It++, args[i]));
|
|
||||||
}
|
|
||||||
if (It != PL.end()) throw std::string("Invalid invoke instruction!");
|
|
||||||
}
|
}
|
||||||
|
if (It != PL.end()) throw std::string("Invalid invoke instruction!");
|
||||||
} else {
|
} else {
|
||||||
if (args.size() < 4) throw std::string("Invalid invoke instruction!");
|
// FIXME: Args[1] is a dummy padding field
|
||||||
if (args[0] != Type::LabelTyID || args[2] != Type::LabelTyID)
|
|
||||||
|
if (Args.size() < 6) throw std::string("Invalid invoke instruction!");
|
||||||
|
if (Args[2] != Type::LabelTyID || Args[4] != Type::LabelTyID)
|
||||||
throw std::string("Invalid invoke instruction!");
|
throw std::string("Invalid invoke instruction!");
|
||||||
|
|
||||||
Normal = getBasicBlock(args[1]);
|
Normal = getBasicBlock(Args[3]);
|
||||||
Except = getBasicBlock(args[3]);
|
Except = getBasicBlock(Args[5]);
|
||||||
|
|
||||||
if ((args.size() & 1) != 0) // Must be pairs of type/value
|
if (Args.size() & 1) // Must be pairs of type/value
|
||||||
throw std::string("Invalid invoke instruction!");
|
throw std::string("Invalid invoke instruction!");
|
||||||
|
|
||||||
for (unsigned i = 4; i < args.size(); i += 2)
|
for (unsigned i = 6; i < Args.size(); i += 2)
|
||||||
Params.push_back(getValue(args[i], args[i+1]));
|
Params.push_back(getValue(Args[i], Args[i+1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Raw->NumOperands > 3)
|
|
||||||
delete Raw->VarArgs;
|
|
||||||
return new InvokeInst(F, Normal, Except, Params);
|
return new InvokeInst(F, Normal, Except, Params);
|
||||||
}
|
}
|
||||||
case Instruction::Malloc:
|
case Instruction::Malloc:
|
||||||
if (Raw->NumOperands > 2) throw std::string("Invalid malloc instruction!");
|
if (Args.size() > 2) throw std::string("Invalid malloc instruction!");
|
||||||
if (!isa<PointerType>(Raw->Ty))
|
if (!isa<PointerType>(InstTy))
|
||||||
throw std::string("Invalid malloc instruction!");
|
throw std::string("Invalid malloc instruction!");
|
||||||
|
|
||||||
return new MallocInst(cast<PointerType>(Raw->Ty)->getElementType(),
|
return new MallocInst(cast<PointerType>(InstTy)->getElementType(),
|
||||||
Raw->NumOperands ? getValue(Type::UIntTyID,
|
Args.size() ? getValue(Type::UIntTyID,
|
||||||
Raw->Arg1) : 0);
|
Args[0]) : 0);
|
||||||
|
|
||||||
case Instruction::Alloca:
|
case Instruction::Alloca:
|
||||||
if (Raw->NumOperands > 2) throw std::string("Invalid alloca instruction!");
|
if (Args.size() > 2) throw std::string("Invalid alloca instruction!");
|
||||||
if (!isa<PointerType>(Raw->Ty))
|
if (!isa<PointerType>(InstTy))
|
||||||
throw std::string("Invalid alloca instruction!");
|
throw std::string("Invalid alloca instruction!");
|
||||||
|
|
||||||
return new AllocaInst(cast<PointerType>(Raw->Ty)->getElementType(),
|
return new AllocaInst(cast<PointerType>(InstTy)->getElementType(),
|
||||||
Raw->NumOperands ? getValue(Type::UIntTyID,
|
Args.size() ? getValue(Type::UIntTyID,
|
||||||
Raw->Arg1) : 0);
|
Args[0]) : 0);
|
||||||
case Instruction::Free:
|
case Instruction::Free:
|
||||||
if (!isa<PointerType>(Raw->Ty))
|
if (!isa<PointerType>(InstTy))
|
||||||
throw std::string("Invalid free instruction!");
|
throw std::string("Invalid free instruction!");
|
||||||
return new FreeInst(getValue(Raw->Ty, Raw->Arg1));
|
return new FreeInst(getValue(InstTy, Args[0]));
|
||||||
|
|
||||||
case Instruction::GetElementPtr: {
|
case Instruction::GetElementPtr: {
|
||||||
std::vector<Value*> Idx;
|
if (Args.size() == 0 || !isa<PointerType>(InstTy))
|
||||||
if (!isa<PointerType>(Raw->Ty))
|
|
||||||
throw std::string("Invalid getelementptr instruction!");
|
throw std::string("Invalid getelementptr instruction!");
|
||||||
const CompositeType *TopTy = dyn_cast<CompositeType>(Raw->Ty);
|
|
||||||
|
|
||||||
switch (Raw->NumOperands) {
|
std::vector<Value*> Idx;
|
||||||
case 0: throw std::string("Invalid getelementptr instruction!");
|
|
||||||
case 1: break;
|
|
||||||
case 2:
|
|
||||||
if (!TopTy) throw std::string("Invalid getelementptr instruction!");
|
|
||||||
Idx.push_back(getValue(TopTy->getIndexType(), Raw->Arg2));
|
|
||||||
break;
|
|
||||||
case 3: {
|
|
||||||
if (!TopTy) throw std::string("Invalid getelementptr instruction!");
|
|
||||||
Idx.push_back(getValue(TopTy->getIndexType(), Raw->Arg2));
|
|
||||||
|
|
||||||
const Type *ETy = GetElementPtrInst::getIndexedType(TopTy, Idx, true);
|
const Type *NextTy = InstTy;
|
||||||
const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
|
for (unsigned i = 1, e = Args.size(); i != e; ++i) {
|
||||||
if (!ElTy) throw std::string("Invalid getelementptr instruction!");
|
const CompositeType *TopTy = dyn_cast_or_null<CompositeType>(NextTy);
|
||||||
|
if (!TopTy) throw std::string("Invalid getelementptr instruction!");
|
||||||
Idx.push_back(getValue(ElTy->getIndexType(), Raw->Arg3));
|
Idx.push_back(getValue(TopTy->getIndexType(), Args[i]));
|
||||||
break;
|
NextTy = GetElementPtrInst::getIndexedType(InstTy, Idx, true);
|
||||||
}
|
|
||||||
default:
|
|
||||||
if (!TopTy) throw std::string("Invalid getelementptr instruction!");
|
|
||||||
Idx.push_back(getValue(TopTy->getIndexType(), Raw->Arg2));
|
|
||||||
|
|
||||||
std::vector<unsigned> &args = *Raw->VarArgs;
|
|
||||||
for (unsigned i = 0, E = args.size(); i != E; ++i) {
|
|
||||||
const Type *ETy = GetElementPtrInst::getIndexedType(Raw->Ty, Idx, true);
|
|
||||||
const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
|
|
||||||
if (!ElTy) throw std::string("Invalid getelementptr instruction!");
|
|
||||||
Idx.push_back(getValue(ElTy->getIndexType(), args[i]));
|
|
||||||
}
|
|
||||||
delete Raw->VarArgs;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GetElementPtrInst(getValue(Raw->Ty, Raw->Arg1), Idx);
|
return new GetElementPtrInst(getValue(InstTy, Args[0]), Idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 62: // volatile load
|
case 62: // volatile load
|
||||||
case Instruction::Load:
|
case Instruction::Load:
|
||||||
if (Raw->NumOperands != 1 || !isa<PointerType>(Raw->Ty))
|
if (Args.size() != 1 || !isa<PointerType>(InstTy))
|
||||||
throw std::string("Invalid load instruction!");
|
throw std::string("Invalid load instruction!");
|
||||||
return new LoadInst(getValue(Raw->Ty, Raw->Arg1), "", Raw->Opcode == 62);
|
return new LoadInst(getValue(InstTy, Args[0]), "", RI.Opcode == 62);
|
||||||
|
|
||||||
case 63: // volatile store
|
case 63: // volatile store
|
||||||
case Instruction::Store: {
|
case Instruction::Store: {
|
||||||
if (!isa<PointerType>(Raw->Ty) || Raw->NumOperands != 2)
|
if (!isa<PointerType>(InstTy) || Args.size() != 2)
|
||||||
throw std::string("Invalid store instruction!");
|
throw std::string("Invalid store instruction!");
|
||||||
|
|
||||||
Value *Ptr = getValue(Raw->Ty, Raw->Arg2);
|
Value *Ptr = getValue(InstTy, Args[1]);
|
||||||
const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
|
const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
|
||||||
return new StoreInst(getValue(ValTy, Raw->Arg1), Ptr, Raw->Opcode == 63);
|
return new StoreInst(getValue(ValTy, Args[0]), Ptr, RI.Opcode == 63);
|
||||||
}
|
}
|
||||||
case Instruction::Unwind:
|
case Instruction::Unwind:
|
||||||
if (Raw->NumOperands != 0) throw std::string("Invalid unwind instruction!");
|
if (Args.size() != 0) throw std::string("Invalid unwind instruction!");
|
||||||
return new UnwindInst();
|
return new UnwindInst();
|
||||||
} // end switch(Raw->Opcode)
|
} // end switch(RI.Opcode)
|
||||||
|
|
||||||
std::cerr << "Unrecognized instruction! " << Raw->Opcode
|
std::cerr << "Unrecognized instruction! " << RI.Opcode
|
||||||
<< " ADDR = 0x" << (void*)Buf << "\n";
|
<< " ADDR = 0x" << (void*)Buf << "\n";
|
||||||
throw std::string("Unrecognized instruction!");
|
throw std::string("Unrecognized instruction!");
|
||||||
}
|
}
|
||||||
|
@@ -49,17 +49,15 @@ unsigned BytecodeParser::getTypeSlot(const Type *Ty) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Type *BytecodeParser::getType(unsigned ID) {
|
const Type *BytecodeParser::getType(unsigned ID) {
|
||||||
if (ID < Type::NumPrimitiveIDs) {
|
if (ID < Type::NumPrimitiveIDs)
|
||||||
const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID);
|
if (const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID))
|
||||||
if (T) return T;
|
return T;
|
||||||
}
|
|
||||||
|
|
||||||
//cerr << "Looking up Type ID: " << ID << "\n";
|
//cerr << "Looking up Type ID: " << ID << "\n";
|
||||||
|
|
||||||
if (ID < Type::NumPrimitiveIDs) {
|
if (ID < Type::NumPrimitiveIDs)
|
||||||
const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID);
|
if (const Type *T = Type::getPrimitiveType((Type::PrimitiveID)ID))
|
||||||
if (T) return T; // Asked for a primitive type...
|
return T; // Asked for a primitive type...
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, derived types need offset...
|
// Otherwise, derived types need offset...
|
||||||
ID -= FirstDerivedTyID;
|
ID -= FirstDerivedTyID;
|
||||||
@@ -73,10 +71,10 @@ const Type *BytecodeParser::getType(unsigned ID) {
|
|||||||
if (ID < FunctionTypeValues.size())
|
if (ID < FunctionTypeValues.size())
|
||||||
return FunctionTypeValues[ID].get();
|
return FunctionTypeValues[ID].get();
|
||||||
|
|
||||||
return 0;
|
throw std::string("Illegal type reference!");
|
||||||
}
|
}
|
||||||
|
|
||||||
int BytecodeParser::insertValue(Value *Val, ValueTable &ValueTab) {
|
unsigned BytecodeParser::insertValue(Value *Val, ValueTable &ValueTab) {
|
||||||
assert((!HasImplicitZeroInitializer || !isa<Constant>(Val) ||
|
assert((!HasImplicitZeroInitializer || !isa<Constant>(Val) ||
|
||||||
Val->getType()->isPrimitiveType() ||
|
Val->getType()->isPrimitiveType() ||
|
||||||
!cast<Constant>(Val)->isNullValue()) &&
|
!cast<Constant>(Val)->isNullValue()) &&
|
||||||
@@ -200,10 +198,7 @@ BasicBlock *BytecodeParser::ParseBasicBlock(const unsigned char *&Buf,
|
|||||||
|
|
||||||
while (Buf < EndBuf) {
|
while (Buf < EndBuf) {
|
||||||
Instruction *Inst = ParseInstruction(Buf, EndBuf);
|
Instruction *Inst = ParseInstruction(Buf, EndBuf);
|
||||||
if (insertValue(Inst, Values) == -1) {
|
insertValue(Inst, Values);
|
||||||
throw std::string("Could not insert value.");
|
|
||||||
}
|
|
||||||
|
|
||||||
BB->getInstList().push_back(Inst);
|
BB->getInstList().push_back(Inst);
|
||||||
BCR_TRACE(4, Inst);
|
BCR_TRACE(4, Inst);
|
||||||
}
|
}
|
||||||
@@ -221,9 +216,7 @@ void BytecodeParser::ParseSymbolTable(const unsigned char *&Buf,
|
|||||||
if (read_vbr(Buf, EndBuf, NumEntries) ||
|
if (read_vbr(Buf, EndBuf, NumEntries) ||
|
||||||
read_vbr(Buf, EndBuf, Typ)) throw Error_readvbr;
|
read_vbr(Buf, EndBuf, Typ)) throw Error_readvbr;
|
||||||
const Type *Ty = getType(Typ);
|
const Type *Ty = getType(Typ);
|
||||||
if (Ty == 0) throw std::string("Invalid type read in symbol table.");
|
BCR_TRACE(3, "Plane Type: '" << *Ty << "' with " << NumEntries <<
|
||||||
|
|
||||||
BCR_TRACE(3, "Plane Type: '" << Ty << "' with " << NumEntries <<
|
|
||||||
" entries\n");
|
" entries\n");
|
||||||
|
|
||||||
for (unsigned i = 0; i < NumEntries; ++i) {
|
for (unsigned i = 0; i < NumEntries; ++i) {
|
||||||
@@ -328,10 +321,8 @@ void BytecodeParser::materializeFunction(Function* F) {
|
|||||||
const FunctionType::ParamTypes &Params =F->getFunctionType()->getParamTypes();
|
const FunctionType::ParamTypes &Params =F->getFunctionType()->getParamTypes();
|
||||||
Function::aiterator AI = F->abegin();
|
Function::aiterator AI = F->abegin();
|
||||||
for (FunctionType::ParamTypes::const_iterator It = Params.begin();
|
for (FunctionType::ParamTypes::const_iterator It = Params.begin();
|
||||||
It != Params.end(); ++It, ++AI) {
|
It != Params.end(); ++It, ++AI)
|
||||||
if (insertValue(AI, Values) == -1)
|
insertValue(AI, Values);
|
||||||
throw std::string("Error reading function arguments!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep track of how many basic blocks we have read in...
|
// Keep track of how many basic blocks we have read in...
|
||||||
unsigned BlockNum = 0;
|
unsigned BlockNum = 0;
|
||||||
@@ -435,7 +426,7 @@ void BytecodeParser::ParseModuleGlobalInfo(const unsigned char *&Buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Type *Ty = getType(SlotNo);
|
const Type *Ty = getType(SlotNo);
|
||||||
if (!Ty || !isa<PointerType>(Ty))
|
if (!isa<PointerType>(Ty))
|
||||||
throw std::string("Global not pointer type! Ty = " +
|
throw std::string("Global not pointer type! Ty = " +
|
||||||
Ty->getDescription());
|
Ty->getDescription());
|
||||||
|
|
||||||
@@ -444,10 +435,8 @@ void BytecodeParser::ParseModuleGlobalInfo(const unsigned char *&Buf,
|
|||||||
// Create the global variable...
|
// Create the global variable...
|
||||||
GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, Linkage,
|
GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, Linkage,
|
||||||
0, "", TheModule);
|
0, "", TheModule);
|
||||||
int DestSlot = insertValue(GV, ModuleValues);
|
|
||||||
if (DestSlot == -1) throw Error_DestSlot;
|
|
||||||
BCR_TRACE(2, "Global Variable of type: " << *Ty << "\n");
|
BCR_TRACE(2, "Global Variable of type: " << *Ty << "\n");
|
||||||
ResolveReferencesToValue(GV, (unsigned)DestSlot);
|
ResolveReferencesToValue(GV, insertValue(GV, ModuleValues));
|
||||||
|
|
||||||
if (VarType & 2) { // Does it have an initializer?
|
if (VarType & 2) { // Does it have an initializer?
|
||||||
unsigned InitSlot;
|
unsigned InitSlot;
|
||||||
@@ -462,11 +451,10 @@ void BytecodeParser::ParseModuleGlobalInfo(const unsigned char *&Buf,
|
|||||||
if (read_vbr(Buf, End, FnSignature)) throw Error_readvbr;
|
if (read_vbr(Buf, End, FnSignature)) throw Error_readvbr;
|
||||||
while (FnSignature != Type::VoidTyID) { // List is terminated by Void
|
while (FnSignature != Type::VoidTyID) { // List is terminated by Void
|
||||||
const Type *Ty = getType(FnSignature);
|
const Type *Ty = getType(FnSignature);
|
||||||
if (!Ty || !isa<PointerType>(Ty) ||
|
if (!isa<PointerType>(Ty) ||
|
||||||
!isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) {
|
!isa<FunctionType>(cast<PointerType>(Ty)->getElementType()))
|
||||||
throw std::string("Function not ptr to func type! Ty = " +
|
throw std::string("Function not ptr to func type! Ty = " +
|
||||||
Ty->getDescription());
|
Ty->getDescription());
|
||||||
}
|
|
||||||
|
|
||||||
// We create functions by passing the underlying FunctionType to create...
|
// We create functions by passing the underlying FunctionType to create...
|
||||||
Ty = cast<PointerType>(Ty)->getElementType();
|
Ty = cast<PointerType>(Ty)->getElementType();
|
||||||
@@ -479,9 +467,8 @@ void BytecodeParser::ParseModuleGlobalInfo(const unsigned char *&Buf,
|
|||||||
// Insert the placeholder...
|
// Insert the placeholder...
|
||||||
Function *Func = new Function(cast<FunctionType>(Ty),
|
Function *Func = new Function(cast<FunctionType>(Ty),
|
||||||
GlobalValue::InternalLinkage, "", TheModule);
|
GlobalValue::InternalLinkage, "", TheModule);
|
||||||
int DestSlot = insertValue(Func, ModuleValues);
|
unsigned DestSlot = insertValue(Func, ModuleValues);
|
||||||
if (DestSlot == -1) throw Error_DestSlot;
|
ResolveReferencesToValue(Func, DestSlot);
|
||||||
ResolveReferencesToValue(Func, (unsigned)DestSlot);
|
|
||||||
|
|
||||||
// Keep track of this information in a list that is emptied as functions are
|
// Keep track of this information in a list that is emptied as functions are
|
||||||
// loaded...
|
// loaded...
|
||||||
|
@@ -14,8 +14,6 @@
|
|||||||
#include "llvm/Bytecode/Primitives.h"
|
#include "llvm/Bytecode/Primitives.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
|
||||||
class Module;
|
|
||||||
|
|
||||||
// Enable to trace to figure out what the heck is going on when parsing fails
|
// Enable to trace to figure out what the heck is going on when parsing fails
|
||||||
//#define TRACE_LEVEL 10
|
//#define TRACE_LEVEL 10
|
||||||
@@ -27,17 +25,6 @@ class Module;
|
|||||||
#define BCR_TRACE(n, X)
|
#define BCR_TRACE(n, X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct RawInst { // The raw fields out of the bytecode stream...
|
|
||||||
unsigned NumOperands;
|
|
||||||
unsigned Opcode;
|
|
||||||
const Type *Ty;
|
|
||||||
unsigned Arg1, Arg2;
|
|
||||||
union {
|
|
||||||
unsigned Arg3;
|
|
||||||
std::vector<unsigned> *VarArgs; // Contains arg #3,4,5... if NumOperands > 3
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LazyFunctionInfo {
|
struct LazyFunctionInfo {
|
||||||
const unsigned char *Buf, *EndBuf;
|
const unsigned char *Buf, *EndBuf;
|
||||||
unsigned FunctionSlot;
|
unsigned FunctionSlot;
|
||||||
@@ -62,11 +49,9 @@ public:
|
|||||||
|
|
||||||
Module* releaseModule() {
|
Module* releaseModule() {
|
||||||
// Since we're losing control of this Module, we must hand it back complete
|
// Since we're losing control of this Module, we must hand it back complete
|
||||||
materializeModule();
|
Module *M = ModuleProvider::releaseModule();
|
||||||
freeState();
|
freeState();
|
||||||
Module *tempM = TheModule;
|
return M;
|
||||||
TheModule = 0;
|
|
||||||
return tempM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseBytecode(const unsigned char *Buf, unsigned Length,
|
void ParseBytecode(const unsigned char *Buf, unsigned Length,
|
||||||
@@ -165,8 +150,6 @@ private:
|
|||||||
|
|
||||||
Instruction *ParseInstruction(const unsigned char *&Buf,
|
Instruction *ParseInstruction(const unsigned char *&Buf,
|
||||||
const unsigned char *End);
|
const unsigned char *End);
|
||||||
std::auto_ptr<RawInst> ParseRawInst(const unsigned char *&Buf,
|
|
||||||
const unsigned char *End);
|
|
||||||
|
|
||||||
void ParseConstantPool(const unsigned char *&Buf, const unsigned char *EndBuf,
|
void ParseConstantPool(const unsigned char *&Buf, const unsigned char *EndBuf,
|
||||||
ValueTable &Tab, TypeValuesListTy &TypeTab);
|
ValueTable &Tab, TypeValuesListTy &TypeTab);
|
||||||
@@ -185,7 +168,7 @@ private:
|
|||||||
BasicBlock *getBasicBlock(unsigned ID);
|
BasicBlock *getBasicBlock(unsigned ID);
|
||||||
Constant *getConstantValue(const Type *Ty, unsigned num);
|
Constant *getConstantValue(const Type *Ty, unsigned num);
|
||||||
|
|
||||||
int insertValue(Value *V, ValueTable &Table); // -1 = Failure
|
unsigned insertValue(Value *V, ValueTable &Table);
|
||||||
|
|
||||||
unsigned getTypeSlot(const Type *Ty);
|
unsigned getTypeSlot(const Type *Ty);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user