From 196c2fc845713d7ce2072a48f560f326b90b733a Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sat, 25 May 2019 16:23:37 +0100 Subject: Add dodgy window method to clear callbacks Until we can determine *how* the compartment isn't cleaning up properly in the duktape context, this will at least mean we don't get unpleasant callback related issues when compartments are reset during browsing. Signed-off-by: Daniel Silverstone --- content/handlers/javascript/duktape/Window.bnd | 33 ++++++++++++++++++++++++++ content/handlers/javascript/duktape/dukky.c | 7 +++++- 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'content/handlers/javascript') diff --git a/content/handlers/javascript/duktape/Window.bnd b/content/handlers/javascript/duktape/Window.bnd index 3aed29991..cbf283f79 100644 --- a/content/handlers/javascript/duktape/Window.bnd +++ b/content/handlers/javascript/duktape/Window.bnd @@ -179,6 +179,28 @@ static void window_remove_callback_by_handle(duk_context *ctx, } RING_ITERATE_END(window->schedule_ring, sched); } +/* This is the dodgy compartment closedown method */ +static duk_ret_t dukky_window_closedown_compartment(duk_context *ctx) +{ + window_private_t *priv = NULL; + + duk_push_global_object(ctx); + duk_get_prop_string(ctx, -1, dukky_magic_string_private); + priv = duk_get_pointer(ctx, -1); + duk_pop_2(ctx); + + if (priv == NULL) { + return 0; + } + + NSLOG(dukky, DEEPDEBUG, "Closing down compartment"); + while (priv->schedule_ring != NULL) { + window_remove_callback_by_handle(ctx, priv, priv->schedule_ring->handle); + } + + return 0; +} + %}; }; @@ -228,6 +250,17 @@ prototype Window() EXPOSE(encodeURI); EXPOSE(encodeURIComponent); #undef EXPOSE + /* Add s3kr1t method to close the compartment */ + duk_dup(ctx, 0); + duk_push_string(ctx, MAGIC(closedownCompartment)); + duk_push_c_function(ctx, dukky_window_closedown_compartment, DUK_VARARGS); + duk_def_prop(ctx, -3, + DUK_DEFPROP_HAVE_VALUE | + DUK_DEFPROP_HAVE_WRITABLE | + DUK_DEFPROP_HAVE_ENUMERABLE | + DUK_DEFPROP_ENUMERABLE | + DUK_DEFPROP_HAVE_CONFIGURABLE); + duk_pop(ctx); %} getter Window::document() diff --git a/content/handlers/javascript/duktape/dukky.c b/content/handlers/javascript/duktape/dukky.c index 70e9be881..a828667ef 100644 --- a/content/handlers/javascript/duktape/dukky.c +++ b/content/handlers/javascript/duktape/dukky.c @@ -607,11 +607,16 @@ void js_destroycontext(jscontext *ctx) jsobject *js_newcompartment(jscontext *ctx, void *win_priv, void *doc_priv) { assert(ctx != NULL); - /* Pop any active thread off */ NSLOG(dukky, DEBUG, "New javascript/duktape compartment, win_priv=%p, doc_priv=%p", win_priv, doc_priv); + /* Pop any active thread off */ if (CTX != NULL) { + /* Closing down the extant compartment */ + NSLOG(dukky, DEEPDEBUG, "Closing down extant compartment..."); + duk_get_global_string(CTX, MAGIC(closedownCompartment)); + dukky_pcall(CTX, 0, true); + NSLOG(dukky, DEEPDEBUG, "Popping the thread off the stack"); duk_set_top(ctx->ctx, 0); duk_gc(ctx->ctx, 0); duk_gc(ctx->ctx, DUK_GC_COMPACT); -- cgit v1.2.3