Skip to content

Commit 8da4719

Browse files
committed
Fix: allow get/set descriptor without getter
1 parent 686d6b0 commit 8da4719

File tree

2 files changed

+32
-75
lines changed

2 files changed

+32
-75
lines changed

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

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@
106106
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyVarargsHandleCloseNodeGen;
107107
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyObjectBuiltins.HPyObjectNewNode;
108108
import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyGetSetDescriptorGetterRootNode;
109-
import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyGetSetDescriptorNotWritableRootNode;
110109
import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyGetSetDescriptorSetterRootNode;
111110
import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyLegacyGetSetDescriptorGetterRoot;
112111
import com.oracle.graal.python.builtins.objects.cext.hpy.HPyExternalFunctionNodes.HPyLegacyGetSetDescriptorSetterRoot;
@@ -516,17 +515,19 @@ static GetSetDescriptor doGeneric(GraalHPyContext context, Object owner, Object
516515
Object getterFunPtr;
517516
Object setterFunPtr;
518517
Object closurePtr;
519-
boolean readOnly;
518+
boolean hasGetter;
519+
boolean hasSetter;
520520
try {
521521
getterFunPtr = interopLibrary.readMember(legacyGetSetDef, "get");
522-
if (!(resultLib.isNull(getterFunPtr) || resultLib.isExecutable(getterFunPtr))) {
522+
hasGetter = !resultLib.isNull(getterFunPtr);
523+
if (hasGetter && !resultLib.isExecutable(getterFunPtr)) {
523524
LOGGER.warning(() -> String.format("get of %s is not callable", getSetDescrName));
524525
}
525526
setterFunPtr = interopLibrary.readMember(legacyGetSetDef, "set");
526-
if (!(resultLib.isNull(setterFunPtr) || resultLib.isExecutable(setterFunPtr))) {
527+
hasSetter = !resultLib.isNull(setterFunPtr);
528+
if (hasSetter && !resultLib.isExecutable(setterFunPtr)) {
527529
LOGGER.warning(() -> String.format("set of %s is not callable", getSetDescrName));
528530
}
529-
readOnly = resultLib.isNull(setterFunPtr);
530531
closurePtr = interopLibrary.readMember(legacyGetSetDef, "closure");
531532
} catch (UnknownIdentifierException e) {
532533
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -537,15 +538,21 @@ static GetSetDescriptor doGeneric(GraalHPyContext context, Object owner, Object
537538
}
538539

539540
PythonLanguage lang = PythonLanguage.get(raiseNode);
540-
PBuiltinFunction getterObject = HPyLegacyGetSetDescriptorGetterRoot.createLegacyFunction(context, lang, owner, getSetDescrName, getterFunPtr, closurePtr);
541-
Object setterObject;
542-
if (readOnly) {
543-
setterObject = HPyGetSetDescriptorNotWritableRootNode.createFunction(context.getContext(), owner, getSetDescrName);
541+
PBuiltinFunction getterObject;
542+
if (hasGetter) {
543+
getterObject = HPyLegacyGetSetDescriptorGetterRoot.createLegacyFunction(context, lang, owner, getSetDescrName, getterFunPtr, closurePtr);
544544
} else {
545+
getterObject = null;
546+
}
547+
548+
PBuiltinFunction setterObject;
549+
if (hasSetter) {
545550
setterObject = HPyLegacyGetSetDescriptorSetterRoot.createLegacyFunction(context, lang, owner, getSetDescrName, setterFunPtr, closurePtr);
551+
} else {
552+
setterObject = null;
546553
}
547554

548-
GetSetDescriptor getSetDescriptor = factory.createGetSetDescriptor(getterObject, setterObject, getSetDescrName, owner, !readOnly);
555+
GetSetDescriptor getSetDescriptor = factory.createGetSetDescriptor(getterObject, setterObject, getSetDescrName, owner, hasSetter);
549556
writeDocNode.execute(getSetDescriptor, SpecialAttributeNames.T___DOC__, getSetDescrDoc);
550557
return getSetDescriptor;
551558
}
@@ -797,26 +804,33 @@ static GetSetDescriptor doIt(GraalHPyContext context, Object type, Object member
797804

798805
// signature: self, closure
799806
Object getterFunctionPtr = memberDefLib.readMember(memberDef, "getter_impl");
800-
if (context.isDebugMode() || !valueLib.isExecutable(getterFunctionPtr)) {
807+
boolean hasGetter = !valueLib.isNull(getterFunctionPtr);
808+
if (hasGetter && (context.isDebugMode() || !valueLib.isExecutable(getterFunctionPtr))) {
801809
getterFunctionPtr = attachFunctionTypeNode.execute(context, getterFunctionPtr, LLVMType.HPyFunc_getter);
802810
}
803811

804812
// signature: self, value, closure
805813
Object setterFunctionPtr = memberDefLib.readMember(memberDef, "setter_impl");
806-
boolean readOnly = valueLib.isNull(setterFunctionPtr);
807-
if (!readOnly && (context.isDebugMode() || !valueLib.isExecutable(setterFunctionPtr))) {
814+
boolean hasSetter = !valueLib.isNull(setterFunctionPtr);
815+
if (hasSetter && (context.isDebugMode() || !valueLib.isExecutable(setterFunctionPtr))) {
808816
setterFunctionPtr = attachFunctionTypeNode.execute(context, setterFunctionPtr, LLVMType.HPyFunc_setter);
809817
}
810818

811-
PBuiltinFunction getterObject = HPyGetSetDescriptorGetterRootNode.createFunction(context, type, name, getterFunctionPtr, closurePtr);
812-
Object setterObject;
813-
if (readOnly) {
814-
setterObject = HPyGetSetDescriptorNotWritableRootNode.createFunction(context.getContext(), type, name);
819+
PBuiltinFunction getterObject;
820+
if (hasGetter) {
821+
getterObject = HPyGetSetDescriptorGetterRootNode.createFunction(context, type, name, getterFunctionPtr, closurePtr);
815822
} else {
823+
getterObject = null;
824+
}
825+
826+
PBuiltinFunction setterObject;
827+
if (hasSetter) {
816828
setterObject = HPyGetSetDescriptorSetterRootNode.createFunction(context, type, name, setterFunctionPtr, closurePtr);
829+
} else {
830+
setterObject = null;
817831
}
818832

819-
GetSetDescriptor getSetDescriptor = factory.createGetSetDescriptor(getterObject, setterObject, name, type, !readOnly);
833+
GetSetDescriptor getSetDescriptor = factory.createGetSetDescriptor(getterObject, setterObject, name, type, !hasSetter);
820834
writeDocNode.execute(getSetDescriptor, SpecialAttributeNames.T___DOC__, memberDoc);
821835
return getSetDescriptor;
822836
} catch (UnsupportedMessageException | UnknownIdentifierException e) {

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

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@
9494
import com.oracle.graal.python.builtins.objects.function.PKeyword;
9595
import com.oracle.graal.python.builtins.objects.function.Signature;
9696
import com.oracle.graal.python.builtins.objects.memoryview.CExtPyBuffer;
97-
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
9897
import com.oracle.graal.python.nodes.ErrorMessages;
9998
import com.oracle.graal.python.nodes.IndirectCallNode;
10099
import com.oracle.graal.python.nodes.PGuards;
@@ -103,7 +102,6 @@
103102
import com.oracle.graal.python.nodes.argument.ReadIndexedArgumentNode;
104103
import com.oracle.graal.python.nodes.argument.ReadVarArgsNode;
105104
import com.oracle.graal.python.nodes.argument.ReadVarKeywordsNode;
106-
import com.oracle.graal.python.nodes.object.GetClassNode;
107105
import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext;
108106
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
109107
import com.oracle.graal.python.runtime.PythonContext;
@@ -1499,61 +1497,6 @@ public static PBuiltinFunction createLegacyFunction(GraalHPyContext context, Pyt
14991497
}
15001498
}
15011499

1502-
static final class HPyGetSetDescriptorNotWritableRootNode extends HPyGetSetDescriptorRootNode {
1503-
private static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("$self", "value"), null, true);
1504-
1505-
@Child private PRaiseNode raiseNode;
1506-
@Child private GetClassNode getClassNode;
1507-
@Child private GetNameNode getNameNode;
1508-
1509-
private HPyGetSetDescriptorNotWritableRootNode(PythonLanguage language, TruffleString name) {
1510-
super(language, name);
1511-
}
1512-
1513-
@Override
1514-
protected Object[] createArguments(VirtualFrame frame, Object closure) {
1515-
if (raiseNode == null) {
1516-
CompilerDirectives.transferToInterpreterAndInvalidate();
1517-
raiseNode = insert(PRaiseNode.create());
1518-
}
1519-
if (getClassNode == null) {
1520-
CompilerDirectives.transferToInterpreterAndInvalidate();
1521-
getClassNode = insert(GetClassNode.create());
1522-
}
1523-
if (getNameNode == null) {
1524-
CompilerDirectives.transferToInterpreterAndInvalidate();
1525-
getNameNode = insert(GetNameNode.create());
1526-
}
1527-
Object type = getClassNode.execute(PArguments.getArgument(frame, 0));
1528-
throw raiseNode.raise(PythonBuiltinClassType.AttributeError, ErrorMessages.ATTR_S_OF_S_IS_NOT_WRITABLE, getName(), getNameNode.execute(type));
1529-
}
1530-
1531-
@Override
1532-
protected HPyConvertArgsToSulongNode createArgumentConversionNode() {
1533-
// not required since the 'createArguments' method will throw an error
1534-
return null;
1535-
}
1536-
1537-
@Override
1538-
protected HPyCheckFunctionResultNode createResultConversionNode() {
1539-
// not required since the 'createArguments' method will throw an error
1540-
return null;
1541-
}
1542-
1543-
@Override
1544-
public Signature getSignature() {
1545-
return SIGNATURE;
1546-
}
1547-
1548-
@TruffleBoundary
1549-
public static PBuiltinFunction createFunction(PythonContext context, Object enclosingType, TruffleString propertyName) {
1550-
PythonLanguage lang = context.getLanguage();
1551-
RootCallTarget callTarget = lang.createCachedCallTarget(l -> new HPyGetSetDescriptorNotWritableRootNode(l, propertyName), HPyGetSetDescriptorNotWritableRootNode.class, propertyName);
1552-
PythonObjectFactory factory = context.factory();
1553-
return factory.createBuiltinFunction(propertyName, enclosingType, 0, 0, callTarget);
1554-
}
1555-
}
1556-
15571500
/**
15581501
* Root node to call a C functions with signature
15591502
* {@code int (*HPyFunc_getbufferproc)(HPyContext ctx, HPy self, HPy_buffer *buffer, int flags)}

0 commit comments

Comments
 (0)