Skip to content

Commit

Permalink
Fix alignment for nested types
Browse files Browse the repository at this point in the history
  • Loading branch information
zhanhb committed Oct 21, 2017
1 parent a0b8dcc commit b47c65b
Showing 1 changed file with 21 additions and 6 deletions.
27 changes: 21 additions & 6 deletions src/main/java/jnr/ffi/Struct.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static final class Info {
int size = 0;
int minAlign = 1;
boolean isUnion = false;
boolean resetIndex = false;

This comment has been minimized.

Copy link
@goto1134

goto1134 Oct 22, 2017

Contributor

Why did you delete this flag? It is used for alignin unions.

This comment has been minimized.

Copy link
@zhanhb

zhanhb Oct 22, 2017

Author Contributor

For union type, we have two situations to reset the index.
First: a non array type.
Second: the first element of an array
The method nextOffset I add has already judged both situations.

int currentSize = -1; // only used when this is an enum and add array elements

This comment has been minimized.

Copy link
@goto1134

goto1134 Oct 22, 2017

Contributor

It has only two values, -1 and 0, as I see. Why not boolean?


Alignment alignment = new Alignment(0);

Expand Down Expand Up @@ -93,6 +93,20 @@ private jnr.ffi.Pointer allocateMemory(int flags) {
}
}

private int nextOffset(int size, int alignment) {
if (isUnion) {
if (currentSize > -1) { // add element to an array
int result = align(this.currentSize, alignment);
this.currentSize = result + size;

This comment has been minimized.

Copy link
@zhanhb

zhanhb Oct 22, 2017

Author Contributor

currentSize will be change to the index of current adding array.

return result;
} else {
return 0;
}
} else {
return align(this.size, alignment);
}
}

public final void useMemory(jnr.ffi.Pointer io) {
this.memory = io;
}
Expand All @@ -105,7 +119,7 @@ protected final int addField(int sizeBits, int alignBits, Offset offset) {

protected final int addField(int sizeBits, int alignBits) {
final int alignment = this.alignment.intValue() > 0 ? Math.min(this.alignment.intValue(), (alignBits >> 3)) : (alignBits >> 3);
final int offset = resetIndex ? 0 : align(this.size, alignment);
final int offset = nextOffset(sizeBits >> 3, alignment);
this.size = Math.max(this.size, offset + (sizeBits >> 3));
this.minAlign = Math.max(this.minAlign, alignment);
return offset;
Expand Down Expand Up @@ -139,7 +153,7 @@ protected Struct(Runtime runtime, Struct enclosing) {
*/
protected Struct(Runtime runtime, final boolean isUnion) {
this(runtime);
__info.resetIndex = isUnion;
__info.currentSize = -1;
__info.isUnion = isUnion;
}

Expand Down Expand Up @@ -314,14 +328,14 @@ protected abstract class Member {
* Starts an array construction session
*/
protected final void arrayBegin() {
__info.resetIndex = false;
__info.currentSize = 0;
}

/**
* Ends an array construction session
*/
protected final void arrayEnd() {
__info.resetIndex = __info.isUnion;
__info.currentSize = -1;
}

/**
Expand Down Expand Up @@ -684,10 +698,11 @@ protected UTF8String[] array(UTF8String[] array, int stringLength) {

protected final <T extends Struct> T inner(T struct) {
int alignment = __info.alignment.intValue() > 0 ? Math.min(__info.alignment.intValue(), struct.__info.getMinimumAlignment()) : struct.__info.getMinimumAlignment();
int offset = __info.resetIndex ? 0 : align(__info.size, alignment);
int offset = __info.nextOffset(struct.__info.size, alignment);
struct.__info.enclosing = this;
struct.__info.offset = offset;
__info.size = Math.max(__info.size, offset + struct.__info.size);
__info.minAlign = Math.max(__info.minAlign, alignment);
return struct;
}

Expand Down

0 comments on commit b47c65b

Please sign in to comment.