40
40
*/
41
41
package com .oracle .graal .python .builtins .objects .thread ;
42
42
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 ;
43
49
import com .oracle .graal .python .builtins .objects .dict .PDict ;
44
50
import com .oracle .graal .python .builtins .objects .function .PKeyword ;
45
51
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 ;
46
66
import com .oracle .truffle .api .object .Shape ;
47
67
68
+ @ ExportLibrary (InteropLibrary .class )
69
+ @ ImportStatic (SpecialMethodSlot .class )
48
70
public final class PThreadLocal extends PythonBuiltinObject {
49
71
private final ThreadLocal <PDict > threadLocalDict ;
50
72
private final Object [] args ;
@@ -57,8 +79,14 @@ public PThreadLocal(Object cls, Shape instanceShape, Object[] args, PKeyword[] k
57
79
this .keywords = keywords ;
58
80
}
59
81
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 );
62
90
}
63
91
64
92
public Object [] getArgs () {
@@ -68,4 +96,81 @@ public Object[] getArgs() {
68
96
public PKeyword [] getKeywords () {
69
97
return keywords ;
70
98
}
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
+ }
71
176
}
0 commit comments