Commit 27d135e6 authored by Roman Yurchak's avatar Roman Yurchak Committed by GitHub

Merge pull request #198 from mdboom/singleton-constants

Use constant hiwire ids for singleton values
parents a966927c fdab0249
#include <emscripten.h>
#include "hiwire.h"
// Define special ids for singleton constants. These must be less than -1 to
// avoid being reused for other values.
#define HW_UNDEFINED -2
#define HW_TRUE -3
#define HW_FALSE -4
#define HW_NULL -5
EM_JS(void, hiwire_setup, (), {
// These ids must match the constants above, but we can't use them from JS
var hiwire = { objects : {}, counter : 1 };
hiwire.objects[-2] = undefined;
hiwire.objects[-3] = true;
hiwire.objects[-4] = false;
hiwire.objects[-5] = null;
Module.hiwire_new_value = function(jsval)
{
......@@ -19,12 +33,18 @@ EM_JS(void, hiwire_setup, (), {
Module.hiwire_decref = function(idval)
{
if (idval < 0) {
return;
}
var objects = hiwire.objects;
delete objects[idval];
};
});
EM_JS(int, hiwire_incref, (int idval), {
if (idval < 0) {
return;
}
return Module.hiwire_new_value(Module.hiwire_get_value(idval));
});
......@@ -76,15 +96,29 @@ EM_JS(int, hiwire_bytes, (int ptr, int len), {
return Module.hiwire_new_value(bytes);
});
EM_JS(int, hiwire_undefined, (), {
return Module.hiwire_new_value(undefined);
});
int
hiwire_undefined()
{
return HW_UNDEFINED;
}
EM_JS(int, hiwire_null, (), { return Module.hiwire_new_value(null); });
int
hiwire_null()
{
return HW_NULL;
}
EM_JS(int, hiwire_true, (), { return Module.hiwire_new_value(true); });
int
hiwire_true()
{
return HW_TRUE;
}
EM_JS(int, hiwire_false, (), { return Module.hiwire_new_value(false); });
int
hiwire_false()
{
return HW_FALSE;
}
EM_JS(void, hiwire_throw_error, (int idmsg), {
var jsmsg = Module.hiwire_get_value(idmsg);
......@@ -159,20 +193,20 @@ EM_JS(void, hiwire_delete_member_obj, (int idobj, int ididx), {
delete jsobj[jsidx];
});
EM_JS(void, hiwire_call, (int idfunc, int idargs), {
EM_JS(int, hiwire_call, (int idfunc, int 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(void, hiwire_call_member, (int idobj, int ptrname, int idargs), {
EM_JS(int, hiwire_call_member, (int idobj, int ptrname, int 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(void, hiwire_new, (int idobj, int idargs), {
EM_JS(int, hiwire_new, (int idobj, int idargs), {
function newCall(Cls)
{
return new (Function.prototype.bind.apply(Cls, arguments));
......@@ -219,7 +253,7 @@ EM_JS(int, hiwire_next, (int idobj), {
// clang-format off
if (jsobj.next === undefined) {
// clang-format on
return -1;
return HW_ERROR;
}
return Module.hiwire_new_value(jsobj.next());
......
......@@ -14,6 +14,8 @@
* object. There may be one or more keys pointing to the same object.
*/
#define HW_ERROR -1
/**
* Initialize the variables and functions required for hiwire.
*/
......@@ -359,7 +361,7 @@ hiwire_greater_than_equal(int ida, int idb);
/**
* Calls the `next` function on an iterator.
*
* Returns: -1 if `next` function is undefined.
* Returns: HW_ERROR if `next` function is undefined.
*/
int
hiwire_next(int idobj);
......
......@@ -17,7 +17,7 @@ pythonexc2js()
PyErr_Fetch(&type, &value, &traceback);
PyErr_NormalizeException(&type, &value, &traceback);
int excval = -1;
int excval = HW_ERROR;
int exc;
if (type == NULL || type == Py_None || value == NULL || value == Py_None) {
......@@ -86,7 +86,7 @@ exit:
hiwire_throw_error(excval);
return -1;
return HW_ERROR;
}
static int
......@@ -129,13 +129,13 @@ _python2js(PyObject* x, PyObject* map)
} else if (PyLong_Check(x)) {
long x_long = PyLong_AsLongLong(x);
if (x_long == -1 && PyErr_Occurred()) {
return -1;
return HW_ERROR;
}
return hiwire_int(x_long);
} else if (PyFloat_Check(x)) {
double x_double = PyFloat_AsDouble(x);
if (x_double == -1.0 && PyErr_Occurred()) {
return -1;
return HW_ERROR;
}
return hiwire_double(x_double);
} else if (PyUnicode_Check(x)) {
......@@ -151,13 +151,13 @@ _python2js(PyObject* x, PyObject* map)
return hiwire_string_ucs4(data, length);
default:
PyErr_SetString(PyExc_ValueError, "Unknown Unicode KIND");
return -1;
return HW_ERROR;
}
} else if (PyBytes_Check(x)) {
char* x_buff;
Py_ssize_t length;
if (PyBytes_AsStringAndSize(x, &x_buff, &length)) {
return -1;
return HW_ERROR;
}
return hiwire_bytes((int)(void*)x_buff, length);
} else if (JsProxy_Check(x)) {
......@@ -166,7 +166,7 @@ _python2js(PyObject* x, PyObject* map)
int jsarray = hiwire_array();
if (_python2js_add_to_cache(map, x, jsarray)) {
hiwire_decref(jsarray);
return -1;
return HW_ERROR;
}
size_t length = PySequence_Size(x);
for (size_t i = 0; i < length; ++i) {
......@@ -181,11 +181,11 @@ _python2js(PyObject* x, PyObject* map)
return pyproxy_new((int)x);
}
int jsitem = _python2js_cache(pyitem, map);
if (jsitem == -1) {
if (jsitem == HW_ERROR) {
_python2js_remove_from_cache(map, x);
Py_DECREF(pyitem);
hiwire_decref(jsarray);
return -1;
return HW_ERROR;
}
Py_DECREF(pyitem);
hiwire_push_array(jsarray, jsitem);
......@@ -193,30 +193,30 @@ _python2js(PyObject* x, PyObject* map)
}
if (_python2js_remove_from_cache(map, x)) {
hiwire_decref(jsarray);
return -1;
return HW_ERROR;
}
return jsarray;
} else if (PyDict_Check(x)) {
int jsdict = hiwire_object();
if (_python2js_add_to_cache(map, x, jsdict)) {
hiwire_decref(jsdict);
return -1;
return HW_ERROR;
}
PyObject *pykey, *pyval;
Py_ssize_t pos = 0;
while (PyDict_Next(x, &pos, &pykey, &pyval)) {
int jskey = _python2js_cache(pykey, map);
if (jskey == -1) {
if (jskey == HW_ERROR) {
_python2js_remove_from_cache(map, x);
hiwire_decref(jsdict);
return -1;
return HW_ERROR;
}
int jsval = _python2js_cache(pyval, map);
if (jsval == -1) {
if (jsval == HW_ERROR) {
_python2js_remove_from_cache(map, x);
hiwire_decref(jskey);
hiwire_decref(jsdict);
return -1;
return HW_ERROR;
}
hiwire_push_object_pair(jsdict, jskey, jsval);
hiwire_decref(jskey);
......@@ -224,7 +224,7 @@ _python2js(PyObject* x, PyObject* map)
}
if (_python2js_remove_from_cache(map, x)) {
hiwire_decref(jsdict);
return -1;
return HW_ERROR;
}
return jsdict;
} else {
......@@ -254,7 +254,7 @@ _python2js_add_to_cache(PyObject* map, PyObject* pyparent, int jsparent)
if (PyDict_SetItem(map, pyparentid, jsparentid)) {
Py_DECREF(pyparentid);
Py_DECREF(jsparentid);
return -1;
return HW_ERROR;
}
Py_DECREF(pyparentid);
Py_DECREF(jsparentid);
......@@ -266,7 +266,7 @@ _python2js_remove_from_cache(PyObject* map, PyObject* pyparent)
{
PyObject* pyparentid = PyLong_FromSize_t((size_t)pyparent);
if (PyDict_DelItem(map, pyparentid)) {
return -1;
return HW_ERROR;
}
Py_DECREF(pyparentid);
return 0;
......@@ -280,7 +280,7 @@ _python2js_cache(PyObject* x, PyObject* map)
int result;
if (val) {
result = PyLong_AsLong(val);
if (result != -1) {
if (result != HW_ERROR) {
result = hiwire_incref(result);
}
Py_DECREF(val);
......@@ -298,7 +298,7 @@ python2js(PyObject* x)
int result = _python2js_cache(x, map);
Py_DECREF(map);
if (result == -1) {
if (result == HW_ERROR) {
return pythonexc2js();
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment