/** * gjs_runtime_destroy: * @runtime: a #JSRuntime * * Calls JS_DestroyRuntime() on runtime and frees data allocated by * gjs_runtime_init(); these are unified into a single call because we * need to order things so that the allocated data is cleaned up * after JS_DestroyRuntime(). We might have finalizers run by * JS_DestroyRuntime() that rely on the information stored in the data, * such as the dynamic class structs. * * This should only be called by GJS, not by applications. */ void gjs_runtime_destroy(JSRuntime *runtime) { RuntimeData *rd; void *key; void *value; rd = JS_GetRuntimePrivate(runtime); if (rd->context_stack != NULL || rd->current_frame.depth != 0) gjs_fatal("gjs_runtime_destroy() called during gjs_push_context()"); gjs_debug(GJS_DEBUG_CONTEXT, "Destroying JS runtime"); JS_DestroyRuntime(runtime); gjs_debug(GJS_DEBUG_CONTEXT, "Destroying any remaining dataset items on runtime"); while (gjs_g_hash_table_remove_one(rd->dynamic_classes, &key, &value)) { JSClass *clasp = value; gjs_debug(GJS_DEBUG_GREPO, "Finalizing dynamic class '%s'", clasp->name); g_free( (char*) clasp->name); /* we know we malloc'd the char* even though it's const */ g_slice_free(DynamicJSClass, (DynamicJSClass*) clasp); } g_hash_table_destroy(rd->dynamic_classes); g_slice_free(RuntimeData, rd); }
static void runtime_data_destroy_notify(void *data) { RuntimeData *rd = data; void *key; void *value; while (gjs_g_hash_table_remove_one(rd->dynamic_classes, &key, &value)) { JSClass *clasp = value; gjs_debug(GJS_DEBUG_GREPO, "Finalizing dynamic class '%s'", clasp->name); g_free( (char*) clasp->name); /* we know we malloc'd the char* even though it's const */ g_slice_free(DynamicJSClass, (DynamicJSClass*) clasp); } g_hash_table_destroy(rd->dynamic_classes); g_slice_free(RuntimeData, rd); }