forked from OSchip/llvm-project
Implement constant pointers, and null specifically in the parser, bytecode writer, and
bytecode reader. llvm-svn: 668
This commit is contained in:
parent
436248f236
commit
fbdec250b3
|
@ -128,6 +128,7 @@ uninitialized { return UNINIT; }
|
|||
implementation { return IMPLEMENTATION; }
|
||||
\.\.\. { return DOTDOTDOT; }
|
||||
string { return STRING; }
|
||||
null { return NULL_TOK; }
|
||||
|
||||
void { llvmAsmlval.PrimType = Type::VoidTy ; return VOID; }
|
||||
bool { llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; }
|
||||
|
|
|
@ -63,9 +63,11 @@ static inline void ThrowException(const string &message,
|
|||
// putting classes with ctor's in unions. :(
|
||||
//
|
||||
struct ValID {
|
||||
int Type; // 0 = number, 1 = name, 2 = const pool,
|
||||
// 3 = unsigned const pool, 4 = const string,
|
||||
// 5 = const fp
|
||||
enum {
|
||||
NumberVal, NameVal, ConstSIntVal, ConstUIntVal, ConstStringVal,
|
||||
ConstFPVal, ConstNullVal
|
||||
} Type;
|
||||
|
||||
union {
|
||||
int Num; // If it's a numeric reference
|
||||
char *Name; // If it's a named reference. Memory must be free'd.
|
||||
|
@ -75,35 +77,40 @@ struct ValID {
|
|||
};
|
||||
|
||||
static ValID create(int Num) {
|
||||
ValID D; D.Type = 0; D.Num = Num; return D;
|
||||
ValID D; D.Type = NumberVal; D.Num = Num; return D;
|
||||
}
|
||||
|
||||
static ValID create(char *Name) {
|
||||
ValID D; D.Type = 1; D.Name = Name; return D;
|
||||
ValID D; D.Type = NameVal; D.Name = Name; return D;
|
||||
}
|
||||
|
||||
static ValID create(int64_t Val) {
|
||||
ValID D; D.Type = 2; D.ConstPool64 = Val; return D;
|
||||
ValID D; D.Type = ConstSIntVal; D.ConstPool64 = Val; return D;
|
||||
}
|
||||
|
||||
static ValID create(uint64_t Val) {
|
||||
ValID D; D.Type = 3; D.UConstPool64 = Val; return D;
|
||||
ValID D; D.Type = ConstUIntVal; D.UConstPool64 = Val; return D;
|
||||
}
|
||||
|
||||
static ValID create_conststr(char *Name) {
|
||||
ValID D; D.Type = 4; D.Name = Name; return D;
|
||||
ValID D; D.Type = ConstStringVal; D.Name = Name; return D;
|
||||
}
|
||||
|
||||
static ValID create(double Val) {
|
||||
ValID D; D.Type = 5; D.ConstPoolFP = Val; return D;
|
||||
ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val; return D;
|
||||
}
|
||||
|
||||
static ValID createNull() {
|
||||
ValID D; D.Type = ConstNullVal; return D;
|
||||
}
|
||||
|
||||
inline void destroy() const {
|
||||
if (Type == 1 || Type == 4) free(Name); // Free this strdup'd memory...
|
||||
if (Type == NameVal || Type == ConstStringVal)
|
||||
free(Name); // Free this strdup'd memory...
|
||||
}
|
||||
|
||||
inline ValID copy() const {
|
||||
if (Type != 1 && Type != 4) return *this;
|
||||
if (Type != NameVal && Type != ConstStringVal) return *this;
|
||||
ValID Result = *this;
|
||||
Result.Name = strdup(Name);
|
||||
return Result;
|
||||
|
@ -111,11 +118,16 @@ struct ValID {
|
|||
|
||||
inline string getName() const {
|
||||
switch (Type) {
|
||||
case 0: return string("#") + itostr(Num);
|
||||
case 1: return Name;
|
||||
case 4: return string("\"") + Name + string("\"");
|
||||
case 5: return ftostr(ConstPoolFP);
|
||||
default: return string("%") + itostr(ConstPool64);
|
||||
case NumberVal : return string("#") + itostr(Num);
|
||||
case NameVal : return Name;
|
||||
case ConstStringVal: return string("\"") + Name + string("\"");
|
||||
case ConstFPVal : return ftostr(ConstPoolFP);
|
||||
case ConstNullVal : return "null";
|
||||
case ConstUIntVal :
|
||||
case ConstSIntVal : return string("%") + itostr(ConstPool64);
|
||||
default:
|
||||
assert(0 && "Unknown value!");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -180,7 +180,7 @@ static Value *getVal(const Type *Ty, const ValID &D,
|
|||
assert(Ty != Type::TypeTy && "Should use getTypeVal for types!");
|
||||
|
||||
switch (D.Type) {
|
||||
case 0: { // Is it a numbered definition?
|
||||
case ValID::NumberVal: { // Is it a numbered definition?
|
||||
unsigned type = Ty->getUniqueID();
|
||||
unsigned Num = (unsigned)D.Num;
|
||||
|
||||
|
@ -202,7 +202,7 @@ static Value *getVal(const Type *Ty, const ValID &D,
|
|||
|
||||
return CurMeth.Values[type][Num];
|
||||
}
|
||||
case 1: { // Is it a named definition?
|
||||
case ValID::NameVal: { // Is it a named definition?
|
||||
string Name(D.Name);
|
||||
SymbolTable *SymTab = 0;
|
||||
if (CurMeth.CurrentMethod)
|
||||
|
@ -223,16 +223,17 @@ static Value *getVal(const Type *Ty, const ValID &D,
|
|||
return N;
|
||||
}
|
||||
|
||||
case 2: // Is it a constant pool reference??
|
||||
case 3: // Is it an unsigned const pool reference?
|
||||
case 4: // Is it a string const pool reference?
|
||||
case 5:{ // Is it a floating point const pool reference?
|
||||
case ValID::ConstSIntVal: // Is it a constant pool reference??
|
||||
case ValID::ConstUIntVal: // Is it an unsigned const pool reference?
|
||||
case ValID::ConstStringVal: // Is it a string const pool reference?
|
||||
case ValID::ConstFPVal: // Is it a floating point const pool reference?
|
||||
case ValID::ConstNullVal: { // Is it a null value?
|
||||
ConstPoolVal *CPV = 0;
|
||||
|
||||
// Check to make sure that "Ty" is an integral type, and that our
|
||||
// value will fit into the specified type...
|
||||
switch (D.Type) {
|
||||
case 2:
|
||||
case ValID::ConstSIntVal:
|
||||
if (Ty == Type::BoolTy) { // Special handling for boolean data
|
||||
CPV = ConstPoolBool::get(D.ConstPool64 != 0);
|
||||
} else {
|
||||
|
@ -243,7 +244,7 @@ static Value *getVal(const Type *Ty, const ValID &D,
|
|||
CPV = ConstPoolSInt::get(Ty, D.ConstPool64);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case ValID::ConstUIntVal:
|
||||
if (!ConstPoolUInt::isValueValidForType(Ty, D.UConstPool64)) {
|
||||
if (!ConstPoolSInt::isValueValidForType(Ty, D.ConstPool64)) {
|
||||
ThrowException("Integral constant pool reference is invalid!");
|
||||
|
@ -254,16 +255,22 @@ static Value *getVal(const Type *Ty, const ValID &D,
|
|||
CPV = ConstPoolUInt::get(Ty, D.UConstPool64);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case ValID::ConstStringVal:
|
||||
cerr << "FIXME: TODO: String constants [sbyte] not implemented yet!\n";
|
||||
abort();
|
||||
break;
|
||||
case 5:
|
||||
case ValID::ConstFPVal:
|
||||
if (!ConstPoolFP::isValueValidForType(Ty, D.ConstPoolFP))
|
||||
ThrowException("FP constant invalid for type!!");
|
||||
else
|
||||
CPV = ConstPoolFP::get(Ty, D.ConstPoolFP);
|
||||
CPV = ConstPoolFP::get(Ty, D.ConstPoolFP);
|
||||
break;
|
||||
case ValID::ConstNullVal:
|
||||
if (!Ty->isPointerType())
|
||||
ThrowException("Cannot create a a non pointer null!");
|
||||
CPV = ConstPoolPointer::getNullPointer(Ty->castPointerType());
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Unhandled case!");
|
||||
}
|
||||
assert(CPV && "How did we escape creating a constant??");
|
||||
return CPV;
|
||||
|
@ -508,6 +515,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
|
|||
PATypeHolder<Type> *TypeVal;
|
||||
PATypeHolder<ArrayType> *ArrayTypeTy;
|
||||
PATypeHolder<StructType> *StructTypeTy;
|
||||
PATypeHolder<PointerType> *PointerTypeTy;
|
||||
Value *ValueVal;
|
||||
|
||||
list<MethodArgument*> *MethodArgList;
|
||||
|
@ -573,13 +581,14 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
|
|||
%token <PrimType> FLOAT DOUBLE TYPE LABEL
|
||||
%type <ArrayTypeTy> ArrayType ArrayTypeI
|
||||
%type <StructTypeTy> StructType StructTypeI
|
||||
%type <PointerTypeTy> PointerType PointerTypeI
|
||||
|
||||
%token <StrVal> VAR_ID LABELSTR STRINGCONSTANT
|
||||
%type <StrVal> OptVAR_ID OptAssign
|
||||
|
||||
|
||||
%token IMPLEMENTATION TRUE FALSE BEGINTOK END DECLARE GLOBAL CONSTANT UNINIT
|
||||
%token TO DOTDOTDOT STRING
|
||||
%token TO DOTDOTDOT STRING NULL_TOK
|
||||
|
||||
// Basic Block Terminating Operators
|
||||
%token <TermOpVal> RET BR SWITCH
|
||||
|
@ -692,6 +701,10 @@ StructTypeI : '{' TypeListI '}' { // Structure type?
|
|||
$$ = newTH(StructType::get(vector<const Type*>()));
|
||||
}
|
||||
|
||||
PointerTypeI : UpRTypes '*' { // Pointer type?
|
||||
$$ = newTHC<PointerType>(HandleUpRefs(PointerType::get(*$1)));
|
||||
delete $1; // Delete the type handle
|
||||
}
|
||||
|
||||
// Include derived types in the Types production.
|
||||
//
|
||||
|
@ -716,16 +729,15 @@ UpRTypes : '\\' EUINT64VAL { // Type UpReference
|
|||
| StructTypeI { // Structure type?
|
||||
$$ = newTHC<Type>(*$1); delete $1;
|
||||
}
|
||||
| UpRTypes '*' { // Pointer type?
|
||||
$$ = newTH(HandleUpRefs(PointerType::get(*$1)));
|
||||
delete $1; // Delete the type handle
|
||||
| PointerTypeI { // Pointer type?
|
||||
$$ = newTHC<Type>(*$1); delete $1;
|
||||
}
|
||||
|
||||
// Define some helpful top level types that do not allow UpReferences to escape
|
||||
//
|
||||
ArrayType : ArrayTypeI { TypeDone($$ = $1); }
|
||||
StructType : StructTypeI { TypeDone($$ = $1); }
|
||||
|
||||
ArrayType : ArrayTypeI { TypeDone($$ = $1); }
|
||||
StructType : StructTypeI { TypeDone($$ = $1); }
|
||||
PointerType : PointerTypeI { TypeDone($$ = $1); }
|
||||
|
||||
|
||||
// TypeList - Used for struct declarations and as a basis for method type
|
||||
|
@ -1051,6 +1063,10 @@ ConstValueRef : ESINT64VAL { // A reference to a direct constant
|
|||
| FALSE {
|
||||
$$ = ValID::create((int64_t)0);
|
||||
}
|
||||
| NULL_TOK {
|
||||
$$ = ValID::createNull();
|
||||
}
|
||||
|
||||
/*
|
||||
| STRINGCONSTANT { // Quoted strings work too... especially for methods
|
||||
$$ = ValID::create_conststr($1);
|
||||
|
|
|
@ -250,7 +250,7 @@ bool BytecodeParser::parseConstPoolValue(const uchar *&Buf,
|
|||
}
|
||||
|
||||
case Type::StructTyID: {
|
||||
const StructType *ST = (const StructType*)Ty;
|
||||
const StructType *ST = Ty->castStructType();
|
||||
const StructType::ElementTypes &ET = ST->getElementTypes();
|
||||
|
||||
vector<ConstPoolVal *> Elements;
|
||||
|
@ -267,6 +267,17 @@ bool BytecodeParser::parseConstPoolValue(const uchar *&Buf,
|
|||
break;
|
||||
}
|
||||
|
||||
case Type::PointerTyID: {
|
||||
const PointerType *PT = Ty->castPointerType();
|
||||
unsigned SubClass;
|
||||
if (read_vbr(Buf, EndBuf, SubClass)) return failure(true);
|
||||
if (SubClass != 0) return failure(true);
|
||||
|
||||
|
||||
V = ConstPoolPointer::getNullPointer(PT);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
cerr << __FILE__ << ":" << __LINE__
|
||||
<< ": Don't know how to deserialize constant value of type '"
|
||||
|
|
|
@ -141,6 +141,11 @@ bool BytecodeWriter::outputConstant(const ConstPoolVal *CPV) {
|
|||
break;
|
||||
}
|
||||
|
||||
case Type::PointerTyID: {
|
||||
output_vbr((unsigned)0, Out);
|
||||
break;
|
||||
}
|
||||
|
||||
case Type::FloatTyID: { // Floating point types...
|
||||
float Tmp = (float)((const ConstPoolFP*)CPV)->getValue();
|
||||
output_data(&Tmp, &Tmp+1, Out);
|
||||
|
|
Loading…
Reference in New Issue