Don't crash when assigning attributes of the GeneratorExit const singleton
This commit is contained in:
parent
6e9909c65e
commit
b499275bb5
@ -773,6 +773,16 @@ typedef long long mp_longint_impl_t;
|
|||||||
#define MICROPY_WARNINGS (0)
|
#define MICROPY_WARNINGS (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Whether to support chained exceptions
|
||||||
|
#ifndef MICROPY_CPYTHON_EXCEPTION_CHAIN
|
||||||
|
#define MICROPY_CPYTHON_EXCEPTION_CHAIN (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Whether the statically allocated GeneratorExit exception may be const
|
||||||
|
#ifndef MICROPY_CONST_GENERATOREXIT_OBJ
|
||||||
|
#define MICROPY_CONST_GENERATOREXIT_OBJ (!MICROPY_CPYTHON_EXCEPTION_CHAIN)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Whether to support warning categories
|
// Whether to support warning categories
|
||||||
#ifndef MICROPY_WARNINGS_CATEGORY
|
#ifndef MICROPY_WARNINGS_CATEGORY
|
||||||
#define MICROPY_WARNINGS_CATEGORY (0)
|
#define MICROPY_WARNINGS_CATEGORY (0)
|
||||||
|
4
py/obj.h
4
py/obj.h
@ -791,7 +791,9 @@ extern const struct _mp_obj_dict_t mp_const_empty_dict_obj;
|
|||||||
extern const struct _mp_obj_traceback_t mp_const_empty_traceback_obj;
|
extern const struct _mp_obj_traceback_t mp_const_empty_traceback_obj;
|
||||||
extern const struct _mp_obj_singleton_t mp_const_ellipsis_obj;
|
extern const struct _mp_obj_singleton_t mp_const_ellipsis_obj;
|
||||||
extern const struct _mp_obj_singleton_t mp_const_notimplemented_obj;
|
extern const struct _mp_obj_singleton_t mp_const_notimplemented_obj;
|
||||||
extern const struct _mp_obj_exception_t mp_const_GeneratorExit_obj;
|
#if MICROPY_CONST_GENERATOREXIT_OBJ
|
||||||
|
extern const struct _mp_obj_exception_t mp_static_GeneratorExit_obj;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Fixed empty map. Useful when calling keyword-receiving functions
|
// Fixed empty map. Useful when calling keyword-receiving functions
|
||||||
// without any keywords from C, etc.
|
// without any keywords from C, etc.
|
||||||
|
@ -218,9 +218,11 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
|||||||
mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
if (dest[0] != MP_OBJ_NULL) {
|
if (dest[0] != MP_OBJ_NULL) {
|
||||||
// store/delete attribute
|
// store/delete attribute
|
||||||
if (self == &mp_const_GeneratorExit_obj) {
|
#if MICROPY_CONST_GENERATOREXIT_OBJ
|
||||||
|
if (self == &mp_static_GeneratorExit_obj) {
|
||||||
mp_raise_AttributeError(MP_ERROR_TEXT("can't set attribute"));
|
mp_raise_AttributeError(MP_ERROR_TEXT("can't set attribute"));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (attr == MP_QSTR___traceback__) {
|
if (attr == MP_QSTR___traceback__) {
|
||||||
if (dest[1] == mp_const_none) {
|
if (dest[1] == mp_const_none) {
|
||||||
self->traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj;
|
self->traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj;
|
||||||
|
@ -38,7 +38,12 @@
|
|||||||
#include "supervisor/shared/translate/translate.h"
|
#include "supervisor/shared/translate/translate.h"
|
||||||
|
|
||||||
// Instance of GeneratorExit exception - needed by generator.close()
|
// Instance of GeneratorExit exception - needed by generator.close()
|
||||||
const mp_obj_exception_t mp_const_GeneratorExit_obj = {{&mp_type_GeneratorExit}, (mp_obj_tuple_t *)&mp_const_empty_tuple_obj, (mp_obj_traceback_t *)&mp_const_empty_traceback_obj};
|
#if MICROPY_CONST_GENERATOREXIT_OBJ
|
||||||
|
const
|
||||||
|
#else
|
||||||
|
static
|
||||||
|
#endif
|
||||||
|
mp_obj_exception_t mp_static_GeneratorExit_obj = {{&mp_type_GeneratorExit}, (mp_obj_tuple_t *)&mp_const_empty_tuple_obj, (mp_obj_traceback_t *)&mp_const_empty_traceback_obj};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* generator wrapper */
|
/* generator wrapper */
|
||||||
@ -362,9 +367,19 @@ STATIC mp_obj_t gen_instance_throw(size_t n_args, const mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gen_instance_throw_obj, 2, 4, gen_instance_throw);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gen_instance_throw_obj, 2, 4, gen_instance_throw);
|
||||||
|
|
||||||
|
static mp_obj_t generatorexit(void) {
|
||||||
|
#if MICROPY_CPYTHON_EXCEPTION_CHAIN
|
||||||
|
MP_STATIC_ASSERT(!MICROPY_CONST_GENERATOREXIT_OBJ);
|
||||||
|
mp_static_GeneratorExit_obj.context = NULL;
|
||||||
|
mp_static_GeneratorExit_obj.cause = NULL;
|
||||||
|
mp_static_GeneratorExit_obj.suppress_context = false;
|
||||||
|
#endif
|
||||||
|
return MP_OBJ_FROM_PTR(&mp_static_GeneratorExit_obj);
|
||||||
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) {
|
STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) {
|
||||||
mp_obj_t ret;
|
mp_obj_t ret;
|
||||||
switch (mp_obj_gen_resume(self_in, mp_const_none, MP_OBJ_FROM_PTR(&mp_const_GeneratorExit_obj), &ret)) {
|
switch (mp_obj_gen_resume(self_in, mp_const_none, generatorexit(), &ret)) {
|
||||||
case MP_VM_RETURN_YIELD:
|
case MP_VM_RETURN_YIELD:
|
||||||
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("generator ignored GeneratorExit"));
|
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("generator ignored GeneratorExit"));
|
||||||
|
|
||||||
|
5
py/vm.c
5
py/vm.c
@ -1391,7 +1391,10 @@ unwind_loop:
|
|||||||
// - constant GeneratorExit object, because it's const
|
// - constant GeneratorExit object, because it's const
|
||||||
// - exceptions re-raised by END_FINALLY
|
// - exceptions re-raised by END_FINALLY
|
||||||
// - exceptions re-raised explicitly by "raise"
|
// - exceptions re-raised explicitly by "raise"
|
||||||
if (nlr.ret_val != &mp_const_GeneratorExit_obj
|
if ( true
|
||||||
|
#if MICROPY_CONST_GENERATOREXIT_OBJ
|
||||||
|
&& nlr.ret_val != &mp_static_GeneratorExit_obj
|
||||||
|
#endif
|
||||||
&& *code_state->ip != MP_BC_END_FINALLY
|
&& *code_state->ip != MP_BC_END_FINALLY
|
||||||
&& *code_state->ip != MP_BC_RAISE_LAST) {
|
&& *code_state->ip != MP_BC_RAISE_LAST) {
|
||||||
const byte *ip = code_state->fun_bc->bytecode;
|
const byte *ip = code_state->fun_bc->bytecode;
|
||||||
|
Loading…
Reference in New Issue
Block a user