Implement constant pointers, and null specifically in the parser, bytecode writer, and

bytecode reader.

llvm-svn: 668
This commit is contained in:
Chris Lattner 2001-09-30 22:46:54 +00:00
parent 436248f236
commit fbdec250b3
5 changed files with 81 additions and 36 deletions

View File

@ -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; }

View File

@ -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();
}
}
};

View File

@ -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);

View File

@ -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 '"

View File

@ -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);