Skip to content

Commit 5e3c59b

Browse files
fangerertimfel
authored andcommitted
Fix HPy's test_capsule
1 parent beba1ba commit 5e3c59b

File tree

5 files changed

+123
-41
lines changed

5 files changed

+123
-41
lines changed

graalpython/com.oracle.graal.python.cext/hpy/hpy.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -765,11 +765,11 @@ HPyAPI_STORAGE HPy_ssize_t _HPy_IMPL_NAME(Long_AsSsize_t)(HPyContext *ctx, HPy h
765765
}
766766

767767
HPyAPI_STORAGE void* _HPy_IMPL_NAME(Long_AsVoidPtr)(HPyContext *ctx, HPy h) {
768-
return (void *) UPCALL_I64(ctx_Long_AsVoidPtr, ctx, h);
768+
return (void *) UPCALL_I64(ctx_Long_AsVoidPtr, ctx, h);
769769
}
770770

771771
HPyAPI_STORAGE double _HPy_IMPL_NAME(Long_AsDouble)(HPyContext *ctx, HPy h) {
772-
return UPCALL_DOUBLE(ctx_Long_AsDouble, ctx, h);
772+
return UPCALL_DOUBLE(ctx_Long_AsDouble, ctx, h);
773773
}
774774

775775
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Float_FromDouble)(HPyContext *ctx, double v)
@@ -988,11 +988,11 @@ HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_SetObject)(HPyContext *ctx, HPy h_type, H
988988
}
989989

990990
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Err_SetFromErrnoWithFilename)(HPyContext *ctx, HPy h_type, const char *filename_fsencoded) {
991-
return UPCALL_HPY(ctx_Err_SetFromErrnoWithFilename, ctx, h_type, filename_fsencoded);
991+
return UPCALL_HPY(ctx_Err_SetFromErrnoWithFilename, ctx, h_type, filename_fsencoded);
992992
}
993993

994994
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Err_SetFromErrnoWithFilenameObjects)(HPyContext *ctx, HPy h_type, HPy filename1, HPy filename2) {
995-
return UPCALL_HPY(ctx_Err_SetFromErrnoWithFilenameObjects, ctx, h_type, filename1, filename2);
995+
return UPCALL_HPY(ctx_Err_SetFromErrnoWithFilenameObjects, ctx, h_type, filename1, filename2);
996996
}
997997

998998
HPyAPI_STORAGE int _HPy_IMPL_NAME(Err_Occurred)(HPyContext *ctx)
@@ -1001,7 +1001,7 @@ HPyAPI_STORAGE int _HPy_IMPL_NAME(Err_Occurred)(HPyContext *ctx)
10011001
}
10021002

10031003
HPyAPI_STORAGE int _HPy_IMPL_NAME(Err_ExceptionMatches)(HPyContext *ctx, HPy exc) {
1004-
return (int) UPCALL_I32(ctx_Err_ExceptionMatches, ctx, exc);
1004+
return (int) UPCALL_I32(ctx_Err_ExceptionMatches, ctx, exc);
10051005
}
10061006

10071007
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Err_NoMemory)(HPyContext *ctx)
@@ -1023,15 +1023,15 @@ HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Err_NewExceptionWithDoc)(HPyContext *ctx, cons
10231023
}
10241024

10251025
HPyAPI_STORAGE int _HPy_IMPL_NAME(Err_WarnEx)(HPyContext *ctx, HPy category, const char *message, HPy_ssize_t stack_level) {
1026-
return (int) UPCALL_I32(ctx_Err_WarnEx, ctx, category, message, stack_level);
1026+
return (int) UPCALL_I32(ctx_Err_WarnEx, ctx, category, message, stack_level);
10271027
}
10281028

10291029
HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_WriteUnraisable)(HPyContext *ctx, HPy obj) {
1030-
UPCALL_VOID(ctx_Err_WriteUnraisable, ctx, obj);
1030+
UPCALL_VOID(ctx_Err_WriteUnraisable, ctx, obj);
10311031
}
10321032

10331033
HPyAPI_STORAGE void _HPy_IMPL_NAME(FatalError)(HPyContext *ctx, const char *msg) {
1034-
UPCALL_VOID(ctx_FatalError, ctx, msg);
1034+
UPCALL_VOID(ctx_FatalError, ctx, msg);
10351035
}
10361036

10371037
HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(IsTrue)(HPyContext *ctx, HPy h)
@@ -1095,7 +1095,7 @@ HPyAPI_STORAGE HPy _HPy_IMPL_NAME_NOPREFIX(GetItem_s)(HPyContext *ctx, HPy obj,
10951095
}
10961096

10971097
HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(Contains)(HPyContext *ctx, HPy container, HPy key) {
1098-
return (int) UPCALL_I32(ctx_Contains, ctx, container, key);
1098+
return (int) UPCALL_I32(ctx_Contains, ctx, container, key);
10991099
}
11001100

11011101
HPyAPI_STORAGE int _HPy_IMPL_NAME_NOPREFIX(SetItem)(HPyContext *ctx, HPy obj, HPy key, HPy value)
@@ -1224,7 +1224,7 @@ HPyAPI_STORAGE int _HPy_IMPL_NAME(Unicode_Check)(HPyContext *ctx, HPy h)
12241224
}
12251225

12261226
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_AsASCIIString)(HPyContext *ctx, HPy h) {
1227-
return UPCALL_HPY(ctx_Unicode_AsASCIIString, ctx, h);
1227+
return UPCALL_HPY(ctx_Unicode_AsASCIIString, ctx, h);
12281228
}
12291229

12301230
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_AsLatin1String)(HPyContext *ctx, HPy h) {
@@ -1251,23 +1251,23 @@ HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_DecodeFSDefault)(HPyContext *ctx, cons
12511251
}
12521252

12531253
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_DecodeFSDefaultAndSize)(HPyContext *ctx, const char *v, HPy_ssize_t size) {
1254-
return UPCALL_HPY(ctx_Unicode_DecodeFSDefaultAndSize, ctx, v, size);
1254+
return UPCALL_HPY(ctx_Unicode_DecodeFSDefaultAndSize, ctx, v, size);
12551255
}
12561256

12571257
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_EncodeFSDefault)(HPyContext *ctx, HPy h) {
1258-
return UPCALL_HPY(ctx_Unicode_EncodeFSDefault, ctx, h);
1258+
return UPCALL_HPY(ctx_Unicode_EncodeFSDefault, ctx, h);
12591259
}
12601260

12611261
HPyAPI_STORAGE uint32_t _HPy_IMPL_NAME(Unicode_ReadChar)(HPyContext *ctx, HPy h, HPy_ssize_t index) {
12621262
return (uint32_t) UPCALL_I32(ctx_Unicode_ReadChar, ctx, h, index);
12631263
}
12641264

12651265
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_DecodeLatin1)(HPyContext *ctx, const char *s, HPy_ssize_t size, const char *errors) {
1266-
return UPCALL_HPY(ctx_Unicode_DecodeLatin1, ctx, s, size, errors );
1266+
return UPCALL_HPY(ctx_Unicode_DecodeLatin1, ctx, s, size, errors );
12671267
}
12681268

12691269
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_DecodeASCII)(HPyContext *ctx, const char *s, HPy_ssize_t size, const char *errors) {
1270-
return UPCALL_HPY(ctx_Unicode_DecodeASCII, ctx, s, size, errors );
1270+
return UPCALL_HPY(ctx_Unicode_DecodeASCII, ctx, s, size, errors );
12711271
}
12721272

12731273
HPyAPI_STORAGE int _HPy_IMPL_NAME(List_Check)(HPyContext *ctx, HPy h)
@@ -1452,15 +1452,15 @@ HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Capsule_New)(HPyContext *ctx, void *pointer, c
14521452
}
14531453

14541454
HPyAPI_STORAGE void *_HPy_IMPL_NAME(Capsule_Get)(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *name) {
1455-
return UPCALL_HPY(ctx_Capsule_Get, ctx, capsule, key, name);
1455+
return UPCALL_HPY(ctx_Capsule_Get, ctx, capsule, (int32_t)key, name);
14561456
}
14571457

14581458
HPyAPI_STORAGE int _HPy_IMPL_NAME(Capsule_IsValid)(HPyContext *ctx, HPy capsule, const char *name) {
14591459
return (int) UPCALL_I32(ctx_Capsule_IsValid, ctx, capsule, name);
14601460
}
14611461

14621462
HPyAPI_STORAGE int _HPy_IMPL_NAME(Capsule_Set)(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value) {
1463-
return (int) UPCALL_I32(ctx_Capsule_Set, ctx, capsule, key, value);
1463+
return (int) UPCALL_I32(ctx_Capsule_Set, ctx, capsule, (int32_t)key, value);
14641464
}
14651465

14661466
HPyAPI_STORAGE int _HPy_IMPL_NAME(Type_CheckSlot)(HPyContext *ctx, HPy type, HPyDef *expected) {

graalpython/com.oracle.graal.python.cext/include/hpy/universal/autogen_ctx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ typedef HPyGlobal* _HPyGlobalPtr;
4747
#define HPyField void*
4848
#define HPyThreadState void*
4949
#define HPyGlobal void*
50+
#define _HPyCapsule_key int32_t
5051
#endif
5152

5253

@@ -318,4 +319,5 @@ struct _HPyContext_s {
318319
#undef HPyField
319320
#undef HPyThreadState
320321
#undef HPyGlobal
322+
#undef _HPyCapsule_key
321323
#endif

graalpython/com.oracle.graal.python.cext/include/hpy/universal/autogen_trampolines.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,15 +645,15 @@ HPyAPI_FUNC HPy HPyCapsule_New(HPyContext *ctx, void *pointer, const char *name,
645645
}
646646

647647
HPyAPI_FUNC void *HPyCapsule_Get(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, const char *name) {
648-
return ctx->ctx_Capsule_Get ( ctx, UNWRAP(capsule), key, name );
648+
return ctx->ctx_Capsule_Get ( ctx, UNWRAP(capsule), (int32_t)key, name );
649649
}
650650

651651
HPyAPI_FUNC int HPyCapsule_IsValid(HPyContext *ctx, HPy capsule, const char *name) {
652652
return ctx->ctx_Capsule_IsValid ( ctx, UNWRAP(capsule), name );
653653
}
654654

655655
HPyAPI_FUNC int HPyCapsule_Set(HPyContext *ctx, HPy capsule, _HPyCapsule_key key, void *value) {
656-
return ctx->ctx_Capsule_Set ( ctx, UNWRAP(capsule), key, value );
656+
return ctx->ctx_Capsule_Set ( ctx, UNWRAP(capsule), (int32_t)key, value );
657657
}
658658

659659
HPyAPI_FUNC HPy HPy_FromPyObject(HPyContext *ctx, cpy_PyObject *obj) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java

Lines changed: 100 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@
6363
import static com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNativeSymbol.GRAAL_HPY_WRITE_UL;
6464

6565
import java.io.PrintWriter;
66+
import java.nio.ByteBuffer;
67+
import java.nio.charset.CharacterCodingException;
6668
import java.nio.charset.Charset;
69+
import java.nio.charset.CodingErrorAction;
6770
import java.nio.charset.StandardCharsets;
6871
import java.util.logging.Level;
6972

@@ -230,9 +233,6 @@
230233
import com.oracle.truffle.api.object.DynamicObjectLibrary;
231234
import com.oracle.truffle.api.profiles.ConditionProfile;
232235
import com.oracle.truffle.api.profiles.ValueProfile;
233-
import java.nio.ByteBuffer;
234-
import java.nio.charset.CharacterCodingException;
235-
import java.nio.charset.CodingErrorAction;
236236

237237
@SuppressWarnings("static-method")
238238
public abstract class GraalHPyContextFunctions {
@@ -3418,13 +3418,18 @@ Object execute(Object[] arguments,
34183418
@Cached HPyAsContextNode asContextNode,
34193419
@Cached FromCharPointerNode fromCharPointerNode,
34203420
@Cached HPyAsHandleNode asHandleNode,
3421+
@CachedLibrary(limit = "1") InteropLibrary interopLib,
34213422
@Cached CastToJavaStringNode castStr,
3423+
@Cached HPyRaiseNode raiseNode,
34223424
@Cached GilNode gil) throws ArityException {
34233425
checkArity(arguments, 4);
34243426
boolean mustRelease = gil.acquire();
34253427
try {
34263428
GraalHPyContext context = asContextNode.execute(arguments[0]);
34273429
PyCapsule result = new PyCapsule();
3430+
if (interopLib.isNull(arguments[1])) {
3431+
return raiseNode.raiseWithoutFrame(context, GraalHPyHandle.NULL_HANDLE, ValueError, "HPyCapsule_New called with null pointer");
3432+
}
34283433
result.setPointer(arguments[1]);
34293434
try {
34303435
if (!nameLib.isPointer(arguments[2]) || nameLib.asPointer(arguments[2]) != 0) {
@@ -3443,6 +3448,7 @@ Object execute(Object[] arguments,
34433448

34443449
@ExportLibrary(InteropLibrary.class)
34453450
public static final class GraalHPyCapsuleGet extends GraalHPyContextFunction {
3451+
static final String SUFFIX = " called with invalid PyCapsule object";
34463452

34473453
@TruffleBoundary
34483454
private static byte[] getBytes(PyCapsule pyCapsule) {
@@ -3453,27 +3459,28 @@ private static byte[] getBytes(PyCapsule pyCapsule) {
34533459
Object execute(Object[] arguments,
34543460
@Cached HPyAsContextNode asContextNode,
34553461
@Cached HPyAsPythonObjectNode asCapsule,
3462+
@CachedLibrary(limit = "1") InteropLibrary interopLib,
34563463
@Cached FromCharPointerNode fromCharPointerNode,
34573464
@Cached CastToJavaStringNode castStr,
34583465
@Cached CastToJavaIntExactNode castInt,
3466+
@Cached PRaiseNode raiseNode,
3467+
@Cached HPyTransformExceptionToNativeNode transformExceptionToNativeNode,
34593468
@Cached GilNode gil) throws ArityException {
34603469
checkArity(arguments, 4);
34613470
boolean mustRelease = gil.acquire();
3471+
GraalHPyContext context = null;
34623472
try {
3463-
GraalHPyContext context = asContextNode.execute(arguments[0]);
3473+
context = asContextNode.execute(arguments[0]);
34643474
Object capsule = asCapsule.execute(context, arguments[1]);
3465-
if (!(capsule instanceof PyCapsule)) {
3466-
throw CompilerDirectives.shouldNotReachHere("TODO: raise ValueError");
3467-
}
3468-
PyCapsule pyCapsule = (PyCapsule) capsule;
3469-
String name = castStr.execute(fromCharPointerNode.execute(arguments[3]));
3470-
if (!pyCapsule.getName().equals(name)) {
3471-
throw CompilerDirectives.shouldNotReachHere("TODO: raise ValueError");
3472-
}
34733475
int key = castInt.execute(arguments[2]);
3476+
isLegalCapsule(capsule, key, raiseNode);
3477+
PyCapsule pyCapsule = (PyCapsule) capsule;
34743478
Object result;
34753479
switch (key) {
34763480
case CapsuleKey.Pointer:
3481+
if (!nameMatches(pyCapsule, arguments[3], interopLib, fromCharPointerNode, castStr)) {
3482+
throw raiseNode.raise(ValueError, "HPyCapsule_GetPointer called with incorrect name");
3483+
}
34773484
result = pyCapsule.getPointer();
34783485
break;
34793486
case CapsuleKey.Context:
@@ -3486,13 +3493,55 @@ Object execute(Object[] arguments,
34863493
result = pyCapsule.getDestructor();
34873494
break;
34883495
default:
3489-
throw CompilerDirectives.shouldNotReachHere("TODO: raise ValueError");
3496+
throw CompilerDirectives.shouldNotReachHere("invalid key");
3497+
}
3498+
// never allow Java 'null' to be returned
3499+
if (result == null) {
3500+
return context.getContext().getNativeNull().getPtr();
34903501
}
34913502
return result;
3503+
} catch (PException e) {
3504+
transformExceptionToNativeNode.execute(context, e);
3505+
return GraalHPyHandle.NULL_HANDLE;
34923506
} finally {
34933507
gil.release(mustRelease);
34943508
}
34953509
}
3510+
3511+
private static boolean nameMatches(PyCapsule capsule, Object namePtr, InteropLibrary interopLib, FromCharPointerNode fromCharPointerNode, CastToJavaStringNode castStr) {
3512+
boolean isCapsuleNameNull = capsule.getName() == null;
3513+
boolean isNamePtrNull = interopLib.isNull(namePtr);
3514+
3515+
// if one of them is NULL, then both need to be NULL
3516+
if (isCapsuleNameNull || isNamePtrNull) {
3517+
return isCapsuleNameNull && isNamePtrNull;
3518+
}
3519+
3520+
String name = castStr.execute(fromCharPointerNode.execute(namePtr));
3521+
return capsule.getName().equals(name);
3522+
}
3523+
3524+
private static void isLegalCapsule(Object object, int key, PRaiseNode raiseNode) {
3525+
if (!(object instanceof PyCapsule) || ((PyCapsule) object).getPointer() == null) {
3526+
throw raiseNode.raise(ValueError, getErrorMessage(key));
3527+
}
3528+
}
3529+
3530+
@TruffleBoundary
3531+
private static String getErrorMessage(int key) {
3532+
switch (key) {
3533+
case CapsuleKey.Pointer:
3534+
return "HPyCapsule_GetPointer" + SUFFIX;
3535+
case CapsuleKey.Context:
3536+
return "HPyCapsule_GetContext" + SUFFIX;
3537+
case CapsuleKey.Name:
3538+
return "HPyCapsule_GetName" + SUFFIX;
3539+
case CapsuleKey.Destructor:
3540+
return "HPyCapsule_GetDestructor" + SUFFIX;
3541+
default:
3542+
throw CompilerDirectives.shouldNotReachHere("invalid key");
3543+
}
3544+
}
34963545
}
34973546

34983547
@ExportLibrary(InteropLibrary.class)
@@ -3504,19 +3553,24 @@ Object execute(Object[] arguments,
35043553
@Cached FromCharPointerNode fromCharPointerNode,
35053554
@Cached CastToJavaStringNode castStr,
35063555
@Cached CastToJavaIntExactNode castInt,
3556+
@Cached PRaiseNode raiseNode,
3557+
@CachedLibrary(limit = "1") InteropLibrary interopLib,
3558+
@Cached HPyTransformExceptionToNativeNode transformExceptionToNativeNode,
35073559
@Cached GilNode gil) throws ArityException {
35083560
checkArity(arguments, 4);
35093561
boolean mustRelease = gil.acquire();
3562+
GraalHPyContext context = null;
35103563
try {
3511-
GraalHPyContext context = asContextNode.execute(arguments[0]);
3564+
context = asContextNode.execute(arguments[0]);
35123565
Object capsule = asCapsule.execute(context, arguments[1]);
3513-
if (!(capsule instanceof PyCapsule)) {
3514-
throw CompilerDirectives.shouldNotReachHere("TODO: raise ValueError");
3515-
}
3516-
PyCapsule pyCapsule = (PyCapsule) capsule;
35173566
int key = castInt.execute(arguments[2]);
3567+
isLegalCapsule(capsule, key, raiseNode);
3568+
PyCapsule pyCapsule = (PyCapsule) capsule;
35183569
switch (key) {
35193570
case CapsuleKey.Pointer:
3571+
if (interopLib.isNull(arguments[3])) {
3572+
throw raiseNode.raise(ValueError, "PyCapsule_SetPointer called with null pointer");
3573+
}
35203574
pyCapsule.setPointer(arguments[3]);
35213575
break;
35223576
case CapsuleKey.Context:
@@ -3529,13 +3583,38 @@ Object execute(Object[] arguments,
35293583
pyCapsule.setDestructor(arguments[3]);
35303584
break;
35313585
default:
3532-
throw CompilerDirectives.shouldNotReachHere("TODO: raise ValueError");
3586+
throw CompilerDirectives.shouldNotReachHere("invalid key");
35333587
}
35343588
return 0;
3589+
} catch (PException e) {
3590+
transformExceptionToNativeNode.execute(context, e);
3591+
return -1;
35353592
} finally {
35363593
gil.release(mustRelease);
35373594
}
35383595
}
3596+
3597+
private static void isLegalCapsule(Object object, int key, PRaiseNode raiseNode) {
3598+
if (!(object instanceof PyCapsule) || ((PyCapsule) object).getPointer() == null) {
3599+
throw raiseNode.raise(ValueError, getErrorMessage(key));
3600+
}
3601+
}
3602+
3603+
@TruffleBoundary
3604+
private static String getErrorMessage(int key) {
3605+
switch (key) {
3606+
case CapsuleKey.Pointer:
3607+
return "HPyCapsule_GetPointer" + GraalHPyCapsuleGet.SUFFIX;
3608+
case CapsuleKey.Context:
3609+
return "HPyCapsule_GetContext" + GraalHPyCapsuleGet.SUFFIX;
3610+
case CapsuleKey.Name:
3611+
return "HPyCapsule_GetName" + GraalHPyCapsuleGet.SUFFIX;
3612+
case CapsuleKey.Destructor:
3613+
return "HPyCapsule_GetDestructor" + GraalHPyCapsuleGet.SUFFIX;
3614+
default:
3615+
throw CompilerDirectives.shouldNotReachHere("invalid key");
3616+
}
3617+
}
35393618
}
35403619

35413620
@ExportLibrary(InteropLibrary.class)
@@ -3544,6 +3623,7 @@ public static final class GraalHPyCapsuleIsValid extends GraalHPyContextFunction
35443623
Object execute(Object[] arguments,
35453624
@Cached HPyAsContextNode asContextNode,
35463625
@Cached HPyAsPythonObjectNode asCapsule,
3626+
@CachedLibrary(limit = "1") InteropLibrary interopLib,
35473627
@Cached FromCharPointerNode fromCharPointerNode,
35483628
@Cached CastToJavaStringNode castStr,
35493629
@Cached GilNode gil) throws ArityException {
@@ -3556,8 +3636,7 @@ Object execute(Object[] arguments,
35563636
return 0;
35573637
}
35583638
PyCapsule pyCapsule = (PyCapsule) capsule;
3559-
String name = castStr.execute(fromCharPointerNode.execute(arguments[3]));
3560-
if (!pyCapsule.getName().equals(name)) {
3639+
if (!GraalHPyCapsuleGet.nameMatches(pyCapsule, arguments[2], interopLib, fromCharPointerNode, castStr)) {
35613640
return 0;
35623641
}
35633642
return 1;

0 commit comments

Comments
 (0)