Skip to content

Commit 199e839

Browse files
committed
add wrappers for GetSetDescr, MethodDescr, MethodDef (...) so we can read and write their documentation
1 parent e9c09fa commit 199e839

File tree

9 files changed

+749
-1
lines changed

9 files changed

+749
-1
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,13 @@ declare_type(PyFloat_Type, float, PyFloatObject);
129129
declare_type(PySlice_Type, slice, PySliceObject);
130130
declare_type(PyByteArray_Type, bytearray, PyByteArrayObject);
131131
declare_type(PyCFunction_Type, builtin_function_or_method, PyCFunctionObject);
132+
declare_type(PyWrapperDescr_Type, method_descriptor, PyWrapperDescrObject); // LS: previously wrapper_descriptor
133+
// tfel: Both method_descriptor maps to both PyWrapperDescr_Type and
134+
// PyMethodDescr_Type. This reflects our interpreter, but we need to make sure
135+
// that the dynamic type for method_descriptor is always going to be
136+
// PyMethodDescr_Type, so these two declarations cannot be in the wrong order
132137
declare_type(PyMethodDescr_Type, method_descriptor, PyMethodDescrObject);
133138
declare_type(PyGetSetDescr_Type, getset_descriptor, PyGetSetDescrObject);
134-
declare_type(PyWrapperDescr_Type, method_descriptor, PyWrapperDescrObject); // LS: previously wrapper_descriptor
135139
declare_type(PyMemberDescr_Type, property, PyMemberDescrObject); // LS: previously member_descriptor
136140
declare_type(_PyExc_BaseException, BaseException, PyBaseExceptionObject);
137141
declare_type(PyBuffer_Type, buffer, PyBufferDecorator);
@@ -298,6 +302,10 @@ const char* PyTruffle_StringToCstr(void* o, int32_t strLen) {
298302
return str;
299303
}
300304

305+
const char* PyTruffle_CstrToString(const char* o) {
306+
return polyglot_from_string(o, SRC_CS);
307+
}
308+
301309
#define PRIMITIVE_ARRAY_TO_NATIVE(__jtype__, __ctype__, __polyglot_type__, __element_cast__) \
302310
void* PyTruffle_##__jtype__##ArrayToNative(const void* jarray, int64_t len) { \
303311
int64_t i; \

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,14 @@ public final class NativeMemberNames {
110110
public static final String SQ_REPEAT = "sq_repeat";
111111
public static final String MEMORYVIEW_FLAGS = "flags";
112112
public static final String D_COMMON = "d_common";
113+
public static final String D_MEMBER = "d_member";
114+
public static final String D_GETSET = "d_getset";
115+
public static final String D_METHOD = "d_method";
116+
public static final String D_BASE = "d_base";
117+
public static final String D_QUALNAME = "d_qualname";
118+
public static final String D_NAME = "d_name";
119+
public static final String D_TYPE = "d_type";
120+
public static final String M_ML = "m_ml";
113121

114122
@CompilationFinal(dimensions = 1) public static final String[] values;
115123
static {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.builtins.objects.cext;
42+
43+
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PythonNativeWrapper;
44+
import com.oracle.graal.python.builtins.objects.object.PythonObject;
45+
import com.oracle.truffle.api.interop.ForeignAccess;
46+
import com.oracle.truffle.api.interop.TruffleObject;
47+
48+
/**
49+
* Wraps a PythonObject to provide a native view with a shape like {@code PyGetSetDef}.
50+
*/
51+
public class PyGetSetDefWrapper extends PythonNativeWrapper {
52+
53+
public PyGetSetDefWrapper(PythonObject delegate) {
54+
super(delegate);
55+
}
56+
57+
static boolean isInstance(TruffleObject o) {
58+
return o instanceof PyGetSetDefWrapper;
59+
}
60+
61+
@Override
62+
public ForeignAccess getForeignAccess() {
63+
return PyGetSetDefWrapperMRForeign.ACCESS;
64+
}
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.builtins.objects.cext;
42+
43+
import com.oracle.graal.python.builtins.objects.PNone;
44+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.AsCharPointer;
45+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.FromCharPointerNode;
46+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToSulongNode;
47+
import com.oracle.graal.python.builtins.objects.cext.PyGetSetDefWrapperMRFactory.ReadFieldNodeGen;
48+
import com.oracle.graal.python.builtins.objects.cext.PyGetSetDefWrapperMRFactory.WriteFieldNodeGen;
49+
import com.oracle.graal.python.builtins.objects.object.PythonObject;
50+
import com.oracle.graal.python.nodes.SpecialAttributeNames;
51+
import com.oracle.graal.python.nodes.SpecialMethodNames;
52+
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
53+
import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode;
54+
import com.oracle.truffle.api.CompilerDirectives;
55+
import com.oracle.truffle.api.dsl.Cached;
56+
import com.oracle.truffle.api.dsl.ImportStatic;
57+
import com.oracle.truffle.api.dsl.Specialization;
58+
import com.oracle.truffle.api.interop.MessageResolution;
59+
import com.oracle.truffle.api.interop.Resolve;
60+
import com.oracle.truffle.api.nodes.Node;
61+
62+
@MessageResolution(receiverType = PyGetSetDefWrapper.class)
63+
public class PyGetSetDefWrapperMR {
64+
@Resolve(message = "READ")
65+
abstract static class ReadNode extends Node {
66+
@Child private ReadFieldNode readFieldNode = ReadFieldNodeGen.create();
67+
68+
public Object access(PyGetSetDefWrapper object, String key) {
69+
return readFieldNode.execute(object.getDelegate(), key);
70+
}
71+
}
72+
73+
@Resolve(message = "WRITE")
74+
abstract static class WriteNode extends Node {
75+
@Child private WriteFieldNode writeFieldNode = WriteFieldNodeGen.create();
76+
77+
public int access(PyGetSetDefWrapper object, String key, Object value) {
78+
writeFieldNode.execute(object.getDelegate(), key, value);
79+
return 0;
80+
}
81+
}
82+
83+
@ImportStatic({SpecialMethodNames.class})
84+
abstract static class ReadFieldNode extends Node {
85+
public static final String NAME = "name";
86+
public static final String DOC = "doc";
87+
88+
@Child private ToSulongNode toSulongNode;
89+
@Child private AsCharPointer asCharPointerNode;
90+
91+
public abstract Object execute(Object delegate, String key);
92+
93+
protected boolean eq(String expected, String actual) {
94+
return expected.equals(actual);
95+
}
96+
97+
private ToSulongNode getToSulongNode() {
98+
if (toSulongNode == null) {
99+
CompilerDirectives.transferToInterpreterAndInvalidate();
100+
toSulongNode = insert(ToSulongNode.create());
101+
}
102+
return toSulongNode;
103+
}
104+
105+
private AsCharPointer getAsCharPointer() {
106+
if (asCharPointerNode == null) {
107+
CompilerDirectives.transferToInterpreterAndInvalidate();
108+
asCharPointerNode = insert(AsCharPointer.create());
109+
}
110+
return asCharPointerNode;
111+
}
112+
113+
@Specialization(guards = {"eq(NAME, key)"})
114+
Object getName(PythonObject object, @SuppressWarnings("unused") String key,
115+
@Cached("key") @SuppressWarnings("unused") String cachedKey,
116+
@Cached("create(__GETATTRIBUTE__)") LookupAndCallBinaryNode getAttrNode) {
117+
Object doc = getAttrNode.executeObject(object, SpecialAttributeNames.__NAME__);
118+
if (doc == PNone.NONE) {
119+
return getToSulongNode().execute(PNone.NO_VALUE);
120+
} else {
121+
return getAsCharPointer().execute(doc);
122+
}
123+
}
124+
125+
@Specialization(guards = {"eq(DOC, key)"})
126+
Object getDoc(PythonObject object, @SuppressWarnings("unused") String key,
127+
@Cached("key") @SuppressWarnings("unused") String cachedKey,
128+
@Cached("create(__GETATTRIBUTE__)") LookupAndCallBinaryNode getAttrNode) {
129+
Object doc = getAttrNode.executeObject(object, SpecialAttributeNames.__DOC__);
130+
if (doc == PNone.NONE) {
131+
return getToSulongNode().execute(PNone.NO_VALUE);
132+
} else {
133+
return getAsCharPointer().execute(doc);
134+
}
135+
}
136+
}
137+
138+
@ImportStatic({SpecialMethodNames.class})
139+
abstract static class WriteFieldNode extends Node {
140+
public static final String DOC = "doc";
141+
142+
@Child private FromCharPointerNode fromCharPointerNode;
143+
144+
public abstract void execute(Object delegate, String key, Object value);
145+
146+
protected boolean eq(String expected, String actual) {
147+
return expected.equals(actual);
148+
}
149+
150+
private FromCharPointerNode getFromCharPointer() {
151+
if (fromCharPointerNode == null) {
152+
CompilerDirectives.transferToInterpreterAndInvalidate();
153+
fromCharPointerNode = insert(FromCharPointerNode.create());
154+
}
155+
return fromCharPointerNode;
156+
}
157+
158+
@Specialization(guards = {"eq(DOC, key)"})
159+
void getDoc(PythonObject object, @SuppressWarnings("unused") String key, Object value,
160+
@Cached("key") @SuppressWarnings("unused") String cachedKey,
161+
@Cached("create(__SETATTR__)") LookupAndCallTernaryNode setAttrNode) {
162+
setAttrNode.execute(object, SpecialAttributeNames.__DOC__, getFromCharPointer().execute(value));
163+
}
164+
}
165+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.builtins.objects.cext;
42+
43+
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PythonNativeWrapper;
44+
import com.oracle.graal.python.builtins.objects.object.PythonObject;
45+
import com.oracle.truffle.api.interop.ForeignAccess;
46+
import com.oracle.truffle.api.interop.TruffleObject;
47+
48+
/**
49+
* Wraps a PythonObject to provide a native view with a shape like {@code PyMemberDef}.
50+
*/
51+
public class PyMemberDefWrapper extends PythonNativeWrapper {
52+
53+
public PyMemberDefWrapper(PythonObject delegate) {
54+
super(delegate);
55+
}
56+
57+
static boolean isInstance(TruffleObject o) {
58+
return o instanceof PyMemberDefWrapper;
59+
}
60+
61+
@Override
62+
public ForeignAccess getForeignAccess() {
63+
return PyMemberDefWrapperMRForeign.ACCESS;
64+
}
65+
}

0 commit comments

Comments
 (0)