@@ -21,6 +21,7 @@ typedef struct {
2121
2222// The exception raised by this module.
2323static PyObject * JSException = NULL ;
24+ static PyObject * StackOverflow = NULL ;
2425// Converts a JSValue to a Python object.
2526//
2627// Takes ownership of the JSValue and will deallocate it (refcount reduced by 1).
@@ -210,7 +211,11 @@ static PyObject *quickjs_to_python(ContextData *context_obj, JSValue value) {
210211 JSValue exception = JS_GetException (context );
211212 JSValue error_string = JS_ToString (context , exception );
212213 const char * cstring = JS_ToCString (context , error_string );
213- PyErr_Format (JSException , "%s" , cstring );
214+ if (strstr (cstring , "stack overflow" ) != NULL ) {
215+ PyErr_Format (StackOverflow , "%s" , cstring );
216+ } else {
217+ PyErr_Format (JSException , "%s" , cstring );
218+ }
214219 JS_FreeCString (context , cstring );
215220 JS_FreeValue (context , error_string );
216221 JS_FreeValue (context , exception );
@@ -349,6 +354,18 @@ static PyObject *context_set_time_limit(ContextData *self, PyObject *args) {
349354 Py_RETURN_NONE ;
350355}
351356
357+ // _quickjs.Context.set_max_stack_size
358+ //
359+ // Sets the max stack size in bytes.
360+ static PyObject * context_set_max_stack_size (ContextData * self , PyObject * args ) {
361+ Py_ssize_t limit ;
362+ if (!PyArg_ParseTuple (args , "n" , & limit )) {
363+ return NULL ;
364+ }
365+ JS_SetMaxStackSize (self -> context , limit );
366+ Py_RETURN_NONE ;
367+ }
368+
352369// _quickjs.Context.memory
353370//
354371// Sets the CPU time limit of the context. This will be used in an interrupt handler.
@@ -420,6 +437,10 @@ static PyMethodDef context_methods[] = {
420437 (PyCFunction )context_set_time_limit ,
421438 METH_VARARGS ,
422439 "Sets the CPU time limit in seconds (C function clock() is used)." },
440+ {"set_max_stack_size" ,
441+ (PyCFunction )context_set_max_stack_size ,
442+ METH_VARARGS ,
443+ "Sets the maximum stack size in bytes. Default is 256kB." },
423444 {"memory" , (PyCFunction )context_memory , METH_NOARGS , "Returns the memory usage as a dict." },
424445 {"gc" , (PyCFunction )context_gc , METH_NOARGS , "Runs garbage collection." },
425446 {NULL } /* Sentinel */
@@ -468,11 +489,16 @@ PyMODINIT_FUNC PyInit__quickjs(void) {
468489 if (JSException == NULL ) {
469490 return NULL ;
470491 }
492+ StackOverflow = PyErr_NewException ("_quickjs.StackOverflow" , JSException , NULL );
493+ if (StackOverflow == NULL ) {
494+ return NULL ;
495+ }
471496
472497 Py_INCREF (& Context );
473498 PyModule_AddObject (module , "Context" , (PyObject * )& Context );
474499 Py_INCREF (& Object );
475500 PyModule_AddObject (module , "Object" , (PyObject * )& Object );
476501 PyModule_AddObject (module , "JSException" , JSException );
502+ PyModule_AddObject (module , "StackOverflow" , StackOverflow );
477503 return module ;
478504}
0 commit comments