From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 125 ++++++++++++++++++++++------------------- dlls/jscript/jscript.h | 1 + 2 files changed, 69 insertions(+), 57 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 9e87c38004f..f2e5109352e 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -775,6 +775,72 @@ static jsdisp_t *gc_stack_pop(struct gc_ctx *gc_ctx) return obj; }
+HRESULT gc_unmark(struct gc_ctx *gc_ctx, jsdisp_t *obj) +{ + dispex_prop_t *prop, *props_end; + script_ctx_t *ctx = obj->ctx; + jsdisp_t *link, *link2; + HRESULT hres; + + hres = gc_stack_push(gc_ctx, NULL); + if(FAILED(hres)) + return hres; + + do + { + obj->gc_marked = FALSE; + + for(prop = obj->props, props_end = prop + obj->prop_cnt; prop < props_end; prop++) { + switch(prop->type) { + case PROP_JSVAL: + if(!is_object_instance(prop->u.val)) + continue; + link = to_jsdisp(get_object(prop->u.val)); + link2 = NULL; + break; + case PROP_ACCESSOR: + link = prop->u.accessor.getter; + link2 = prop->u.accessor.setter; + break; + default: + continue; + } + if(link && link->gc_marked && link->ctx == ctx) { + hres = gc_stack_push(gc_ctx, link); + if(FAILED(hres)) + break; + } + if(link2 && link2->gc_marked && link2->ctx == ctx) { + hres = gc_stack_push(gc_ctx, link2); + if(FAILED(hres)) + break; + } + } + + if(FAILED(hres)) + break; + + if(obj->prototype && obj->prototype->gc_marked && obj->prototype->ctx == ctx) { + hres = gc_stack_push(gc_ctx, obj->prototype); + if(FAILED(hres)) + break; + } + + if(obj->builtin_info->gc_traverse) { + hres = obj->builtin_info->gc_traverse(gc_ctx, GC_TRAVERSE, obj); + if(FAILED(hres)) + break; + } + + do obj = gc_stack_pop(gc_ctx); while(obj && !obj->gc_marked); + } while(obj); + + if(FAILED(hres)) + do obj = gc_stack_pop(gc_ctx); while(obj); + + return hres; +} + HRESULT gc_run(script_ctx_t *ctx) { /* Save original refcounts in a linked list of chunks */ @@ -783,10 +849,10 @@ HRESULT gc_run(script_ctx_t *ctx) struct chunk *next; LONG ref[1020]; } *head, *chunk; - jsdisp_t *obj, *obj2, *link, *link2; dispex_prop_t *prop, *props_end; struct gc_ctx gc_ctx = { 0 }; unsigned chunk_idx = 0; + jsdisp_t *obj, *link; HRESULT hres = S_OK; struct list *iter;
@@ -845,64 +911,9 @@ HRESULT gc_run(script_ctx_t *ctx) if(!obj->ref || !obj->gc_marked) continue;
- hres = gc_stack_push(&gc_ctx, NULL); + hres = gc_unmark(&gc_ctx, obj); if(FAILED(hres)) break; - - obj2 = obj; - do - { - obj2->gc_marked = FALSE; - - for(prop = obj2->props, props_end = prop + obj2->prop_cnt; prop < props_end; prop++) { - switch(prop->type) { - case PROP_JSVAL: - if(!is_object_instance(prop->u.val)) - continue; - link = to_jsdisp(get_object(prop->u.val)); - link2 = NULL; - break; - case PROP_ACCESSOR: - link = prop->u.accessor.getter; - link2 = prop->u.accessor.setter; - break; - default: - continue; - } - if(link && link->gc_marked && link->ctx == ctx) { - hres = gc_stack_push(&gc_ctx, link); - if(FAILED(hres)) - break; - } - if(link2 && link2->gc_marked && link2->ctx == ctx) { - hres = gc_stack_push(&gc_ctx, link2); - if(FAILED(hres)) - break; - } - } - - if(FAILED(hres)) - break; - - if(obj2->prototype && obj2->prototype->gc_marked && obj2->prototype->ctx == ctx) { - hres = gc_stack_push(&gc_ctx, obj2->prototype); - if(FAILED(hres)) - break; - } - - if(obj2->builtin_info->gc_traverse) { - hres = obj2->builtin_info->gc_traverse(&gc_ctx, GC_TRAVERSE, obj2); - if(FAILED(hres)) - break; - } - - do obj2 = gc_stack_pop(&gc_ctx); while(obj2 && !obj2->gc_marked); - } while(obj2); - - if(FAILED(hres)) { - do obj2 = gc_stack_pop(&gc_ctx); while(obj2); - break; - } } free(gc_ctx.next);
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 46644b8247b..7be8e3bc24c 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -149,6 +149,7 @@ HRESULT create_named_item_script_obj(script_ctx_t*,named_item_t*); named_item_t *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned); void release_named_item(named_item_t*); HRESULT gc_run(script_ctx_t*); +HRESULT gc_unmark(struct gc_ctx*,jsdisp_t*); HRESULT gc_process_linked_obj(struct gc_ctx*,enum gc_traverse_op,jsdisp_t*,jsdisp_t*,void**); HRESULT gc_process_linked_val(struct gc_ctx*,enum gc_traverse_op,jsdisp_t*,jsval_t*);