aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-04-16 16:35:08 -0700
committerAlon Zakai <alonzakai@gmail.com>2011-04-16 16:35:08 -0700
commitb48fb4d83121ee776cce12a7be43afed7332bd7d (patch)
tree7385ab05f2380e194ed0236624d20253c0fc20f5
parent11420a30683911e32c14dcf8286d4b256462b351 (diff)
proper support for packed structs
-rw-r--r--src/intertyper.js5
-rw-r--r--src/runtime.js2
-rw-r--r--tests/runner.py31
3 files changed, 36 insertions, 2 deletions
diff --git a/src/intertyper.js b/src/intertyper.js
index fe4eb929..efeba90a 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -315,11 +315,13 @@ function intertyper(data, parseFunctions, baseLineNum) {
}
if (item.tokens[2].text == 'type') {
var fields = [];
+ var packed = false;
if (Runtime.isNumberType(item.tokens[3].text)) {
// Clang sometimes has |= i32| instead of |= { i32 }|
fields = [item.tokens[3].text];
} else if (item.tokens[3].text != 'opaque') {
- if (item.tokens[3].type == '<') { // type <{ i8 }> - TODO: check spec
+ if (item.tokens[3].type == '<') {
+ packed = true;
item.tokens[3] = tokenizer.processItem({ lineText: '{ ' + item.tokens[3].item.tokens[0].text + ' }' }, true).tokens[0];
}
var subTokens = item.tokens[3].tokens;
@@ -335,6 +337,7 @@ function intertyper(data, parseFunctions, baseLineNum) {
intertype: 'type',
name_: item.tokens[0].text,
fields: fields,
+ packed: packed,
lineNum: item.lineNum
}];
} else {
diff --git a/src/runtime.js b/src/runtime.js
index acd5ed8d..6c3d630c 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -113,7 +113,7 @@ Runtime = {
dprint('Unclear type in struct: ' + field + ', in ' + type.name_);
assert(0);
}
- alignSize = Math.min(alignSize, QUANTUM_SIZE);
+ alignSize = type.packed ? 1 : 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;
diff --git a/tests/runner.py b/tests/runner.py
index d7a6409e..635a4d0f 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -1228,6 +1228,37 @@ if 'benchmark' not in sys.argv:
'''
self.do_test(src, '*96,97,98,101,101*')
+ def test_pack(self):
+ src = '''
+ #include <stdio.h>
+ #include <string.h>
+
+ #pragma pack(push,1)
+ typedef struct header
+ {
+ unsigned char id;
+ unsigned short colour;
+ unsigned char desc;
+ } header;
+ #pragma pack(pop)
+
+ typedef struct fatheader
+ {
+ unsigned char id;
+ unsigned short colour;
+ unsigned char desc;
+ } fatheader;
+
+ int main( int argc, const char *argv[] ) {
+ header h, *ph = 0;
+ fatheader fh, *pfh = 0;
+ printf("*%d,%d,%d*\\n", sizeof(header), (int)((int)&h.desc - (int)&h.id), (int)(&ph[1])-(int)(&ph[0]));
+ printf("*%d,%d,%d*\\n", sizeof(fatheader), (int)((int)&fh.desc - (int)&fh.id), (int)(&pfh[1])-(int)(&pfh[0]));
+ return 0;
+ }
+ '''
+ self.do_test(src, '*4,3,4*\n*6,4,6*')
+
def test_varargs(self):
src = '''
#include <stdio.h>