Skip to content
Permalink
Browse files

8254983: jextract fails to hande layout paths nested structs/union

Reviewed-by: jvernee, sundar
  • Loading branch information
mcimadamore committed Oct 20, 2020
1 parent 4f8777e commit d841b847a43608086340a55aee214073c48e6fb3
@@ -25,6 +25,7 @@
package jdk.internal.jextract.impl;

import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.GroupLayout;
import jdk.incubator.foreign.MemoryLayout;
import jdk.incubator.jextract.Type;

@@ -241,7 +242,7 @@ String uniqueNestedClassName(String name) {
return nestedClassNames.add(name.toLowerCase()) ? name : (name + "$" + nestedClassNameCount++);
}

StructBuilder newStructBuilder(String name, String parentLayoutFieldName, MemoryLayout parentLayout, Type type) {
return new StructBuilder(this, name, parentLayoutFieldName, parentLayout, type);
StructBuilder newStructBuilder(String name, GroupLayout parentLayout, Type type) {
return new StructBuilder(this, name, parentLayout, type);
}
}
@@ -27,7 +27,7 @@

public abstract class NestedClassBuilder extends JavaSourceBuilder {

private final JavaSourceBuilder enclosing;
protected final JavaSourceBuilder enclosing;

public NestedClassBuilder(JavaSourceBuilder enclosing, Kind kind, String className) {
super(enclosing.builder, kind, enclosing.uniqueNestedClassName(className), enclosing.pkgName, enclosing.constantHelper, enclosing.annotationWriter);
@@ -197,13 +197,11 @@ public Void visitScoped(Declaration.Scoped d, Declaration parent) {
case UNION: {
structClass = true;
String className = d.name().isEmpty() ? parent.name() : d.name();
MemoryLayout parentLayout = parentLayout(d);
String parentLayoutFieldName = className + "$struct";
currentBuilder = currentBuilder.newStructBuilder(className, parentLayoutFieldName,
parentLayout, Type.declared(d));
GroupLayout parentLayout = (GroupLayout)parentLayout(d);
currentBuilder = currentBuilder.newStructBuilder(className, parentLayout, Type.declared(d));
addStructDefinition(d, currentBuilder.className);
currentBuilder.classBegin();
currentBuilder.addLayoutGetter(parentLayoutFieldName, d.layout().get());
currentBuilder.addLayoutGetter(((StructBuilder)currentBuilder).layoutField(), d.layout().get());
break;
}
}
@@ -24,6 +24,7 @@
*/
package jdk.internal.jextract.impl;

import jdk.incubator.foreign.GroupLayout;
import jdk.incubator.foreign.MemoryLayout;
import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.jextract.Declaration;
@@ -34,17 +35,14 @@
*/
class StructBuilder extends NestedClassBuilder {

private final String parentLayoutFieldName;
private final MemoryLayout parentLayout;
private final GroupLayout parentLayout;
private final String structAnno;
private final String structArrayAnno;
private final String structPtrAnno;
private final Type structType;

StructBuilder(JavaSourceBuilder enclosing, String className, String parentLayoutFieldName,
MemoryLayout parentLayout, Type structType) {
StructBuilder(JavaSourceBuilder enclosing, String className, GroupLayout parentLayout, Type structType) {
super(enclosing, Kind.CLASS, className);
this.parentLayoutFieldName = parentLayoutFieldName;
this.parentLayout = parentLayout;
this.structAnno = annotationWriter.getCAnnotation(structType);
this.structArrayAnno = annotationWriter.getCAnnotation(Type.array(structType));
@@ -71,12 +69,12 @@ JavaSourceBuilder classEnd() {
}

private String getQualifiedName(String fieldName) {
return className + "$" + fieldName;
return qualifiedName(this) + "$" + fieldName;
}

@Override
void addVarHandleGetter(String javaName, String nativeName, MemoryLayout layout, Class<?> type) {
var desc = constantHelper.addFieldVarHandle(getQualifiedName(javaName), nativeName, layout, type, parentLayoutFieldName, parentLayout);
var desc = constantHelper.addFieldVarHandle(getQualifiedName(javaName), nativeName, layout, type, layoutField(), parentLayout);
builder.incrAlign();
builder.indent();
builder.append(PUB_MODS + displayName(desc.invocationType().returnType()) + " " + javaName + "$VH() {\n");
@@ -277,6 +275,24 @@ private void addIndexSetter(String javaName, String nativeName, MemoryLayout lay
}

private String fieldVarHandleGetCallString(String javaName, String nativeName, MemoryLayout layout, Class<?> type) {
return getCallString(constantHelper.addFieldVarHandle(javaName, nativeName, layout, type, parentLayoutFieldName, parentLayout));
return getCallString(constantHelper.addFieldVarHandle(javaName, nativeName, layout, type, layoutField(), parentLayout));
}

private String qualifiedName(JavaSourceBuilder builder) {
if (builder instanceof NestedClassBuilder) {
NestedClassBuilder nestedClassBuilder = (NestedClassBuilder)builder;
String prefix = qualifiedName(nestedClassBuilder.enclosing);
return prefix.isEmpty() ?
nestedClassBuilder.className :
prefix + "$" + nestedClassBuilder.className;
} else {
return "";
}
}

String layoutField() {
GroupLayout groupLayout = parentLayout;
String suffix = groupLayout.isUnion() ? "union" : "struct";
return qualifiedName(this) + "$" + suffix;
}
}
@@ -0,0 +1,64 @@
/*
* 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.
*/

import jdk.incubator.foreign.GroupLayout;
import jdk.incubator.foreign.MemorySegment;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static test.jextract.test8254983.test8254983_h.*;

/*
* @test id=classes
* @library ..
* @modules jdk.incubator.jextract
* @bug 8254983
* @summary jextract fails to hande layout paths nested structs/union
* @run driver JtregJextract -t test.jextract.test8254983 -- test8254983.h
* @run testng/othervm -Dforeign.restricted=permit LibTest8254983Test
*/
/*
* @test id=sources
* @library ..
* @modules jdk.incubator.jextract
* @bug 8254983
* @summary jextract fails to hande layout paths nested structs/union
* @run driver JtregJextractSources -t test.jextract.test8254983 -- test8254983.h
* @run testng/othervm -Dforeign.restricted=permit LibTest8254983Test
*/
public class LibTest8254983Test {
@Test
public void testOuterStruct() {
assertEquals(((GroupLayout)Foo._struct.$LAYOUT()).memberLayouts().size(), 1);
MemorySegment str = Foo._struct.allocate();
Foo._struct.x$set(str, 42);
assertEquals(Foo._struct.x$get(str), 42);
}

@Test
public void testInnerStruct() {
assertEquals(((GroupLayout)Foo._union._struct.$LAYOUT()).memberLayouts().size(), 2);
MemorySegment str = Foo._union._struct.allocate();
Foo._union._struct.x$set(str, 42);
assertEquals(Foo._union._struct.x$get(str), 42);
}
}
@@ -0,0 +1,35 @@
/*
* 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 {
struct {
int x;
} _struct;

union {
struct {
int u;
int x;
} _struct;
} _union;
};

0 comments on commit d841b84

Please sign in to comment.