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