Skip to content

Commit

Permalink
Various fixes for @cconstant, @cfield, @RawField, @CEnum, @CBitfield,…
Browse files Browse the repository at this point in the history
… and CConstantValueSupport.
  • Loading branch information
christianhaeubl committed Mar 29, 2024
1 parent 324b856 commit bf5f8b4
Show file tree
Hide file tree
Showing 47 changed files with 1,349 additions and 1,219 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -89,8 +89,7 @@ private ValueAccess() {
* This method is useful during native image generation, when the annotated method cannot be
* called.
*
* @param declaringClass The class that contains the method annotated with {@link CConstant}
* .
* @param declaringClass The class that contains the method.
* @param methodName The name of the method annotated with {@link CConstant}.
* @param returnType The desired type of the returned value. For integer-kind constants, the
* supported types are {@link Long}, {@link Integer}, and {@link Boolean}. For
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -63,9 +63,13 @@
* enumeration value. This annotation is optional and only needed if an attribute has a non-default
* value.
* <p>
* Note that C enumeration are merely a type-safe way to specify integer constants in C. Therefore,
* C enumeration values can be imported to Java as a regular {@link CConstant}; and {@link CEnum}
* can be used to import regular integer C constants as a Java enumeration.
* Note that in C, the keyword "enum" is merely a type-safe way to specify integer constants.
* Therefore, it is also possible to import C enumeration values as regular {@link CConstant}s into
* Java.
* <p>
* {@link CEnum} can also be used to import multiple (potentially unrelated) regular integer C
* constants into a single Java enumeration. However, please note that each C constant will be
* converted to the C type that {@link CEnum} specifies.
* <p>
* The annotated class, or an outer class that contains the class, must be annotated with
* {@link CContext}.
Expand All @@ -77,8 +81,8 @@
public @interface CEnum {

/**
* Specifies the name of the imported C enum type. If no name is provided, <code>int</code> is
* used instead.
* Specifies the name of the imported C enum type. If no name is provided, the C data type
* <code>int</code> is used instead.
*
* @since 19.0
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -65,7 +65,7 @@
* The receiver is the pointer to the struct that is accessed, i.e., the base address of the memory
* access.
* <p>
* The {@code FieldType} must be must be a primitive integer type or a {@link WordBase word type}.
* The {@code FieldType} must be a primitive integer type or a {@link WordBase word type}.
* <p>
* The optional parameter {@code locationIdentity} specifies the {@link LocationIdentity} to be used
* for the memory access. Two memory accesses with two different location identities are guaranteed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -46,12 +46,13 @@
import java.lang.annotation.Target;

/**
* Informational only. Used to provide information about the base type of a type mentioned in a
* System Java annotation. Currently use with {@link CPointerTo} to inform about the base primitive
* type of the type pointed to.
* Informational only. Used to document the base type of a type mentioned in a System Java
* annotation. Currently use with {@link CPointerTo} to inform about the base primitive type of the
* type pointed to.
*
* @since 19.0
*/
@Deprecated(since = "24.1", forRemoval = true)
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface CTypedefOfInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,25 @@
*/
package com.oracle.svm.core.posix.headers;

import com.oracle.svm.core.c.libc.GLibC;
import com.oracle.svm.core.c.libc.LibCSpecific;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.c.CContext;
import org.graalvm.nativeimage.c.constant.CConstant;
import org.graalvm.nativeimage.c.function.CFunction;
import org.graalvm.nativeimage.c.function.CLibrary;
import org.graalvm.nativeimage.c.function.CFunction.Transition;
import org.graalvm.nativeimage.c.function.CLibrary;
import org.graalvm.nativeimage.c.struct.CField;
import org.graalvm.nativeimage.c.struct.CPointerTo;
import org.graalvm.nativeimage.c.struct.CStruct;
import org.graalvm.nativeimage.c.struct.CTypedefOfInfo;
import org.graalvm.nativeimage.c.type.CCharPointer;
import org.graalvm.word.Pointer;
import org.graalvm.word.PointerBase;
import org.graalvm.word.SignedWord;
import org.graalvm.word.WordBase;

import com.oracle.svm.core.c.libc.GLibC;
import com.oracle.svm.core.c.libc.LibCSpecific;

// Checkstyle: stop

/**
Expand Down Expand Up @@ -106,7 +106,6 @@ public static class GNUExtensions {
public interface Lmid_t extends SignedWord {
}

@CTypedefOfInfo("long int")
@CPointerTo(nameOfCType = "Lmid_t")
public interface Lmid_tPointer extends PointerBase {
Lmid_t read();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,19 @@

import jdk.graal.compiler.core.common.calc.UnsignedMath;

public class EnumArrayLookup extends EnumRuntimeData {

public class CEnumArrayLookup extends CEnumRuntimeData {
private final long cOffset;
private Enum<?>[] cToJava;
private final Enum<?>[] cToJava;

public EnumArrayLookup(long[] javaToC, long cOffset, Enum<?>[] cToJava) {
super(javaToC);
public CEnumArrayLookup(long[] javaToC, int bytesInC, boolean isCValueUnsigned, long cOffset, Enum<?>[] cToJava) {
super(javaToC, bytesInC, isCValueUnsigned);
this.cOffset = cOffset;
this.cToJava = cToJava;
}

@Override
protected Enum<?> convertCToJava(long cValue) {
long arrayIdx = cValue - cOffset;
protected Enum<?> lookupEnum(long value) {
long arrayIdx = value - cOffset;
if (UnsignedMath.aboveOrEqual(arrayIdx, cToJava.length)) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,16 @@

import java.util.Map;

public class EnumMapLookup extends EnumRuntimeData {
public class CEnumMapLookup extends CEnumRuntimeData {
private final Map<Long, Enum<?>> cToJava;

private Map<Long, Enum<?>> cToJava;

public EnumMapLookup(long[] javaToC, Map<Long, Enum<?>> cToJava) {
super(javaToC);
public CEnumMapLookup(long[] javaToC, int bytesInC, boolean isCValueUnsigned, Map<Long, Enum<?>> cToJava) {
super(javaToC, bytesInC, isCValueUnsigned);
this.cToJava = cToJava;
}

@Override
protected Enum<?> convertCToJava(long cValue) {
return cToJava.get(cValue);
protected Enum<?> lookupEnum(long value) {
return cToJava.get(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@
*/
package com.oracle.svm.core.c.enums;

public class EnumNoLookup extends EnumRuntimeData {

public EnumNoLookup(long[] javaToC) {
super(javaToC);
public class CEnumNoLookup extends CEnumRuntimeData {
public CEnumNoLookup(long[] javaToC, int bytesInC, boolean isCValueUnsigned) {
super(javaToC, bytesInC, isCValueUnsigned);
}

@Override
protected Enum<?> convertCToJava(long cValue) {
protected Enum<?> lookupEnum(long value) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2014, 2024, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package com.oracle.svm.core.c.enums;

import org.graalvm.word.SignedWord;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordFactory;

import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.jdk.UninterruptibleUtils.CodeUtil;

public abstract class CEnumRuntimeData {
private static final NullPointerException CACHED_NULL_EXCEPTION = new NullPointerException(
"null enum object cannot be converted to C enum integer (typically for automatic conversions on return to C code)");

/** Stores the sign- or zero-extended C values (depending on the signedness of the C enum). */
private final long[] javaToC;
private final int bytesInC;
private final boolean isCEnumTypeUnsigned;

protected CEnumRuntimeData(long[] javaToC, int bytesInC, boolean isCEnumTypeUnsigned) {
this.javaToC = javaToC;
this.bytesInC = bytesInC;
this.isCEnumTypeUnsigned = isCEnumTypeUnsigned;
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public final boolean enumToBoolean(Enum<?> value) {
return enumToLong(value) != 0L;
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public final byte enumToByte(Enum<?> value) {
return (byte) enumToLong(value);
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public final int enumToShort(Enum<?> value) {
return (short) enumToLong(value);
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public final char enumToChar(Enum<?> value) {
return (char) CodeUtil.zeroExtend(enumToLong(value), bytesInC * Byte.SIZE);
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public final int enumToInt(Enum<?> value) {
return (int) enumToLong(value);
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public final long enumToLong(Enum<?> value) {
if (value == null) {
throw CACHED_NULL_EXCEPTION;
}
return javaToC[value.ordinal()];
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public final SignedWord enumToSignedWord(Enum<?> value) {
long result = enumToLong(value);
return WordFactory.signed(result);
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
public final UnsignedWord enumToUnsignedWord(Enum<?> value) {
long result = CodeUtil.zeroExtend(enumToLong(value), bytesInC * Byte.SIZE);
return WordFactory.unsigned(result);
}

/**
* Reduce the C value to the bits that fit into the C enum type. Then, sign- or zero-extend that
* value to 64-bit so that it can be compared to the data in the image heap.
*/
public final Enum<?> longToEnum(long rawValue) {
long lookupValue;
if (isCEnumTypeUnsigned) {
lookupValue = CodeUtil.zeroExtend(rawValue, bytesInC * Byte.SIZE);
} else {
lookupValue = CodeUtil.signExtend(rawValue, bytesInC * Byte.SIZE);
}
return lookupEnum(lookupValue);
}

protected abstract Enum<?> lookupEnum(long value);
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -713,4 +713,28 @@ public interface CharReplacer {
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
char replace(char val);
}

public static class CodeUtil {
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public static long signExtend(long value, int inputBits) {
if (inputBits < 64) {
if ((value >>> (inputBits - 1) & 1) == 1) {
return value | (-1L << inputBits);
} else {
return value & ~(-1L << inputBits);
}
} else {
return value;
}
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public static long zeroExtend(long value, int inputBits) {
if (inputBits < 64) {
return value & ~(-1L << inputBits);
} else {
return value;
}
}
}
}
Loading

0 comments on commit bf5f8b4

Please sign in to comment.