diff --git a/src/core/error_handling.c b/src/core/error_handling.c index f1e62614384..779707f8bac 100644 --- a/src/core/error_handling.c +++ b/src/core/error_handling.c @@ -5,6 +5,7 @@ #include "error_handling.h" #include "jsproxy.h" #include "pyproxy.h" +#include "python2js.h" #include #include @@ -57,10 +58,10 @@ set_error(PyObject* err) EM_JS_REF( JsRef, new_error, -(const char* type, const char* msg, PyObject* err), +(JsRef type, JsRef msg, PyObject* err), { return Hiwire.new_value( - new API.PythonError(UTF8ToString(type), UTF8ToString(msg), err)); + new API.PythonError(Hiwire.get_value(type), Hiwire.get_value(msg), err)); }); // clang-format on @@ -192,21 +193,23 @@ wrap_exception() PyObject* type = NULL; PyObject* value = NULL; PyObject* traceback = NULL; - PyObject* typestr = NULL; + PyObject* py_typestr = NULL; + JsRef js_typestr = NULL; PyObject* pystr = NULL; + JsRef jsstr = NULL; JsRef jserror = NULL; fetch_and_normalize_exception(&type, &value, &traceback); store_sys_last_exception(type, value, traceback); - typestr = _PyObject_GetAttrId(type, &PyId___qualname__); - FAIL_IF_NULL(typestr); - const char* typestr_utf8 = PyUnicode_AsUTF8(typestr); - FAIL_IF_NULL(typestr_utf8); + py_typestr = _PyObject_GetAttrId(type, &PyId___qualname__); + FAIL_IF_NULL(py_typestr); + js_typestr = python2js(py_typestr); + FAIL_IF_NULL(js_typestr); pystr = format_exception_traceback(type, value, traceback); FAIL_IF_NULL(pystr); - const char* pystr_utf8 = PyUnicode_AsUTF8(pystr); - FAIL_IF_NULL(pystr_utf8); - jserror = new_error(typestr_utf8, pystr_utf8, value); + jsstr = python2js(pystr); + FAIL_IF_NULL(jsstr); + jserror = new_error(js_typestr, jsstr, value); FAIL_IF_NULL(jserror); success = true; @@ -220,13 +223,20 @@ wrap_exception() PySys_WriteStderr("\nOriginal exception was:\n"); PyErr_Display(type, value, traceback); } - jserror = new_error( - "PyodideInternalError", "Error occurred while formatting traceback", 0); + Js_static_string(InternalError, "PyodideInternalError"); + Js_static_string(error_formatting_tb, + "Error occurred while formatting traceback"); + jserror = new_error(JsString_FromId(&InternalError), + JsString_FromId(&error_formatting_tb), + 0); } Py_CLEAR(type); Py_CLEAR(value); Py_CLEAR(traceback); + Py_CLEAR(py_typestr); + hiwire_CLEAR(js_typestr); Py_CLEAR(pystr); + hiwire_CLEAR(jsstr); return jserror; } diff --git a/src/core/hiwire.c b/src/core/hiwire.c index 12e27706c0d..222e53dbb64 100644 --- a/src/core/hiwire.c +++ b/src/core/hiwire.c @@ -868,33 +868,23 @@ EM_JS_REF(JsRef, JsObject_Get, (JsRef idobj, JsRef idkey), { return Hiwire.new_value(result); }); -EM_JS_REF(JsRef, JsObject_GetString, (JsRef idobj, const char* ptrkey), { - const jsobj = Hiwire.get_value(idobj); - const jskey = normalizeReservedWords(UTF8ToString(ptrkey)); - const result = jsobj[jskey]; - // clang-format off - if (result === undefined && !(jskey in jsobj)) { - // clang-format on - return ERROR_REF; - } - return Hiwire.new_value(result); -}); - // clang-format off EM_JS_NUM(errcode, -JsObject_SetString, -(JsRef idobj, const char* ptrkey, JsRef idval), +JsObject_Set, +(JsRef idobj, JsRef idkey, JsRef idval), { - let jsobj = Hiwire.get_value(idobj); - let jskey = normalizeReservedWords(UTF8ToString(ptrkey)); - let jsval = Hiwire.get_value(idval); + const jsobj = Hiwire.get_value(idobj); + const key = Hiwire.get_value(idkey); + const jskey = normalizeReservedWords(key); + const jsval = Hiwire.get_value(idval); jsobj[jskey] = jsval; }); // clang-format on -EM_JS_NUM(errcode, JsObject_DeleteString, (JsRef idobj, const char* ptrkey), { - let jsobj = Hiwire.get_value(idobj); - let jskey = normalizeReservedWords(UTF8ToString(ptrkey)); +EM_JS_NUM(errcode, JsObject_Delete, (JsRef idobj, JsRef idkey), { + const jsobj = Hiwire.get_value(idobj); + const key = Hiwire.get_value(idkey); + const jskey = normalizeReservedWords(key); delete jsobj[jskey]; }); diff --git a/src/core/hiwire.h b/src/core/hiwire.h index d68226fd52d..eeb0c4769c6 100644 --- a/src/core/hiwire.h +++ b/src/core/hiwire.h @@ -510,15 +510,6 @@ JsArray_Clear(JsRef idobj); JsRef JsObject_New(); -/** - * Get an object member by string. - * - * - * Returns: New reference - */ -JsRef -JsObject_GetString(JsRef idobj, const char* ptrname); - JsRef JsObject_Get(JsRef idobj, JsRef name); @@ -526,13 +517,13 @@ JsObject_Get(JsRef idobj, JsRef name); * Set an object member by string. */ errcode WARN_UNUSED -JsObject_SetString(JsRef idobj, const char* ptrname, JsRef idval); +JsObject_Set(JsRef idobj, JsRef name, JsRef idval); /** * Delete an object member by string. */ errcode WARN_UNUSED -JsObject_DeleteString(JsRef idobj, const char* ptrname); +JsObject_Delete(JsRef idobj, JsRef name); /** * Get the methods on an object, both on itself and what it inherits. diff --git a/src/core/jsproxy.c b/src/core/jsproxy.c index 2cdc9021a52..e8ca3327cca 100644 --- a/src/core/jsproxy.c +++ b/src/core/jsproxy.c @@ -345,6 +345,7 @@ JsProxy_GetAttr(PyObject* self, PyObject* attr) FAIL(); } jskey = python2js(attr); + FAIL_IF_NULL(jskey); idresult = JsObject_Get(JsProxy_REF(self), jskey); if (idresult == NULL) { @@ -378,10 +379,10 @@ JsProxy_SetAttr(PyObject* self, PyObject* attr, PyObject* pyvalue) { bool success = false; JsRef idvalue = NULL; + JsRef jskey = NULL; const char* key = PyUnicode_AsUTF8(attr); FAIL_IF_NULL(key); - if (strncmp(key, "__", 2) == 0) { // Avoid creating reference loops between Python and JavaScript with js // modules. Such reference loops make it hard to avoid leaking memory. @@ -392,16 +393,21 @@ JsProxy_SetAttr(PyObject* self, PyObject* attr, PyObject* pyvalue) } } + jskey = python2js(attr); + FAIL_IF_NULL(jskey); + if (pyvalue == NULL) { - FAIL_IF_MINUS_ONE(JsObject_DeleteString(JsProxy_REF(self), key)); + FAIL_IF_MINUS_ONE(JsObject_Delete(JsProxy_REF(self), jskey)); } else { idvalue = python2js(pyvalue); - FAIL_IF_MINUS_ONE(JsObject_SetString(JsProxy_REF(self), key, idvalue)); + FAIL_IF_NULL(idvalue); + FAIL_IF_MINUS_ONE(JsObject_Set(JsProxy_REF(self), jskey, idvalue)); } success = true; finally: hiwire_CLEAR(idvalue); + hiwire_CLEAR(jskey); return success ? 0 : -1; } @@ -2904,6 +2910,7 @@ JsMethod_ConvertArgs(PyObject* const* args, JsRef idargs = NULL; JsRef idarg = NULL; JsRef idkwargs = NULL; + JsRef namejs = NULL; idargs = JsArray_New(); FAIL_IF_NULL(idargs); @@ -2934,10 +2941,12 @@ JsMethod_ConvertArgs(PyObject* const* args, Py_ssize_t nkwargs = PyTuple_Size(kwnames); for (Py_ssize_t i = 0, k = nargs; i < nkwargs; ++i, ++k) { PyObject* name = PyTuple_GET_ITEM(kwnames, i); /* borrowed! */ - const char* name_utf8 = PyUnicode_AsUTF8(name); + namejs = python2js(name); + FAIL_IF_NULL(namejs); idarg = python2js_track_proxies(args[k], proxies, false); FAIL_IF_NULL(idarg); - FAIL_IF_MINUS_ONE(JsObject_SetString(idkwargs, name_utf8, idarg)); + FAIL_IF_MINUS_ONE(JsObject_Set(idkwargs, namejs, idarg)); + hiwire_CLEAR(namejs); hiwire_CLEAR(idarg); } FAIL_IF_MINUS_ONE(JsArray_Push(idargs, idkwargs)); @@ -2947,6 +2956,7 @@ JsMethod_ConvertArgs(PyObject* const* args, finally: hiwire_CLEAR(idarg); hiwire_CLEAR(idkwargs); + hiwire_CLEAR(namejs); if (!success) { hiwire_CLEAR(idargs); }