aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/runtime.js16
-rw-r--r--tests/runner.py47
2 files changed, 56 insertions, 7 deletions
diff --git a/src/runtime.js b/src/runtime.js
index 165ecce6..6b0d4be6 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -116,21 +116,24 @@ Runtime = {
// which would remove much of the complexity here.
calculateStructAlignment: function calculateStructAlignment(type, otherTypes) {
type.flatSize = 0;
+ type.alignSize = 0;
var diffs = [];
- var prev = -1, maxSize = -1;
+ var prev = -1;
type.flatIndexes = type.fields.map(function(field) {
- var size;
+ var size, alignSize;
if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
size = Runtime.getNativeFieldSize(field, true); // pack char; char; in structs, also char[X]s.
- maxSize = Math.max(maxSize, size);
+ alignSize = size;
} else if (Runtime.isStructType(field)) {
size = otherTypes[field].flatSize;
- maxSize = Math.max(maxSize, QUANTUM_SIZE);
+ alignSize = otherTypes[field].alignSize;
} else {
dprint('Unclear type in struct: ' + field + ', in ' + type.name_);
assert(0);
}
- var curr = Runtime.alignMemory(type.flatSize, Math.min(QUANTUM_SIZE, size)); // if necessary, place this on aligned memory
+ alignSize = Math.min(alignSize, QUANTUM_SIZE);
+ type.alignSize = Math.max(type.alignSize, alignSize);
+ var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
type.flatSize = curr + size;
if (prev >= 0) {
diffs.push(curr-prev);
@@ -138,7 +141,7 @@ Runtime = {
prev = curr;
return curr;
});
- type.flatSize = Runtime.alignMemory(type.flatSize, maxSize);
+ type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
if (diffs.length == 0) {
type.flatFactor = type.flatSize;
} else if (Runtime.dedup(diffs).length == 1) {
@@ -147,7 +150,6 @@ Runtime = {
type.needsFlattening = (type.flatFactor != 1);
return type.flatIndexes;
}
-
};
function getRuntime() {
diff --git a/tests/runner.py b/tests/runner.py
index 9d7a53fa..f1f9b947 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -618,6 +618,53 @@ if 'benchmark' not in sys.argv:
'''
self.do_test(src, '*1410,0*')
+ def test_sup(self):
+ src = '''
+ #include <stdio.h>
+
+ struct S4 { int x; }; // size: 4
+ struct S4_2 { short x, y; }; // size: 4, but for alignment purposes, 2
+ struct S6 { short x, y, z; }; // size: 6
+ struct S6w { char x[6]; }; // size: 6 also
+ struct S6z { int x; short y; }; // size: 8, since we align to a multiple of the biggest - 4
+
+ struct C___ { S6 a, b, c; int later; };
+ struct Carr { S6 a[3]; int later; }; // essentially the same, but differently defined
+ struct C__w { S6 a; S6w b; S6 c; int later; }; // same size, different struct
+ struct Cp1_ { int pre; short a; S6 b, c; int later; }; // fillers for a
+ struct Cp2_ { int a; short pre; S6 b, c; int later; }; // fillers for a (get addr of the other filler)
+ struct Cint { S6 a; int b; S6 c; int later; }; // An int (different size) for b
+ struct C4__ { S6 a; S4 b; S6 c; int later; }; // Same size as int from before, but a struct
+ struct C4_2 { S6 a; S4_2 b; S6 c; int later; }; // Same size as int from before, but a struct with max element size 2
+ struct C__z { S6 a; S6z b; S6 c; int later; }; // different size, 8 instead of 6
+
+ int main()
+ {
+ #define TEST(struc) \\
+ { \\
+ struc *s = 0; \\
+ printf("*%s: %d,%d,%d,%d<%d*\\n", #struc, (int)&(s->a), (int)&(s->b), (int)&(s->c), (int)&(s->later), sizeof(struc)); \\
+ }
+ #define TEST_ARR(struc) \\
+ { \\
+ struc *s = 0; \\
+ printf("*%s: %d,%d,%d,%d<%d*\\n", #struc, (int)&(s->a[0]), (int)&(s->a[1]), (int)&(s->a[2]), (int)&(s->later), sizeof(struc)); \\
+ }
+ printf("sizeofs:%d,%d\\n", sizeof(S6), sizeof(S6z));
+ TEST(C___);
+ TEST_ARR(Carr);
+ TEST(C__w);
+ TEST(Cp1_);
+ TEST(Cp2_);
+ TEST(Cint);
+ TEST(C4__);
+ TEST(C4_2);
+ TEST(C__z);
+ return 1;
+ }
+ '''
+ self.do_test(src, 'sizeofs:6,8\n*C___: 0,6,12,20<24*\n*Carr: 0,6,12,20<24*\n*C__w: 0,6,12,20<24*\n*Cp1_: 4,6,12,20<24*\n*Cp2_: 0,6,12,20<24*\n*Cint: 0,8,12,20<24*\n*C4__: 0,8,12,20<24*\n*C4_2: 0,6,10,16<20*\n*C__z: 0,8,16,24<28*')
+
def test_assert(self):
src = '''
#include <stdio.h>