Skip to content

Commit 56b00ef

Browse files
committed
Add getMember to PThreadLocal
1 parent bd6246b commit 56b00ef

File tree

2 files changed

+112
-18
lines changed

2 files changed

+112
-18
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/PThreadLocal.java

Lines changed: 107 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,33 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.thread;
4242

43+
import java.util.ArrayList;
44+
import java.util.List;
45+
46+
import com.oracle.graal.python.builtins.objects.PNone;
47+
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
48+
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary;
4349
import com.oracle.graal.python.builtins.objects.dict.PDict;
4450
import com.oracle.graal.python.builtins.objects.function.PKeyword;
4551
import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
52+
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
53+
import com.oracle.graal.python.nodes.PGuards;
54+
import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
55+
import com.oracle.graal.python.nodes.object.GetClassNode;
56+
import com.oracle.graal.python.util.PythonUtils;
57+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
58+
import com.oracle.truffle.api.dsl.Cached;
59+
import com.oracle.truffle.api.dsl.Cached.Shared;
60+
import com.oracle.truffle.api.dsl.ImportStatic;
61+
import com.oracle.truffle.api.interop.InteropLibrary;
62+
import com.oracle.truffle.api.library.CachedLibrary;
63+
import com.oracle.truffle.api.library.ExportLibrary;
64+
import com.oracle.truffle.api.library.ExportMessage;
65+
import com.oracle.truffle.api.library.ExportMessage.Ignore;
4666
import com.oracle.truffle.api.object.Shape;
4767

68+
@ExportLibrary(InteropLibrary.class)
69+
@ImportStatic(SpecialMethodSlot.class)
4870
public final class PThreadLocal extends PythonBuiltinObject {
4971
private final ThreadLocal<PDict> threadLocalDict;
5072
private final Object[] args;
@@ -57,8 +79,14 @@ public PThreadLocal(Object cls, Shape instanceShape, Object[] args, PKeyword[] k
5779
this.keywords = keywords;
5880
}
5981

60-
public ThreadLocal<PDict> getThreadLocalDict() {
61-
return threadLocalDict;
82+
@TruffleBoundary
83+
public PDict getThreadLocalDict() {
84+
return threadLocalDict.get();
85+
}
86+
87+
@TruffleBoundary
88+
public void setThreadLocalDict(PDict dict) {
89+
threadLocalDict.set(dict);
6290
}
6391

6492
public Object[] getArgs() {
@@ -68,4 +96,81 @@ public Object[] getArgs() {
6896
public PKeyword[] getKeywords() {
6997
return keywords;
7098
}
99+
100+
@ExportMessage
101+
Object getMembers(@SuppressWarnings("unused") boolean includeInternal,
102+
@Shared("hlib") @CachedLibrary(limit = "3") HashingStorageLibrary hlib) {
103+
List<String> keys = getLocalAttributes(hlib);
104+
return new Keys(keys.toArray(PythonUtils.EMPTY_STRING_ARRAY));
105+
}
106+
107+
@TruffleBoundary
108+
private List<String> getLocalAttributes(HashingStorageLibrary hlib) {
109+
PDict localDict = getThreadLocalDict();
110+
List<String> keys = new ArrayList<>();
111+
if (localDict != null) {
112+
for (HashingStorage.DictEntry e : hlib.entries(localDict.getDictStorage())) {
113+
if (e.getKey() instanceof String) {
114+
String strKey = (String) e.getKey();
115+
keys.add(strKey);
116+
}
117+
}
118+
}
119+
return keys;
120+
}
121+
122+
@Ignore
123+
private Object readMember(String member, HashingStorageLibrary hlib) {
124+
PDict localDict = getThreadLocalDict();
125+
return localDict == null ? null : hlib.getItem(localDict.getDictStorage(), member);
126+
}
127+
128+
@ExportMessage
129+
public boolean isMemberReadable(String member,
130+
@Shared("hlib") @CachedLibrary(limit = "3") HashingStorageLibrary hlib) {
131+
return readMember(member, hlib) != null;
132+
}
133+
134+
@ExportMessage
135+
public boolean isMemberModifiable(String member,
136+
@Shared("hlib") @CachedLibrary(limit = "3") HashingStorageLibrary hlib) {
137+
return readMember(member, hlib) != null;
138+
}
139+
140+
@ExportMessage
141+
public boolean isMemberInsertable(String member,
142+
@Shared("hlib") @CachedLibrary(limit = "3") HashingStorageLibrary hlib) {
143+
return !isMemberReadable(member, hlib);
144+
}
145+
146+
@ExportMessage
147+
public boolean isMemberInvocable(String member,
148+
@Shared("hlib") @CachedLibrary(limit = "3") HashingStorageLibrary hlib) {
149+
PDict localDict = getThreadLocalDict();
150+
return localDict != null && PGuards.isCallable(hlib.getItem(localDict.getDictStorage(), member));
151+
}
152+
153+
@ExportMessage
154+
public boolean isMemberRemovable(String member,
155+
@Shared("hlib") @CachedLibrary(limit = "3") HashingStorageLibrary hlib) {
156+
return isMemberReadable(member, hlib);
157+
}
158+
159+
@ExportMessage
160+
public boolean hasMemberReadSideEffects(String member,
161+
@Shared("hlib") @CachedLibrary(limit = "3") HashingStorageLibrary hlib,
162+
@Shared("getClass") @Cached GetClassNode getClassNode,
163+
@Cached(parameters = "Get") LookupCallableSlotInMRONode lookupGet) {
164+
Object attr = readMember(member, hlib);
165+
return attr != null && lookupGet.execute(getClassNode.execute(attr)) != PNone.NO_VALUE;
166+
}
167+
168+
@ExportMessage
169+
public boolean hasMemberWriteSideEffects(String member,
170+
@Shared("hlib") @CachedLibrary(limit = "3") HashingStorageLibrary hlib,
171+
@Shared("getClass") @Cached GetClassNode getClassNode,
172+
@Cached(parameters = "Set") LookupCallableSlotInMRONode lookupSet) {
173+
Object attr = readMember(member, hlib);
174+
return attr != null && lookupSet.execute(getClassNode.execute(attr)) != PNone.NO_VALUE;
175+
}
71176
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalNodes.java

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
import com.oracle.graal.python.nodes.SpecialMethodNames;
4747
import com.oracle.graal.python.nodes.call.CallNode;
4848
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
49-
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5049
import com.oracle.truffle.api.dsl.Cached;
5150
import com.oracle.truffle.api.dsl.Specialization;
5251
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -61,24 +60,14 @@ PDict get(VirtualFrame frame, PThreadLocal self,
6160
@Cached PythonObjectFactory factory,
6261
@Cached PyObjectLookupAttr lookup,
6362
@Cached CallNode callNode) {
64-
PDict storage = getStorage(self);
65-
if (storage == null) {
66-
storage = factory.createDict();
67-
setStorage(self, storage);
63+
PDict dict = self.getThreadLocalDict();
64+
if (dict == null) {
65+
dict = factory.createDict();
66+
self.setThreadLocalDict(dict);
6867
Object initMethod = lookup.execute(frame, self, SpecialMethodNames.__INIT__);
6968
callNode.execute(frame, initMethod, self.getArgs(), self.getKeywords());
7069
}
71-
return storage;
72-
}
73-
74-
@TruffleBoundary
75-
private static PDict getStorage(PThreadLocal self) {
76-
return self.getThreadLocalDict().get();
77-
}
78-
79-
@TruffleBoundary
80-
private static void setStorage(PThreadLocal self, PDict storage) {
81-
self.getThreadLocalDict().set(storage);
70+
return dict;
8271
}
8372
}
8473
}

0 commit comments

Comments
 (0)