proper flattening of nested structures +test

This commit is contained in:
alon@honor 2010-09-14 20:10:32 -07:00
Родитель a8d7622f69
Коммит 0dd0f40a7a
2 изменённых файлов: 60 добавлений и 15 удалений

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

@ -1107,6 +1107,7 @@ function analyzer(data) {
while (more) {
more = false;
values(item.types).forEach(function(type) {
if (type.flatIndexes) return;
var ready = true;
type.fields.forEach(function(field) {
//print('// zz getT: ' + type.name_ + ' : ' + field);
@ -1126,31 +1127,26 @@ function analyzer(data) {
return;
}
type.flatSize = 0;
type.needsFlattening = false;
var sizes = [];
type.flatIndexes = type.fields.map(function(field) {
var curr = type.flatSize;
var soFar = type.flatSize;
var size = 1;
if (isStructType(field)) {
dprint('types', 'type: ' + type.name_ + ' is so far of size ' + curr + ' and has ' + field + ' which is sized ' + item.types[field].flatSize);
var size = item.types[field].flatSize;
type.flatSize += size;
sizes.push(size);
type.needsFlattening = true;
} else {
type.flatSize ++;
size = item.types[field].flatSize;
}
return curr;
type.flatSize += size;
sizes.push(size);
return soFar;
});
dprint('types', 'type: ' + type.name_ + ' has FINAL size of ' + type.flatSize);
if (type.needsFlattening && dedup(sizes).length == 1) {
if (dedup(sizes).length == 1) {
type.flatFactor = sizes[0];
}
type.needsFlattening = (this.flatFactor != 1);
dprint('types', 'type: ' + type.name_ + ' : ' + JSON.stringify(type.fields));
dprint('types', ' has final size of ' + type.flatSize + ', flatting: ' + type.needsFlattening + ' ? ' + (type.flatFactor ? type.flatFactor : JSON.stringify(type.flatIndexes)));
});
}
values(item.types).forEach(function(type) {
dprint('types', 'type: ' + type.name_);// + ' : ' + JSON.stringify(type.fields));
});
item.typed = true;
return [item];
},

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

@ -670,6 +670,55 @@ class T(unittest.TestCase):
'''
self.do_test(src, '*staticccz*')
def test_nestedstructs(self):
src = '''
#include <stdio.h>
#include "emscripten.h"
struct base {
int x;
float y;
union {
int a;
float b;
};
char c;
};
struct hashtableentry {
int key;
base data;
};
struct hashset {
typedef hashtableentry entry;
struct chain { entry elem; chain *next; };
// struct chainchunk { chain chains[100]; chainchunk *next; };
};
struct hashtable : hashset {
hashtable() {
base *b = NULL;
entry *e = NULL;
chain *c = NULL;
printf("*%d,%d,%d,%d,%d,%d|%d,%d,%d,%d,%d,%d,%d,%d|%d,%d,%d,%d,%d,%d,%d,%d,%d,%d*\\n",
ES_SIZEOF(base),
int(&(b->x)), int(&(b->y)), int(&(b->a)), int(&(b->b)), int(&(b->c)),
ES_SIZEOF(hashtableentry),
int(&(e->key)), int(&(e->data)), int(&(e->data.x)), int(&(e->data.y)), int(&(e->data.a)), int(&(e->data.b)), int(&(e->data.c)),
ES_SIZEOF(hashset::chain),
int(&(c->elem)), int(&(c->next)), int(&(c->elem.key)), int(&(c->elem.data)), int(&(c->elem.data.x)), int(&(c->elem.data.y)), int(&(c->elem.data.a)), int(&(c->elem.data.b)), int(&(c->elem.data.c))
);
}
};
int main() {
hashtable t;
return 0;
}
'''
self.do_test(src, '*4,0,1,2,2,3|5,0,1,1,2,3,3,4|6,0,5,0,1,1,2,3,3,4*')
def test_fannkuch(self):
results = [ (1,0), (2,1), (3,2), (4,4), (5,7), (6,10), (7, 16), (8,22) ]
for i, j in results: