aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralon@honor <none@none>2010-09-14 20:10:32 -0700
committeralon@honor <none@none>2010-09-14 20:10:32 -0700
commit0dd0f40a7a2c2fdf5e8344d492b3575fab8268a6 (patch)
treed44f340caa56c9533483dacc72daf66b338c5f5b
parenta8d7622f69054a6970906b2512f3107ea1e29c58 (diff)
proper flattening of nested structures +test
-rw-r--r--src/parser.js26
-rw-r--r--tests/runner.py49
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: