let generateStructInfo process nested structs

This commit is contained in:
Alon Zakai 2011-07-17 22:06:26 -07:00
Родитель 756e3e1ae4
Коммит 9bcf21de1f
3 изменённых файлов: 37 добавлений и 12 удалений

Просмотреть файл

@ -134,7 +134,6 @@ var Types = {
if (shorter === longer) return;
if (shorter in this.types) return;
this.types[shorter] = this.types[longer];
delete this.types[longer];
}, this);
},

Просмотреть файл

@ -167,11 +167,17 @@ Runtime = {
// generateStructInfo(['field1', 'field2'], '%struct.UserStructType');
// (Note that you will need the full %struct.* name here at compile time,
// but not at runtime. The reason is that during compilation we cannot simplify
// the type names yet.)
generateStructInfo: function(struct, typeName) {
// the type names yet. At runtime, you can provide either the short or the
// full name.)
//
// When providing a typeName, you can generate information for nested
// structs, for example, struct = ['field1', { field2: ['sub1', 'sub2', 'sub3'] }, 'field3']
// which repesents a structure whose 2nd field is another structure.
generateStructInfo: function(struct, typeName, offset) {
var type, alignment;
if (typeName) {
type = Types.types[typeName];
offset = offset || 0;
type = typeof Types === 'undefined' ? Runtime.typeInfo[typeName] : Types.types[typeName];
if (!type) return null;
assert(type.fields.length === struct.length, 'Number of named fields must match the type for ' + typeName);
alignment = type.flatIndexes;
@ -182,9 +188,22 @@ Runtime = {
var ret = {
__size__: type.flatSize
};
struct.forEach(function(item, i) {
ret[typeof item === 'string' ? item : item[1]] = alignment[i];
});
if (typeName) {
struct.forEach(function(item, i) {
if (typeof item === 'string') {
ret[item] = alignment[i] + offset;
} else {
// embedded struct
var key;
for (var k in item) key = k;
ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
}
});
} else {
struct.forEach(function(item, i) {
ret[item[1]] = alignment[i];
});
}
return ret;
}
};

Просмотреть файл

@ -2732,12 +2732,17 @@ Child2:9
struct UserStruct {
int x;
char y;
void *z;
short z;
};
struct Encloser {
short x;
UserStruct us;
int y;
};
int main() {
UserStruct u;
u.y = 5;
printf("*ok:%d*\\n", u.y);
Encloser e;
e.us.y = 5;
printf("*ok:%d*\\n", e.us.y);
return 0;
}
'''
@ -2748,13 +2753,15 @@ Child2:9
'''
if (Runtime.typeInfo) {
print('|' + Runtime.typeInfo.UserStruct.fields + '|' + Runtime.typeInfo.UserStruct.flatIndexes + '|');
var t = Runtime.generateStructInfo(['x', { us: ['x', 'y', 'z'] }, 'y'], 'Encloser')
print('|' + [t.x, t.us.x, t.us.y, t.us.z, t.y] + '|');
} else {
print('No type info.');
}
'''
)
open(filename, 'w').write(src)
self.do_test(src, '*ok:5*\n|i32,i8,i8*|0,4,8|', post_build=post)
self.do_test(src, '*ok:5*\n|i32,i8,i16|0,4,6|\n|0,4,8,10,12|', post_build=post)
# Make sure that without the setting, we don't spam the .js with the type info
RUNTIME_TYPE_INFO = 0