let generateStructInfo process nested structs
This commit is contained in:
Родитель
756e3e1ae4
Коммит
9bcf21de1f
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче