EM_JS wrappers to convert calls to use Python error conventions (#1051)

This commit is contained in:
Hood Chatham 2021-01-06 14:48:15 -08:00 committed by GitHub
parent 6ef0ebbfdf
commit a58c8d7186
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 256 additions and 140 deletions

View File

@ -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 \

25
src/core/error_handling.c Normal file
View File

@ -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;
}

55
src/core/error_handling.h Normal file
View File

@ -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

View File

@ -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);

View File

@ -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);
/**

View File

@ -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

View File

@ -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);

View File

@ -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 = {

View File

@ -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 { \

View File

@ -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 */