25
25
package com .oracle .svm .hosted .c .codegen ;
26
26
27
27
import static com .oracle .svm .core .util .VMError .shouldNotReachHere ;
28
- import static com .oracle .svm .core .util .VMError .shouldNotReachHereUnexpectedInput ;
29
28
import static com .oracle .svm .hosted .NativeImageOptions .CStandards .C11 ;
30
29
import static com .oracle .svm .hosted .NativeImageOptions .CStandards .C99 ;
31
30
32
31
import java .io .BufferedWriter ;
33
32
import java .io .IOException ;
33
+ import java .lang .reflect .AnnotatedType ;
34
34
import java .nio .channels .ClosedByInterruptException ;
35
35
import java .nio .charset .StandardCharsets ;
36
36
import java .nio .file .Files ;
40
40
import java .util .Arrays ;
41
41
import java .util .Collections ;
42
42
import java .util .List ;
43
- import java .util .Optional ;
44
43
45
44
import org .graalvm .nativeimage .c .function .CFunctionPointer ;
46
45
import org .graalvm .nativeimage .c .function .InvokeCFunctionPointer ;
47
- import org .graalvm .word .SignedWord ;
48
- import org .graalvm .word .UnsignedWord ;
46
+ import org .graalvm .nativeimage .c .type .CTypedef ;
49
47
50
48
import com .oracle .svm .core .util .InterruptImageBuilding ;
51
49
import com .oracle .svm .core .util .UserError ;
@@ -108,11 +106,11 @@ public void includeFiles(List<String> headerFiles) {
108
106
if (headerFile .startsWith ("<" ) && headerFile .endsWith (">" )) {
109
107
headerFileName = headerFile .substring (1 , headerFile .length () - 1 );
110
108
Path headerFilePath = Paths .get (headerFileName );
111
- appendln ("#include " + "<" + headerFilePath . toString () + ">" );
109
+ appendln ("#include " + "<" + headerFilePath + ">" );
112
110
} else if (headerFile .startsWith ("\" " ) && headerFile .endsWith ("\" " )) {
113
111
headerFileName = headerFile .substring (1 , headerFile .length () - 1 );
114
112
Path headerFilePath = Paths .get (headerFileName );
115
- appendln ("#include " + "\" " + headerFilePath . toString () + "\" " );
113
+ appendln ("#include " + "\" " + headerFilePath + "\" " );
116
114
} else {
117
115
throw UserError .abort ("Header file name must be surrounded by <...> or \" ...\" : %s" , headerFile );
118
116
}
@@ -130,7 +128,7 @@ public CSourceCodeWriter printf(String firstArg, String secondArg, String thirdA
130
128
}
131
129
132
130
public CSourceCodeWriter indents () {
133
- assert currentLine .length () == 0 : "indenting in the middle of a line" ;
131
+ assert currentLine .isEmpty () : "indenting in the middle of a line" ;
134
132
for (int i = 0 ; i < indentLevel ; i ++) {
135
133
append (INDENT4 );
136
134
}
@@ -167,7 +165,7 @@ public CSourceCodeWriter append(String str) {
167
165
}
168
166
169
167
public Path writeFile (String fileName ) {
170
- assert currentLine .length () == 0 : "last line not finished" ;
168
+ assert currentLine .isEmpty () : "last line not finished" ;
171
169
172
170
Path outputFile = tempDirectory .resolve (fileName );
173
171
try (BufferedWriter writer = Files .newBufferedWriter (outputFile , StandardCharsets .UTF_8 )) {
@@ -184,83 +182,82 @@ public Path writeFile(String fileName) {
184
182
return outputFile ;
185
183
}
186
184
187
- public static String toCTypeName (ResolvedJavaMethod method , ResolvedJavaType type , Optional <String > useSiteTypedef , boolean isConst , boolean isUnsigned , MetaAccessProvider metaAccess ,
188
- NativeLibraries nativeLibs ) {
189
- boolean isNumericInteger = type .getJavaKind ().isNumericInteger ();
190
- UserError .guarantee (isNumericInteger || !isUnsigned ,
191
- "Only integer types can be unsigned. %s is not an integer type in %s" , type , method );
192
-
193
- boolean isUnsignedWord = metaAccess .lookupJavaType (UnsignedWord .class ).isAssignableFrom (type );
194
- boolean isSignedWord = metaAccess .lookupJavaType (SignedWord .class ).isAssignableFrom (type );
195
- boolean isWord = isUnsignedWord || isSignedWord ;
196
- boolean isObject = type .getJavaKind () == JavaKind .Object && !isWord ;
197
- UserError .guarantee (isObject || !isConst ,
198
- "Only pointer types can be const. %s in method %s is not a pointer type." , type , method );
199
-
200
- if (useSiteTypedef .isPresent ()) {
201
- return (isConst ? "const " : "" ) + useSiteTypedef .get ();
202
- } else if (isNumericInteger ) {
203
- return toCIntegerType (type , isUnsigned );
204
- } else if (isUnsignedWord ) {
205
- return "size_t" ;
206
- } else if (isSignedWord ) {
207
- return "ssize_t" ;
208
- } else if (isObject ) {
185
+ public static String toCTypeName (ResolvedJavaMethod method , ResolvedJavaType type , AnnotatedType annotatedType , boolean isConst , MetaAccessProvider metaAccess , NativeLibraries nativeLibs ) {
186
+ CTypedef typeDef = annotatedType .getAnnotation (CTypedef .class );
187
+ if (typeDef != null ) {
188
+ return (isConst ? "const " : "" ) + typeDef .name ();
189
+ }
190
+
191
+ JavaKind kind = type .getJavaKind ();
192
+ if (kind .isObject () && !nativeLibs .isIntegerType (type )) {
209
193
return (isConst ? "const " : "" ) + cTypeForObject (type , metaAccess , nativeLibs );
210
- } else {
211
- switch (type .getJavaKind ()) {
212
- case Double :
213
- return "double" ;
214
- case Float :
215
- return "float" ;
216
- case Void :
217
- return "void" ;
218
- default :
219
- throw shouldNotReachHereUnexpectedInput (type .getJavaKind ()); // ExcludeFromJacocoGeneratedReport
220
- }
221
194
}
195
+
196
+ UserError .guarantee (!isConst , "Only pointer types can be const. %s in method %s is not a pointer type." , type , method );
197
+ return cTypeForPrimitive (method , type , annotatedType , nativeLibs );
222
198
}
223
199
224
200
private static String cTypeForObject (ResolvedJavaType type , MetaAccessProvider metaAccess , NativeLibraries nativeLibs ) {
225
201
ElementInfo elementInfo = nativeLibs .findElementInfo (type );
226
- if (elementInfo instanceof PointerToInfo ) {
227
- PointerToInfo pointerToInfo = (PointerToInfo ) elementInfo ;
202
+ if (elementInfo instanceof PointerToInfo pointerToInfo ) {
228
203
return (pointerToInfo .getTypedefName () != null ? pointerToInfo .getTypedefName () : pointerToInfo .getName () + "*" );
229
- } else if (elementInfo instanceof StructInfo ) {
230
- StructInfo structInfo = (StructInfo ) elementInfo ;
204
+ } else if (elementInfo instanceof StructInfo structInfo ) {
231
205
return structInfo .getTypedefName () != null ? structInfo .getTypedefName () : structInfo .getName () + "*" ;
232
206
} else if (elementInfo instanceof EnumInfo ) {
233
207
return elementInfo .getName ();
234
- } else if (isFunctionPointer (metaAccess , type )) {
235
- return InfoTreeBuilder .getTypedefName (type ) != null ? InfoTreeBuilder .getTypedefName (type ) : "void *" ;
208
+ } else if (isFunctionPointer (metaAccess , type ) && InfoTreeBuilder .getTypedefName (type ) != null ) {
209
+ return InfoTreeBuilder .getTypedefName (type );
210
+ } else {
211
+ return "void *" ;
236
212
}
237
- return "void *" ;
238
213
}
239
214
240
- private static String toCIntegerType ( ResolvedJavaType type , boolean isUnsigned ) {
215
+ private static String cTypeForPrimitive ( ResolvedJavaMethod method , ResolvedJavaType type , AnnotatedType annotatedType , NativeLibraries nativeLibs ) {
241
216
boolean c11Compatible = NativeImageOptions .getCStandard ().compatibleWith (C11 );
242
217
String prefix = "" ;
243
- if (isUnsigned ) {
218
+ if (isUnsigned ( annotatedType ) ) {
244
219
prefix = c11Compatible ? "u" : "unsigned " ;
245
220
}
246
- switch (type .getJavaKind ()) {
247
- case Boolean :
248
- if (NativeImageOptions .getCStandard ().compatibleWith (CStandards .C99 )) {
249
- return "bool" ;
250
- } else {
251
- return "int" ;
252
- }
221
+
222
+ JavaKind javaKind = type .getJavaKind ();
223
+ switch (javaKind ) {
253
224
case Byte :
254
225
return prefix + (c11Compatible ? "int8_t" : "char" );
255
- case Char :
256
226
case Short :
227
+ case Char :
257
228
return prefix + (c11Compatible ? "int16_t" : "short" );
258
229
case Int :
259
230
return prefix + (c11Compatible ? "int32_t" : "int" );
260
231
case Long :
261
232
return prefix + (c11Compatible ? "int64_t" : "long long int" );
262
233
}
263
- throw VMError .shouldNotReachHere ("All types integer types should be covered. Got " + type .getJavaKind ());
234
+
235
+ UserError .guarantee (prefix .isEmpty (), "Only integer types can be annotated with @%s. %s in method %s is not an integer type." ,
236
+ org .graalvm .nativeimage .c .type .CUnsigned .class .getSimpleName (), type , method );
237
+ switch (javaKind ) {
238
+ case Boolean :
239
+ if (NativeImageOptions .getCStandard ().compatibleWith (CStandards .C99 )) {
240
+ return "bool" ;
241
+ } else {
242
+ return "int" ;
243
+ }
244
+ case Float :
245
+ return "float" ;
246
+ case Double :
247
+ return "double" ;
248
+ case Void :
249
+ return "void" ;
250
+ case Object :
251
+ /* SignedWord or UnsignedWord. */
252
+ assert nativeLibs .isIntegerType (type );
253
+ return nativeLibs .isSigned (type ) ? "ssize_t" : "size_t" ;
254
+ default :
255
+ throw VMError .shouldNotReachHere ("Unexpected Java kind " + javaKind );
256
+ }
257
+ }
258
+
259
+ private static boolean isUnsigned (AnnotatedType type ) {
260
+ return type .isAnnotationPresent (org .graalvm .nativeimage .c .type .CUnsigned .class ) || type .isAnnotationPresent (com .oracle .svm .core .c .CUnsigned .class );
264
261
}
265
262
266
263
private static boolean isFunctionPointer (MetaAccessProvider metaAccess , ResolvedJavaType type ) {
0 commit comments