-
-
Notifications
You must be signed in to change notification settings - Fork 3k
[mypyc] new error_kind and branch variant to handle call_negative_bool_emit #9035
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[mypyc] new error_kind and branch variant to handle call_negative_bool_emit #9035
Conversation
Generated code: before: PyObject *cpy_r_r0;
char cpy_r_r1;
char cpy_r_r2;
PyObject *cpy_r_r3;
CPyL0: ;
CPyTagged_IncRef(cpy_r_y);
cpy_r_r0 = CPyTagged_StealAsObject(cpy_r_y);
cpy_r_r1 = PySet_Discard(cpy_r_x, cpy_r_r0) >= 0;
CPy_DecRef(cpy_r_r0);
if (unlikely(!cpy_r_r1)) {
CPy_AddTraceback("foo.py", "fossss", 4, CPyStatic_globals);
goto CPyL2;
} else
goto CPyL1; after: PyObject *cpy_r_r0;
Py_ssize_t cpy_r_r1;
char cpy_r_r2;
PyObject *cpy_r_r3;
CPyL0: ;
CPyTagged_IncRef(cpy_r_y);
cpy_r_r0 = CPyTagged_StealAsObject(cpy_r_y);
cpy_r_r1 = PySet_Discard(cpy_r_x, cpy_r_r0);
CPy_DecRef(cpy_r_r0);
if (unlikely(cpy_r_r1 < 0)) {
CPy_AddTraceback("foo.py", "fossss", 4, CPyStatic_globals);
goto CPyL2;
} else
goto CPyL1; |
And for the remaining int __tmp1 = PyObject_IsInstance(cpy_r_x, cpy_r_r0);
if (__tmp1 < 0)
cpy_r_r1 = 2;
else
cpy_r_r1 = __tmp1;
if (unlikely(cpy_r_r1 == 2)) {
CPy_AddTraceback("foo.py", "check", 8, CPyStatic_globals);
goto CPyL2;
} else
goto CPyL1; It actually checks if the temp is < 0 and then check the error value( |
The overall approach looks good. This also simplifies the generated code, which is nice. One detail that I noticed is that it would be better to use the
Yeah, the |
Well, some strange errors running
compile these testcases using mypyc via command line would work, though. Updates: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments; not a full review.
For the
But the problem is clear that direct coercion provides no help. To keep the current semantics, we need an additional branch to finally know whether it should be r0 or error_value to set into r1.
|
I think that
|
If we have python code like and the change you mentioned: result = isinstance(x, str) How should we make sure(which part to change) that Updates: |
Ohh that's bad, we have both 32/64 bit CI platforms but the IR tests text are fixed( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates, looks good now! Just a few minor comments.
Hmm some tests are failing because the types are different on 32-bit platforms. To work around this, you can make it possible to represent an integer type that varies by the register width in test cases (e.g. The test runner is in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, looks good!
|
||
# replace native_int with platform specific ints | ||
int_format_str = 'int32' if IS_32_BIT_PLATFORM else 'int64' | ||
expected_output = [s.replace('native_int', int_format_str) for s in expected_output] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the same code is repeated twice, it would make sense to move this into a helper function. This can be done in a separate PR and isn't really necessary, since it's only two lines of code.
related mypyc/mypyc#734 and mypyc/mypyc#741.
Introducing
ERR_NEG_INT
error_kind andNEG_INT_EXPR
branch variant to support checking the return value of a call is non-negative.set.discard
is used as an example. With some modifications, this would also supportnegative_int_emit
.