mirror of
https://github.com/micropython/micropython.git
synced 2025-07-21 21:11:12 +02:00
webassembly: Track the current depth of calls to external C functions.
So it's possible to know when an external C function is being called at the top-level, eg by JavaScript without any intermediate C->JS->C calls. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -44,6 +44,19 @@
|
|||||||
#include "library.h"
|
#include "library.h"
|
||||||
#include "proxy_c.h"
|
#include "proxy_c.h"
|
||||||
|
|
||||||
|
// This counter tracks the current depth of calls into C code that originated
|
||||||
|
// externally, ie from JavaScript. When the counter is 0 that corresponds to
|
||||||
|
// the top-level call into C.
|
||||||
|
static size_t external_call_depth = 0;
|
||||||
|
|
||||||
|
void external_call_depth_inc(void) {
|
||||||
|
++external_call_depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void external_call_depth_dec(void) {
|
||||||
|
--external_call_depth;
|
||||||
|
}
|
||||||
|
|
||||||
void mp_js_init(int heap_size) {
|
void mp_js_init(int heap_size) {
|
||||||
#if MICROPY_ENABLE_GC
|
#if MICROPY_ENABLE_GC
|
||||||
char *heap = (char *)malloc(heap_size * sizeof(char));
|
char *heap = (char *)malloc(heap_size * sizeof(char));
|
||||||
@@ -79,6 +92,7 @@ void mp_js_register_js_module(const char *name, uint32_t *value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void mp_js_do_import(const char *name, uint32_t *out) {
|
void mp_js_do_import(const char *name, uint32_t *out) {
|
||||||
|
external_call_depth_inc();
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
mp_obj_t ret = mp_import_name(qstr_from_str(name), mp_const_none, MP_OBJ_NEW_SMALL_INT(0));
|
mp_obj_t ret = mp_import_name(qstr_from_str(name), mp_const_none, MP_OBJ_NEW_SMALL_INT(0));
|
||||||
@@ -97,9 +111,11 @@ void mp_js_do_import(const char *name, uint32_t *out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_obj_cside(ret, out);
|
proxy_convert_mp_to_js_obj_cside(ret, out);
|
||||||
} else {
|
} else {
|
||||||
// uncaught exception
|
// uncaught exception
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, out);
|
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,6 +125,7 @@ void mp_js_do_exec(const char *src, size_t len, uint32_t *out) {
|
|||||||
gc_collect_start();
|
gc_collect_start();
|
||||||
gc_collect_end();
|
gc_collect_end();
|
||||||
|
|
||||||
|
external_call_depth_inc();
|
||||||
mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT;
|
mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT;
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
@@ -118,9 +135,11 @@ void mp_js_do_exec(const char *src, size_t len, uint32_t *out) {
|
|||||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, false);
|
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, false);
|
||||||
mp_obj_t ret = mp_call_function_0(module_fun);
|
mp_obj_t ret = mp_call_function_0(module_fun);
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_obj_cside(ret, out);
|
proxy_convert_mp_to_js_obj_cside(ret, out);
|
||||||
} else {
|
} else {
|
||||||
// uncaught exception
|
// uncaught exception
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, out);
|
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,7 +155,10 @@ void mp_js_repl_init(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int mp_js_repl_process_char(int c) {
|
int mp_js_repl_process_char(int c) {
|
||||||
return pyexec_event_repl_process_char(c);
|
external_call_depth_inc();
|
||||||
|
int ret = pyexec_event_repl_process_char(c);
|
||||||
|
external_call_depth_dec();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MICROPY_GC_SPLIT_HEAP_AUTO
|
#if MICROPY_GC_SPLIT_HEAP_AUTO
|
||||||
|
@@ -176,6 +176,7 @@ void proxy_convert_mp_to_js_exc_cside(void *exc, uint32_t *out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void proxy_c_to_js_call(uint32_t c_ref, uint32_t n_args, uint32_t *args_value, uint32_t *out) {
|
void proxy_c_to_js_call(uint32_t c_ref, uint32_t n_args, uint32_t *args_value, uint32_t *out) {
|
||||||
|
external_call_depth_inc();
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
mp_obj_t args[n_args];
|
mp_obj_t args[n_args];
|
||||||
@@ -185,14 +186,17 @@ void proxy_c_to_js_call(uint32_t c_ref, uint32_t n_args, uint32_t *args_value, u
|
|||||||
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
||||||
mp_obj_t member = mp_call_function_n_kw(obj, n_args, 0, args);
|
mp_obj_t member = mp_call_function_n_kw(obj, n_args, 0, args);
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_obj_cside(member, out);
|
proxy_convert_mp_to_js_obj_cside(member, out);
|
||||||
} else {
|
} else {
|
||||||
// uncaught exception
|
// uncaught exception
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, out);
|
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void proxy_c_to_js_dir(uint32_t c_ref, uint32_t *out) {
|
void proxy_c_to_js_dir(uint32_t c_ref, uint32_t *out) {
|
||||||
|
external_call_depth_inc();
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
||||||
@@ -210,9 +214,11 @@ void proxy_c_to_js_dir(uint32_t c_ref, uint32_t *out) {
|
|||||||
dir = mp_builtin_dir_obj.fun.var(1, args);
|
dir = mp_builtin_dir_obj.fun.var(1, args);
|
||||||
}
|
}
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_obj_cside(dir, out);
|
proxy_convert_mp_to_js_obj_cside(dir, out);
|
||||||
} else {
|
} else {
|
||||||
// uncaught exception
|
// uncaught exception
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, out);
|
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,6 +241,7 @@ bool proxy_c_to_js_has_attr(uint32_t c_ref, const char *attr_in) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void proxy_c_to_js_lookup_attr(uint32_t c_ref, const char *attr_in, uint32_t *out) {
|
void proxy_c_to_js_lookup_attr(uint32_t c_ref, const char *attr_in, uint32_t *out) {
|
||||||
|
external_call_depth_inc();
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
||||||
@@ -255,19 +262,27 @@ void proxy_c_to_js_lookup_attr(uint32_t c_ref, const char *attr_in, uint32_t *ou
|
|||||||
member = mp_load_attr(obj, attr);
|
member = mp_load_attr(obj, attr);
|
||||||
}
|
}
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_obj_cside(member, out);
|
proxy_convert_mp_to_js_obj_cside(member, out);
|
||||||
} else {
|
} else {
|
||||||
// uncaught exception
|
// uncaught exception
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, out);
|
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool proxy_c_to_js_store_helper(uint32_t c_ref, const char *attr_in, mp_obj_t value) {
|
static bool proxy_c_to_js_store_helper(uint32_t c_ref, const char *attr_in, uint32_t *value_in) {
|
||||||
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
external_call_depth_inc();
|
||||||
qstr attr = qstr_from_str(attr_in);
|
|
||||||
|
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
|
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
||||||
|
qstr attr = qstr_from_str(attr_in);
|
||||||
|
|
||||||
|
mp_obj_t value = MP_OBJ_NULL;
|
||||||
|
if (value_in != NULL) {
|
||||||
|
value = proxy_convert_js_to_mp_obj_cside(value_in);
|
||||||
|
}
|
||||||
|
|
||||||
if (mp_obj_is_dict_or_ordereddict(obj)) {
|
if (mp_obj_is_dict_or_ordereddict(obj)) {
|
||||||
if (value == MP_OBJ_NULL) {
|
if (value == MP_OBJ_NULL) {
|
||||||
mp_obj_dict_delete(obj, MP_OBJ_NEW_QSTR(attr));
|
mp_obj_dict_delete(obj, MP_OBJ_NEW_QSTR(attr));
|
||||||
@@ -278,20 +293,21 @@ static bool proxy_c_to_js_store_helper(uint32_t c_ref, const char *attr_in, mp_o
|
|||||||
mp_store_attr(obj, attr, value);
|
mp_store_attr(obj, attr, value);
|
||||||
}
|
}
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
|
external_call_depth_dec();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// uncaught exception
|
// uncaught exception
|
||||||
|
external_call_depth_dec();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool proxy_c_to_js_store_attr(uint32_t c_ref, const char *attr_in, uint32_t *value_in) {
|
bool proxy_c_to_js_store_attr(uint32_t c_ref, const char *attr_in, uint32_t *value_in) {
|
||||||
mp_obj_t value = proxy_convert_js_to_mp_obj_cside(value_in);
|
return proxy_c_to_js_store_helper(c_ref, attr_in, value_in);
|
||||||
return proxy_c_to_js_store_helper(c_ref, attr_in, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool proxy_c_to_js_delete_attr(uint32_t c_ref, const char *attr_in) {
|
bool proxy_c_to_js_delete_attr(uint32_t c_ref, const char *attr_in) {
|
||||||
return proxy_c_to_js_store_helper(c_ref, attr_in, MP_OBJ_NULL);
|
return proxy_c_to_js_store_helper(c_ref, attr_in, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t proxy_c_to_js_get_type(uint32_t c_ref) {
|
uint32_t proxy_c_to_js_get_type(uint32_t c_ref) {
|
||||||
@@ -352,18 +368,22 @@ uint32_t proxy_c_to_js_get_iter(uint32_t c_ref) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool proxy_c_to_js_iternext(uint32_t c_ref, uint32_t *out) {
|
bool proxy_c_to_js_iternext(uint32_t c_ref, uint32_t *out) {
|
||||||
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
external_call_depth_inc();
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
|
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
||||||
mp_obj_t iter = mp_iternext_allow_raise(obj);
|
mp_obj_t iter = mp_iternext_allow_raise(obj);
|
||||||
if (iter == MP_OBJ_STOP_ITERATION) {
|
if (iter == MP_OBJ_STOP_ITERATION) {
|
||||||
|
external_call_depth_dec();
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_obj_cside(iter, out);
|
proxy_convert_mp_to_js_obj_cside(iter, out);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
external_call_depth_dec();
|
||||||
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))) {
|
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 false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@@ -475,6 +495,7 @@ static mp_obj_t resume_fun(size_t n_args, const mp_obj_t *args) {
|
|||||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(resume_obj, 5, 5, resume_fun);
|
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(resume_obj, 5, 5, resume_fun);
|
||||||
|
|
||||||
void proxy_c_to_js_resume(uint32_t c_ref, uint32_t *args) {
|
void proxy_c_to_js_resume(uint32_t c_ref, uint32_t *args) {
|
||||||
|
external_call_depth_inc();
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
if (nlr_push(&nlr) == 0) {
|
if (nlr_push(&nlr) == 0) {
|
||||||
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
mp_obj_t obj = proxy_c_get_obj(c_ref);
|
||||||
@@ -482,9 +503,11 @@ void proxy_c_to_js_resume(uint32_t c_ref, uint32_t *args) {
|
|||||||
mp_obj_t reject = proxy_convert_js_to_mp_obj_cside(args + 2 * 3);
|
mp_obj_t reject = proxy_convert_js_to_mp_obj_cside(args + 2 * 3);
|
||||||
mp_obj_t ret = proxy_resume_execute(obj, mp_const_none, mp_const_none, resolve, reject);
|
mp_obj_t ret = proxy_resume_execute(obj, mp_const_none, mp_const_none, resolve, reject);
|
||||||
nlr_pop();
|
nlr_pop();
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_obj_cside(ret, args);
|
proxy_convert_mp_to_js_obj_cside(ret, args);
|
||||||
} else {
|
} else {
|
||||||
// uncaught exception
|
// uncaught exception
|
||||||
|
external_call_depth_dec();
|
||||||
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, args);
|
proxy_convert_mp_to_js_exc_cside(nlr.ret_val, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,9 @@ typedef struct _mp_obj_jsproxy_t {
|
|||||||
extern const mp_obj_type_t mp_type_jsproxy;
|
extern const mp_obj_type_t mp_type_jsproxy;
|
||||||
extern const mp_obj_type_t mp_type_JsException;
|
extern const mp_obj_type_t mp_type_JsException;
|
||||||
|
|
||||||
|
void external_call_depth_inc(void);
|
||||||
|
void external_call_depth_dec(void);
|
||||||
|
|
||||||
void proxy_c_init(void);
|
void proxy_c_init(void);
|
||||||
mp_obj_t proxy_convert_js_to_mp_obj_cside(uint32_t *value);
|
mp_obj_t proxy_convert_js_to_mp_obj_cside(uint32_t *value);
|
||||||
void proxy_convert_mp_to_js_obj_cside(mp_obj_t obj, uint32_t *out);
|
void proxy_convert_mp_to_js_obj_cside(mp_obj_t obj, uint32_t *out);
|
||||||
|
Reference in New Issue
Block a user