Skip to content
Permalink
Browse files
8252756: jextract does not handle VLAs/Incomplete Arrays/Flexible arrays
Reviewed-by: mcimadamore
  • Loading branch information
JornVernee committed Sep 3, 2020
1 parent eb0768a commit 2407b9da6ff47cf1fda0b9a12b7bff6c87758fed
@@ -32,6 +32,7 @@
import jdk.internal.clang.Cursor;
import jdk.internal.clang.CursorKind;
import jdk.internal.clang.Type;
import jdk.internal.clang.TypeKind;

import java.nio.ByteOrder;
import java.util.ArrayList;
@@ -70,10 +71,6 @@ static MemoryLayout compute(long offsetInParent, Type parent, Type type) {
}

final MemoryLayout compute() {
if (Utils.hasIncompleteArray(cursor)) {
//for now do this - incomplete arrays not supported well in clang
return MemoryLayout.ofStruct(MemoryLayout.ofPaddingBits(cursor.type().size() * 8));
}
Stream<Cursor> fieldCursors = Utils.flattenableChildren(cursor);
for (Cursor fc : fieldCursors.collect(Collectors.toList())) {
/*
@@ -124,7 +121,10 @@ MemoryLayout fieldLayout(Cursor c) {
}

long fieldSize(Cursor c) {
return c.isBitField()? c.getBitFieldWidth() : c.type().size() * 8;
if (c.type().kind() == TypeKind.IncompleteArray) {
return 0;
}
return c.isBitField() ? c.getBitFieldWidth() : c.type().size() * 8;
}

//Todo: fixme
@@ -31,6 +31,7 @@
import jdk.incubator.foreign.ValueLayout;
import jdk.internal.clang.Cursor;
import jdk.internal.clang.Type;
import jdk.internal.clang.TypeKind;

import java.util.List;

@@ -69,6 +70,9 @@ MemoryLayout fieldLayout(Cursor c) {

@Override
long fieldSize(Cursor c) {
if (c.type().kind() == TypeKind.IncompleteArray) {
return 0;
}
return c.type().size() * 8;
}

@@ -201,26 +201,6 @@ static Stream<Cursor> flattenableChildren(Cursor c) {
.filter(cx -> cx.isAnonymousStruct() || cx.kind() == CursorKind.FieldDecl);
}

static Optional<Cursor> lastChild(Cursor c) {
List<Cursor> children = flattenableChildren(c)
.collect(Collectors.toList());
return children.isEmpty() ? Optional.empty() : Optional.of(children.get(children.size() - 1));
}

static boolean hasIncompleteArray(Cursor c) {
switch (c.kind()) {
case FieldDecl:
return c.type().kind() == TypeKind.IncompleteArray;
case UnionDecl:
return flattenableChildren(c)
.anyMatch(Utils::hasIncompleteArray);
case StructDecl:
return lastChild(c).map(Utils::hasIncompleteArray).orElse(false);
default:
throw new IllegalStateException("Unhandled cursor kind: " + c.kind());
}
}

// return builtin Record types accessible from the given Type
static Stream<Cursor> getBuiltinRecordTypes(Type type) {
List<Cursor> recordTypes = new ArrayList<>();
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/*
* @test
* @library .. /test/lib
* @modules jdk.incubator.jextract
*
* @run testng/othervm -Dforeign.restricted=permit IncompleteArrayTest
*/

import jdk.incubator.foreign.MemoryLayout;
import org.testng.annotations.Test;

import static jdk.incubator.foreign.CSupport.C_INT;
import static jdk.incubator.foreign.CSupport.C_POINTER;
import static org.testng.Assert.*;

import java.nio.file.Path;

public class IncompleteArrayTest extends JextractToolRunner {

@Test
public void testIncompleteArray() {
Path output = getOutputFilePath("incompleteArray_out");
Path input = getInputFilePath("incompleteArray.h");
run(
"-t", "org.jextract",
"-d", output,
"--",
input).checkSuccess();
try (Loader loader = classLoader(output)) {
Class<?> cls = loader.loadClass("org.jextract.incompleteArray_h$Foo");
assertNotNull(cls);

MemoryLayout actualLayout = findLayout(cls);
MemoryLayout expectedLayout = MemoryLayout.ofStruct(
C_INT.withName("size"),
MemoryLayout.ofPaddingBits(32),
MemoryLayout.ofSequence(C_POINTER).withName("data")
).withName("Foo");
assertEquals(actualLayout, expectedLayout);
} finally {
//deleteDir(output);
}
}

}
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

struct Foo {
int size;
void* data[]; // incomplete array
};

0 comments on commit 2407b9d

Please sign in to comment.