mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-21 14:50:44 +01:00
[python] Update to MicroPython 1.9.4
This commit is contained in:
committed by
EmilieNumworks
parent
caff93cda0
commit
73250e727a
@@ -83,8 +83,10 @@ void mp_init(void) {
|
||||
MICROPY_PORT_INIT_FUNC;
|
||||
#endif
|
||||
|
||||
#if MICROPY_ENABLE_COMPILER
|
||||
// optimization disabled by default
|
||||
MP_STATE_VM(mp_optimise_value) = 0;
|
||||
#endif
|
||||
|
||||
// init global module dict
|
||||
mp_obj_dict_init(&MP_STATE_VM(mp_loaded_modules_dict), 3);
|
||||
@@ -214,7 +216,7 @@ void mp_delete_global(qstr qst) {
|
||||
}
|
||||
|
||||
mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
|
||||
DEBUG_OP_printf("unary " UINT_FMT " %p\n", op, arg);
|
||||
DEBUG_OP_printf("unary " UINT_FMT " %q %p\n", op, mp_unary_op_method_name[op], arg);
|
||||
|
||||
if (op == MP_UNARY_OP_NOT) {
|
||||
// "not x" is the negative of whether "x" is true per Python semantics
|
||||
@@ -275,7 +277,7 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
|
||||
}
|
||||
|
||||
mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
DEBUG_OP_printf("binary " UINT_FMT " %p %p\n", op, lhs, rhs);
|
||||
DEBUG_OP_printf("binary " UINT_FMT " %q %p %p\n", op, mp_binary_op_method_name[op], lhs, rhs);
|
||||
|
||||
// TODO correctly distinguish inplace operators for mutable objects
|
||||
// lookup logic that CPython uses for +=:
|
||||
@@ -413,7 +415,6 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
// use standard precision
|
||||
return MP_OBJ_NEW_SMALL_INT(lhs_val * rhs_val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MP_BINARY_OP_FLOOR_DIVIDE:
|
||||
case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE:
|
||||
@@ -488,10 +489,10 @@ 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); break;
|
||||
case MP_BINARY_OP_MORE: return mp_obj_new_bool(lhs_val > rhs_val); break;
|
||||
case MP_BINARY_OP_LESS_EQUAL: return mp_obj_new_bool(lhs_val <= rhs_val); break;
|
||||
case MP_BINARY_OP_MORE_EQUAL: return mp_obj_new_bool(lhs_val >= rhs_val); break;
|
||||
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;
|
||||
@@ -523,38 +524,12 @@ mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
}
|
||||
}
|
||||
|
||||
/* deal with `in`
|
||||
*
|
||||
* NOTE `a in b` is `b.__contains__(a)`, hence why the generic dispatch
|
||||
* needs to go below with swapped arguments
|
||||
*/
|
||||
// Convert MP_BINARY_OP_IN to MP_BINARY_OP_CONTAINS with swapped args.
|
||||
if (op == MP_BINARY_OP_IN) {
|
||||
mp_obj_type_t *type = mp_obj_get_type(rhs);
|
||||
if (type->binary_op != NULL) {
|
||||
mp_obj_t res = type->binary_op(op, rhs, lhs);
|
||||
if (res != MP_OBJ_NULL) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if (type->getiter != NULL) {
|
||||
/* second attempt, walk the iterator */
|
||||
mp_obj_iter_buf_t iter_buf;
|
||||
mp_obj_t iter = mp_getiter(rhs, &iter_buf);
|
||||
mp_obj_t next;
|
||||
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
|
||||
if (mp_obj_equal(next, lhs)) {
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
return mp_const_false;
|
||||
}
|
||||
|
||||
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 is not iterable", mp_obj_get_type_str(rhs)));
|
||||
}
|
||||
op = MP_BINARY_OP_CONTAINS;
|
||||
mp_obj_t temp = lhs;
|
||||
lhs = rhs;
|
||||
rhs = temp;
|
||||
}
|
||||
|
||||
// generic binary_op supplied by type
|
||||
@@ -583,6 +558,20 @@ generic_binary_op:
|
||||
}
|
||||
#endif
|
||||
|
||||
if (op == MP_BINARY_OP_CONTAINS) {
|
||||
// If type didn't support containment then explicitly walk the iterator.
|
||||
// mp_getiter will raise the appropriate exception if lhs is not iterable.
|
||||
mp_obj_iter_buf_t iter_buf;
|
||||
mp_obj_t iter = mp_getiter(lhs, &iter_buf);
|
||||
mp_obj_t next;
|
||||
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
|
||||
if (mp_obj_equal(next, rhs)) {
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
return mp_const_false;
|
||||
}
|
||||
|
||||
unsupported_op:
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_TypeError("unsupported type for operator");
|
||||
@@ -681,7 +670,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||
|
||||
// allocate memory for the new array of args
|
||||
args2_alloc = 1 + n_args + 2 * (n_kw + kw_dict_len);
|
||||
args2 = m_new(mp_obj_t, args2_alloc);
|
||||
args2 = mp_nonlocal_alloc(args2_alloc * sizeof(mp_obj_t));
|
||||
|
||||
// copy the self
|
||||
if (self != MP_OBJ_NULL) {
|
||||
@@ -702,7 +691,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||
|
||||
// allocate memory for the new array of args
|
||||
args2_alloc = 1 + n_args + len + 2 * (n_kw + kw_dict_len);
|
||||
args2 = m_new(mp_obj_t, args2_alloc);
|
||||
args2 = mp_nonlocal_alloc(args2_alloc * sizeof(mp_obj_t));
|
||||
|
||||
// copy the self
|
||||
if (self != MP_OBJ_NULL) {
|
||||
@@ -718,7 +707,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||
|
||||
// allocate memory for the new array of args
|
||||
args2_alloc = 1 + n_args + 2 * (n_kw + kw_dict_len) + 3;
|
||||
args2 = m_new(mp_obj_t, args2_alloc);
|
||||
args2 = mp_nonlocal_alloc(args2_alloc * sizeof(mp_obj_t));
|
||||
|
||||
// copy the self
|
||||
if (self != MP_OBJ_NULL) {
|
||||
@@ -735,7 +724,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||
mp_obj_t item;
|
||||
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
|
||||
if (args2_len >= args2_alloc) {
|
||||
args2 = m_renew(mp_obj_t, args2, args2_alloc, args2_alloc * 2);
|
||||
args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), args2_alloc * 2 * sizeof(mp_obj_t));
|
||||
args2_alloc *= 2;
|
||||
}
|
||||
args2[args2_len++] = item;
|
||||
@@ -761,8 +750,8 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||
if (MP_MAP_SLOT_IS_FILLED(map, i)) {
|
||||
// the key must be a qstr, so intern it if it's a string
|
||||
mp_obj_t key = map->table[i].key;
|
||||
if (MP_OBJ_IS_TYPE(key, &mp_type_str)) {
|
||||
key = mp_obj_str_intern(key);
|
||||
if (!MP_OBJ_IS_QSTR(key)) {
|
||||
key = mp_obj_str_intern_checked(key);
|
||||
}
|
||||
args2[args2_len++] = key;
|
||||
args2[args2_len++] = map->table[i].value;
|
||||
@@ -786,13 +775,13 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||
if (new_alloc < 4) {
|
||||
new_alloc = 4;
|
||||
}
|
||||
args2 = m_renew(mp_obj_t, args2, args2_alloc, new_alloc);
|
||||
args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), new_alloc * sizeof(mp_obj_t));
|
||||
args2_alloc = new_alloc;
|
||||
}
|
||||
|
||||
// the key must be a qstr, so intern it if it's a string
|
||||
if (MP_OBJ_IS_TYPE(key, &mp_type_str)) {
|
||||
key = mp_obj_str_intern(key);
|
||||
if (!MP_OBJ_IS_QSTR(key)) {
|
||||
key = mp_obj_str_intern_checked(key);
|
||||
}
|
||||
|
||||
// get the value corresponding to the key
|
||||
@@ -818,7 +807,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ob
|
||||
mp_call_prepare_args_n_kw_var(have_self, n_args_n_kw, args, &out_args);
|
||||
|
||||
mp_obj_t res = mp_call_function_n_kw(out_args.fun, out_args.n_args, out_args.n_kw, out_args.args);
|
||||
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
|
||||
mp_nonlocal_free(out_args.args, out_args.n_alloc * sizeof(mp_obj_t));
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1097,6 +1086,22 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
|
||||
}
|
||||
}
|
||||
|
||||
// Acts like mp_load_method_maybe but catches AttributeError, and all other exceptions if requested
|
||||
void mp_load_method_protected(mp_obj_t obj, qstr attr, mp_obj_t *dest, bool catch_all_exc) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_load_method_maybe(obj, attr, dest);
|
||||
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_FROM_PTR(&mp_type_AttributeError))) {
|
||||
// Re-raise the exception
|
||||
nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -1228,13 +1233,12 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
|
||||
|
||||
if (type->iternext != NULL && send_value == mp_const_none) {
|
||||
mp_obj_t ret = type->iternext(self_in);
|
||||
*ret_val = ret;
|
||||
if (ret != MP_OBJ_STOP_ITERATION) {
|
||||
*ret_val = ret;
|
||||
return MP_VM_RETURN_YIELD;
|
||||
} else {
|
||||
// Emulate raise StopIteration()
|
||||
// Special case, handled in vm.c
|
||||
*ret_val = MP_OBJ_NULL;
|
||||
return MP_VM_RETURN_NORMAL;
|
||||
}
|
||||
}
|
||||
@@ -1296,7 +1300,7 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
|
||||
// will be propagated up. This behavior is approved by test_pep380.py
|
||||
// test_delegation_of_close_to_non_generator(),
|
||||
// test_delegating_throw_to_non_generator()
|
||||
*ret_val = throw_value;
|
||||
*ret_val = mp_make_raise_obj(throw_value);
|
||||
return MP_VM_RETURN_EXCEPTION;
|
||||
}
|
||||
}
|
||||
@@ -1350,6 +1354,8 @@ import_error:
|
||||
return dest[0];
|
||||
}
|
||||
|
||||
#if MICROPY_ENABLE_EXTERNAL_IMPORT
|
||||
|
||||
// See if it's a package, then can try FS import
|
||||
if (!mp_obj_is_package(module)) {
|
||||
goto import_error;
|
||||
@@ -1360,11 +1366,12 @@ import_error:
|
||||
const char *pkg_name = mp_obj_str_get_data(dest[0], &pkg_name_len);
|
||||
|
||||
const uint dot_name_len = pkg_name_len + 1 + qstr_len(name);
|
||||
char *dot_name = alloca(dot_name_len);
|
||||
char *dot_name = mp_local_alloc(dot_name_len);
|
||||
memcpy(dot_name, pkg_name, pkg_name_len);
|
||||
dot_name[pkg_name_len] = '.';
|
||||
memcpy(dot_name + pkg_name_len + 1, qstr_str(name), qstr_len(name));
|
||||
qstr dot_name_q = qstr_from_strn(dot_name, dot_name_len);
|
||||
mp_local_free(dot_name);
|
||||
|
||||
mp_obj_t args[5];
|
||||
args[0] = MP_OBJ_NEW_QSTR(dot_name_q);
|
||||
@@ -1375,6 +1382,13 @@ import_error:
|
||||
|
||||
// TODO lookup __import__ and call that instead of going straight to builtin implementation
|
||||
return mp_builtin___import__(5, args);
|
||||
|
||||
#else
|
||||
|
||||
// Package import not supported with external imports disabled
|
||||
goto import_error;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void mp_import_all(mp_obj_t module) {
|
||||
@@ -1468,3 +1482,10 @@ NORETURN void mp_raise_OSError(int errno_) {
|
||||
NORETURN void mp_raise_NotImplementedError(const char *msg) {
|
||||
mp_raise_msg(&mp_type_NotImplementedError, msg);
|
||||
}
|
||||
|
||||
#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)));
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user