summaryrefslogtreecommitdiffstatshomepage
path: root/ports/unix/coverage.c
diff options
context:
space:
mode:
Diffstat (limited to 'ports/unix/coverage.c')
-rw-r--r--ports/unix/coverage.c90
1 files changed, 88 insertions, 2 deletions
diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c
index 2b65b47fc5..0df6bf279a 100644
--- a/ports/unix/coverage.c
+++ b/ports/unix/coverage.c
@@ -184,6 +184,18 @@ static void pairheap_test(size_t nops, int *ops) {
mp_printf(&mp_plat_print, "\n");
}
+static mp_sched_node_t mp_coverage_sched_node;
+static bool coverage_sched_function_continue;
+
+static void coverage_sched_function(mp_sched_node_t *node) {
+ (void)node;
+ mp_printf(&mp_plat_print, "scheduled function\n");
+ if (coverage_sched_function_continue) {
+ // Re-scheduling node will cause it to run again next time scheduled functions are run
+ mp_sched_schedule_node(&mp_coverage_sched_node, coverage_sched_function);
+ }
+}
+
// function to run extra tests for things that can't be checked by scripts
static mp_obj_t extra_coverage(void) {
// mp_printf (used by ports that don't have a native printf)
@@ -208,6 +220,7 @@ static mp_obj_t extra_coverage(void) {
mp_printf(&mp_plat_print, "%X\n", 0x80000000); // should print unsigned
mp_printf(&mp_plat_print, "abc\n%"); // string ends in middle of format specifier
mp_printf(&mp_plat_print, "%%\n"); // literal % character
+ mp_printf(&mp_plat_print, ".%-3s.\n", "a"); // left adjust
}
// GC
@@ -463,6 +476,38 @@ static mp_obj_t extra_coverage(void) {
mp_int_t value_signed;
mpz_as_int_checked(&mpz, &value_signed);
mp_printf(&mp_plat_print, "%d\n", (int)value_signed);
+
+ // hash the zero mpz integer
+ mpz_set_from_int(&mpz, 0);
+ mp_printf(&mp_plat_print, "%d\n", mpz_hash(&mpz));
+
+ // convert the mpz zero integer to int
+ mp_printf(&mp_plat_print, "%d\n", mpz_as_int_checked(&mpz, &value_signed));
+ mp_printf(&mp_plat_print, "%d\n", value_signed);
+
+ // mpz_set_from_float with 0 as argument
+ mpz_set_from_float(&mpz, 0);
+ mp_printf(&mp_plat_print, "%f\n", mpz_as_float(&mpz));
+
+ // convert a large integer value (stored in a mpz) to mp_uint_t and to ll;
+ mp_obj_t obj_bigint = mp_obj_new_int_from_uint((mp_uint_t)0xdeadbeef);
+ mp_printf(&mp_plat_print, "%x\n", mp_obj_get_uint(obj_bigint));
+ obj_bigint = mp_obj_new_int_from_ll(0xc0ffee777c0ffeell);
+ long long value_ll = mp_obj_get_ll(obj_bigint);
+ mp_printf(&mp_plat_print, "%x%08x\n", (uint32_t)(value_ll >> 32), (uint32_t)value_ll);
+
+ // convert a large integer value (stored via a struct object) to uint and to ll
+ // `deadbeef` global is an uctypes.struct defined by extra_coverage.py
+ obj_bigint = mp_load_global(MP_QSTR_deadbeef);
+ mp_printf(&mp_plat_print, "%x\n", mp_obj_get_uint(obj_bigint));
+ value_ll = mp_obj_get_ll(obj_bigint);
+ mp_printf(&mp_plat_print, "%x%08x\n", (uint32_t)(value_ll >> 32), (uint32_t)value_ll);
+
+ // convert a smaller integer value to mp_uint_t and to ll
+ obj_bigint = mp_obj_new_int_from_uint(0xc0ffee);
+ mp_printf(&mp_plat_print, "%x\n", mp_obj_get_uint(obj_bigint));
+ value_ll = mp_obj_get_ll(obj_bigint);
+ mp_printf(&mp_plat_print, "%x%08x\n", (uint32_t)(value_ll >> 32), (uint32_t)value_ll);
}
// runtime utils
@@ -480,7 +525,7 @@ static mp_obj_t extra_coverage(void) {
mp_call_function_2_protected(MP_OBJ_FROM_PTR(&mp_builtin_divmod_obj), mp_obj_new_str_from_cstr("abc"), mp_obj_new_str_from_cstr("abc"));
// mp_obj_int_get_checked with mp_obj_int_t that has a value that is a small integer
- mp_printf(&mp_plat_print, "%d\n", mp_obj_int_get_checked(mp_obj_int_new_mpz()));
+ mp_printf(&mp_plat_print, "%d\n", mp_obj_int_get_checked(MP_OBJ_FROM_PTR(mp_obj_int_new_mpz())));
// mp_obj_int_get_uint_checked with non-negative small-int
mp_printf(&mp_plat_print, "%d\n", (int)mp_obj_int_get_uint_checked(MP_OBJ_NEW_SMALL_INT(1)));
@@ -505,6 +550,22 @@ static mp_obj_t extra_coverage(void) {
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
}
+ // mp_obj_get_uint from a non-int object (should raise exception)
+ if (nlr_push(&nlr) == 0) {
+ mp_obj_get_uint(mp_const_none);
+ nlr_pop();
+ } else {
+ mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
+ }
+
+ // mp_obj_int_get_ll from a non-int object (should raise exception)
+ if (nlr_push(&nlr) == 0) {
+ mp_obj_get_ll(mp_const_none);
+ nlr_pop();
+ } else {
+ mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
+ }
+
// call mp_obj_new_exception_args (it's a part of the public C API and not used in the core)
mp_obj_print_exception(&mp_plat_print, mp_obj_new_exception_args(&mp_type_ValueError, 0, NULL));
}
@@ -557,12 +618,24 @@ static mp_obj_t extra_coverage(void) {
fun_bc.context = &context;
fun_bc.child_table = NULL;
fun_bc.bytecode = (const byte *)"\x01"; // just needed for n_state
+ #if MICROPY_PY_SYS_SETTRACE
+ struct _mp_raw_code_t rc = {};
+ fun_bc.rc = &rc;
+ #endif
mp_code_state_t *code_state = m_new_obj_var(mp_code_state_t, state, mp_obj_t, 1);
code_state->fun_bc = &fun_bc;
code_state->ip = (const byte *)"\x00"; // just needed for an invalid opcode
code_state->sp = &code_state->state[0];
code_state->exc_sp_idx = 0;
code_state->old_globals = NULL;
+ #if MICROPY_STACKLESS
+ code_state->prev = NULL;
+ #endif
+ #if MICROPY_PY_SYS_SETTRACE
+ code_state->prev_state = NULL;
+ code_state->frame = NULL;
+ #endif
+
mp_vm_return_kind_t ret = mp_execute_bytecode(code_state, MP_OBJ_NULL);
mp_printf(&mp_plat_print, "%d %d\n", ret, mp_obj_get_type(code_state->state[0]) == &mp_type_NotImplementedError);
}
@@ -621,6 +694,19 @@ static mp_obj_t extra_coverage(void) {
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
}
mp_handle_pending(true);
+
+ coverage_sched_function_continue = true;
+ mp_sched_schedule_node(&mp_coverage_sched_node, coverage_sched_function);
+ for (int i = 0; i < 3; ++i) {
+ mp_printf(&mp_plat_print, "loop\n");
+ mp_handle_pending(true);
+ }
+ // Clear this flag to prevent the function scheduling itself again
+ coverage_sched_function_continue = false;
+ // Will only run the first time through this loop, then not scheduled again
+ for (int i = 0; i < 3; ++i) {
+ mp_handle_pending(true);
+ }
}
// ringbuf
@@ -794,7 +880,7 @@ static mp_obj_t extra_coverage(void) {
mp_obj_streamtest_t *s2 = mp_obj_malloc(mp_obj_streamtest_t, &mp_type_stest_textio2);
// return a tuple of data for testing on the Python side
- mp_obj_t items[] = {(mp_obj_t)&str_no_hash_obj, (mp_obj_t)&bytes_no_hash_obj, MP_OBJ_FROM_PTR(s), MP_OBJ_FROM_PTR(s2)};
+ mp_obj_t items[] = {MP_OBJ_FROM_PTR(&str_no_hash_obj), MP_OBJ_FROM_PTR(&bytes_no_hash_obj), MP_OBJ_FROM_PTR(s), MP_OBJ_FROM_PTR(s2)};
return mp_obj_new_tuple(MP_ARRAY_SIZE(items), items);
}
MP_DEFINE_CONST_FUN_OBJ_0(extra_coverage_obj, extra_coverage);