Skip to content

Commit 5258e67

Browse files
committed
Trash temporary locals after destructive assignment to pass test_callbacks_on_callback, more systematic fix will be GR-64479
1 parent 59513d1 commit 5258e67

File tree

2 files changed

+43
-15
lines changed

2 files changed

+43
-15
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/bytecode_dsl/RootNodeCompiler.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3146,17 +3146,20 @@ public Void visit(ExprTy.Subscript node) {
31463146

31473147
/**
31483148
* This method unpacks the rhs (a sequence/iterable) to the elements on the lhs
3149-
* (specified by {@code nodes}.
3149+
* specified by {@code nodes}.
31503150
*/
31513151
private void visitIterableAssign(ExprTy[] nodes) {
31523152
b.beginBlock();
31533153

3154-
/**
3154+
/*
31553155
* The rhs should be fully evaluated and unpacked into the expected number of
31563156
* elements before storing values into the lhs (e.g., if an lhs element is f().attr,
31573157
* but computing or unpacking rhs throws, f() is not computed). Thus, the unpacking
31583158
* step stores the unpacked values into intermediate variables, and then those
31593159
* variables are copied into the lhs elements afterward.
3160+
*
3161+
* On top of that, in order to pass the target BytecodeLocal variables as
3162+
* LocalRangeAccessor, they must have consecutive indices.
31603163
*/
31613164
BytecodeLocal[] targets = new BytecodeLocal[nodes.length];
31623165
for (int i = 0; i < targets.length; i++) {
@@ -3196,6 +3199,7 @@ private void visitIterableAssign(ExprTy[] nodes) {
31963199
target.accept(new StoreVisitor(() -> {
31973200
b.emitLoadLocal(targets[index]);
31983201
}));
3202+
b.emitClearLocal(targets[index]);
31993203
}
32003204

32013205
b.endBlock();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,10 @@ public static void doIt(VirtualFrame frame, Object value, Object primary, Object
19561956
}
19571957
}
19581958

1959+
/**
1960+
* This operation is used to implement destructing assignment where the rhs should be fully
1961+
* evaluated and unpacked into temporary variables and then assigned to the targets.
1962+
*/
19591963
@Operation(storeBytecodeIndex = true)
19601964
@ConstantOperand(type = LocalRangeAccessor.class)
19611965
@ImportStatic({PGuards.class})
@@ -1974,7 +1978,7 @@ public static void doUnpackSequence(VirtualFrame localFrame, LocalRangeAccessor
19741978
CompilerAsserts.partialEvaluationConstant(count);
19751979

19761980
if (len != count) {
1977-
raiseError(inliningTarget, raiseNode, len, count);
1981+
throw raiseError(inliningTarget, raiseNode, len, count);
19781982
}
19791983

19801984
for (int i = 0; i < count; i++) {
@@ -1983,16 +1987,15 @@ public static void doUnpackSequence(VirtualFrame localFrame, LocalRangeAccessor
19831987
}
19841988

19851989
@InliningCutoff
1986-
private static void raiseError(Node inliningTarget, PRaiseNode raiseNode, int len, int count) {
1990+
private static PException raiseError(Node inliningTarget, PRaiseNode raiseNode, int len, int count) {
19871991
if (len < count) {
1988-
throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, count, len);
1992+
throw raiseNotEnoughValues(inliningTarget, raiseNode, count, len);
19891993
} else {
1990-
throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOO_MANY_VALUES_TO_UNPACK, count);
1994+
throw raiseTooManyValues(inliningTarget, raiseNode, count);
19911995
}
19921996
}
19931997

19941998
@Specialization
1995-
@ExplodeLoop
19961999
@InliningCutoff
19972000
public static void doUnpackIterable(VirtualFrame virtualFrame, LocalRangeAccessor results, Object collection,
19982001
@Bind Node inliningTarget,
@@ -2003,29 +2006,50 @@ public static void doUnpackIterable(VirtualFrame virtualFrame, LocalRangeAccesso
20032006
@Exclusive @Cached PRaiseNode raiseNode) {
20042007
int count = results.getLength();
20052008
CompilerAsserts.partialEvaluationConstant(count);
2006-
20072009
Object iterator;
20082010
try {
20092011
iterator = getIter.execute(virtualFrame, inliningTarget, collection);
20102012
} catch (PException e) {
20112013
e.expectTypeError(inliningTarget, notIterableProfile);
2012-
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection);
2014+
throw raiseNotIterableError(collection, inliningTarget, raiseNode);
2015+
}
2016+
extractItems(virtualFrame, inliningTarget, bytecode, getNextNode, raiseNode, iterator, results, count);
2017+
try {
2018+
getNextNode.execute(virtualFrame, inliningTarget, iterator);
2019+
} catch (IteratorExhausted e) {
2020+
return;
20132021
}
2022+
throw raiseTooManyValues(inliningTarget, raiseNode, count);
2023+
}
2024+
2025+
@ExplodeLoop
2026+
private static void extractItems(VirtualFrame virtualFrame, Node inliningTarget, BytecodeNode bytecode, PyIterNextNode getNextNode, PRaiseNode raiseNode, Object iterator,
2027+
LocalRangeAccessor results, int count) {
2028+
CompilerAsserts.partialEvaluationConstant(count);
20142029
for (int i = 0; i < count; i++) {
20152030
try {
20162031
Object value = getNextNode.execute(virtualFrame, inliningTarget, iterator);
20172032
results.setObject(bytecode, virtualFrame, i, value);
20182033
} catch (IteratorExhausted e) {
2019-
throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, count, i);
2034+
raiseNotEnoughValues(inliningTarget, raiseNode, count, i);
20202035
}
20212036
}
2022-
try {
2023-
Object value = getNextNode.execute(virtualFrame, inliningTarget, iterator);
2024-
} catch (IteratorExhausted e) {
2025-
return;
2026-
}
2037+
}
2038+
2039+
@InliningCutoff
2040+
private static PException raiseNotIterableError(Object collection, Node inliningTarget, PRaiseNode raiseNode) {
2041+
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.CANNOT_UNPACK_NON_ITERABLE, collection);
2042+
}
2043+
2044+
@InliningCutoff
2045+
private static PException raiseTooManyValues(Node inliningTarget, PRaiseNode raiseNode, int count) {
20272046
throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.TOO_MANY_VALUES_TO_UNPACK, count);
20282047
}
2048+
2049+
@InliningCutoff
2050+
private static PException raiseNotEnoughValues(Node inliningTarget, PRaiseNode raiseNode, int expected, int actual) {
2051+
throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NOT_ENOUGH_VALUES_TO_UNPACK, expected, actual);
2052+
}
20292053
}
20302054

20312055
@Operation(storeBytecodeIndex = true)

0 commit comments

Comments
 (0)