...
 
Commits (17)
......@@ -46,7 +46,7 @@ STATIC mp_obj_t mod_rtems_timer_delete(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_rtems_timer_delete_obj, mod_rtems_timer_delete);
STATIC rtems_timer_service_routine f(rtems_id id, void* user_data) {
mp_printf(&mp_plat_print, "||| here %d %p\n", (int)id, user_data);
//mp_printf(&mp_plat_print, "||| here %d %p\n", (int)id, user_data);
((byte*)user_data)[0] = 0;
}
......
......@@ -6,6 +6,8 @@
* MicroPython to LEON platforms", contract number 4000114080/15/NL/FE/as.
*/
#include <string.h>
#include "py/nlr.h"
#include "py/compile.h"
#include "py/runtime.h"
......@@ -282,6 +284,8 @@ mp_import_stat_t mp_import_stat(const char *path) {
return MP_IMPORT_STAT_FILE;
}
}
#else
(void)path;
#endif
// the requested file is not found
......@@ -296,12 +300,15 @@ mp_raw_code_t *mp_raw_code_load_file(const char *filename) {
return rf->raw_code;
}
}
#else
(void)filename;
#endif
// the requested file is not found
nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "can't import"));
}
#if defined(MICROPY_SPARC_NUM_REG_WINDOWS)
// This is called by the memory manager when a garbage collection is needed.
void gc_collect(void) {
gc_collect_start();
......@@ -326,10 +333,11 @@ void gc_collect(void) {
gc_collect_end();
}
#endif
// This is called if there is no exception handler registered to catch an exception.
void nlr_jump_fail(void *val) {
mp_printf(&mp_plat_print, "fatal error: nlr_jump_fail\n");
mp_printf(&mp_plat_print, "FATAL: uncaught NLR %p\n", val);
for (;;) {
}
}
......
#include <stdint.h>
#include <math.h>
static const double toint = 4503599627370496.0; // 2**52
double nearbyint(double x) {
union { double f; uint64_t i; } u = {x};
int e = u.i >> 52 & 0x7ff;
int s = u.i >> 63;
if (e >= 0x3ff + 52) {
// Large enough that it doesn't have a fraction
} else if (s) {
x -= toint;
x += toint;
if (x == 0) {
x = -0.0;
}
} else {
x += toint;
x -= toint;
}
return x;
}
......@@ -48,6 +48,7 @@ SRC_C = \
lib/libc/strcmp.c \
lib/libc/strlen.c \
lib/libc/strncmp.c \
$(LEON_COMMON)/nearbyint.c \
$(LEON_COMMON)/mputil.c \
$(LEON_COMMON)/mphalport.c \
$(LEON_COMMON)/modtime.c \
......
......@@ -48,6 +48,7 @@ SRC_C = \
lib/libc/strcmp.c \
lib/libc/strlen.c \
lib/libc/strncmp.c \
$(LEON_COMMON)/nearbyint.c \
$(LEON_COMMON)/mputil.c \
$(LEON_COMMON)/mphalport.c \
$(LEON_COMMON)/modtime.c \
......
......@@ -202,12 +202,14 @@
// definitions specific to VM (vs cross-compiler)
#define MICROPY_ENABLE_COMPILER (0)
#define MICROPY_ENABLE_EXTERNAL_IMPORT (0)
#define MICROPY_READER_POSIX (0)
#define MICROPY_PERSISTENT_CODE_LOAD (1)
#define MICROPY_PERSISTENT_CODE_SAVE (0)
#define MICROPY_DYNAMIC_COMPILER (0)
#define MICROPY_USE_INTERNAL_PRINTF (0)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (0)
#define MICROPY_PY_MICROPYTHON_STACK_USE (1)
#define MICROPY_PY___FILE__ (1)
#define MICROPY_USE_INTERNAL_ERRNO (1)
......
......@@ -5,6 +5,7 @@ array('I', [1, 2, 3]) 3
1 -1
2
True
NotImplementedError
0
array('i')
False
......
......@@ -16,7 +16,11 @@ print(len(a), a[0])
a1 = array.array('l', [1, 2, 3])
a2 = array.array('L', [1, 2, 3])
print(a2[1])
print(a1 == a2)
print(a1 == array.array('l', [1, 2, 3]))
try:
print(a1 == a2)
except NotImplementedError:
print('NotImplementedError')
# Empty arrays
print(len(array.array('h')))
......
# test await expression
import sys
if sys.implementation.name == 'micropython':
if not hasattr(sys.implementation, 'name') or sys.implementation.name == 'micropython':
# uPy allows normal generators to be awaitables
coroutine = lambda f: f
else:
......
# test waiting within "async for" aiter/anext functions
import sys
if sys.implementation.name == 'micropython':
if not hasattr(sys.implementation, 'name') or sys.implementation.name == 'micropython':
# uPy allows normal generators to be awaitables
coroutine = lambda f: f
else:
......
# test waiting within async with enter/exit functions
import sys
if sys.implementation.name == 'micropython':
if not hasattr(sys.implementation, 'name') or sys.implementation.name == 'micropython':
# uPy allows normal generators to be awaitables
coroutine = lambda f: f
else:
......
......@@ -44,6 +44,8 @@
#define DEBUG_printf(...) (void)0
#endif
#if MICROPY_ENABLE_EXTERNAL_IMPORT
#define PATH_SEP_CHAR '/'
bool mp_obj_is_package(mp_obj_t module) {
......@@ -389,19 +391,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
}
// found weak linked module
module_obj = el->value;
if (MICROPY_MODULE_BUILTIN_INIT) {
// look for __init__ and call it if it exists
// Note: this code doesn't work fully correctly because it allows the
// __init__ function to be called twice if the module is imported by its
// non-weak-link name. Also, this code is duplicated in objmodule.c.
mp_obj_t dest[2];
mp_load_method_maybe(el->value, MP_QSTR___init__, dest);
if (dest[0] != MP_OBJ_NULL) {
mp_call_method_n_kw(0, 0, dest);
// register module so __init__ is not called again
mp_module_register(mod_name, el->value);
}
}
mp_module_call_init(mod_name, module_obj);
} else {
no_exist:
#else
......@@ -485,4 +475,41 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
// Otherwise, we need to return top-level package
return top_module_obj;
}
#else // MICROPY_ENABLE_EXTERNAL_IMPORT
mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
// Check that it's not a relative import
if (n_args >= 5 && MP_OBJ_SMALL_INT_VALUE(args[4]) != 0) {
mp_raise_NotImplementedError("relative import");
}
// Check if module already exists, and return it if it does
qstr module_name_qstr = mp_obj_str_get_qstr(args[0]);
mp_obj_t module_obj = mp_module_get(module_name_qstr);
if (module_obj != MP_OBJ_NULL) {
return module_obj;
}
#if MICROPY_MODULE_WEAK_LINKS
// Check if there is a weak link to this module
mp_map_elem_t *el = mp_map_lookup((mp_map_t*)&mp_builtin_module_weak_links_map, MP_OBJ_NEW_QSTR(module_name_qstr), MP_MAP_LOOKUP);
if (el != NULL) {
// Found weak-linked module
mp_module_call_init(module_name_qstr, el->value);
return el->value;
}
#endif
// Couldn't find the module, so fail
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
mp_raise_msg(&mp_type_ImportError, "module not found");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError,
"no module named '%q'", module_name_qstr));
}
}
#endif // MICROPY_ENABLE_EXTERNAL_IMPORT
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin___import___obj, 1, 5, mp_builtin___import__);
......@@ -104,15 +104,15 @@ STATIC mp_obj_t mp_micropython_qstr_info(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_micropython_qstr_info_obj, 0, 1, mp_micropython_qstr_info);
#if MICROPY_STACK_CHECK
#endif // MICROPY_PY_MICROPYTHON_MEM_INFO
#if MICROPY_PY_MICROPYTHON_STACK_USE
STATIC mp_obj_t mp_micropython_stack_use(void) {
return MP_OBJ_NEW_SMALL_INT(mp_stack_usage());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_stack_use_obj, mp_micropython_stack_use);
#endif
#endif // MICROPY_PY_MICROPYTHON_MEM_INFO
#if MICROPY_ENABLE_PYSTACK
STATIC mp_obj_t mp_micropython_pystack_use(void) {
return MP_OBJ_NEW_SMALL_INT(mp_pystack_usage());
......@@ -168,10 +168,10 @@ STATIC const mp_rom_map_elem_t mp_module_micropython_globals_table[] = {
#endif
{ MP_ROM_QSTR(MP_QSTR_mem_info), MP_ROM_PTR(&mp_micropython_mem_info_obj) },
{ MP_ROM_QSTR(MP_QSTR_qstr_info), MP_ROM_PTR(&mp_micropython_qstr_info_obj) },
#if MICROPY_STACK_CHECK
#endif
#if MICROPY_PY_MICROPYTHON_STACK_USE
{ MP_ROM_QSTR(MP_QSTR_stack_use), MP_ROM_PTR(&mp_micropython_stack_use_obj) },
#endif
#endif
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF && (MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE == 0)
{ MP_ROM_QSTR(MP_QSTR_alloc_emergency_exception_buf), MP_ROM_PTR(&mp_alloc_emergency_exception_buf_obj) },
#endif
......
......@@ -405,6 +405,13 @@
/*****************************************************************************/
/* Python internal features */
// Whether to enable import of external modules
// When disabled, only importing of built-in modules is supported
// When enabled, a port must implement mp_import_stat (among other things)
#ifndef MICROPY_ENABLE_EXTERNAL_IMPORT
#define MICROPY_ENABLE_EXTERNAL_IMPORT (1)
#endif
// Whether to use the POSIX reader for importing files
#ifndef MICROPY_READER_POSIX
#define MICROPY_READER_POSIX (0)
......@@ -905,6 +912,11 @@ typedef double mp_float_t;
#define MICROPY_PY_MICROPYTHON_MEM_INFO (0)
#endif
// Whether to provide "micropython.stack_use" function
#ifndef MICROPY_PY_MICROPYTHON_STACK_USE
#define MICROPY_PY_MICROPYTHON_STACK_USE (MICROPY_PY_MICROPYTHON_MEM_INFO)
#endif
// Whether to provide "array" module. Note that large chunk of the
// underlying code is shared with "bytearray" builtin type, so to
// get real savings, it should be disabled too.
......
......@@ -434,7 +434,7 @@ STATIC size_t mpn_mul(mpz_dig_t *idig, mpz_dig_t *jdig, size_t jlen, mpz_dig_t *
size_t jl = jlen;
for (mpz_dig_t *jd = jdig; jl > 0; --jl, ++jd, ++id) {
carry += (mpz_dbl_dig_t)*id + (mpz_dbl_dig_t)*jd * (mpz_dbl_dig_t)*kdig; // will never overflow so long as DIG_SIZE <= 8*sizeof(mpz_dbl_dig_t)/2
carry += (mpz_dbl_dig_t)*id + (mpz_dbl_dig_t)*jd * (mpz_dbl_dig_t)*kdig; // will never overflow so long as DIG_SIZE <= 8*sizeof(mpz_dbl_dig_t)/2 /* polyspace DEFECT:NULL_PTR [No action planned:Low] "jd won't be NULL; kdig won't be NULL" */
*id = carry & DIG_MASK;
carry >>= DIG_SIZE;
}
......@@ -1346,7 +1346,7 @@ void mpz_pow_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs) {
mpz_set_from_int(dest, 1);
while (n->len > 0) {
if ((n->dig[0] & 1) != 0) {
if ((n->dig[0] & 1) != 0) { /* polyspace DEFECT:NULL_PTR [No action planned:Low] "n->dig won't be NULL" */
mpz_mul_inpl(dest, dest, x);
}
n->len = mpn_shr(n->dig, n->dig, n->len, 1);
......@@ -1380,7 +1380,7 @@ void mpz_pow3_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs, const mpz_t
mpz_t quo; mpz_init_zero(&quo);
while (n->len > 0) {
if ((n->dig[0] & 1) != 0) {
if ((n->dig[0] & 1) != 0) { /* polyspace DEFECT:NULL_PTR [No action planned:Low] "n->dig won't be NULL" */
mpz_mul_inpl(dest, dest, x);
mpz_divmod_inpl(&quo, dest, dest, mod);
}
......
......@@ -301,7 +301,10 @@ STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs
if (!mp_get_buffer(rhs_in, &rhs_bufinfo, MP_BUFFER_READ)) {
return mp_const_false;
}
if (!MP_OBJ_IS_TYPE(rhs_in, &mp_type_array) || lhs_bufinfo.typecode != rhs_bufinfo.typecode) {
// Only allow: bytearray==bytes, bytearray==bytearray, array(T)==array(T)
if (!((lhs_bufinfo.typecode == BYTEARRAY_TYPECODE && MP_OBJ_IS_TYPE(rhs_in, &mp_type_bytes))
|| (lhs_bufinfo.typecode == BYTEARRAY_TYPECODE && rhs_bufinfo.typecode == BYTEARRAY_TYPECODE)
|| (MP_OBJ_IS_TYPE(rhs_in, &mp_type_array) && lhs_bufinfo.typecode == rhs_bufinfo.typecode))) {
mp_raise_NotImplementedError("array equality with different types");
}
return mp_obj_new_bool(mp_seq_cmp_bytes(op, lhs_bufinfo.buf, lhs_bufinfo.len, rhs_bufinfo.buf, rhs_bufinfo.len));
......
......@@ -215,9 +215,9 @@ STATIC void dump_args(const mp_obj_t *a, size_t sz) {
code_state->fun_bc = _fun_bc; \
code_state->ip = 0; \
uint8_t scope_flags = mp_setup_code_state(code_state, n_args, n_kw, args); \
/* set the scope flags for this function */ \
code_state->old_scope_flags = MP_STATE_THREAD(scope_flags); \
MP_STATE_THREAD(scope_flags) = scope_flags; \
code_state->old_globals = mp_globals_get(); \
#if MICROPY_STACKLESS
mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
......
......@@ -255,17 +255,7 @@ mp_obj_t mp_module_get(qstr module_name) {
#endif
return MP_OBJ_NULL;
}
if (MICROPY_MODULE_BUILTIN_INIT) {
// look for __init__ and call it if it exists
mp_obj_t dest[2];
mp_load_method_maybe(el->value, MP_QSTR___init__, dest);
if (dest[0] != MP_OBJ_NULL) {
mp_call_method_n_kw(0, 0, dest);
// register module so __init__ is not called again
mp_module_register(module_name, el->value);
}
}
mp_module_call_init(module_name, el->value);
}
// module found, return it
......@@ -276,3 +266,19 @@ void mp_module_register(qstr qst, mp_obj_t module) {
mp_map_t *mp_loaded_modules_map = &MP_STATE_VM(mp_loaded_modules_dict).map;
mp_map_lookup(mp_loaded_modules_map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = module;
}
#if MICROPY_MODULE_BUILTIN_INIT
void mp_module_call_init(qstr module_name, mp_obj_t module_obj) {
// Look for __init__ and call it if it exists
mp_obj_t dest[2];
mp_load_method_maybe(module_obj, MP_QSTR___init__, dest);
if (dest[0] != MP_OBJ_NULL) {
mp_call_method_n_kw(0, 0, dest);
// Register module so __init__ is not called again.
// If a module can be referenced by more than one name (eg due to weak links)
// then __init__ will still be called for each distinct import, and it's then
// up to the particular module to make sure it's __init__ code only runs once.
mp_module_register(module_name, module_obj);
}
}
#endif
......@@ -34,4 +34,13 @@ extern const mp_map_t mp_builtin_module_weak_links_map;
mp_obj_t mp_module_get(qstr module_name);
void mp_module_register(qstr qstr, mp_obj_t module);
#if MICROPY_MODULE_BUILTIN_INIT
void mp_module_call_init(qstr module_name, mp_obj_t module_obj);
#else
static inline void mp_module_call_init(qstr module_name, mp_obj_t module_obj) {
(void)module_name;
(void)module_obj;
}
#endif
#endif // MICROPY_INCLUDED_PY_OBJMODULE_H
......@@ -351,8 +351,8 @@ mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i
// easy to "fix" this with a bit of extra logic below, but it costs code
// size and execution time so we don't.
const byte *rhs_data;
size_t rhs_len;
const byte *rhs_data = NULL;
size_t rhs_len = 0;
if (lhs_type == mp_obj_get_type(rhs_in)) {
GET_STR_DATA_LEN(rhs_in, rhs_data_, rhs_len_);
rhs_data = rhs_data_;
......
......@@ -85,7 +85,7 @@ STATIC mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *args) {
mp_obj_instance_t *self = MP_OBJ_TO_PTR(args[0]);
const mp_obj_type_t *native_base = NULL;
instance_count_native_bases(self->base.type, &native_base);
self->subobj[0] = native_base->make_new(native_base, n_args - 1, 0, args + 1);
self->subobj[0] = native_base->make_new(native_base, n_args - 1, 0, args + 1); /* polyspace DEFECT:NULL_PTR [No action planned:Low] "native_base won't be NULL" */
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(native_base_init_wrapper_obj, 1, MP_OBJ_FUN_ARGS_MAX, native_base_init_wrapper);
......
......@@ -1343,6 +1343,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;
......@@ -1369,6 +1371,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) {
......