Most of these globals were leaking before as they were never freed at all. Also, they have to be freed during script ctx destruction because an unintialized script might still make use of them (e.g. retrieving a builtin function via PROPERTYGET requires ctx->function_constr to be available).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
The previous patch already has tests for that builtin PROPERTYGET thing (with the DISPID obtained before setting it to uninitialized).
dlls/jscript/global.c | 1 + dlls/jscript/jscript.c | 27 +++++++++++------------ dlls/jscript/jscript.h | 49 ++++++++++++++++++++++++------------------ 3 files changed, 41 insertions(+), 36 deletions(-)
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index c0ed954..1fe68b2 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -1085,6 +1085,7 @@ HRESULT init_global(script_ctx_t *ctx)
if(ctx->global) return S_OK; + script_globals_release(ctx);
hres = create_dispex(ctx, &JSGlobal_info, NULL, &ctx->global); if(FAILED(hres)) diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index d6028e6..3189528 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -71,11 +71,23 @@ typedef struct { jsexcept_t ei; } JScriptError;
+void script_globals_release(script_ctx_t *ctx) +{ + unsigned i; + for(i = 0; i < ARRAY_SIZE(ctx->global_objects); i++) { + if(ctx->global_objects[i]) { + jsdisp_release(ctx->global_objects[i]); + ctx->global_objects[i] = NULL; + } + } +} + void script_release(script_ctx_t *ctx) { if(--ctx->ref) return;
+ script_globals_release(ctx); jsval_release(ctx->acc); if(ctx->cc) release_cc(ctx->cc); @@ -483,21 +495,6 @@ static void decrease_state(JScript *This, SCRIPTSTATE state) This->ctx->site = NULL; }
- if(This->ctx->map_prototype) { - jsdisp_release(This->ctx->map_prototype); - This->ctx->map_prototype = NULL; - } - - if(This->ctx->set_prototype) { - jsdisp_release(This->ctx->set_prototype); - This->ctx->set_prototype = NULL; - } - - if(This->ctx->object_prototype) { - jsdisp_release(This->ctx->object_prototype); - This->ctx->object_prototype = NULL; - } - if(This->ctx->global) { jsdisp_release(This->ctx->global); This->ctx->global = NULL; diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 000bcc2..c5c9043 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -388,29 +388,36 @@ struct _script_ctx_t { DWORD last_match_length;
jsdisp_t *global; - jsdisp_t *function_constr; - jsdisp_t *array_constr; - jsdisp_t *bool_constr; - jsdisp_t *date_constr; - jsdisp_t *enumerator_constr; - jsdisp_t *error_constr; - jsdisp_t *eval_error_constr; - jsdisp_t *range_error_constr; - jsdisp_t *reference_error_constr; - jsdisp_t *regexp_error_constr; - jsdisp_t *syntax_error_constr; - jsdisp_t *type_error_constr; - jsdisp_t *uri_error_constr; - jsdisp_t *number_constr; - jsdisp_t *object_constr; - jsdisp_t *object_prototype; - jsdisp_t *regexp_constr; - jsdisp_t *string_constr; - jsdisp_t *vbarray_constr; - jsdisp_t *map_prototype; - jsdisp_t *set_prototype; + union { + struct { + jsdisp_t *function_constr; + jsdisp_t *array_constr; + jsdisp_t *bool_constr; + jsdisp_t *date_constr; + jsdisp_t *enumerator_constr; + jsdisp_t *error_constr; + jsdisp_t *eval_error_constr; + jsdisp_t *range_error_constr; + jsdisp_t *reference_error_constr; + jsdisp_t *regexp_error_constr; + jsdisp_t *syntax_error_constr; + jsdisp_t *type_error_constr; + jsdisp_t *uri_error_constr; + jsdisp_t *number_constr; + jsdisp_t *object_constr; + jsdisp_t *object_prototype; + jsdisp_t *regexp_constr; + jsdisp_t *string_constr; + jsdisp_t *vbarray_constr; + jsdisp_t *map_prototype; + jsdisp_t *set_prototype; + }; + jsdisp_t *global_objects[21]; + }; }; +C_ASSERT(RTL_SIZEOF_THROUGH_FIELD(script_ctx_t, set_prototype) == RTL_SIZEOF_THROUGH_FIELD(script_ctx_t, global_objects));
+void script_globals_release(script_ctx_t *ctx) DECLSPEC_HIDDEN; void script_release(script_ctx_t*) DECLSPEC_HIDDEN;
static inline void script_addref(script_ctx_t *ctx)