mirror of https://github.com/pyodide/pyodide.git
EM_JS wrappers to convert calls to use Python error conventions (#1051)
This commit is contained in:
parent
6ef0ebbfdf
commit
a58c8d7186
1
Makefile
1
Makefile
|
@ -56,6 +56,7 @@ all: check \
|
|||
|
||||
build/pyodide.asm.js: src/core/main.o src/core/jsimport.o \
|
||||
src/core/jsproxy.o src/core/js2python.o \
|
||||
src/core/error_handling.o \
|
||||
src/core/pyproxy.o \
|
||||
src/core/python2js.o \
|
||||
src/core/python2js_buffer.o \
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#include "error_handling.h"
|
||||
#include "Python.h"
|
||||
#include "hiwire.h"
|
||||
#include "jsproxy.h"
|
||||
#include <emscripten.h>
|
||||
|
||||
void
|
||||
PyodideErr_SetJsError(JsRef err)
|
||||
{
|
||||
PyObject* py_err = JsProxy_new_error(err);
|
||||
PyErr_SetObject((PyObject*)(py_err->ob_type), py_err);
|
||||
}
|
||||
|
||||
int
|
||||
error_handling_init()
|
||||
{
|
||||
EM_ASM({
|
||||
Module.handle_js_error = function(e){
|
||||
let err = Module.hiwire.new_value(e);
|
||||
PyodideErr_SetJsError(err);
|
||||
Module.hiwire.decref(err);
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef ERROR_HANDLING_H
|
||||
#define ERROR_HANDLING_H
|
||||
|
||||
/** Wrap EM_JS so that it produces functions that follow the Python return
|
||||
* conventions. We catch javascript errors and proxy them and use
|
||||
* `PyErr_SetObject` to hand them off to python. We need two variants, one
|
||||
* for functions that return pointers / references (return 0)
|
||||
* the other for functions that return numbers (return -1).
|
||||
*/
|
||||
|
||||
typedef int errcode;
|
||||
|
||||
// Hiwire wants to import us for errcode, so import hiwire after typedef.
|
||||
#include "hiwire.h"
|
||||
#include <emscripten.h>
|
||||
|
||||
int
|
||||
error_handling_init();
|
||||
|
||||
// WARNING: These wrappers around EM_JS cause macros in body to be expanded.
|
||||
// This causes trouble with true and false.
|
||||
// In types.h we provide nonstandard definitions:
|
||||
// false ==> (!!0)
|
||||
// true ==> (!!1)
|
||||
// These work as expected in both C and javascript.
|
||||
|
||||
// clang-format off
|
||||
#define EM_JS_REF(ret, func_name, args, body...) \
|
||||
EM_JS(ret, func_name, args, { \
|
||||
/* "use strict"; TODO: enable this. */ \
|
||||
try /* intentionally no braces, body already has them */ \
|
||||
body /* <== body of func */ \
|
||||
catch (e) { \
|
||||
/* Dummied out until calling code is ready to catch these errors */ \
|
||||
throw e; \
|
||||
Module.handle_js_error(e); \
|
||||
return 0; \
|
||||
} \
|
||||
})
|
||||
|
||||
#define EM_JS_NUM(ret, func_name, args, body...) \
|
||||
EM_JS(ret, func_name, args, { \
|
||||
/* "use strict"; TODO: enable this. */ \
|
||||
try /* intentionally no braces, body already has them */ \
|
||||
body /* <== body of func */ \
|
||||
catch (e) { \
|
||||
/* Dummied out until calling code is ready to catch these errors */ \
|
||||
throw e; \
|
||||
Module.handle_js_error(e); \
|
||||
return -1; \
|
||||
} \
|
||||
})
|
||||
// clang-format on
|
||||
|
||||
#endif // ERROR_HANDLING_H
|
|
@ -1,3 +1,4 @@
|
|||
#include "error_handling.h"
|
||||
#include <emscripten.h>
|
||||
|
||||
#include "hiwire.h"
|
||||
|
@ -102,7 +103,7 @@ EM_JS(int, hiwire_init, (), {
|
|||
return 0;
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_incref, (JsRef idval), {
|
||||
EM_JS_REF(JsRef, hiwire_incref, (JsRef idval), {
|
||||
// clang-format off
|
||||
if ((idval & 1) === 0) {
|
||||
// least significant bit unset ==> idval is a singleton.
|
||||
|
@ -113,15 +114,19 @@ EM_JS(JsRef, hiwire_incref, (JsRef idval), {
|
|||
return Module.hiwire.new_value(Module.hiwire.get_value(idval));
|
||||
});
|
||||
|
||||
EM_JS(void, hiwire_decref, (JsRef idval), { Module.hiwire.decref(idval); });
|
||||
EM_JS_NUM(errcode, hiwire_decref, (JsRef idval), {
|
||||
Module.hiwire.decref(idval);
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_int, (int val), { return Module.hiwire.new_value(val); });
|
||||
|
||||
EM_JS(JsRef, hiwire_double, (double val), {
|
||||
EM_JS_REF(JsRef, hiwire_int, (int val), {
|
||||
return Module.hiwire.new_value(val);
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_string_ucs4, (const char* ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_double, (double val), {
|
||||
return Module.hiwire.new_value(val);
|
||||
});
|
||||
|
||||
EM_JS_REF(JsRef, hiwire_string_ucs4, (const char* ptr, int len), {
|
||||
var jsstr = "";
|
||||
var idx = ptr / 4;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
|
@ -130,7 +135,7 @@ EM_JS(JsRef, hiwire_string_ucs4, (const char* ptr, int len), {
|
|||
return Module.hiwire.new_value(jsstr);
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_string_ucs2, (const char* ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_string_ucs2, (const char* ptr, int len), {
|
||||
var jsstr = "";
|
||||
var idx = ptr / 2;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
|
@ -139,7 +144,7 @@ EM_JS(JsRef, hiwire_string_ucs2, (const char* ptr, int len), {
|
|||
return Module.hiwire.new_value(jsstr);
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_string_ucs1, (const char* ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_string_ucs1, (const char* ptr, int len), {
|
||||
var jsstr = "";
|
||||
var idx = ptr;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
|
@ -148,81 +153,84 @@ EM_JS(JsRef, hiwire_string_ucs1, (const char* ptr, int len), {
|
|||
return Module.hiwire.new_value(jsstr);
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_string_utf8, (const char* ptr), {
|
||||
EM_JS_REF(JsRef, hiwire_string_utf8, (const char* ptr), {
|
||||
return Module.hiwire.new_value(UTF8ToString(ptr));
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_string_ascii, (const char* ptr), {
|
||||
EM_JS_REF(JsRef, hiwire_string_ascii, (const char* ptr), {
|
||||
return Module.hiwire.new_value(AsciiToString(ptr));
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_bytes, (char* ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_bytes, (char* ptr, int len), {
|
||||
var bytes = new Uint8ClampedArray(Module.HEAPU8.buffer, ptr, len);
|
||||
return Module.hiwire.new_value(bytes);
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_int8array, (i8 * ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_int8array, (i8 * ptr, int len), {
|
||||
var array = new Int8Array(Module.HEAPU8.buffer, ptr, len);
|
||||
return Module.hiwire.new_value(array);
|
||||
})
|
||||
|
||||
EM_JS(JsRef, hiwire_uint8array, (u8 * ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_uint8array, (u8 * ptr, int len), {
|
||||
var array = new Uint8Array(Module.HEAPU8.buffer, ptr, len);
|
||||
return Module.hiwire.new_value(array);
|
||||
})
|
||||
|
||||
EM_JS(JsRef, hiwire_int16array, (i16 * ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_int16array, (i16 * ptr, int len), {
|
||||
var array = new Int16Array(Module.HEAPU8.buffer, ptr, len);
|
||||
return Module.hiwire.new_value(array);
|
||||
})
|
||||
|
||||
EM_JS(JsRef, hiwire_uint16array, (u16 * ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_uint16array, (u16 * ptr, int len), {
|
||||
var array = new Uint16Array(Module.HEAPU8.buffer, ptr, len);
|
||||
return Module.hiwire.new_value(array);
|
||||
})
|
||||
|
||||
EM_JS(JsRef, hiwire_int32array, (i32 * ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_int32array, (i32 * ptr, int len), {
|
||||
var array = new Int32Array(Module.HEAPU8.buffer, ptr, len);
|
||||
return Module.hiwire.new_value(array);
|
||||
})
|
||||
|
||||
EM_JS(JsRef, hiwire_uint32array, (u32 * ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_uint32array, (u32 * ptr, int len), {
|
||||
var array = new Uint32Array(Module.HEAPU8.buffer, ptr, len);
|
||||
return Module.hiwire.new_value(array);
|
||||
})
|
||||
|
||||
EM_JS(JsRef, hiwire_float32array, (f32 * ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_float32array, (f32 * ptr, int len), {
|
||||
var array = new Float32Array(Module.HEAPU8.buffer, ptr, len);
|
||||
return Module.hiwire.new_value(array);
|
||||
})
|
||||
|
||||
EM_JS(JsRef, hiwire_float64array, (f64 * ptr, int len), {
|
||||
EM_JS_REF(JsRef, hiwire_float64array, (f64 * ptr, int len), {
|
||||
var array = new Float64Array(Module.HEAPU8.buffer, ptr, len);
|
||||
return Module.hiwire.new_value(array);
|
||||
})
|
||||
|
||||
EM_JS(void, hiwire_throw_error, (JsRef idmsg), {
|
||||
EM_JS_NUM(errcode, hiwire_throw_error, (JsRef idmsg), {
|
||||
var jsmsg = Module.hiwire.get_value(idmsg);
|
||||
Module.hiwire.decref(idmsg);
|
||||
throw new Error(jsmsg);
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_array, (), { return Module.hiwire.new_value([]); });
|
||||
EM_JS_REF(JsRef, hiwire_array, (), { return Module.hiwire.new_value([]); });
|
||||
|
||||
EM_JS(void, hiwire_push_array, (JsRef idarr, JsRef idval), {
|
||||
EM_JS_NUM(errcode, hiwire_push_array, (JsRef idarr, JsRef idval), {
|
||||
Module.hiwire.get_value(idarr).push(Module.hiwire.get_value(idval));
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_object, (), { return Module.hiwire.new_value({}); });
|
||||
EM_JS_REF(JsRef, hiwire_object, (), { return Module.hiwire.new_value({}); });
|
||||
|
||||
EM_JS(void, hiwire_push_object_pair, (JsRef idobj, JsRef idkey, JsRef idval), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jskey = Module.hiwire.get_value(idkey);
|
||||
var jsval = Module.hiwire.get_value(idval);
|
||||
jsobj[jskey] = jsval;
|
||||
});
|
||||
EM_JS_NUM(errcode,
|
||||
hiwire_push_object_pair,
|
||||
(JsRef idobj, JsRef idkey, JsRef idval),
|
||||
{
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jskey = Module.hiwire.get_value(idkey);
|
||||
var jsval = Module.hiwire.get_value(idval);
|
||||
jsobj[jskey] = jsval;
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_get_global, (const char* ptrname), {
|
||||
EM_JS_REF(JsRef, hiwire_get_global, (const char* ptrname), {
|
||||
var jsname = UTF8ToString(ptrname);
|
||||
if (jsname in self) {
|
||||
return Module.hiwire.new_value(self[jsname]);
|
||||
|
@ -231,7 +239,7 @@ EM_JS(JsRef, hiwire_get_global, (const char* ptrname), {
|
|||
}
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_get_member_string, (JsRef idobj, const char* ptrkey), {
|
||||
EM_JS_REF(JsRef, hiwire_get_member_string, (JsRef idobj, const char* ptrkey), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jskey = UTF8ToString(ptrkey);
|
||||
if (jskey in jsobj) {
|
||||
|
@ -241,32 +249,35 @@ EM_JS(JsRef, hiwire_get_member_string, (JsRef idobj, const char* ptrkey), {
|
|||
}
|
||||
});
|
||||
|
||||
EM_JS(void,
|
||||
hiwire_set_member_string,
|
||||
(JsRef idobj, const char* ptrkey, JsRef idval),
|
||||
{
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jskey = UTF8ToString(ptrkey);
|
||||
var jsval = Module.hiwire.get_value(idval);
|
||||
jsobj[jskey] = jsval;
|
||||
});
|
||||
EM_JS_NUM(errcode,
|
||||
hiwire_set_member_string,
|
||||
(JsRef idobj, const char* ptrkey, JsRef idval),
|
||||
{
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jskey = UTF8ToString(ptrkey);
|
||||
var jsval = Module.hiwire.get_value(idval);
|
||||
jsobj[jskey] = jsval;
|
||||
});
|
||||
|
||||
EM_JS(void, hiwire_delete_member_string, (JsRef idobj, const char* ptrkey), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jskey = UTF8ToString(ptrkey);
|
||||
delete jsobj[jskey];
|
||||
});
|
||||
EM_JS_NUM(errcode,
|
||||
hiwire_delete_member_string,
|
||||
(JsRef idobj, const char* ptrkey),
|
||||
{
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jskey = UTF8ToString(ptrkey);
|
||||
delete jsobj[jskey];
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_get_member_int, (JsRef idobj, int idx), {
|
||||
EM_JS_REF(JsRef, hiwire_get_member_int, (JsRef idobj, int idx), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
return Module.hiwire.new_value(jsobj[idx]);
|
||||
});
|
||||
|
||||
EM_JS(void, hiwire_set_member_int, (JsRef idobj, int idx, JsRef idval), {
|
||||
EM_JS_NUM(errcode, hiwire_set_member_int, (JsRef idobj, int idx, JsRef idval), {
|
||||
Module.hiwire.get_value(idobj)[idx] = Module.hiwire.get_value(idval);
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_get_member_obj, (JsRef idobj, JsRef ididx), {
|
||||
EM_JS_REF(JsRef, hiwire_get_member_obj, (JsRef idobj, JsRef ididx), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jsidx = Module.hiwire.get_value(ididx);
|
||||
if (jsidx in jsobj) {
|
||||
|
@ -276,20 +287,23 @@ EM_JS(JsRef, hiwire_get_member_obj, (JsRef idobj, JsRef ididx), {
|
|||
}
|
||||
});
|
||||
|
||||
EM_JS(void, hiwire_set_member_obj, (JsRef idobj, JsRef ididx, JsRef idval), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jsidx = Module.hiwire.get_value(ididx);
|
||||
var jsval = Module.hiwire.get_value(idval);
|
||||
jsobj[jsidx] = jsval;
|
||||
});
|
||||
EM_JS_NUM(errcode,
|
||||
hiwire_set_member_obj,
|
||||
(JsRef idobj, JsRef ididx, JsRef idval),
|
||||
{
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jsidx = Module.hiwire.get_value(ididx);
|
||||
var jsval = Module.hiwire.get_value(idval);
|
||||
jsobj[jsidx] = jsval;
|
||||
});
|
||||
|
||||
EM_JS(void, hiwire_delete_member_obj, (JsRef idobj, JsRef ididx), {
|
||||
EM_JS_NUM(errcode, hiwire_delete_member_obj, (JsRef idobj, JsRef ididx), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jsidx = Module.hiwire.get_value(ididx);
|
||||
delete jsobj[jsidx];
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_dir, (JsRef idobj), {
|
||||
EM_JS_REF(JsRef, hiwire_dir, (JsRef idobj), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var result = [];
|
||||
do {
|
||||
|
@ -298,23 +312,23 @@ EM_JS(JsRef, hiwire_dir, (JsRef idobj), {
|
|||
return Module.hiwire.new_value(result);
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_call, (JsRef idfunc, JsRef idargs), {
|
||||
EM_JS_REF(JsRef, hiwire_call, (JsRef idfunc, JsRef idargs), {
|
||||
var jsfunc = Module.hiwire.get_value(idfunc);
|
||||
var jsargs = Module.hiwire.get_value(idargs);
|
||||
return Module.hiwire.new_value(jsfunc.apply(jsfunc, jsargs));
|
||||
});
|
||||
|
||||
EM_JS(JsRef,
|
||||
hiwire_call_member,
|
||||
(JsRef idobj, const char* ptrname, JsRef idargs),
|
||||
{
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jsname = UTF8ToString(ptrname);
|
||||
var jsargs = Module.hiwire.get_value(idargs);
|
||||
return Module.hiwire.new_value(jsobj[jsname].apply(jsobj, jsargs));
|
||||
});
|
||||
EM_JS_REF(JsRef,
|
||||
hiwire_call_member,
|
||||
(JsRef idobj, const char* ptrname, JsRef idargs),
|
||||
{
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
var jsname = UTF8ToString(ptrname);
|
||||
var jsargs = Module.hiwire.get_value(idargs);
|
||||
return Module.hiwire.new_value(jsobj[jsname].apply(jsobj, jsargs));
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_new, (JsRef idobj, JsRef idargs), {
|
||||
EM_JS_REF(JsRef, hiwire_new, (JsRef idobj, JsRef idargs), {
|
||||
function newCall(Cls)
|
||||
{
|
||||
return new (Function.prototype.bind.apply(Cls, arguments));
|
||||
|
@ -325,37 +339,37 @@ EM_JS(JsRef, hiwire_new, (JsRef idobj, JsRef idargs), {
|
|||
return Module.hiwire.new_value(newCall.apply(newCall, jsargs));
|
||||
});
|
||||
|
||||
EM_JS(int, hiwire_get_length, (JsRef idobj), {
|
||||
EM_JS_NUM(int, hiwire_get_length, (JsRef idobj), {
|
||||
return Module.hiwire.get_value(idobj).length;
|
||||
});
|
||||
|
||||
EM_JS(bool, hiwire_get_bool, (JsRef idobj), {
|
||||
EM_JS_NUM(bool, hiwire_get_bool, (JsRef idobj), {
|
||||
var val = Module.hiwire.get_value(idobj);
|
||||
// clang-format off
|
||||
return (val && (val.length === undefined || val.length)) ? 1 : 0;
|
||||
// clang-format on
|
||||
});
|
||||
|
||||
EM_JS(bool, hiwire_is_function, (JsRef idobj), {
|
||||
EM_JS_NUM(bool, hiwire_is_function, (JsRef idobj), {
|
||||
// clang-format off
|
||||
return typeof Module.hiwire.get_value(idobj) === 'function';
|
||||
// clang-format on
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_to_string, (JsRef idobj), {
|
||||
EM_JS_REF(JsRef, hiwire_to_string, (JsRef idobj), {
|
||||
return Module.hiwire.new_value(Module.hiwire.get_value(idobj).toString());
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_typeof, (JsRef idobj), {
|
||||
EM_JS_REF(JsRef, hiwire_typeof, (JsRef idobj), {
|
||||
return Module.hiwire.new_value(typeof Module.hiwire.get_value(idobj));
|
||||
});
|
||||
|
||||
EM_JS(char*, hiwire_constructor_name, (JsRef idobj), {
|
||||
EM_JS_REF(char*, hiwire_constructor_name, (JsRef idobj), {
|
||||
return stringToNewUTF8(Module.hiwire.get_value(idobj).constructor.name);
|
||||
});
|
||||
|
||||
#define MAKE_OPERATOR(name, op) \
|
||||
EM_JS(bool, hiwire_##name, (JsRef ida, JsRef idb), { \
|
||||
EM_JS_NUM(bool, hiwire_##name, (JsRef ida, JsRef idb), { \
|
||||
return (Module.hiwire.get_value(ida) op Module.hiwire.get_value(idb)) ? 1 \
|
||||
: 0; \
|
||||
})
|
||||
|
@ -367,7 +381,7 @@ MAKE_OPERATOR(not_equal, !=);
|
|||
MAKE_OPERATOR(greater_than, >);
|
||||
MAKE_OPERATOR(greater_than_equal, >=);
|
||||
|
||||
EM_JS(JsRef, hiwire_next, (JsRef idobj), {
|
||||
EM_JS_REF(JsRef, hiwire_next, (JsRef idobj), {
|
||||
// clang-format off
|
||||
if (idobj === Module.hiwire.UNDEFINED) {
|
||||
return Module.hiwire.ERROR;
|
||||
|
@ -378,7 +392,7 @@ EM_JS(JsRef, hiwire_next, (JsRef idobj), {
|
|||
// clang-format on
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_get_iterator, (JsRef idobj), {
|
||||
EM_JS_REF(JsRef, hiwire_get_iterator, (JsRef idobj), {
|
||||
// clang-format off
|
||||
if (idobj === Module.hiwire.UNDEFINED) {
|
||||
return Module.hiwire.ERROR;
|
||||
|
@ -396,37 +410,37 @@ EM_JS(JsRef, hiwire_get_iterator, (JsRef idobj), {
|
|||
// clang-format on
|
||||
})
|
||||
|
||||
EM_JS(bool, hiwire_nonzero, (JsRef idobj), {
|
||||
EM_JS_NUM(bool, hiwire_nonzero, (JsRef idobj), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
// TODO: should this be !== 0?
|
||||
return (jsobj != 0) ? 1 : 0;
|
||||
});
|
||||
|
||||
EM_JS(bool, hiwire_is_typedarray, (JsRef idobj), {
|
||||
EM_JS_NUM(bool, hiwire_is_typedarray, (JsRef idobj), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
// clang-format off
|
||||
return (jsobj['byteLength'] !== undefined) ? 1 : 0;
|
||||
// clang-format on
|
||||
});
|
||||
|
||||
EM_JS(bool, hiwire_is_on_wasm_heap, (JsRef idobj), {
|
||||
EM_JS_NUM(bool, hiwire_is_on_wasm_heap, (JsRef idobj), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
// clang-format off
|
||||
return (jsobj.buffer === Module.HEAPU8.buffer) ? 1 : 0;
|
||||
// clang-format on
|
||||
});
|
||||
|
||||
EM_JS(int, hiwire_get_byteOffset, (JsRef idobj), {
|
||||
EM_JS_NUM(int, hiwire_get_byteOffset, (JsRef idobj), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
return jsobj['byteOffset'];
|
||||
});
|
||||
|
||||
EM_JS(int, hiwire_get_byteLength, (JsRef idobj), {
|
||||
EM_JS_NUM(int, hiwire_get_byteLength, (JsRef idobj), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
return jsobj['byteLength'];
|
||||
});
|
||||
|
||||
EM_JS(void, hiwire_copy_to_ptr, (JsRef idobj, void* ptr), {
|
||||
EM_JS_NUM(errcode, hiwire_copy_to_ptr, (JsRef idobj, void* ptr), {
|
||||
var jsobj = Module.hiwire.get_value(idobj);
|
||||
// clang-format off
|
||||
var buffer = (jsobj['buffer'] !== undefined) ? jsobj.buffer : jsobj;
|
||||
|
@ -434,34 +448,34 @@ EM_JS(void, hiwire_copy_to_ptr, (JsRef idobj, void* ptr), {
|
|||
Module.HEAPU8.set(new Uint8Array(buffer), ptr);
|
||||
});
|
||||
|
||||
EM_JS(void,
|
||||
hiwire_get_dtype,
|
||||
(JsRef idobj, char** format_ptr, Py_ssize_t* size_ptr),
|
||||
{
|
||||
if (!Module.hiwire.dtype_map) {
|
||||
let alloc = stringToNewUTF8;
|
||||
Module.hiwire.dtype_map = new Map([
|
||||
[ 'Int8Array', [ alloc('b'), 1 ] ],
|
||||
[ 'Uint8Array', [ alloc('B'), 1 ] ],
|
||||
[ 'Uint8ClampedArray', [ alloc('B'), 1 ] ],
|
||||
[ 'Int16Array', [ alloc('h'), 2 ] ],
|
||||
[ 'Uint16Array', [ alloc('H'), 2 ] ],
|
||||
[ 'Int32Array', [ alloc('i'), 4 ] ],
|
||||
[ 'Uint32Array', [ alloc('I'), 4 ] ],
|
||||
[ 'Float32Array', [ alloc('f'), 4 ] ],
|
||||
[ 'Float64Array', [ alloc('d'), 8 ] ],
|
||||
[ 'ArrayBuffer', [ alloc('B'), 1 ] ], // Default to Uint8;
|
||||
]);
|
||||
}
|
||||
let jsobj = Module.hiwire.get_value(idobj);
|
||||
let[format_utf8, size] =
|
||||
Module.hiwire.dtype_map.get(jsobj.constructor.name) || [ 0, 0 ];
|
||||
// Store results into arguments
|
||||
setValue(format_ptr, format_utf8, "i8*");
|
||||
setValue(size_ptr, size, "i32");
|
||||
});
|
||||
EM_JS_NUM(errcode,
|
||||
hiwire_get_dtype,
|
||||
(JsRef idobj, char** format_ptr, Py_ssize_t* size_ptr),
|
||||
{
|
||||
if (!Module.hiwire.dtype_map) {
|
||||
let alloc = stringToNewUTF8;
|
||||
Module.hiwire.dtype_map = new Map([
|
||||
[ 'Int8Array', [ alloc('b'), 1 ] ],
|
||||
[ 'Uint8Array', [ alloc('B'), 1 ] ],
|
||||
[ 'Uint8ClampedArray', [ alloc('B'), 1 ] ],
|
||||
[ 'Int16Array', [ alloc('h'), 2 ] ],
|
||||
[ 'Uint16Array', [ alloc('H'), 2 ] ],
|
||||
[ 'Int32Array', [ alloc('i'), 4 ] ],
|
||||
[ 'Uint32Array', [ alloc('I'), 4 ] ],
|
||||
[ 'Float32Array', [ alloc('f'), 4 ] ],
|
||||
[ 'Float64Array', [ alloc('d'), 8 ] ],
|
||||
[ 'ArrayBuffer', [ alloc('B'), 1 ] ], // Default to Uint8;
|
||||
]);
|
||||
}
|
||||
let jsobj = Module.hiwire.get_value(idobj);
|
||||
let[format_utf8, size] =
|
||||
Module.hiwire.dtype_map.get(jsobj.constructor.name) || [ 0, 0 ];
|
||||
// Store results into arguments
|
||||
setValue(format_ptr, format_utf8, "i8*");
|
||||
setValue(size_ptr, size, "i32");
|
||||
});
|
||||
|
||||
EM_JS(JsRef, hiwire_subarray, (JsRef idarr, int start, int end), {
|
||||
EM_JS_REF(JsRef, hiwire_subarray, (JsRef idarr, int start, int end), {
|
||||
var jsarr = Module.hiwire.get_value(idarr);
|
||||
var jssub = jsarr.subarray(start, end);
|
||||
return Module.hiwire.new_value(jssub);
|
||||
|
|
|
@ -32,6 +32,9 @@ struct _JsRefStruct
|
|||
|
||||
typedef struct _JsRefStruct* JsRef;
|
||||
|
||||
// Error handling will want to see JsRef.
|
||||
#include "error_handling.h"
|
||||
|
||||
// Special JsRefs for singleton constants.
|
||||
// (These must be even because the least significance bit is set to 0 for
|
||||
// singleton constants.)
|
||||
|
@ -57,7 +60,7 @@ hiwire_incref(JsRef idval);
|
|||
/**
|
||||
* Decrease the reference count on an object.
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_decref(JsRef idval);
|
||||
|
||||
/**
|
||||
|
@ -276,7 +279,7 @@ hiwire_array();
|
|||
* If the user no longer needs the value outside of the array, it is the user's
|
||||
* responsibility to decref it.
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_push_array(JsRef idobj, JsRef idval);
|
||||
|
||||
/**
|
||||
|
@ -293,7 +296,7 @@ hiwire_object();
|
|||
* If the user no longer needs the key or value outside of the object, it is the
|
||||
* user's responsibility to decref them.
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_push_object_pair(JsRef idobj, JsRef idkey, JsRef idval);
|
||||
|
||||
/**
|
||||
|
@ -302,7 +305,7 @@ hiwire_push_object_pair(JsRef idobj, JsRef idkey, JsRef idval);
|
|||
* The message is conventionally a Javascript string, but that is not required.
|
||||
* TODO: should be hiwire_set_error.
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_throw_error(JsRef idmsg);
|
||||
|
||||
/**
|
||||
|
@ -325,14 +328,14 @@ hiwire_get_member_string(JsRef idobj, const char* ptrname);
|
|||
/**
|
||||
* Set an object member by string.
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_set_member_string(JsRef idobj, const char* ptrname, JsRef idval);
|
||||
|
||||
/**
|
||||
* Delete an object member by string.
|
||||
*
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_delete_member_string(JsRef idobj, const char* ptrname);
|
||||
|
||||
/**
|
||||
|
@ -351,7 +354,7 @@ hiwire_get_member_int(JsRef idobj, int idx);
|
|||
* The integer is a C integer, not an id reference to a Javascript integer.
|
||||
*
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_set_member_int(JsRef idobj, int idx, JsRef idval);
|
||||
|
||||
/**
|
||||
|
@ -366,14 +369,14 @@ hiwire_get_member_obj(JsRef idobj, JsRef ididx);
|
|||
* Set an object member by object.
|
||||
*
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_set_member_obj(JsRef idobj, JsRef ididx, JsRef idval);
|
||||
|
||||
/**
|
||||
* Delete an object member by object.
|
||||
*
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_delete_member_obj(JsRef idobj, JsRef ididx);
|
||||
|
||||
/**
|
||||
|
@ -554,13 +557,13 @@ hiwire_get_byteOffset(JsRef idobj);
|
|||
* Copies the buffer contents of a given typed array or buffer into the memory
|
||||
* at ptr.
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_copy_to_ptr(JsRef idobj, void* ptr);
|
||||
|
||||
/**
|
||||
* Get a data type identifier for a given typedarray.
|
||||
*/
|
||||
void
|
||||
errcode
|
||||
hiwire_get_dtype(JsRef idobj, char** format_ptr, Py_ssize_t* size_ptr);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "js2python.h"
|
||||
#include "error_handling.h"
|
||||
|
||||
#include <emscripten.h>
|
||||
|
||||
|
@ -79,8 +80,7 @@ _js2python_error(JsRef id)
|
|||
}
|
||||
|
||||
// TODO: Add some meaningful order
|
||||
|
||||
EM_JS(PyObject*, __js2python, (JsRef id), {
|
||||
EM_JS_REF(PyObject*, __js2python, (JsRef id), {
|
||||
function __js2python_string(value)
|
||||
{
|
||||
// The general idea here is to allocate a Python string and then
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <emscripten.h>
|
||||
#include <stdalign.h>
|
||||
|
||||
#include "error_handling.h"
|
||||
#include "hiwire.h"
|
||||
#include "js2python.h"
|
||||
#include "jsimport.h"
|
||||
|
@ -59,6 +60,7 @@ main(int argc, char** argv)
|
|||
}
|
||||
Py_DECREF(sys);
|
||||
|
||||
TRY_INIT(error_handling);
|
||||
TRY_INIT(js2python);
|
||||
TRY_INIT(JsImport);
|
||||
TRY_INIT(JsProxy);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "error_handling.h"
|
||||
#include <Python.h>
|
||||
#include <emscripten.h>
|
||||
|
||||
|
@ -144,7 +145,7 @@ _pyproxy_destroy(PyObject* ptrobj)
|
|||
EM_ASM(delete Module.PyProxies[ptrobj];);
|
||||
}
|
||||
|
||||
EM_JS(JsRef, pyproxy_use, (PyObject * ptrobj), {
|
||||
EM_JS_REF(JsRef, pyproxy_use, (PyObject * ptrobj), {
|
||||
// Checks if there is already an existing proxy on ptrobj
|
||||
|
||||
if (Module.PyProxies.hasOwnProperty(ptrobj)) {
|
||||
|
@ -154,7 +155,7 @@ EM_JS(JsRef, pyproxy_use, (PyObject * ptrobj), {
|
|||
return Module.hiwire.ERROR;
|
||||
})
|
||||
|
||||
EM_JS(JsRef, pyproxy_new, (PyObject * ptrobj), {
|
||||
EM_JS_REF(JsRef, pyproxy_new, (PyObject * ptrobj), {
|
||||
// Technically, this leaks memory, since we're holding on to a reference
|
||||
// to the proxy forever. But we have that problem anyway since we don't
|
||||
// have a destructor in Javascript to free the Python object.
|
||||
|
@ -169,7 +170,7 @@ EM_JS(JsRef, pyproxy_new, (PyObject * ptrobj), {
|
|||
return Module.hiwire.new_value(proxy);
|
||||
});
|
||||
|
||||
EM_JS(int, pyproxy_init, (), {
|
||||
EM_JS_NUM(int, pyproxy_init, (), {
|
||||
// clang-format off
|
||||
Module.PyProxies = {};
|
||||
Module.PyProxy = {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "runpython.h"
|
||||
#include "error_handling.h"
|
||||
#include "hiwire.h"
|
||||
#include "pyproxy.h"
|
||||
#include "python2js.h"
|
||||
|
@ -39,22 +40,25 @@ _runPythonDebug(char* code)
|
|||
return id;
|
||||
}
|
||||
|
||||
EM_JS(int, runpython_init_js, (JsRef pyodide_py_proxy, JsRef globals_proxy), {
|
||||
Module.pyodide_py = Module.hiwire.get_value(pyodide_py_proxy);
|
||||
Module.globals = Module.hiwire.get_value(globals_proxy);
|
||||
EM_JS_NUM(int,
|
||||
runpython_init_js,
|
||||
(JsRef pyodide_py_proxy, JsRef globals_proxy),
|
||||
{
|
||||
Module.pyodide_py = Module.hiwire.get_value(pyodide_py_proxy);
|
||||
Module.globals = Module.hiwire.get_value(globals_proxy);
|
||||
|
||||
// Use this to test python code separate from pyproxy.apply.
|
||||
Module.runPythonDebug = function(code)
|
||||
{
|
||||
let pycode = stringToNewUTF8(code);
|
||||
let idresult = Module.__runPythonDebug(pycode);
|
||||
let jsresult = Module.hiwire.get_value(idresult);
|
||||
Module.hiwire.decref(idresult);
|
||||
_free(pycode);
|
||||
return jsresult;
|
||||
};
|
||||
return 0;
|
||||
});
|
||||
// Use this to test python code separate from pyproxy.apply.
|
||||
Module.runPythonDebug = function(code)
|
||||
{
|
||||
let pycode = stringToNewUTF8(code);
|
||||
let idresult = Module.__runPythonDebug(pycode);
|
||||
let jsresult = Module.hiwire.get_value(idresult);
|
||||
Module.hiwire.decref(idresult);
|
||||
_free(pycode);
|
||||
return jsresult;
|
||||
};
|
||||
return 0;
|
||||
});
|
||||
|
||||
#define QUIT_IF_NULL(x) \
|
||||
do { \
|
||||
|
|
|
@ -4,6 +4,16 @@
|
|||
#include "stdbool.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#undef false
|
||||
#undef true
|
||||
// These work for both C and javascript.
|
||||
// In C !!0 ==> 0 and in javascript !!0 ==> false
|
||||
// In C !!1 ==> 1 and in javascript !!1 ==> true
|
||||
// clang-format off
|
||||
#define false (!!0)
|
||||
#define true (!!1)
|
||||
// clang-format on
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
|
@ -15,4 +25,5 @@ typedef int64_t i64;
|
|||
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
|
||||
#endif /* MY_LINUX_TYPES_H */
|
||||
|
|
Loading…
Reference in New Issue