more type-generator refinements

This commit is contained in:
Joel Dice 2007-06-04 08:16:17 -06:00
parent e95478650c
commit f35d89cfa4
2 changed files with 106 additions and 342 deletions

View File

@ -39,8 +39,6 @@ class Object {
typedef enum { typedef enum {
Scalar, Scalar,
Array, Array,
ConstantArray,
Constant,
Pod, Pod,
Type, Type,
Pair, Pair,
@ -127,7 +125,6 @@ class Scalar : public Object {
const char* typeName; const char* typeName;
const char* name; const char* name;
unsigned elementSize; unsigned elementSize;
bool nogc;
bool noassert; bool noassert;
bool hide; bool hide;
@ -141,7 +138,6 @@ class Scalar : public Object {
o->typeName = typeName; o->typeName = typeName;
o->name = name; o->name = name;
o->elementSize = size; o->elementSize = size;
o->nogc = false;
o->noassert = false; o->noassert = false;
o->hide = false; o->hide = false;
return o; return o;
@ -175,7 +171,6 @@ arrayElementSize(Object* o)
{ {
switch (o->type) { switch (o->type) {
case Object::Array: case Object::Array:
case Object::ConstantArray:
return static_cast<Array*>(o)->elementSize; return static_cast<Array*>(o)->elementSize;
default: default:
@ -207,37 +202,12 @@ arrayPositionString(Object* o)
} }
} }
class ConstantArray : public Array {
public:
unsigned length;
static ConstantArray* make(Object* owner, Object* typeObject,
const char* typeName, const char* name,
const char* lengthString,
const char* positionString, unsigned elementSize,
unsigned length)
{
ConstantArray* o = allocate<ConstantArray>();
o->type = Object::ConstantArray;
o->owner = owner;
o->typeObject = typeObject;
o->typeName = typeName;
o->name = name;
o->lengthString = lengthString;
o->elementSize = elementSize;
o->positionString = positionString;
o->length = length;
return o;
}
};
Object* Object*
memberOwner(Object* o) memberOwner(Object* o)
{ {
switch (o->type) { switch (o->type) {
case Object::Scalar: case Object::Scalar:
case Object::Array: case Object::Array:
case Object::ConstantArray:
return static_cast<Scalar*>(o)->owner; return static_cast<Scalar*>(o)->owner;
default: default:
@ -251,7 +221,6 @@ memberTypeObject(Object* o)
switch (o->type) { switch (o->type) {
case Object::Scalar: case Object::Scalar:
case Object::Array: case Object::Array:
case Object::ConstantArray:
return static_cast<Scalar*>(o)->typeObject; return static_cast<Scalar*>(o)->typeObject;
default: default:
@ -265,7 +234,6 @@ memberTypeName(Object* o)
switch (o->type) { switch (o->type) {
case Object::Scalar: case Object::Scalar:
case Object::Array: case Object::Array:
case Object::ConstantArray:
return static_cast<Scalar*>(o)->typeName; return static_cast<Scalar*>(o)->typeName;
default: default:
@ -279,7 +247,6 @@ memberName(Object* o)
switch (o->type) { switch (o->type) {
case Object::Scalar: case Object::Scalar:
case Object::Array: case Object::Array:
case Object::ConstantArray:
return static_cast<Scalar*>(o)->name; return static_cast<Scalar*>(o)->name;
default: default:
@ -287,13 +254,6 @@ memberName(Object* o)
} }
} }
unsigned
constantLength(Object* o)
{
assert(o->type == Object::ConstantArray);
return static_cast<ConstantArray*>(o)->length;
}
unsigned unsigned
memberSize(Object* o) memberSize(Object* o)
{ {
@ -301,10 +261,6 @@ memberSize(Object* o)
case Object::Scalar: case Object::Scalar:
return static_cast<Scalar*>(o)->elementSize; return static_cast<Scalar*>(o)->elementSize;
case Object::ConstantArray:
return static_cast<ConstantArray*>(o)->length *
static_cast<ConstantArray*>(o)->elementSize;
default: default:
UNREACHABLE; UNREACHABLE;
} }
@ -316,7 +272,6 @@ memberElementSize(Object* o)
switch (o->type) { switch (o->type) {
case Object::Scalar: case Object::Scalar:
case Object::Array: case Object::Array:
case Object::ConstantArray:
return static_cast<Scalar*>(o)->elementSize; return static_cast<Scalar*>(o)->elementSize;
default: default:
@ -324,27 +279,12 @@ memberElementSize(Object* o)
} }
} }
bool&
memberNoGc(Object* o)
{
switch (o->type) {
case Object::Scalar:
case Object::Array:
case Object::ConstantArray:
return static_cast<Scalar*>(o)->nogc;
default:
UNREACHABLE;
}
}
bool& bool&
memberNoAssert(Object* o) memberNoAssert(Object* o)
{ {
switch (o->type) { switch (o->type) {
case Object::Scalar: case Object::Scalar:
case Object::Array: case Object::Array:
case Object::ConstantArray:
return static_cast<Scalar*>(o)->noassert; return static_cast<Scalar*>(o)->noassert;
default: default:
@ -358,7 +298,6 @@ memberHide(Object* o)
switch (o->type) { switch (o->type) {
case Object::Scalar: case Object::Scalar:
case Object::Array: case Object::Array:
case Object::ConstantArray:
return static_cast<Scalar*>(o)->hide; return static_cast<Scalar*>(o)->hide;
default: default:
@ -374,8 +313,6 @@ class Type : public Object {
List members; List members;
List subtypes; List subtypes;
bool hideConstructor; bool hideConstructor;
bool op;
bool code;
static Type* make(Object::ObjectType type, const char* name, static Type* make(Object::ObjectType type, const char* name,
const char* shortName) const char* shortName)
@ -388,8 +325,6 @@ class Type : public Object {
o->members.first = o->members.last = 0; o->members.first = o->members.last = 0;
o->subtypes.first = o->subtypes.last = 0; o->subtypes.first = o->subtypes.last = 0;
o->hideConstructor = false; o->hideConstructor = false;
o->op = false;
o->code = false;
return o; return o;
} }
}; };
@ -492,58 +427,6 @@ typeHideConstructor(Object* o)
} }
} }
bool&
typeOp(Object* o)
{
switch (o->type) {
case Object::Type:
return static_cast<Type*>(o)->op;
default:
UNREACHABLE;
}
}
bool&
typeCode(Object* o)
{
switch (o->type) {
case Object::Type:
return static_cast<Type*>(o)->code;
default:
UNREACHABLE;
}
}
class Constant : public Object {
public:
const char* name;
const char* value;
static Constant* make(const char* name, const char* value) {
Constant* o = allocate<Constant>();
o->type = Object::Constant;
o->name = name;
o->value = value;
return o;
}
};
const char*
constantName(Object* o)
{
assert(o->type == Object::Constant);
return static_cast<Constant*>(o)->name;
}
const char*
constant(Object* o)
{
assert(o->type == Object::Constant);
return static_cast<Constant*>(o)->value;
}
class Number : public Object { class Number : public Object {
public: public:
unsigned value; unsigned value;
@ -724,10 +607,6 @@ declaration(const char* name, Object* declarations)
if (equal(name, typeName(o))) return o; if (equal(name, typeName(o))) return o;
break; break;
case Object::Constant:
if (equal(name, constantName(o))) return o;
break;
default: UNREACHABLE; default: UNREACHABLE;
} }
} }
@ -759,9 +638,6 @@ class MemberIterator {
unsigned size_; unsigned size_;
unsigned padding_; unsigned padding_;
unsigned alignment_; unsigned alignment_;
unsigned arrayLengthMember_;
unsigned arrayPositionMember_;
int dependency_;
MemberIterator(Object* type, bool skipSupers = false): MemberIterator(Object* type, bool skipSupers = false):
types(derivationChain(type)), types(derivationChain(type)),
@ -772,10 +648,7 @@ class MemberIterator {
offset_(type->type == Object::Pod ? 0 : sizeof(void*)), offset_(type->type == Object::Pod ? 0 : sizeof(void*)),
size_(0), size_(0),
padding_(0), padding_(0),
alignment_(0), alignment_(0)
arrayLengthMember_(0),
arrayPositionMember_(0),
dependency_(-1)
{ {
while (skipSupers and hasMore() and this->type != type) next(); while (skipSupers and hasMore() and this->type != type) next();
padding_ = 0; padding_ = 0;
@ -800,13 +673,9 @@ class MemberIterator {
assert(hasMore()); assert(hasMore());
if (member) { if (member) {
if (member->type == Object::Array) { assert(member->type == Object::Scalar);
dependency_ = index_;
offset_ = 0;
} else {
offset_ += size_; offset_ += size_;
} }
}
member = car(members); member = car(members);
members = cdr(members); members = cdr(members);
@ -814,18 +683,13 @@ class MemberIterator {
++ index_; ++ index_;
switch (member->type) { switch (member->type) {
case Object::Scalar: case Object::ConstantArray: { case Object::Scalar: {
arrayLengthMember_ = 0;
arrayPositionMember_ = 0;
size_ = memberSize(member); size_ = memberSize(member);
padding_ = pad(size_, alignment_); padding_ = pad(size_, alignment_);
alignment_ = (alignment_ + size_ + padding_) % sizeof(void*); alignment_ = (alignment_ + size_ + padding_) % sizeof(void*);
} break; } break;
case Object::Array: { case Object::Array: {
arrayLengthMember_ = findMember(type, arrayLengthString(member));
arrayPositionMember_ = arrayPositionString(member) ?
findMember(type, arrayPositionString(member)) : 0;
size_ = 0x7FFFFFFF; size_ = 0x7FFFFFFF;
padding_ = pad(memberElementSize(member), alignment_); padding_ = pad(memberElementSize(member), alignment_);
alignment_ = 0; alignment_ = 0;
@ -839,13 +703,6 @@ class MemberIterator {
return member; return member;
} }
static unsigned findMember(Object* type, const char* name) {
for (MemberIterator it(type); it.hasMore();) {
if (equal(memberName(it.next()), name)) return it.index();
}
UNREACHABLE;
}
unsigned offset() { unsigned offset() {
return offset_; return offset_;
} }
@ -866,18 +723,6 @@ class MemberIterator {
return index_; return index_;
} }
unsigned arrayLengthMember() {
return arrayLengthMember_;
}
unsigned arrayPositionMember() {
return arrayPositionMember_;
}
int dependency() {
return dependency_;
}
unsigned alignment() { unsigned alignment() {
return alignment_; return alignment_;
} }
@ -934,19 +779,6 @@ sizeOf(const char* type, Object* declarations)
} }
} }
int
constant(const char* name, Object* declarations)
{
for (Object* p = declarations; p; p = cdr(p)) {
Object* o = car(p);
if (o->type == Type::Constant and equal(name, constantName(o)))
return atoi(constant(o));
}
fprintf(stderr, "unknown constant: %s\n", name);
abort();
}
Object* Object*
parseArray(Object::ObjectType type, Object* t, Object* p, Object* declarations) parseArray(Object::ObjectType type, Object* t, Object* p, Object* declarations)
{ {
@ -955,22 +787,9 @@ parseArray(Object::ObjectType type, Object* t, Object* p, Object* declarations)
p = cdr(p); p = cdr(p);
const char* name = string(car(p)); const char* name = string(car(p));
p = cdr(p);
const char* length = string(car(p));
p = cdr(p);
const char* position = p ? string(car(p)) : length;
unsigned elementSize = sizeOf(typeName, declarations);
if (type == Object::ConstantArray) {
unsigned size = constant(length, declarations) * elementSize;
return ConstantArray::make(t, declaration(typeName, declarations),
typeName, name, length, position, elementSize,
size);
} else {
return Array::make(t, declaration(typeName, declarations), return Array::make(t, declaration(typeName, declarations),
typeName, name, length, position, elementSize); typeName, name, length, position,
} sizeOf(typeName, declarations));
} }
Object* Object*
@ -979,12 +798,6 @@ parseMember(Object* t, Object* p, Object* declarations)
const char* spec = string(car(p)); const char* spec = string(car(p));
if (equal(spec, "array")) { if (equal(spec, "array")) {
return parseArray(Object::Array, t, cdr(p), declarations); return parseArray(Object::Array, t, cdr(p), declarations);
} else if (equal(spec, "constant-array")) {
return parseArray(Object::ConstantArray, t, cdr(p), declarations);
} else if (equal(spec, "nogc")) {
Object* member = parseMember(t, cdr(p), declarations);
memberNoGc(member) = true;
return member;
} else if (equal(spec, "noassert")) { } else if (equal(spec, "noassert")) {
Object* member = parseMember(t, cdr(p), declarations); Object* member = parseMember(t, cdr(p), declarations);
memberNoAssert(member) = true; memberNoAssert(member) = true;
@ -1028,7 +841,6 @@ memberEqual(Object* a, Object* b)
switch (a->type) { switch (a->type) {
case Object::Scalar: case Object::Scalar:
return equal(memberTypeName(a), memberTypeName(b)) return equal(memberTypeName(a), memberTypeName(b))
and memberNoGc(a) == memberNoGc(b)
and memberNoAssert(a) == memberNoAssert(b) and memberNoAssert(a) == memberNoAssert(b)
and memberHide(a) == memberHide(b); and memberHide(a) == memberHide(b);
@ -1120,26 +932,8 @@ parseDeclaration(Object* p, Object* declarations)
Object* t = parseType(Object::Type, cdr(p), declarations); Object* t = parseType(Object::Type, cdr(p), declarations);
typeOp(t) = true; typeOp(t) = true;
return t; return t;
} else if (equal(spec, "code")) {
const char* name = string(car(cdr(p)));
Type* t = Type::make(Object::Type, name, name);
typeSuper(t) = declaration("annotatedOp", declarations);
assert(typeSuper(t));
assert(typeSuper(t)->type == Object::Type);
addSubtype(typeSuper(t), t);
typeOp(t) = true;
typeCode(t) = true;
return t;
} else if (equal(spec, "pod")) { } else if (equal(spec, "pod")) {
return parseType(Object::Pod, cdr(p), declarations); return parseType(Object::Pod, cdr(p), declarations);
} else if (equal(spec, "constant")) {
p = cdr(p);
const char* name = string(car(p));
p = cdr(p);
const char* value = string(car(p));
return Constant::make(name, value);
} else { } else {
fprintf(stderr, "unexpected declaration spec: %s\n", spec); fprintf(stderr, "unexpected declaration spec: %s\n", spec);
abort(); abort();
@ -1304,7 +1098,7 @@ typeBodyOffset(Object* type, Object* offset)
while (it.hasMore()) { while (it.hasMore()) {
Object* m = it.next(); Object* m = it.next();
switch (m->type) { switch (m->type) {
case Object::Scalar: case Object::ConstantArray: { case Object::Scalar: {
offset = cons(Number::make(it.space()), offset); offset = cons(Number::make(it.space()), offset);
} break; } break;
@ -1363,25 +1157,6 @@ writePods(Output* out, Object* declarations)
} }
} }
void
writeConstants(Output* out, Object* declarations)
{
for (Object* p = declarations; p; p = cdr(p)) {
Object* o = car(p);
switch (o->type) {
case Object::Constant: {
out->write("const unsigned ");
out->write(capitalize(constantName(o)));
out->write(" = ");
out->write(constant(o));
out->write(";\n\n");
} break;
default: break;
}
}
}
void void
writeAccessors(Output* out, Object* declarations) writeAccessors(Output* out, Object* declarations)
{ {
@ -1395,7 +1170,7 @@ writeAccessors(Output* out, Object* declarations)
for (MemberIterator it(o, true); it.hasMore();) { for (MemberIterator it(o, true); it.hasMore();) {
Object* m = it.next(); Object* m = it.next();
switch (m->type) { switch (m->type) {
case Object::Scalar: case Object::ConstantArray: { case Object::Scalar: {
if (it.padding()) offset = cons(Number::make(it.padding()), offset); if (it.padding()) offset = cons(Number::make(it.padding()), offset);
writeAccessor(out, m, offset); writeAccessor(out, m, offset);
if (memberNoAssert(m)) writeAccessor(out, m, offset, true); if (memberNoAssert(m)) writeAccessor(out, m, offset, true);
@ -1511,8 +1286,7 @@ typeProtectedMemberCount(Object* o)
for (MemberIterator it(o); it.hasMore();) { for (MemberIterator it(o); it.hasMore();) {
Object* m = it.next(); Object* m = it.next();
if (m->type == Object::Scalar if (m->type == Object::Scalar
and equal(memberTypeName(m), "object") and equal(memberTypeName(m), "object"))
and not memberNoGc(m))
{ {
++ count; ++ count;
} }
@ -1527,8 +1301,7 @@ writeProtected(Output* out, Object* o)
for (MemberIterator it(o); it.hasMore();) { for (MemberIterator it(o); it.hasMore();) {
Object* m = it.next(); Object* m = it.next();
if (m->type == Object::Scalar if (m->type == Object::Scalar
and equal(memberTypeName(m), "object") and equal(memberTypeName(m), "object"))
and not memberNoGc(m))
{ {
if (wrote) { if (wrote) {
out->write(", "); out->write(", ");
@ -1709,94 +1482,6 @@ writeDeclarations(Output* out, Object* declarations)
default: break; default: break;
} }
} }
for (Object* p = declarations; p; p = cdr(p)) {
Object* o = car(p);
switch (o->type) {
case Object::Type: {
if (typeCode(o)) {
out->write("object ");
out->write(opName(typeName(o)));
out->write("Code;\n");
}
} break;
default: break;
}
}
}
unsigned
podObjectFieldMask(Object* o)
{
unsigned mask = 0;
if (o->type == Object::Pod) {
for (MemberIterator it(o); it.hasMore();) {
Object* m = it.next();
assert(m->type == Object::Scalar);
if (equal(memberTypeName(m), "object") and not memberNoGc(m)) {
assert(it.offset() % sizeof(void*) == 0);
unsigned i = it.offset() / sizeof(void*);
assert(i < (sizeof(unsigned) * 8));
mask |= static_cast<unsigned>(1) << i;
}
}
}
return mask;
}
bool
podHasObjectFields(Object* o)
{
if (o->type == Object::Pod) {
for (MemberIterator it(o); it.hasMore();) {
Object* m = it.next();
assert(m->type == Object::Scalar);
if (equal(memberTypeName(m), "object") and not memberNoGc(m)) {
return true;
}
}
}
return false;
}
const char*
memberEnum(Object* o)
{
switch (o->type) {
case Object::Scalar: {
if (equal(memberTypeName(o), "object")) {
if (memberNoGc(o)) {
return "OtherMember";
} else {
return "ObjectMember";
}
} else if (namesPointer(memberTypeName(o))) {
return "PointerMember";
} else {
return "OtherMember";
}
} break;
case Object::ConstantArray: {
return "OtherMember";
} break;
case Object::Array: {
if (equal(memberTypeName(o), "object")) {
return "ObjectArrayMember";
} else if (memberTypeObject(o)
and memberTypeObject(o)->type == Object::Pod
and podHasObjectFields(memberTypeObject(o)))
{
return "ObjectPodArrayMember";
} else {
return "ArrayMember";
}
} break;
default: UNREACHABLE;
}
} }
unsigned unsigned
@ -1810,6 +1495,91 @@ memberCount(Object* o)
return c; return c;
} }
void
set(uint32_t* mask, unsigned index)
{
if (index < 32) {
mask |= 1 << index;
} else {
UNREACHABLE;
}
}
unsigned
typeFixedSize(Object* type)
{
unsigned length = 0;
for (MemberIterator it(o); it.hasMore();) {
Object* m = it.next();
switch (m->type) {
case Object::Scalar: {
length = pad(it.offset() + it.space());
} break;
case Object::Array: break;
default: UNREACHABLE;
}
}
return length;
}
unsigned
typeArrayElementSize(Object* type)
{
for (MemberIterator it(o); it.hasMore();) {
Object* m = it.next();
switch (m->type) {
case Object::Scalar: break;
case Object::Array: {
return memberElementSize(m);
} break;
default: UNREACHABLE;
}
}
return 0;
}
uint32_t
typeObjectMask(Object* type)
{
assert(typeFixedMaskLength(type) + typeArrayElementMaskLength(type) < 32);
uint32_t mask = 0;
for (MemberIterator it(o); it.hasMore();) {
Object* m = it.next();
unsigned offset = it.offset() / sizeof(void*);
switch (m->type) {
case Object::Scalar: {
if (equal(memberTypeName(m), "object")) {
set(&mask, offset);
}
} break;
case Object::Array: {
if (equal(memberTypeName(m), "object")) {
set(&mask, offset);
} else if (memberTypeObject(m)
and memberTypeObject(m)->type == Object::Pod)
{
for (MemberIterator it(m); it.hasMore();) {
Object* m = it.next();
if (equal(memberTypeName(m), "object")) {
set(&mask, offset + (it.offset() / sizeof(void*)));
}
}
}
} break;
default: UNREACHABLE;
}
}
}
void void
writePrimaryInitialization(Output* out, Object* type) writePrimaryInitialization(Output* out, Object* type)
{ {
@ -1819,13 +1589,7 @@ writePrimaryInitialization(Output* out, Object* type)
out->write("{\n"); out->write("{\n");
if (typeObjectMask(type)) { if (typeObjectMask(type)) {
out->write(" object mask = makeObjectMask("); out->write(" object mask = makeIntArray(t, 1);\n");
out->write(typeMaskLength(type));
out->write(", ");
out->write(typeArrayMaskLength(type));
out->write(", ");
out->write(typeObjectMaskLengthIn32BitWords(type));
out->write(");\n");
out->write(" objectMaskBody(mask)[0] = "); out->write(" objectMaskBody(mask)[0] = ");
out->write(typeObjectMask(type)); out->write(typeObjectMask(type));
@ -1839,7 +1603,11 @@ writePrimaryInitialization(Output* out, Object* type)
out->write("Class = makeClass"); out->write("Class = makeClass");
out->write("(t, "); out->write("(t, ");
out->write(capitalize(typeName(type))); out->write(capitalize(typeName(type)));
out->write("Type, 0, 0, mask, 0, 0, 0);\n"); out->write("Type, ");
out->write(typeFixedSize(type));
out->write(", ");
out->write(typeArrayElementSize(type));
out->write(", mask, 0, 0, 0, 0, 0);\n");
out->write("}\n\n"); out->write("}\n\n");
} }
@ -1892,7 +1660,6 @@ main(int ac, char** av)
if (ac == 1 or equal(av[1], "header")) { if (ac == 1 or equal(av[1], "header")) {
writePods(&out, declarations); writePods(&out, declarations);
writeConstants(&out, declarations);
writeAccessors(&out, declarations); writeAccessors(&out, declarations);
writeConstructorDeclarations(&out, declarations); writeConstructorDeclarations(&out, declarations);
} }

View File

@ -1,17 +1,14 @@
(type class (type class
(uintptr_t id) (uint32_t id)
(uint16_t fixedSize)
(uint16_t arrayElementSize)
(object objectMask)
(object name) (object name)
(object super) (object super)
(object objectMask)
(object fieldTable) (object fieldTable)
(object methodTable) (object methodTable)
(object staticTable)) (object staticTable))
(type objectMask
(uint32_t maskLength)
(uint32_t arrayMaskLength)
(array uint32_t body))
(pod field (pod field
(uint16_t flags) (uint16_t flags)
(object name) (object name)