Skip to content

Commit 8f6d7d8

Browse files
committed
Split lookupAttribute and pass frame to it
1 parent 0ac21e9 commit 8f6d7d8

File tree

17 files changed

+290
-168
lines changed

17 files changed

+290
-168
lines changed

graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/objects/PythonObjectLibraryTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ private void lookupAttr(Callable<Object> createValue, String attrName, boolean e
101101
PythonObjectLibrary lib = PythonObjectLibrary.getFactory().getUncached();
102102
execInContext(() -> {
103103
Object value = createValue.call();
104-
Object attr = lib.lookupAttribute(value, attrName, false, false);
104+
Object attr = lib.lookupAttribute(value, null, attrName);
105105
assertAttr(attr, expectNoValue);
106106

107-
attr = lib.lookupAttribute(value, attrName, true, false);
107+
attr = lib.lookupAttributeOnType(value, attrName);
108108
assertAttr(attr, expectNoValue);
109109
return null;
110110
});

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ public double absDouble(double arg) {
246246
public Object absObject(VirtualFrame frame, Object object,
247247
@CachedLibrary("object") PythonObjectLibrary lib,
248248
@CachedLibrary(limit = "2") PythonObjectLibrary methodLib) {
249-
Object method = lib.lookupSpecialMethod(object, __ABS__);
249+
Object method = lib.lookupAttributeOnType(object, __ABS__);
250250
if (method == NO_VALUE) {
251251
throw raise(TypeError, ErrorMessages.BAD_OPERAND_FOR, "", "abs()", object);
252252
}
@@ -1590,7 +1590,7 @@ PNone printAllGiven(VirtualFrame frame, Object[] values, String sep, String end,
15901590
@CachedLibrary(limit = "2") PythonObjectLibrary methodLib,
15911591
@CachedLibrary(limit = "3") PythonObjectLibrary valueLib) {
15921592
int lastValue = values.length - 1;
1593-
Object writeMethod = fileLib.lookupAttributeStrict(file, "write");
1593+
Object writeMethod = fileLib.lookupAttributeStrict(file, frame, "write");
15941594
for (int i = 0; i < lastValue; i++) {
15951595
methodLib.callFunction(writeMethod, frame, valueLib.asPString(values[i]));
15961596
methodLib.callFunction(writeMethod, frame, sep);
@@ -1600,7 +1600,7 @@ PNone printAllGiven(VirtualFrame frame, Object[] values, String sep, String end,
16001600
}
16011601
methodLib.callFunction(writeMethod, frame, end);
16021602
if (flush) {
1603-
Object flushMethod = fileLib.lookupAttributeStrict(file, "flush");
1603+
Object flushMethod = fileLib.lookupAttributeStrict(file, frame, "flush");
16041604
methodLib.callFunction(flushMethod, frame);
16051605
}
16061606
return PNone.NONE;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
import com.oracle.truffle.api.dsl.ImportStatic;
151151
import com.oracle.truffle.api.dsl.ReportPolymorphism;
152152
import com.oracle.truffle.api.dsl.Specialization;
153+
import com.oracle.truffle.api.frame.Frame;
153154
import com.oracle.truffle.api.frame.VirtualFrame;
154155
import com.oracle.truffle.api.interop.ArityException;
155156
import com.oracle.truffle.api.interop.InteropLibrary;
@@ -219,9 +220,9 @@ public final void clearNativeWrapper(ConditionProfile hasHandleValidAssumptionPr
219220
* are treated differently to other containers in some interop messages.
220221
*/
221222
private static boolean isAbstractMapping(Object receiver, PythonObjectLibrary lib) {
222-
return lib.isSequence(receiver) && lib.lookupAttribute(receiver, KEYS) != PNone.NO_VALUE && //
223-
lib.lookupAttribute(receiver, ITEMS) != PNone.NO_VALUE && //
224-
lib.lookupAttribute(receiver, VALUES) != PNone.NO_VALUE;
223+
return lib.isSequence(receiver) && lib.lookupAttribute(receiver, null, KEYS) != PNone.NO_VALUE && //
224+
lib.lookupAttribute(receiver, null, ITEMS) != PNone.NO_VALUE && //
225+
lib.lookupAttribute(receiver, null, VALUES) != PNone.NO_VALUE;
225226
}
226227

227228
private boolean isAbstractMapping(PythonObjectLibrary thisLib) {
@@ -956,7 +957,7 @@ public int asFileDescriptorWithState(ThreadState state,
956957
@Exclusive @Cached CastToJavaIntExactNode castToJavaIntNode,
957958
@Exclusive @Cached IsBuiltinClassProfile isAttrError) {
958959

959-
Object filenoFunc = libThis.lookupAttribute(this, FILENO);
960+
Object filenoFunc = libThis.lookupAttributeWithState(this, state, FILENO);
960961
if (filenoFunc == PNone.NO_VALUE) {
961962
noFilenoMethodProfile.enter();
962963
throw raiseNode.raise(PythonBuiltinClassType.TypeError, ErrorMessages.ARG_MUST_BE_INT_OR_HAVE_FILENO_METHOD);
@@ -982,56 +983,74 @@ public int asFileDescriptorWithState(ThreadState state,
982983
}
983984

984985
@ExportMessage
985-
public Object lookupAttribute(String name, boolean inheritedOnly, boolean strict,
986+
public Object lookupAttributeInternal(ThreadState state, String name, boolean strict,
987+
@Shared("gotState") @Cached ConditionProfile gotState,
986988
@Exclusive @Cached LookupAttributeNode lookup) {
987-
return lookup.execute(this, name, inheritedOnly, strict);
989+
VirtualFrame frame = null;
990+
if (gotState.profile(state != null)) {
991+
frame = PArguments.frameForCall(state);
992+
}
993+
return lookup.execute(frame, this, name, strict);
988994
}
989995

990996
@GenerateUncached
991997
public abstract static class LookupAttributeNode extends Node {
992-
public abstract Object execute(Object receiver, String name, boolean inheritedOnly, boolean strict);
998+
public abstract Object execute(Frame frame, Object receiver, String name, boolean strict);
993999

9941000
@Specialization
995-
public static Object lookupAttributeImpl(Object receiver, String name, boolean inheritedOnly, boolean strict,
1001+
public static Object lookupAttributeImpl(VirtualFrame frame, Object receiver, String name, boolean strict,
9961002
@Cached LookupInheritedAttributeNode.Dynamic lookup,
997-
@Cached ConditionProfile isInheritedOnlyProfile,
9981003
@Cached ConditionProfile noValueProfile,
9991004
@Cached CallNode callNode,
10001005
@Cached IsBuiltinClassProfile isAttrErrorProfile1,
1001-
@Cached IsBuiltinClassProfile isAttrErrorProfile2,
1002-
@Cached PRaiseNode raiseNode) {
1003-
if (isInheritedOnlyProfile.profile(inheritedOnly)) {
1004-
Object result = lookup.execute(receiver, name);
1005-
if (strict && result == PNone.NO_VALUE) {
1006-
throw raiseNode.raise(AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name);
1007-
}
1008-
return result;
1009-
} else {
1006+
@Cached IsBuiltinClassProfile isAttrErrorProfile2) {
1007+
try {
10101008
Object getAttrFunc = lookup.execute(receiver, __GETATTRIBUTE__);
10111009
try {
1012-
try {
1013-
return callNode.execute(getAttrFunc, receiver, name);
1014-
} catch (PException pe) {
1015-
pe.expect(AttributeError, isAttrErrorProfile1);
1016-
getAttrFunc = lookup.execute(receiver, __GETATTR__);
1017-
if (noValueProfile.profile(getAttrFunc == PNone.NO_VALUE)) {
1018-
if (strict) {
1019-
throw pe;
1020-
} else {
1021-
return PNone.NO_VALUE;
1022-
}
1023-
}
1024-
return callNode.execute(getAttrFunc, receiver, name);
1025-
}
1010+
return callNode.execute(getAttrFunc, receiver, name);
10261011
} catch (PException pe) {
1027-
pe.expect(AttributeError, isAttrErrorProfile2);
1028-
if (strict) {
1029-
throw pe;
1030-
} else {
1031-
return PNone.NO_VALUE;
1012+
pe.expect(AttributeError, isAttrErrorProfile1);
1013+
getAttrFunc = lookup.execute(receiver, __GETATTR__);
1014+
if (noValueProfile.profile(getAttrFunc == PNone.NO_VALUE)) {
1015+
if (strict) {
1016+
throw pe;
1017+
} else {
1018+
return PNone.NO_VALUE;
1019+
}
10321020
}
1021+
return callNode.execute(frame, getAttrFunc, receiver, name);
10331022
}
1023+
} catch (PException pe) {
1024+
pe.expect(AttributeError, isAttrErrorProfile2);
1025+
if (strict) {
1026+
throw pe;
1027+
} else {
1028+
return PNone.NO_VALUE;
1029+
}
1030+
}
1031+
}
1032+
}
1033+
1034+
@ExportMessage
1035+
public Object lookupAttributeOnTypeInternal(String name, boolean strict,
1036+
@CachedLibrary("this") PythonObjectLibrary lib,
1037+
@Exclusive @Cached LookupAttributeOnTypeNode lookup) {
1038+
return lookup.execute(lib.getLazyPythonClass(this), name, strict);
1039+
}
1040+
1041+
@GenerateUncached
1042+
public abstract static class LookupAttributeOnTypeNode extends Node {
1043+
public abstract Object execute(Object type, String name, boolean strict);
1044+
1045+
@Specialization
1046+
public static Object lookupAttributeImpl(Object type, String name, boolean strict,
1047+
@Cached LookupAttributeInMRONode.Dynamic lookup,
1048+
@Cached PRaiseNode raiseNode) {
1049+
Object result = lookup.execute(type, name);
1050+
if (strict && result == PNone.NO_VALUE) {
1051+
throw raiseNode.raise(AttributeError, ErrorMessages.OBJ_S_HAS_NO_ATTR_S, type, name);
10341052
}
1053+
return result;
10351054
}
10361055
}
10371056

@@ -1093,15 +1112,15 @@ Object getAndCall(ThreadState state, Object method, boolean ignoreGetException,
10931112
public Object lookupAndCallSpecialMethodWithState(ThreadState state, String methodName, Object[] arguments,
10941113
@CachedLibrary("this") PythonObjectLibrary plib,
10951114
@Shared("methodLib") @CachedLibrary(limit = "2") PythonObjectLibrary methodLib) {
1096-
Object method = plib.lookupSpecialMethodStrict(this, methodName);
1115+
Object method = plib.lookupAttributeOnTypeStrict(this, methodName);
10971116
return methodLib.callUnboundMethodWithState(method, state, this, arguments);
10981117
}
10991118

11001119
@ExportMessage
11011120
public Object lookupAndCallRegularMethodWithState(ThreadState state, String methodName, Object[] arguments,
11021121
@CachedLibrary("this") PythonObjectLibrary plib,
11031122
@Shared("methodLib") @CachedLibrary(limit = "2") PythonObjectLibrary methodLib) {
1104-
Object method = plib.lookupAttributeStrict(this, methodName);
1123+
Object method = plib.lookupAttributeStrictWithState(this, state, methodName);
11051124
return methodLib.callFunctionWithState(method, state, arguments);
11061125
}
11071126

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ HashingStorage doNoBuiltinKeysAttr(VirtualFrame frame, PHashingCollection col,
205205
}
206206

207207
protected boolean hasIterAttrButNotBuiltin(PHashingCollection col, PythonObjectLibrary lib) {
208-
Object attr = lib.lookupAttribute(col, SpecialMethodNames.__ITER__);
208+
Object attr = lib.lookupAttributeOnType(col, SpecialMethodNames.__ITER__);
209209
return attr != PNone.NO_VALUE && !(attr instanceof PBuiltinMethod || attr instanceof PBuiltinFunction);
210210
}
211211

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictBuiltins.java

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import static com.oracle.graal.python.runtime.exception.PythonErrorType.KeyError;
4444
import static com.oracle.graal.python.runtime.exception.PythonErrorType.RuntimeError;
4545
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
46+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
4647

4748
import java.util.List;
4849

@@ -77,10 +78,8 @@
7778
import com.oracle.graal.python.nodes.PRaiseNode;
7879
import com.oracle.graal.python.nodes.SpecialMethodNames;
7980
import com.oracle.graal.python.nodes.builtins.ListNodes;
80-
import com.oracle.graal.python.nodes.call.CallNode;
8181
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
8282
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
83-
import com.oracle.graal.python.nodes.call.special.LookupAndCallVarargsNode;
8483
import com.oracle.graal.python.nodes.control.GetIteratorExpressionNode.GetIteratorNode;
8584
import com.oracle.graal.python.nodes.control.GetNextNode;
8685
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -92,7 +91,6 @@
9291
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
9392
import com.oracle.graal.python.runtime.PythonCore;
9493
import com.oracle.graal.python.runtime.exception.PException;
95-
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
9694
import com.oracle.graal.python.runtime.sequence.PSequence;
9795
import com.oracle.truffle.api.CompilerDirectives;
9896
import com.oracle.truffle.api.dsl.Cached;
@@ -329,10 +327,9 @@ protected abstract static class DispatchMissingNode extends Node {
329327
protected abstract Object execute(VirtualFrame frame, Object self, Object key);
330328

331329
@Specialization(guards = "hasMissing(self, lib)", limit = "1")
332-
protected Object misssing(Object self, Object key,
333-
@CachedLibrary("self") PythonObjectLibrary lib,
334-
@Exclusive @Cached CallNode callNode) {
335-
return callNode.execute(lib.lookupAttribute(self, __MISSING__), key);
330+
protected Object misssing(VirtualFrame frame, Object self, Object key,
331+
@CachedLibrary("self") PythonObjectLibrary lib) {
332+
return lib.lookupAndCallSpecialMethod(self, frame, __MISSING__, key);
336333
}
337334

338335
@Specialization(guards = "!hasMissing(self, lib)", limit = "1")
@@ -343,7 +340,7 @@ protected Object misssing(VirtualFrame frame, Object self, Object key,
343340
}
344341

345342
protected boolean hasMissing(Object self, PythonObjectLibrary lib) {
346-
Object missing = lib.lookupAttribute(self, __MISSING__);
343+
Object missing = lib.lookupAttributeOnType(self, __MISSING__);
347344
return missing != PNone.NO_VALUE && missing instanceof PMethod;
348345
}
349346
}
@@ -633,7 +630,7 @@ private HashingStorage addAll(PDict self, PDict other, GetDictStorageNode getSto
633630
return newStorage;
634631
}
635632

636-
@Specialization(guards = {"args.length == 1", "!isDict(args)", "hasKeysAttr(args, libArg)"})
633+
@Specialization(guards = {"args.length == 1", "!isDict(args)", "hasKeysAttr(args, frame, libArg)"})
637634
public Object updateMapping(VirtualFrame frame, PDict self, Object[] args, PKeyword[] kwargs,
638635
@SuppressWarnings("unused") @CachedLibrary(limit = "1") PythonObjectLibrary libArg,
639636
@CachedLibrary(limit = "3") HashingStorageLibrary lib,
@@ -650,7 +647,7 @@ public Object updateMapping(VirtualFrame frame, PDict self, Object[] args, PKeyw
650647
return PNone.NONE;
651648
}
652649

653-
@Specialization(guards = {"args.length == 1", "!isDict(args)", "!hasKeysAttr(args, libArg)"})
650+
@Specialization(guards = {"args.length == 1", "!isDict(args)", "!hasKeysAttr(args, frame, libArg)"})
654651
public Object updateSequence(VirtualFrame frame, PDict self, Object[] args, PKeyword[] kwargs,
655652
@SuppressWarnings("unused") @CachedLibrary(limit = "1") PythonObjectLibrary libArg,
656653
@CachedLibrary(limit = "3") HashingStorageLibrary lib,
@@ -703,8 +700,8 @@ protected boolean isSelf(PDict self, Object[] args) {
703700
return isDict(args) && args[0] == self;
704701
}
705702

706-
protected boolean hasKeysAttr(Object[] args, PythonObjectLibrary lib) {
707-
return lib.lookupAttribute(args[0], KEYS) != PNone.NO_VALUE;
703+
protected boolean hasKeysAttr(Object[] args, VirtualFrame frame, PythonObjectLibrary lib) {
704+
return lib.lookupAttribute(args[0], frame, KEYS) != PNone.NO_VALUE;
708705
}
709706

710707
}
@@ -714,7 +711,7 @@ protected boolean hasKeysAttr(Object[] args, PythonObjectLibrary lib) {
714711
@GenerateNodeFactory
715712
public abstract static class FromKeysNode extends PythonBuiltinNode {
716713

717-
@Specialization(guards = {"lib.isIterable(iterable)", "isBuiltinType(cls)", "hasBuiltinSetItem(cls, lib)"})
714+
@Specialization(guards = {"lib.isIterable(iterable)", "isBuiltinType(cls)", "hasBuiltinSetItem(cls, frame, lib)"})
718715
public Object doKeys(VirtualFrame frame, Object cls, Object iterable, Object value,
719716
@SuppressWarnings("unused") @CachedLibrary(limit = "2") PythonObjectLibrary lib,
720717
@CachedLibrary(limit = "2") HashingStorageLibrary libStorage,
@@ -740,24 +737,23 @@ public Object doKeys(VirtualFrame frame, Object cls, Object iterable, Object val
740737
return dict;
741738
}
742739

743-
@Specialization(guards = {"lib.isIterable(iterable)", "!isBuiltinType(cls) || !hasBuiltinSetItem(cls, lib)"})
740+
@Specialization(guards = {"lib.isIterable(iterable)", "!isBuiltinType(cls) || !hasBuiltinSetItem(cls, frame, lib)"})
744741
public Object doKeys(VirtualFrame frame, Object cls, Object iterable, Object value,
745-
@CachedLibrary(limit = "2") PythonObjectLibrary lib,
746-
@Cached("create(__CALL__)") LookupAndCallVarargsNode constructNode,
747-
@Cached CallNode callSetItemNode,
742+
// 2 for method calls, 2 for setitem lookups
743+
@CachedLibrary(limit = "4") PythonObjectLibrary lib,
748744
@Cached GetIteratorNode getIteratorNode,
749745
@Cached GetNextNode nextNode,
750746
@Cached IsBuiltinClassProfile errorProfile,
751747
@Cached ConditionProfile noSetItemProfile) {
752-
Object dict = constructNode.execute(null, cls, new Object[]{cls});
753-
Object attrSetItem = lib.lookupAttribute(dict, __SETITEM__);
748+
Object dict = lib.callObject(cls, frame);
749+
Object setitemMethod = lib.lookupAttributeOnType(dict, __SETITEM__);
754750
Object val = value == PNone.NO_VALUE ? PNone.NONE : value;
755-
if (noSetItemProfile.profile(attrSetItem != PNone.NO_VALUE)) {
751+
if (noSetItemProfile.profile(setitemMethod != PNone.NO_VALUE)) {
756752
Object it = getIteratorNode.executeWith(frame, iterable);
757753
while (true) {
758754
try {
759755
Object key = nextNode.execute(frame, it);
760-
callSetItemNode.execute(frame, attrSetItem, key, val);
756+
lib.callUnboundMethod(setitemMethod, frame, dict, key, val);
761757
} catch (PException e) {
762758
e.expectStopIteration(errorProfile);
763759
break;
@@ -786,8 +782,9 @@ protected boolean isBuiltinType(Object cls) {
786782
return type == PythonBuiltinClassType.PDict;
787783
}
788784

789-
protected boolean hasBuiltinSetItem(Object cls, PythonObjectLibrary lib) {
790-
Object attr = lib.lookupAttribute(cls, __SETITEM__);
785+
protected boolean hasBuiltinSetItem(Object cls, VirtualFrame frame, PythonObjectLibrary lib) {
786+
// msimacek: this should rather use direct MRO lookup
787+
Object attr = lib.lookupAttribute(cls, frame, __SETITEM__);
791788
return attr instanceof PBuiltinMethod || attr instanceof PBuiltinFunction;
792789
}
793790
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ Object reduce(VirtualFrame frame, PBaseException self,
322322
@Cached ArgsNode argsNode) {
323323
Object clazz = lib.getLazyPythonClass(self);
324324
Object args = argsNode.executeObject(frame, self, PNone.NO_VALUE);
325-
Object dict = lib.lookupAttribute(self, __DICT__);
325+
Object dict = lib.lookupAttributeOnTypeStrict(self, __DICT__);
326326
return factory().createTuple(new Object[]{clazz, args, dict});
327327
}
328328
}

0 commit comments

Comments
 (0)