kopia lustrzana https://github.com/micropython/micropython
Merge fb4cde3060
into c3301da176
commit
6ee3bf2940
|
@ -75,7 +75,7 @@ class ThenableEvent:
|
|||
self.waiting = None # Task waiting on completion of this thenable
|
||||
thenable.then(self.set)
|
||||
|
||||
def set(self, value):
|
||||
def set(self, value=None):
|
||||
# Thenable/Promise is fulfilled, set result and schedule any waiting task.
|
||||
self.result = value
|
||||
if self.waiting:
|
||||
|
|
|
@ -58,6 +58,8 @@ enum {
|
|||
PROXY_KIND_JS_PYPROXY = 7,
|
||||
};
|
||||
|
||||
static MP_DEFINE_EXCEPTION(JsException, Exception)
|
||||
|
||||
void proxy_c_init(void) {
|
||||
MP_STATE_PORT(proxy_c_ref) = mp_obj_new_list(0, NULL);
|
||||
mp_obj_list_append(MP_STATE_PORT(proxy_c_ref), MP_OBJ_NULL);
|
||||
|
@ -120,6 +122,15 @@ void proxy_convert_mp_to_js_obj_cside(mp_obj_t obj, uint32_t *out) {
|
|||
} else if (mp_obj_is_jsproxy(obj)) {
|
||||
kind = PROXY_KIND_MP_JSPROXY;
|
||||
out[1] = mp_obj_jsproxy_get_ref(obj);
|
||||
} else if (mp_obj_get_type(obj) == &mp_type_JsException) {
|
||||
mp_obj_exception_t *exc = MP_OBJ_TO_PTR(obj);
|
||||
if (exc->args->len > 0 && mp_obj_is_jsproxy(exc->args->items[0])) {
|
||||
kind = PROXY_KIND_MP_JSPROXY;
|
||||
out[1] = mp_obj_jsproxy_get_ref(exc->args->items[0]);
|
||||
} else {
|
||||
kind = PROXY_KIND_MP_OBJECT;
|
||||
out[1] = proxy_c_add_obj(obj);
|
||||
}
|
||||
} else {
|
||||
if (mp_obj_is_callable(obj)) {
|
||||
kind = PROXY_KIND_MP_CALLABLE;
|
||||
|
@ -151,7 +162,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) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_obj_t args[4] = { mp_const_none, mp_const_none, mp_const_none, mp_const_none };
|
||||
mp_obj_t args[n_args];
|
||||
for (size_t i = 0; i < n_args; ++i) {
|
||||
args[i] = proxy_convert_js_to_mp_obj_cside(args_value + i * 3);
|
||||
}
|
||||
|
@ -288,6 +299,24 @@ void proxy_c_to_js_get_dict(uint32_t c_ref, uint32_t *out) {
|
|||
out[1] = (uintptr_t)map->table;
|
||||
}
|
||||
|
||||
EM_JS(void, js_get_error_info, (int jsref, uint32_t * out_name, uint32_t * out_message), {
|
||||
const error = proxy_js_ref[jsref];
|
||||
proxy_convert_js_to_mp_obj_jsside(error.name, out_name);
|
||||
proxy_convert_js_to_mp_obj_jsside(error.message, out_message);
|
||||
});
|
||||
|
||||
mp_obj_t mp_obj_jsproxy_make_js_exception(mp_obj_t error) {
|
||||
uint32_t out_name[PVN];
|
||||
uint32_t out_message[PVN];
|
||||
js_get_error_info(mp_obj_jsproxy_get_ref(error), out_name, out_message);
|
||||
mp_obj_t args[3] = {
|
||||
error,
|
||||
proxy_convert_js_to_mp_obj_cside(out_name),
|
||||
proxy_convert_js_to_mp_obj_cside(out_message),
|
||||
};
|
||||
return mp_obj_new_exception_args(&mp_type_JsException, MP_ARRAY_SIZE(args), args);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Bridge Python iterator to JavaScript iterator protocol.
|
||||
|
||||
|
@ -371,6 +400,12 @@ static mp_obj_t proxy_resume_execute(mp_obj_t self_in, mp_obj_t send_value, mp_o
|
|||
if (send_value == mp_const_none) {
|
||||
send_value = MP_OBJ_NULL;
|
||||
}
|
||||
// Ensure that the `throw_value` is a proper Python exception instance.
|
||||
if (mp_obj_is_jsproxy(throw_value)) {
|
||||
throw_value = mp_obj_jsproxy_make_js_exception(throw_value);
|
||||
} else {
|
||||
throw_value = mp_make_raise_obj(throw_value);
|
||||
}
|
||||
} else {
|
||||
throw_value = MP_OBJ_NULL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// Test an asyncio task await'ing on a Promise that's resolved without an argument.
|
||||
|
||||
const mp = await (await import(process.argv[2])).loadMicroPython();
|
||||
|
||||
globalThis.foo = new Promise((resolve) => {
|
||||
console.log(1);
|
||||
resolve(); // resolve without an argument
|
||||
console.log(2);
|
||||
});
|
||||
|
||||
mp.runPython(`
|
||||
import asyncio
|
||||
import js
|
||||
|
||||
async def task():
|
||||
print(3)
|
||||
print(await js.foo)
|
||||
print(4)
|
||||
|
||||
asyncio.create_task(task())
|
||||
`);
|
|
@ -0,0 +1,5 @@
|
|||
1
|
||||
2
|
||||
3
|
||||
None
|
||||
4
|
|
@ -0,0 +1,22 @@
|
|||
// Test await'ing on a JavaScript async function that throws a JavaScript Error.
|
||||
|
||||
const mp = await (await import(process.argv[2])).loadMicroPython();
|
||||
|
||||
globalThis.foo = async () => {
|
||||
console.log(2);
|
||||
throw Error("test");
|
||||
};
|
||||
|
||||
await mp.runPythonAsync(`
|
||||
import js
|
||||
print(1)
|
||||
try:
|
||||
await js.foo()
|
||||
except Exception as er:
|
||||
error = er
|
||||
print(error)
|
||||
print(3)
|
||||
`);
|
||||
|
||||
const error = mp.globals.get("error");
|
||||
console.log(error instanceof Error, error.name, error.message);
|
|
@ -0,0 +1,5 @@
|
|||
1
|
||||
2
|
||||
(<JsProxy 6>, 'Error', 'test')
|
||||
3
|
||||
true Error test
|
Ładowanie…
Reference in New Issue