mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 16:57:31 +01:00
Update MicroPython from 1.12 to 1.17
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@@ -34,6 +35,7 @@
|
||||
#include "py/objstr.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/objtype.h"
|
||||
#include "py/objmodule.h"
|
||||
#include "py/objgenerator.h"
|
||||
#include "py/smallint.h"
|
||||
@@ -53,23 +55,23 @@
|
||||
|
||||
const mp_obj_module_t mp_module___main__ = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&MP_STATE_VM(dict_main),
|
||||
.globals = (mp_obj_dict_t *)&MP_STATE_VM(dict_main),
|
||||
};
|
||||
|
||||
void mp_init(void) {
|
||||
qstr_init();
|
||||
|
||||
// no pending exceptions to start with
|
||||
MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
|
||||
MP_STATE_THREAD(mp_pending_exception) = MP_OBJ_NULL;
|
||||
#if MICROPY_ENABLE_SCHEDULER
|
||||
MP_STATE_VM(sched_state) = MP_SCHED_IDLE;
|
||||
MP_STATE_VM(sched_idx) = 0;
|
||||
MP_STATE_VM(sched_len) = 0;
|
||||
#endif
|
||||
|
||||
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||
mp_init_emergency_exception_buf();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MICROPY_KBD_EXCEPTION
|
||||
// initialise the exception object for raising KeyboardInterrupt
|
||||
@@ -77,14 +79,9 @@ void mp_init(void) {
|
||||
MP_STATE_VM(mp_kbd_exception).traceback_alloc = 0;
|
||||
MP_STATE_VM(mp_kbd_exception).traceback_len = 0;
|
||||
MP_STATE_VM(mp_kbd_exception).traceback_data = NULL;
|
||||
MP_STATE_VM(mp_kbd_exception).args = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj;
|
||||
MP_STATE_VM(mp_kbd_exception).args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj;
|
||||
#endif
|
||||
|
||||
// call port specific initialization if any
|
||||
#ifdef MICROPY_PORT_INIT_FUNC
|
||||
MICROPY_PORT_INIT_FUNC;
|
||||
#endif
|
||||
|
||||
#if MICROPY_ENABLE_COMPILER
|
||||
// optimization disabled by default
|
||||
MP_STATE_VM(mp_optimise_value) = 0;
|
||||
@@ -94,7 +91,7 @@ void mp_init(void) {
|
||||
#endif
|
||||
|
||||
// init global module dict
|
||||
mp_obj_dict_init(&MP_STATE_VM(mp_loaded_modules_dict), 3);
|
||||
mp_obj_dict_init(&MP_STATE_VM(mp_loaded_modules_dict), MICROPY_LOADED_MODULES_DICT_SIZE);
|
||||
|
||||
// initialise the __main__ module
|
||||
mp_obj_dict_init(&MP_STATE_VM(dict_main), 1);
|
||||
@@ -109,6 +106,10 @@ void mp_init(void) {
|
||||
MP_STATE_VM(mp_module_builtins_override_dict) = NULL;
|
||||
#endif
|
||||
|
||||
#if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE
|
||||
MP_STATE_VM(track_reloc_code_list) = MP_OBJ_NULL;
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
for (size_t i = 0; i < MICROPY_PY_OS_DUPTERM; ++i) {
|
||||
MP_STATE_VM(dupterm_objs[i]) = MP_OBJ_NULL;
|
||||
@@ -139,19 +140,21 @@ void mp_init(void) {
|
||||
mp_thread_mutex_init(&MP_STATE_VM(gil_mutex));
|
||||
#endif
|
||||
|
||||
// call port specific initialization if any
|
||||
#ifdef MICROPY_PORT_INIT_FUNC
|
||||
MICROPY_PORT_INIT_FUNC;
|
||||
#endif
|
||||
|
||||
MP_THREAD_GIL_ENTER();
|
||||
}
|
||||
|
||||
void mp_deinit(void) {
|
||||
MP_THREAD_GIL_EXIT();
|
||||
|
||||
//mp_obj_dict_free(&dict_main);
|
||||
//mp_map_deinit(&MP_STATE_VM(mp_loaded_modules_map));
|
||||
|
||||
// call port specific deinitialization if any
|
||||
#ifdef MICROPY_PORT_DEINIT_FUNC
|
||||
#ifdef MICROPY_PORT_DEINIT_FUNC
|
||||
MICROPY_PORT_DEINIT_FUNC;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
mp_obj_t mp_load_name(qstr qst) {
|
||||
@@ -181,14 +184,13 @@ mp_obj_t mp_load_global(qstr qst) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
elem = mp_map_lookup((mp_map_t*)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
|
||||
elem = mp_map_lookup((mp_map_t *)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
|
||||
if (elem == NULL) {
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_msg(&mp_type_NameError, "name not defined");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NameError,
|
||||
"name '%q' isn't defined", qst));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_msg(&mp_type_NameError, MP_ERROR_TEXT("name not defined"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_NameError, MP_ERROR_TEXT("name '%q' isn't defined"), qst);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return elem->value;
|
||||
@@ -275,31 +277,37 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(h);
|
||||
} else {
|
||||
mp_obj_type_t *type = mp_obj_get_type(arg);
|
||||
const mp_obj_type_t *type = mp_obj_get_type(arg);
|
||||
if (type->unary_op != NULL) {
|
||||
mp_obj_t result = type->unary_op(op, arg);
|
||||
if (result != MP_OBJ_NULL) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (op == MP_UNARY_OP_BOOL) {
|
||||
// Type doesn't have unary_op (or didn't handle MP_UNARY_OP_BOOL),
|
||||
// so is implicitly True as this code path is impossible to reach
|
||||
// if arg==mp_const_none.
|
||||
return mp_const_true;
|
||||
}
|
||||
// With MP_UNARY_OP_INT, mp_unary_op() becomes a fallback for mp_obj_get_int().
|
||||
// In this case provide a more focused error message to not confuse, e.g. chr(1.0)
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
if (op == MP_UNARY_OP_INT) {
|
||||
mp_raise_TypeError("can't convert to int");
|
||||
} else {
|
||||
mp_raise_TypeError("unsupported type for operator");
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
if (op == MP_UNARY_OP_INT) {
|
||||
mp_raise_TypeError(MP_ERROR_TEXT("can't convert to int"));
|
||||
} else {
|
||||
if (op == MP_UNARY_OP_INT) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"can't convert %s to int", mp_obj_get_type_str(arg)));
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"unsupported type for %q: '%s'",
|
||||
mp_unary_op_method_name[op], mp_obj_get_type_str(arg)));
|
||||
}
|
||||
mp_raise_TypeError(MP_ERROR_TEXT("unsupported type for operator"));
|
||||
}
|
||||
#else
|
||||
if (op == MP_UNARY_OP_INT) {
|
||||
mp_raise_msg_varg(&mp_type_TypeError,
|
||||
MP_ERROR_TEXT("can't convert %s to int"), mp_obj_get_type_str(arg));
|
||||
} else {
|
||||
mp_raise_msg_varg(&mp_type_TypeError,
|
||||
MP_ERROR_TEXT("unsupported type for %q: '%s'"),
|
||||
mp_unary_op_method_name[op], mp_obj_get_type_str(arg));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,19 +330,8 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
|
||||
// deal with == and != for all types
|
||||
if (op == MP_BINARY_OP_EQUAL || op == MP_BINARY_OP_NOT_EQUAL) {
|
||||
if (mp_obj_equal(lhs, rhs)) {
|
||||
if (op == MP_BINARY_OP_EQUAL) {
|
||||
return mp_const_true;
|
||||
} else {
|
||||
return mp_const_false;
|
||||
}
|
||||
} else {
|
||||
if (op == MP_BINARY_OP_EQUAL) {
|
||||
return mp_const_false;
|
||||
} else {
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
// mp_obj_equal_not_equal supports a bunch of shortcuts
|
||||
return mp_obj_equal_not_equal(op, lhs, rhs);
|
||||
}
|
||||
|
||||
// deal with exception_match for all types
|
||||
@@ -377,23 +374,31 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
// << checked explicitly
|
||||
switch (op) {
|
||||
case MP_BINARY_OP_OR:
|
||||
case MP_BINARY_OP_INPLACE_OR: lhs_val |= rhs_val; break;
|
||||
case MP_BINARY_OP_INPLACE_OR:
|
||||
lhs_val |= rhs_val;
|
||||
break;
|
||||
case MP_BINARY_OP_XOR:
|
||||
case MP_BINARY_OP_INPLACE_XOR: lhs_val ^= rhs_val; break;
|
||||
case MP_BINARY_OP_INPLACE_XOR:
|
||||
lhs_val ^= rhs_val;
|
||||
break;
|
||||
case MP_BINARY_OP_AND:
|
||||
case MP_BINARY_OP_INPLACE_AND: lhs_val &= rhs_val; break;
|
||||
case MP_BINARY_OP_INPLACE_AND:
|
||||
lhs_val &= rhs_val;
|
||||
break;
|
||||
case MP_BINARY_OP_LSHIFT:
|
||||
case MP_BINARY_OP_INPLACE_LSHIFT: {
|
||||
if (rhs_val < 0) {
|
||||
// negative shift not allowed
|
||||
mp_raise_ValueError("negative shift count");
|
||||
} else if (rhs_val >= (mp_int_t)BITS_PER_WORD || lhs_val > (MP_SMALL_INT_MAX >> rhs_val) || lhs_val < (MP_SMALL_INT_MIN >> rhs_val)) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("negative shift count"));
|
||||
} else if (rhs_val >= (mp_int_t)(sizeof(lhs_val) * MP_BITS_PER_BYTE)
|
||||
|| lhs_val > (MP_SMALL_INT_MAX >> rhs_val)
|
||||
|| lhs_val < (MP_SMALL_INT_MIN >> rhs_val)) {
|
||||
// left-shift will overflow, so use higher precision integer
|
||||
lhs = mp_obj_new_int_from_ll(lhs_val);
|
||||
goto generic_binary_op;
|
||||
} else {
|
||||
// use standard precision
|
||||
lhs_val <<= rhs_val;
|
||||
lhs_val = (mp_uint_t)lhs_val << rhs_val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -401,21 +406,25 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
case MP_BINARY_OP_INPLACE_RSHIFT:
|
||||
if (rhs_val < 0) {
|
||||
// negative shift not allowed
|
||||
mp_raise_ValueError("negative shift count");
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("negative shift count"));
|
||||
} else {
|
||||
// standard precision is enough for right-shift
|
||||
if (rhs_val >= (mp_int_t)BITS_PER_WORD) {
|
||||
if (rhs_val >= (mp_int_t)(sizeof(lhs_val) * MP_BITS_PER_BYTE)) {
|
||||
// Shifting to big amounts is underfined behavior
|
||||
// in C and is CPU-dependent; propagate sign bit.
|
||||
rhs_val = BITS_PER_WORD - 1;
|
||||
rhs_val = sizeof(lhs_val) * MP_BITS_PER_BYTE - 1;
|
||||
}
|
||||
lhs_val >>= rhs_val;
|
||||
}
|
||||
break;
|
||||
case MP_BINARY_OP_ADD:
|
||||
case MP_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break;
|
||||
case MP_BINARY_OP_INPLACE_ADD:
|
||||
lhs_val += rhs_val;
|
||||
break;
|
||||
case MP_BINARY_OP_SUBTRACT:
|
||||
case MP_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break;
|
||||
case MP_BINARY_OP_INPLACE_SUBTRACT:
|
||||
lhs_val -= rhs_val;
|
||||
break;
|
||||
case MP_BINARY_OP_MULTIPLY:
|
||||
case MP_BINARY_OP_INPLACE_MULTIPLY: {
|
||||
|
||||
@@ -473,9 +482,9 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
case MP_BINARY_OP_INPLACE_POWER:
|
||||
if (rhs_val < 0) {
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
return mp_obj_float_binary_op(op, lhs_val, rhs);
|
||||
return mp_obj_float_binary_op(op, (mp_float_t)lhs_val, rhs);
|
||||
#else
|
||||
mp_raise_ValueError("negative power with no float support");
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("negative power with no float support"));
|
||||
#endif
|
||||
} else {
|
||||
mp_int_t ans = 1;
|
||||
@@ -515,10 +524,14 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
return MP_OBJ_FROM_PTR(tuple);
|
||||
}
|
||||
|
||||
case MP_BINARY_OP_LESS: return mp_obj_new_bool(lhs_val < rhs_val);
|
||||
case MP_BINARY_OP_MORE: return mp_obj_new_bool(lhs_val > rhs_val);
|
||||
case MP_BINARY_OP_LESS_EQUAL: return mp_obj_new_bool(lhs_val <= rhs_val);
|
||||
case MP_BINARY_OP_MORE_EQUAL: return mp_obj_new_bool(lhs_val >= rhs_val);
|
||||
case MP_BINARY_OP_LESS:
|
||||
return mp_obj_new_bool(lhs_val < rhs_val);
|
||||
case MP_BINARY_OP_MORE:
|
||||
return mp_obj_new_bool(lhs_val > rhs_val);
|
||||
case MP_BINARY_OP_LESS_EQUAL:
|
||||
return mp_obj_new_bool(lhs_val <= rhs_val);
|
||||
case MP_BINARY_OP_MORE_EQUAL:
|
||||
return mp_obj_new_bool(lhs_val >= rhs_val);
|
||||
|
||||
default:
|
||||
goto unsupported_op;
|
||||
@@ -529,24 +542,24 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
} else {
|
||||
return mp_obj_new_int_from_ll(lhs_val);
|
||||
}
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
} else if (mp_obj_is_float(rhs)) {
|
||||
mp_obj_t res = mp_obj_float_binary_op(op, lhs_val, rhs);
|
||||
mp_obj_t res = mp_obj_float_binary_op(op, (mp_float_t)lhs_val, rhs);
|
||||
if (res == MP_OBJ_NULL) {
|
||||
goto unsupported_op;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
#if MICROPY_PY_BUILTINS_COMPLEX
|
||||
#endif
|
||||
#if MICROPY_PY_BUILTINS_COMPLEX
|
||||
} else if (mp_obj_is_type(rhs, &mp_type_complex)) {
|
||||
mp_obj_t res = mp_obj_complex_binary_op(op, lhs_val, 0, rhs);
|
||||
mp_obj_t res = mp_obj_complex_binary_op(op, (mp_float_t)lhs_val, 0, rhs);
|
||||
if (res == MP_OBJ_NULL) {
|
||||
goto unsupported_op;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,7 +572,7 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
}
|
||||
|
||||
// generic binary_op supplied by type
|
||||
mp_obj_type_t *type;
|
||||
const mp_obj_type_t *type;
|
||||
generic_binary_op:
|
||||
type = mp_obj_get_type(lhs);
|
||||
if (type->binary_op != NULL) {
|
||||
@@ -569,7 +582,7 @@ generic_binary_op:
|
||||
}
|
||||
}
|
||||
|
||||
#if MICROPY_PY_REVERSE_SPECIAL_METHODS
|
||||
#if MICROPY_PY_REVERSE_SPECIAL_METHODS
|
||||
if (op >= MP_BINARY_OP_OR && op <= MP_BINARY_OP_POWER) {
|
||||
mp_obj_t t = rhs;
|
||||
rhs = lhs;
|
||||
@@ -583,7 +596,7 @@ generic_binary_op:
|
||||
lhs = t;
|
||||
op -= MP_BINARY_OP_REVERSE_OR - MP_BINARY_OP_OR;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (op == MP_BINARY_OP_CONTAINS) {
|
||||
// If type didn't support containment then explicitly walk the iterator.
|
||||
@@ -600,16 +613,16 @@ generic_binary_op:
|
||||
}
|
||||
|
||||
unsupported_op:
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_TypeError("unsupported type for operator");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"unsupported types for %q: '%s', '%s'",
|
||||
mp_binary_op_method_name[op], mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs)));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_TypeError(MP_ERROR_TEXT("unsupported type for operator"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_TypeError,
|
||||
MP_ERROR_TEXT("unsupported types for %q: '%s', '%s'"),
|
||||
mp_binary_op_method_name[op], mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs));
|
||||
#endif
|
||||
|
||||
zero_division:
|
||||
mp_raise_msg(&mp_type_ZeroDivisionError, "divide by zero");
|
||||
mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("divide by zero"));
|
||||
}
|
||||
|
||||
mp_obj_t mp_call_function_0(mp_obj_t fun) {
|
||||
@@ -635,19 +648,19 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, cons
|
||||
DEBUG_OP_printf("calling function %p(n_args=" UINT_FMT ", n_kw=" UINT_FMT ", args=%p)\n", fun_in, n_args, n_kw, args);
|
||||
|
||||
// get the type
|
||||
mp_obj_type_t *type = mp_obj_get_type(fun_in);
|
||||
const mp_obj_type_t *type = mp_obj_get_type(fun_in);
|
||||
|
||||
// do the call
|
||||
if (type->call != NULL) {
|
||||
return type->call(fun_in, n_args, n_kw, args);
|
||||
}
|
||||
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_TypeError("object not callable");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"'%s' object isn't callable", mp_obj_get_type_str(fun_in)));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_TypeError(MP_ERROR_TEXT("object not callable"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_TypeError,
|
||||
MP_ERROR_TEXT("'%s' object isn't callable"), mp_obj_get_type_str(fun_in));
|
||||
#endif
|
||||
}
|
||||
|
||||
// args contains: fun self/NULL arg(0) ... arg(n_args-2) arg(n_args-1) kw_key(0) kw_val(0) ... kw_key(n_kw-1) kw_val(n_kw-1)
|
||||
@@ -871,19 +884,17 @@ void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) {
|
||||
return;
|
||||
|
||||
too_short:
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_ValueError("wrong number of values to unpack");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
||||
"need more than %d values to unpack", (int)seq_len));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("need more than %d values to unpack"), (int)seq_len);
|
||||
#endif
|
||||
too_long:
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_ValueError("wrong number of values to unpack");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
||||
"too many values to unpack (expected %d)", (int)num));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("too many values to unpack (expected %d)"), (int)num);
|
||||
#endif
|
||||
}
|
||||
|
||||
// unpacked items are stored in reverse order into the array pointed to by items
|
||||
@@ -940,12 +951,11 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) {
|
||||
return;
|
||||
|
||||
too_short:
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_ValueError("wrong number of values to unpack");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
||||
"need more than %d values to unpack", (int)seq_len));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("need more than %d values to unpack"), (int)seq_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
mp_obj_t mp_load_attr(mp_obj_t base, qstr attr) {
|
||||
@@ -979,12 +989,12 @@ STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c
|
||||
if (n_args > 0) {
|
||||
const mp_obj_type_t *arg0_type = mp_obj_get_type(args[0]);
|
||||
if (arg0_type != self->type) {
|
||||
if (MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_DETAILED) {
|
||||
mp_raise_TypeError("argument has wrong type");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"argument should be a '%q' not a '%q'", self->type->name, arg0_type->name));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_DETAILED
|
||||
mp_raise_TypeError(MP_ERROR_TEXT("argument has wrong type"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_TypeError,
|
||||
MP_ERROR_TEXT("argument should be a '%q' not a '%q'"), self->type->name, arg0_type->name);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return mp_call_function_n_kw(self->fun, n_args, n_kw, args);
|
||||
@@ -992,6 +1002,7 @@ STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c
|
||||
|
||||
STATIC const mp_obj_type_t mp_type_checked_fun = {
|
||||
{ &mp_type_type },
|
||||
.flags = MP_TYPE_FLAG_BINDS_SELF,
|
||||
.name = MP_QSTR_function,
|
||||
.call = checked_fun_call,
|
||||
};
|
||||
@@ -1010,47 +1021,54 @@ STATIC mp_obj_t mp_obj_new_checked_fun(const mp_obj_type_t *type, mp_obj_t fun)
|
||||
// and put the result in the dest[] array for a possible method call.
|
||||
// Conversion means dealing with static/class methods, callables, and values.
|
||||
// see http://docs.python.org/3/howto/descriptor.html
|
||||
// and also https://mail.python.org/pipermail/python-dev/2015-March/138950.html
|
||||
void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t member, mp_obj_t *dest) {
|
||||
if (mp_obj_is_type(member, &mp_type_staticmethod)) {
|
||||
// return just the function
|
||||
dest[0] = ((mp_obj_static_class_method_t*)MP_OBJ_TO_PTR(member))->fun;
|
||||
} else if (mp_obj_is_type(member, &mp_type_classmethod)) {
|
||||
// return a bound method, with self being the type of this object
|
||||
// this type should be the type of the original instance, not the base
|
||||
// type (which is what is passed in the 'type' argument to this function)
|
||||
if (self != MP_OBJ_NULL) {
|
||||
type = mp_obj_get_type(self);
|
||||
}
|
||||
dest[0] = ((mp_obj_static_class_method_t*)MP_OBJ_TO_PTR(member))->fun;
|
||||
dest[1] = MP_OBJ_FROM_PTR(type);
|
||||
} else if (mp_obj_is_type(member, &mp_type_type)) {
|
||||
// Don't try to bind types (even though they're callable)
|
||||
dest[0] = member;
|
||||
} else if (mp_obj_is_fun(member)
|
||||
|| (mp_obj_is_obj(member)
|
||||
&& (((mp_obj_base_t*)MP_OBJ_TO_PTR(member))->type->name == MP_QSTR_closure
|
||||
|| ((mp_obj_base_t*)MP_OBJ_TO_PTR(member))->type->name == MP_QSTR_generator))) {
|
||||
// only functions, closures and generators objects can be bound to self
|
||||
#if MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG
|
||||
const mp_obj_type_t *m_type = ((mp_obj_base_t*)MP_OBJ_TO_PTR(member))->type;
|
||||
if (self == MP_OBJ_NULL
|
||||
&& (m_type == &mp_type_fun_builtin_0
|
||||
|| m_type == &mp_type_fun_builtin_1
|
||||
|| m_type == &mp_type_fun_builtin_2
|
||||
|| m_type == &mp_type_fun_builtin_3
|
||||
|| m_type == &mp_type_fun_builtin_var)) {
|
||||
// we extracted a builtin method without a first argument, so we must
|
||||
// wrap this function in a type checker
|
||||
dest[0] = mp_obj_new_checked_fun(type, member);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// return a bound method, with self being this object
|
||||
if (mp_obj_is_obj(member)) {
|
||||
const mp_obj_type_t *m_type = ((mp_obj_base_t *)MP_OBJ_TO_PTR(member))->type;
|
||||
if (m_type->flags & MP_TYPE_FLAG_BINDS_SELF) {
|
||||
// `member` is a function that binds self as its first argument.
|
||||
if (m_type->flags & MP_TYPE_FLAG_BUILTIN_FUN) {
|
||||
// `member` is a built-in function, which has special behaviour.
|
||||
if (mp_obj_is_instance_type(type)) {
|
||||
// Built-in functions on user types always behave like a staticmethod.
|
||||
dest[0] = member;
|
||||
}
|
||||
#if MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG
|
||||
else if (self == MP_OBJ_NULL && type != &mp_type_object) {
|
||||
// `member` is a built-in method without a first argument, so wrap
|
||||
// it in a type checker that will check self when it's supplied.
|
||||
// Note that object will do its own checking so shouldn't be wrapped.
|
||||
dest[0] = mp_obj_new_checked_fun(type, member);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
// Return a (built-in) bound method, with self being this object.
|
||||
dest[0] = member;
|
||||
dest[1] = self;
|
||||
}
|
||||
} else {
|
||||
// Return a bound method, with self being this object.
|
||||
dest[0] = member;
|
||||
dest[1] = self;
|
||||
}
|
||||
} else if (m_type == &mp_type_staticmethod) {
|
||||
// `member` is a staticmethod, return the function that it wraps.
|
||||
dest[0] = ((mp_obj_static_class_method_t *)MP_OBJ_TO_PTR(member))->fun;
|
||||
} else if (m_type == &mp_type_classmethod) {
|
||||
// `member` is a classmethod, return a bound method with self being the type of
|
||||
// this object. This type should be the type of the original instance, not the
|
||||
// base type (which is what is passed in the `type` argument to this function).
|
||||
if (self != MP_OBJ_NULL) {
|
||||
type = mp_obj_get_type(self);
|
||||
}
|
||||
dest[0] = ((mp_obj_static_class_method_t *)MP_OBJ_TO_PTR(member))->fun;
|
||||
dest[1] = MP_OBJ_FROM_PTR(type);
|
||||
} else {
|
||||
// `member` is a value, so just return that value.
|
||||
dest[0] = member;
|
||||
dest[1] = self;
|
||||
}
|
||||
} else {
|
||||
// class member is a value, so just return that value
|
||||
// `member` is a value, so just return that value.
|
||||
dest[0] = member;
|
||||
}
|
||||
}
|
||||
@@ -1064,15 +1082,17 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) {
|
||||
dest[1] = MP_OBJ_NULL;
|
||||
|
||||
// get the type
|
||||
mp_obj_type_t *type = mp_obj_get_type(obj);
|
||||
const mp_obj_type_t *type = mp_obj_get_type(obj);
|
||||
|
||||
// look for built-in names
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
if (attr == MP_QSTR___class__) {
|
||||
// a.__class__ is equivalent to type(a)
|
||||
dest[0] = MP_OBJ_FROM_PTR(type);
|
||||
} else
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (attr == MP_QSTR___next__ && type->iternext != NULL) {
|
||||
dest[0] = MP_OBJ_FROM_PTR(&mp_builtin_next_obj);
|
||||
dest[1] = obj;
|
||||
@@ -1100,20 +1120,20 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
|
||||
|
||||
if (dest[0] == MP_OBJ_NULL) {
|
||||
// no attribute/method called attr
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_msg(&mp_type_AttributeError, "no such attribute");
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("no such attribute"));
|
||||
#else
|
||||
// following CPython, we give a more detailed error message for type objects
|
||||
if (mp_obj_is_type(base, &mp_type_type)) {
|
||||
mp_raise_msg_varg(&mp_type_AttributeError,
|
||||
MP_ERROR_TEXT("type object '%q' has no attribute '%q'"),
|
||||
((mp_obj_type_t *)MP_OBJ_TO_PTR(base))->name, attr);
|
||||
} else {
|
||||
// following CPython, we give a more detailed error message for type objects
|
||||
if (mp_obj_is_type(base, &mp_type_type)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError,
|
||||
"type object '%q' has no attribute '%q'",
|
||||
((mp_obj_type_t*)MP_OBJ_TO_PTR(base))->name, attr));
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError,
|
||||
"'%s' object has no attribute '%q'",
|
||||
mp_obj_get_type_str(base), attr));
|
||||
}
|
||||
mp_raise_msg_varg(&mp_type_AttributeError,
|
||||
MP_ERROR_TEXT("'%s' object has no attribute '%q'"),
|
||||
mp_obj_get_type_str(base), attr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1125,7 +1145,7 @@ void mp_load_method_protected(mp_obj_t obj, qstr attr, mp_obj_t *dest, bool catc
|
||||
nlr_pop();
|
||||
} else {
|
||||
if (!catch_all_exc
|
||||
&& !mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t*)nlr.ret_val)->type),
|
||||
&& !mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type),
|
||||
MP_OBJ_FROM_PTR(&mp_type_AttributeError))) {
|
||||
// Re-raise the exception
|
||||
nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val));
|
||||
@@ -1135,7 +1155,7 @@ void mp_load_method_protected(mp_obj_t obj, qstr attr, mp_obj_t *dest, bool catc
|
||||
|
||||
void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
|
||||
DEBUG_OP_printf("store attr %p.%s <- %p\n", base, qstr_str(attr), value);
|
||||
mp_obj_type_t *type = mp_obj_get_type(base);
|
||||
const mp_obj_type_t *type = mp_obj_get_type(base);
|
||||
if (type->attr != NULL) {
|
||||
mp_obj_t dest[2] = {MP_OBJ_SENTINEL, value};
|
||||
type->attr(base, attr, dest);
|
||||
@@ -1144,18 +1164,18 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_msg(&mp_type_AttributeError, "no such attribute");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError,
|
||||
"'%s' object has no attribute '%q'",
|
||||
mp_obj_get_type_str(base), attr));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("no such attribute"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_AttributeError,
|
||||
MP_ERROR_TEXT("'%s' object has no attribute '%q'"),
|
||||
mp_obj_get_type_str(base), attr);
|
||||
#endif
|
||||
}
|
||||
|
||||
mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
|
||||
assert(o_in);
|
||||
mp_obj_type_t *type = mp_obj_get_type(o_in);
|
||||
const mp_obj_type_t *type = mp_obj_get_type(o_in);
|
||||
|
||||
// Check for native getiter which is the identity. We handle this case explicitly
|
||||
// so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used.
|
||||
@@ -1163,13 +1183,13 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
|
||||
return o_in;
|
||||
}
|
||||
|
||||
// if caller did not provide a buffer then allocate one on the heap
|
||||
if (iter_buf == NULL) {
|
||||
iter_buf = m_new_obj(mp_obj_iter_buf_t);
|
||||
}
|
||||
|
||||
// check for native getiter (corresponds to __iter__)
|
||||
if (type->getiter != NULL) {
|
||||
if (iter_buf == NULL && type->getiter != mp_obj_instance_getiter) {
|
||||
// if caller did not provide a buffer then allocate one on the heap
|
||||
// mp_obj_instance_getiter is special, it will allocate only if needed
|
||||
iter_buf = m_new_obj(mp_obj_iter_buf_t);
|
||||
}
|
||||
mp_obj_t iter = type->getiter(o_in, iter_buf);
|
||||
if (iter != MP_OBJ_NULL) {
|
||||
return iter;
|
||||
@@ -1181,23 +1201,29 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
|
||||
mp_load_method_maybe(o_in, MP_QSTR___getitem__, dest);
|
||||
if (dest[0] != MP_OBJ_NULL) {
|
||||
// __getitem__ exists, create and return an iterator
|
||||
if (iter_buf == NULL) {
|
||||
// if caller did not provide a buffer then allocate one on the heap
|
||||
iter_buf = m_new_obj(mp_obj_iter_buf_t);
|
||||
}
|
||||
return mp_obj_new_getitem_iter(dest, iter_buf);
|
||||
}
|
||||
|
||||
// object not iterable
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_TypeError("object not iterable");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"'%s' object isn't iterable", mp_obj_get_type_str(o_in)));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_TypeError(MP_ERROR_TEXT("object not iterable"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_TypeError,
|
||||
MP_ERROR_TEXT("'%s' object isn't iterable"), mp_obj_get_type_str(o_in));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// may return MP_OBJ_STOP_ITERATION as an optimisation instead of raise StopIteration()
|
||||
// may also raise StopIteration()
|
||||
mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
|
||||
mp_obj_type_t *type = mp_obj_get_type(o_in);
|
||||
const mp_obj_type_t *type = mp_obj_get_type(o_in);
|
||||
if (type->iternext != NULL) {
|
||||
MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
|
||||
return type->iternext(o_in);
|
||||
} else {
|
||||
// check for __next__ method
|
||||
@@ -1207,12 +1233,12 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
|
||||
// __next__ exists, call it and return its result
|
||||
return mp_call_method_n_kw(0, 0, dest);
|
||||
} else {
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_TypeError("object not an iterator");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"'%s' object isn't an iterator", mp_obj_get_type_str(o_in)));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_TypeError(MP_ERROR_TEXT("object not an iterator"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_TypeError,
|
||||
MP_ERROR_TEXT("'%s' object isn't an iterator"), mp_obj_get_type_str(o_in));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1221,8 +1247,9 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
|
||||
// may raise other exceptions
|
||||
mp_obj_t mp_iternext(mp_obj_t o_in) {
|
||||
MP_STACK_CHECK(); // enumerate, filter, map and zip can recursively call mp_iternext
|
||||
mp_obj_type_t *type = mp_obj_get_type(o_in);
|
||||
const mp_obj_type_t *type = mp_obj_get_type(o_in);
|
||||
if (type->iternext != NULL) {
|
||||
MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
|
||||
return type->iternext(o_in);
|
||||
} else {
|
||||
// check for __next__ method
|
||||
@@ -1236,40 +1263,44 @@ mp_obj_t mp_iternext(mp_obj_t o_in) {
|
||||
nlr_pop();
|
||||
return ret;
|
||||
} else {
|
||||
if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t*)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_StopIteration))) {
|
||||
return MP_OBJ_STOP_ITERATION;
|
||||
if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_StopIteration))) {
|
||||
return mp_make_stop_iteration(mp_obj_exception_get_value(MP_OBJ_FROM_PTR(nlr.ret_val)));
|
||||
} else {
|
||||
nlr_jump(nlr.ret_val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_TypeError("object not an iterator");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"'%s' object isn't an iterator", mp_obj_get_type_str(o_in)));
|
||||
}
|
||||
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
|
||||
mp_raise_TypeError(MP_ERROR_TEXT("object not an iterator"));
|
||||
#else
|
||||
mp_raise_msg_varg(&mp_type_TypeError,
|
||||
MP_ERROR_TEXT("'%s' object isn't an iterator"), mp_obj_get_type_str(o_in));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Unclear what to do with StopIterarion exception here.
|
||||
mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) {
|
||||
assert((send_value != MP_OBJ_NULL) ^ (throw_value != MP_OBJ_NULL));
|
||||
mp_obj_type_t *type = mp_obj_get_type(self_in);
|
||||
const mp_obj_type_t *type = mp_obj_get_type(self_in);
|
||||
|
||||
if (type == &mp_type_gen_instance) {
|
||||
return mp_obj_gen_resume(self_in, send_value, throw_value, ret_val);
|
||||
}
|
||||
|
||||
if (type->iternext != NULL && send_value == mp_const_none) {
|
||||
MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
|
||||
mp_obj_t ret = type->iternext(self_in);
|
||||
*ret_val = ret;
|
||||
if (ret != MP_OBJ_STOP_ITERATION) {
|
||||
return MP_VM_RETURN_YIELD;
|
||||
} else {
|
||||
// Emulate raise StopIteration()
|
||||
// Special case, handled in vm.c
|
||||
// The generator is finished.
|
||||
// This is an optimised "raise StopIteration(*ret_val)".
|
||||
*ret_val = MP_STATE_THREAD(stop_iteration_arg);
|
||||
if (*ret_val == MP_OBJ_NULL) {
|
||||
*ret_val = mp_const_none;
|
||||
}
|
||||
return MP_VM_RETURN_NORMAL;
|
||||
}
|
||||
}
|
||||
@@ -1322,7 +1353,7 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
|
||||
// test_delegating_throw_to_non_generator()
|
||||
if (mp_obj_exception_match(throw_value, MP_OBJ_FROM_PTR(&mp_type_StopIteration))) {
|
||||
// PEP479: if StopIteration is raised inside a generator it is replaced with RuntimeError
|
||||
*ret_val = mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator raised StopIteration");
|
||||
*ret_val = mp_obj_new_exception_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("generator raised StopIteration"));
|
||||
} else {
|
||||
*ret_val = mp_make_raise_obj(throw_value);
|
||||
}
|
||||
@@ -1343,7 +1374,7 @@ mp_obj_t mp_make_raise_obj(mp_obj_t o) {
|
||||
return o;
|
||||
} else {
|
||||
// o cannot be used as an exception, so return a type error (which will be raised by the caller)
|
||||
return mp_obj_new_exception_msg(&mp_type_TypeError, "exceptions must derive from BaseException");
|
||||
return mp_obj_new_exception_msg(&mp_type_TypeError, MP_ERROR_TEXT("exceptions must derive from BaseException"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1381,8 +1412,8 @@ mp_obj_t mp_import_from(mp_obj_t module, qstr name) {
|
||||
|
||||
if (dest[1] != MP_OBJ_NULL) {
|
||||
// Hopefully we can't import bound method from an object
|
||||
import_error:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "cannot import name %q", name));
|
||||
import_error:
|
||||
mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("can't import name %q"), name);
|
||||
}
|
||||
|
||||
if (dest[0] != MP_OBJ_NULL) {
|
||||
@@ -1453,7 +1484,7 @@ mp_obj_t mp_parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t parse_i
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, parse_input_kind);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, false);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, parse_input_kind == MP_PARSE_SINGLE_INPUT);
|
||||
|
||||
mp_obj_t ret;
|
||||
if (MICROPY_PY_BUILTINS_COMPILE && globals == NULL) {
|
||||
@@ -1483,14 +1514,34 @@ NORETURN void m_malloc_fail(size_t num_bytes) {
|
||||
DEBUG_printf("memory allocation failed, allocating %u bytes\n", (uint)num_bytes);
|
||||
#if MICROPY_ENABLE_GC
|
||||
if (gc_is_locked()) {
|
||||
mp_raise_msg(&mp_type_MemoryError, "memory allocation failed, heap is locked");
|
||||
mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("memory allocation failed, heap is locked"));
|
||||
}
|
||||
#endif
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError,
|
||||
"memory allocation failed, allocating %u bytes", (uint)num_bytes));
|
||||
mp_raise_msg_varg(&mp_type_MemoryError,
|
||||
MP_ERROR_TEXT("memory allocation failed, allocating %u bytes"), (uint)num_bytes);
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg) {
|
||||
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE
|
||||
|
||||
NORETURN void mp_raise_type(const mp_obj_type_t *exc_type) {
|
||||
nlr_raise(mp_obj_new_exception(exc_type));
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_ValueError_no_msg(void) {
|
||||
mp_raise_type(&mp_type_ValueError);
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_TypeError_no_msg(void) {
|
||||
mp_raise_type(&mp_type_TypeError);
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_NotImplementedError_no_msg(void) {
|
||||
mp_raise_type(&mp_type_NotImplementedError);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg) {
|
||||
if (msg == NULL) {
|
||||
nlr_raise(mp_obj_new_exception(exc_type));
|
||||
} else {
|
||||
@@ -1498,25 +1549,46 @@ NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg) {
|
||||
}
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_ValueError(const char *msg) {
|
||||
NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
mp_obj_t exc = mp_obj_new_exception_msg_vlist(exc_type, fmt, args);
|
||||
va_end(args);
|
||||
nlr_raise(exc);
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_ValueError(mp_rom_error_text_t msg) {
|
||||
mp_raise_msg(&mp_type_ValueError, msg);
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_TypeError(const char *msg) {
|
||||
NORETURN void mp_raise_TypeError(mp_rom_error_text_t msg) {
|
||||
mp_raise_msg(&mp_type_TypeError, msg);
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_OSError(int errno_) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_)));
|
||||
NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg) {
|
||||
mp_raise_msg(&mp_type_NotImplementedError, msg);
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_NotImplementedError(const char *msg) {
|
||||
mp_raise_msg(&mp_type_NotImplementedError, msg);
|
||||
#endif
|
||||
|
||||
NORETURN void mp_raise_type_arg(const mp_obj_type_t *exc_type, mp_obj_t arg) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(exc_type, arg));
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_StopIteration(mp_obj_t arg) {
|
||||
if (arg == MP_OBJ_NULL) {
|
||||
mp_raise_type(&mp_type_StopIteration);
|
||||
} else {
|
||||
mp_raise_type_arg(&mp_type_StopIteration, arg);
|
||||
}
|
||||
}
|
||||
|
||||
NORETURN void mp_raise_OSError(int errno_) {
|
||||
mp_raise_type_arg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_));
|
||||
}
|
||||
|
||||
#if MICROPY_STACK_CHECK || MICROPY_ENABLE_PYSTACK
|
||||
NORETURN void mp_raise_recursion_depth(void) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_RuntimeError,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_maximum_space_recursion_space_depth_space_exceeded)));
|
||||
mp_raise_type_arg(&mp_type_RuntimeError, MP_OBJ_NEW_QSTR(MP_QSTR_maximum_space_recursion_space_depth_space_exceeded));
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user