From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/engine.c | 23 ++++++++++++----------- dlls/jscript/engine.h | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index ceaa01b0648..d5659d55f17 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -430,7 +430,7 @@ static void scope_destructor(jsdisp_t *dispex) if(scope->next) scope_release(scope->next);
- if(scope->obj) + if(scope->obj && scope->obj != to_disp(&scope->dispex)) IDispatch_Release(scope->obj); free(scope); } @@ -451,12 +451,14 @@ static HRESULT scope_gc_traverse(struct gc_ctx *gc_ctx, enum gc_traverse_op op, IDispatch *obj = scope->obj; if(obj) { scope->obj = NULL; - IDispatch_Release(obj); + if(obj != to_disp(&scope->dispex)) + IDispatch_Release(obj); } return S_OK; }
- return scope->obj && (jsobj = to_jsdisp(scope->obj)) ? gc_process_linked_obj(gc_ctx, op, dispex, jsobj, (void**)&scope->obj) : S_OK; + return scope->obj && scope->obj != to_disp(&scope->dispex) && (jsobj = to_jsdisp(scope->obj)) + ? gc_process_linked_obj(gc_ctx, op, dispex, jsobj, (void**)&scope->obj) : S_OK; }
static const builtin_info_t scope_info = { @@ -637,8 +639,7 @@ static HRESULT detach_scope(script_ctx_t *ctx, call_frame_t *frame, scope_chain_
if (!scope->obj) { - if (FAILED(hres = create_object(ctx, NULL, &jsobj))) - return hres; + jsobj = &scope->dispex; scope->obj = to_disp(jsobj); } else @@ -953,8 +954,7 @@ static HRESULT scope_init_locals(script_ctx_t *ctx) } else if (!scope->obj) { - if (FAILED(hres = create_object(ctx, NULL, &jsobj))) - return hres; + jsobj = &scope->dispex; scope->obj = to_disp(jsobj); } else @@ -3263,7 +3263,7 @@ static HRESULT setup_scope(script_ctx_t *ctx, call_frame_t *frame, scope_chain_t
frame->pop_variables = i;
- hres = scope_push(ctx, scope_chain, to_disp(variable_object), &scope); + hres = scope_push(ctx, scope_chain, variable_object ? to_disp(variable_object) : NULL, &scope); if(FAILED(hres)) { stack_popn(ctx, ctx->stack_top - orig_stack); return hres; @@ -3345,8 +3345,7 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi if((flags & EXEC_EVAL) && ctx->call_ctx) { variable_obj = jsdisp_addref(ctx->call_ctx->variable_obj); }else if(!(flags & (EXEC_GLOBAL | EXEC_EVAL))) { - hres = create_dispex(ctx, NULL, NULL, &variable_obj); - if(FAILED(hres)) return hres; + variable_obj = NULL; /* set to scope's dispex later */ }else if(bytecode->named_item) { variable_obj = jsdisp_addref(bytecode->named_item->script_obj); }else { @@ -3415,12 +3414,14 @@ HRESULT exec_source(script_ctx_t *ctx, DWORD flags, bytecode_t *bytecode, functi frame->bytecode = bytecode_addref(bytecode);
if(!(flags & (EXEC_GLOBAL|EXEC_EVAL))) { - hres = setup_scope(ctx, frame, scope, variable_obj, argc, argv); + hres = setup_scope(ctx, frame, scope, NULL, argc, argv); if(FAILED(hres)) { release_bytecode(frame->bytecode); free(frame); goto fail; } + variable_obj = jsdisp_addref(&frame->scope->dispex); + frame->scope->obj = to_disp(variable_obj); }else if(scope) { frame->base_scope = frame->scope = scope_addref(scope); } diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 9b29373a0da..b6f26232059 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -223,8 +223,8 @@ static inline bytecode_t *bytecode_addref(bytecode_t *code) }
typedef struct _scope_chain_t { - jsdisp_t dispex; /* FIXME: don't wrap it in a jsdisp (it holds ref and traverse for the garbage collector) */ - IDispatch *obj; + jsdisp_t dispex; + IDispatch *obj; /* Does not hold ref when it's set to scope's dispex (prevents cyclic ref for a very common case) */ unsigned int scope_index; struct _call_frame_t *frame; struct _scope_chain_t *next;