|
2 | 2 |
|
3 | 3 | #include "third-party/quickjs.h" |
4 | 4 |
|
| 5 | +static PyObject* JSException = NULL; |
| 6 | + |
| 7 | +static PyObject* quickjs_to_python(JSContext* context, JSValue value) { |
| 8 | + int tag = JS_VALUE_GET_TAG(value); |
| 9 | +PyObject *return_value = NULL; |
| 10 | + |
| 11 | +if (tag == JS_TAG_INT) { |
| 12 | +return_value = Py_BuildValue("i", JS_VALUE_GET_INT(value)); |
| 13 | +} else if (tag == JS_TAG_BOOL) { |
| 14 | +return_value = Py_BuildValue("O", JS_VALUE_GET_BOOL(value) ? Py_True : Py_False); |
| 15 | +} else if (tag == JS_TAG_NULL) { |
| 16 | +return_value = Py_None; |
| 17 | +} else if (tag == JS_TAG_UNDEFINED) { |
| 18 | +return_value = Py_None; |
| 19 | +} else if (tag == JS_TAG_UNINITIALIZED) { |
| 20 | +return_value = Py_None; |
| 21 | +} else if (tag == JS_TAG_EXCEPTION) { |
| 22 | + JSValue exception = JS_GetException(context); |
| 23 | + JSValue error_string = JS_ToString(context, exception); |
| 24 | + const char *cstring = JS_ToCString(context, error_string); |
| 25 | + PyErr_Format(JSException, "%s", cstring); |
| 26 | +JS_FreeCString(context, cstring); |
| 27 | + JS_FreeValue(context, error_string); |
| 28 | + JS_FreeValue(context, exception); |
| 29 | +} else if (tag == JS_TAG_FLOAT64) { |
| 30 | +return_value = Py_BuildValue("d", JS_VALUE_GET_FLOAT64(value)); |
| 31 | +} else if (tag == JS_TAG_STRING) { |
| 32 | +const char *cstring = JS_ToCString(context, value); |
| 33 | +return_value = Py_BuildValue("s", cstring); |
| 34 | +JS_FreeCString(context, cstring); |
| 35 | +} else { |
| 36 | +// TODO: Raise exception. |
| 37 | +} |
| 38 | + |
| 39 | +JS_FreeValue(context, value); |
| 40 | +if (return_value == Py_None) { |
| 41 | +Py_RETURN_NONE; |
| 42 | +} |
| 43 | +return return_value; |
| 44 | +} |
| 45 | + |
5 | 46 | static PyObject *test(PyObject *self, PyObject *args) { |
6 | 47 | return Py_BuildValue("i", 42); |
7 | 48 | } |
@@ -35,36 +76,7 @@ static PyObject *context_eval(ContextData *self, PyObject *args) { |
35 | 76 | return NULL; |
36 | 77 | } |
37 | 78 | JSValue value = JS_Eval(self->context, code, strlen(code), "<input>", JS_EVAL_TYPE_GLOBAL); |
38 | | -int tag = JS_VALUE_GET_TAG(value); |
39 | | -PyObject *return_value = NULL; |
40 | | - |
41 | | -if (tag == JS_TAG_INT) { |
42 | | -return_value = Py_BuildValue("i", JS_VALUE_GET_INT(value)); |
43 | | -} else if (tag == JS_TAG_BOOL) { |
44 | | -return_value = Py_BuildValue("O", JS_VALUE_GET_BOOL(value) ? Py_True : Py_False); |
45 | | -} else if (tag == JS_TAG_NULL) { |
46 | | -// None |
47 | | -} else if (tag == JS_TAG_UNDEFINED) { |
48 | | -// None |
49 | | -} else if (tag == JS_TAG_UNINITIALIZED) { |
50 | | -// None |
51 | | -} else if (tag == JS_TAG_EXCEPTION) { |
52 | | -// TODO: Raise exception. |
53 | | -} else if (tag == JS_TAG_FLOAT64) { |
54 | | -return_value = Py_BuildValue("d", JS_VALUE_GET_FLOAT64(value)); |
55 | | -} else if (tag == JS_TAG_STRING) { |
56 | | -const char *cstring = JS_ToCString(self->context, value); |
57 | | -return_value = Py_BuildValue("s", cstring); |
58 | | -JS_FreeCString(self->context, cstring); |
59 | | -} else { |
60 | | -// TODO: Raise exception. |
61 | | -} |
62 | | - |
63 | | -JS_FreeValue(self->context, value); |
64 | | -if (return_value == NULL) { |
65 | | -Py_RETURN_NONE; |
66 | | -} |
67 | | -return return_value; |
| 79 | + return quickjs_to_python(self->context, value); |
68 | 80 | } |
69 | 81 |
|
70 | 82 | static PyMethodDef context_methods[] = { |
@@ -104,7 +116,13 @@ PyMODINIT_FUNC PyInit__quickjs(void) { |
104 | 116 | return NULL; |
105 | 117 | } |
106 | 118 |
|
| 119 | + JSException = PyErr_NewException("_quickjs.JSException", NULL, NULL); |
| 120 | + if (JSException == NULL) { |
| 121 | + return NULL; |
| 122 | + } |
| 123 | + |
107 | 124 | Py_INCREF(&Context); |
108 | 125 | PyModule_AddObject(module, "Context", (PyObject *)&Context); |
| 126 | + PyModule_AddObject(module, "JSException", JSException); |
109 | 127 | return module; |
110 | 128 | } |
0 commit comments