68
68
import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .PyObjectSetAttrNode ;
69
69
import com .oracle .graal .python .builtins .objects .PNone ;
70
70
import com .oracle .graal .python .builtins .objects .PythonAbstractObject ;
71
+ import com .oracle .graal .python .builtins .objects .cext .PythonAbstractNativeObject ;
71
72
import com .oracle .graal .python .builtins .objects .cext .PythonNativeClass ;
72
73
import com .oracle .graal .python .builtins .objects .cext .capi .CApiContext ;
73
74
import com .oracle .graal .python .builtins .objects .cext .capi .CApiMemberAccessNodes .ReadMemberNode ;
79
80
import com .oracle .graal .python .builtins .objects .cext .capi .ExternalFunctionNodes .SetterRoot ;
80
81
import com .oracle .graal .python .builtins .objects .cext .common .CArrayWrappers .CArrayWrapper ;
81
82
import com .oracle .graal .python .builtins .objects .cext .common .CExtContext ;
83
+ import com .oracle .graal .python .builtins .objects .cext .structs .CFields ;
84
+ import com .oracle .graal .python .builtins .objects .cext .structs .CStructAccess ;
82
85
import com .oracle .graal .python .builtins .objects .common .DynamicObjectStorage ;
83
86
import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageGetItem ;
84
87
import com .oracle .graal .python .builtins .objects .dict .PDict ;
88
91
import com .oracle .graal .python .builtins .objects .object .PythonObject ;
89
92
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
90
93
import com .oracle .graal .python .builtins .objects .type .PythonAbstractClass ;
94
+ import com .oracle .graal .python .builtins .objects .type .PythonManagedClass ;
91
95
import com .oracle .graal .python .builtins .objects .type .SpecialMethodSlot ;
92
96
import com .oracle .graal .python .builtins .objects .type .TpSlots ;
93
97
import com .oracle .graal .python .builtins .objects .type .TypeNodes ;
98
+ import com .oracle .graal .python .lib .PyDictGetItem ;
94
99
import com .oracle .graal .python .lib .PyDictSetDefault ;
100
+ import com .oracle .graal .python .lib .PyDictSetItem ;
95
101
import com .oracle .graal .python .nodes .HiddenAttr ;
96
102
import com .oracle .graal .python .nodes .SpecialAttributeNames ;
97
- import com .oracle .graal .python .nodes .attributes .LookupAttributeInMRONode ;
98
103
import com .oracle .graal .python .nodes .attributes .WriteAttributeToPythonObjectNode ;
99
104
import com .oracle .graal .python .nodes .classes .IsSubtypeNode ;
105
+ import com .oracle .graal .python .nodes .object .GetDictIfExistsNode ;
100
106
import com .oracle .graal .python .nodes .util .CastToTruffleStringNode ;
101
107
import com .oracle .graal .python .runtime .PythonContext ;
102
108
import com .oracle .graal .python .runtime .PythonOptions ;
122
128
import com .oracle .truffle .api .nodes .Node ;
123
129
import com .oracle .truffle .api .nodes .RootNode ;
124
130
import com .oracle .truffle .api .object .DynamicObject ;
131
+ import com .oracle .truffle .api .object .DynamicObjectLibrary ;
125
132
import com .oracle .truffle .api .object .Shape ;
126
133
import com .oracle .truffle .api .profiles .InlinedExactClassProfile ;
127
134
import com .oracle .truffle .api .strings .TruffleString ;
@@ -135,13 +142,50 @@ abstract static class _PyType_Lookup extends CApiBinaryBuiltinNode {
135
142
Object doGeneric (Object type , Object name ,
136
143
@ Bind ("this" ) Node inliningTarget ,
137
144
@ Cached CastToTruffleStringNode castToTruffleStringNode ,
138
- @ Cached LookupAttributeInMRONode .Dynamic lookupAttributeInMRONode ) {
145
+ @ Cached TypeNodes .GetMroStorageNode getMroStorageNode ,
146
+ @ Cached PythonCextBuiltins .PromoteBorrowedValue promoteBorrowedValue ,
147
+ @ Cached CStructAccess .ReadObjectNode getNativeDict ,
148
+ @ Cached GetDictIfExistsNode getDictIfExistsNode ,
149
+ @ CachedLibrary (limit = "3" ) DynamicObjectLibrary dylib ,
150
+ @ Cached PyDictGetItem getItem ,
151
+ @ Cached PyDictSetItem setItem ) {
139
152
TruffleString key = castToTruffleStringNode .castKnownString (inliningTarget , name );
140
- Object result = lookupAttributeInMRONode .execute (type , key );
141
- if (result == PNone .NO_VALUE ) {
142
- return getNativeNull ();
153
+ MroSequenceStorage mro = getMroStorageNode .execute (inliningTarget , type );
154
+ for (int i = 0 ; i < mro .length (); i ++) {
155
+ PythonAbstractClass cls = mro .getPythonClassItemNormalized (i );
156
+ PDict dict ;
157
+ if (cls instanceof PythonAbstractNativeObject nativeCls ) {
158
+ Object dictObj = getNativeDict .readFromObj (nativeCls , CFields .PyTypeObject__tp_dict );
159
+ if (dictObj instanceof PDict d ) {
160
+ dict = d ;
161
+ } else {
162
+ continue ;
163
+ }
164
+ } else if (cls instanceof PythonManagedClass managedCls ) {
165
+ dict = getDictIfExistsNode .execute (managedCls );
166
+ } else {
167
+ throw CompilerDirectives .shouldNotReachHere ();
168
+ }
169
+ Object value ;
170
+ if (dict == null ) {
171
+ value = dylib .getOrDefault ((DynamicObject ) cls , key , null );
172
+ } else {
173
+ value = getItem .execute (null , inliningTarget , dict , key );
174
+ }
175
+ if (value != null && value != PNone .NO_VALUE ) {
176
+ Object promoted = promoteBorrowedValue .execute (inliningTarget , value );
177
+ if (promoted != null ) {
178
+ if (dict == null ) {
179
+ dylib .put ((DynamicObject ) cls , key , promoted );
180
+ } else {
181
+ setItem .execute (null , inliningTarget , dict , key , promoted );
182
+ }
183
+ return promoted ;
184
+ }
185
+ return value ;
186
+ }
143
187
}
144
- return result ;
188
+ return getNativeNull () ;
145
189
}
146
190
}
147
191
0 commit comments