diff options
-rw-r--r-- | src/parser.js | 26 | ||||
-rw-r--r-- | tests/runner.py | 49 |
2 files changed, 60 insertions, 15 deletions
diff --git a/src/parser.js b/src/parser.js index e4beee08..6f737c43 100644 --- a/src/parser.js +++ b/src/parser.js @@ -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]; }, diff --git a/tests/runner.py b/tests/runner.py index 5398327a..20849681 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -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: |