From: Jacek Caban jacek@codeweavers.com
And use it instead of idx_length. --- dlls/jscript/dispex.c | 34 +++++++++++++++++++++++++++++----- dlls/jscript/engine.c | 8 -------- dlls/jscript/function.c | 6 +++--- dlls/jscript/jscript.h | 3 ++- dlls/jscript/string.c | 16 ++++++---------- 5 files changed, 40 insertions(+), 27 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index ae81accb1b2..81fdc3d4799 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -427,6 +427,17 @@ HRESULT jsdisp_index_lookup(jsdisp_t *obj, const WCHAR *name, unsigned length, s return S_OK; }
+HRESULT jsdisp_next_index(jsdisp_t *obj, unsigned length, unsigned id, struct property_info *desc) +{ + if(id + 1 == length) + return S_FALSE; + desc->id = id + 1; + desc->flags = PROPF_ENUMERABLE; + if(obj->builtin_info->prop_put) + desc->flags |= PROPF_WRITABLE; + return S_OK; +} + static IDispatch *get_this(DISPPARAMS *dp) { DWORD i; @@ -650,15 +661,28 @@ static HRESULT fill_props(jsdisp_t *obj) dispex_prop_t *prop; HRESULT hres;
- if(obj->builtin_info->idx_length) { - unsigned i = 0, len = obj->builtin_info->idx_length(obj); + if(obj->builtin_info->next_prop) { + struct property_info desc; + unsigned id = ~0; WCHAR name[12];
- for(i = 0; i < len; i++) { - swprintf(name, ARRAY_SIZE(name), L"%u", i); - hres = find_prop_name(obj, string_hash(name), name, FALSE, &prop); + for(;;) { + hres = obj->builtin_info->next_prop(obj, id, &desc); if(FAILED(hres)) return hres; + if(hres == S_FALSE) + break; + + swprintf(name, ARRAYSIZE(name), L"%u", desc.id); + + prop = lookup_dispex_prop(obj, string_hash(name), name, FALSE); + if(!prop) { + prop = alloc_prop(obj, name, PROP_EXTERN, desc.flags); + if(!prop) + return E_OUTOFMEMORY; + prop->u.id = desc.id; + } + id = desc.id; } }
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index d20939785fe..e84d2f9b2d8 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -485,13 +485,6 @@ static HRESULT scope_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, struct pro return jsdisp_index_lookup(&scope->dispex, name, scope->detached_vars->argc, desc); }
-static unsigned scope_idx_length(jsdisp_t *dispex) -{ - scope_chain_t *scope = scope_from_dispex(dispex); - - return scope->detached_vars->argc; -} - static HRESULT scope_prop_get(jsdisp_t *dispex, unsigned idx, jsval_t *r) { scope_chain_t *scope = scope_from_dispex(dispex); @@ -554,7 +547,6 @@ static const builtin_info_t scope_info = { JSCLASS_NONE, .destructor = scope_destructor, .lookup_prop = scope_lookup_prop, - .idx_length = scope_idx_length, .prop_get = scope_prop_get, .prop_put = scope_prop_put, .gc_traverse = scope_gc_traverse diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 5af834769ff..654bf12c7e9 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -123,10 +123,10 @@ static HRESULT Arguments_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, struct return jsdisp_index_lookup(&arguments->jsdisp, name, arguments->argc, desc); }
-static unsigned Arguments_idx_length(jsdisp_t *jsdisp) +static HRESULT Arguments_next_prop(jsdisp_t *jsdisp, unsigned id, struct property_info *desc) { ArgumentsInstance *arguments = arguments_from_jsdisp(jsdisp); - return arguments->argc; + return jsdisp_next_index(&arguments->jsdisp, arguments->argc, id, desc); }
static jsval_t *get_argument_ref(ArgumentsInstance *arguments, unsigned idx) @@ -193,7 +193,7 @@ static const builtin_info_t Arguments_info = { .call = Arguments_value, .destructor = Arguments_destructor, .lookup_prop = Arguments_lookup_prop, - .idx_length = Arguments_idx_length, + .next_prop = Arguments_next_prop, .prop_get = Arguments_prop_get, .prop_put = Arguments_prop_put, .gc_traverse = Arguments_gc_traverse diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index a7a9f8cf6d4..5adf2a2590a 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -191,8 +191,8 @@ typedef struct { const builtin_prop_t *props; void (*destructor)(jsdisp_t*); void (*on_put)(jsdisp_t*,const WCHAR*); - unsigned (*idx_length)(jsdisp_t*); HRESULT (*lookup_prop)(jsdisp_t*,const WCHAR*,struct property_info*); + HRESULT (*next_prop)(jsdisp_t*,unsigned,struct property_info*); HRESULT (*prop_get)(jsdisp_t*,unsigned,jsval_t*); HRESULT (*prop_put)(jsdisp_t*,unsigned,jsval_t); HRESULT (*gc_traverse)(struct gc_ctx*,enum gc_traverse_op,jsdisp_t*); @@ -289,6 +289,7 @@ HRESULT jsdisp_get_idx_id(jsdisp_t*,DWORD,DISPID*); HRESULT disp_delete(IDispatch*,DISPID,BOOL*); HRESULT disp_delete_name(script_ctx_t*,IDispatch*,jsstr_t*,BOOL*); HRESULT jsdisp_index_lookup(jsdisp_t*,const WCHAR*,unsigned,struct property_info*); +HRESULT jsdisp_next_index(jsdisp_t*,unsigned,unsigned,struct property_info*); HRESULT jsdisp_delete_idx(jsdisp_t*,DWORD); HRESULT jsdisp_get_own_property(jsdisp_t*,const WCHAR*,BOOL,property_desc_t*); HRESULT jsdisp_define_property(jsdisp_t*,const WCHAR*,property_desc_t*); diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c index f5f01adf871..3cad5c55a79 100644 --- a/dlls/jscript/string.c +++ b/dlls/jscript/string.c @@ -1517,18 +1517,14 @@ static HRESULT String_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, struct pr return jsdisp_index_lookup(&string->dispex, name, jsstr_length(string->str), desc); }
-static unsigned String_idx_length(jsdisp_t *jsdisp) +static HRESULT String_next_prop(jsdisp_t *jsdisp, unsigned id, struct property_info *desc) { StringInstance *string = string_from_jsdisp(jsdisp);
- /* - * NOTE: For invoke version < 2, indexed array is not implemented at all. - * Newer jscript.dll versions implement it on string type, not class, - * which is not how it should work according to spec. IE9 implements it - * properly, but it uses its own JavaScript engine inside MSHTML. We - * implement it here, but in the way IE9 and spec work. - */ - return string->dispex.ctx->version < 2 ? 0 : jsstr_length(string->str); + if(string->dispex.ctx->version < 2) + return S_FALSE; + + return jsdisp_next_index(&string->dispex, jsstr_length(string->str), id, desc); }
static HRESULT String_prop_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r) @@ -1600,7 +1596,7 @@ static const builtin_info_t StringInst_info = { .props = StringInst_props, .destructor = String_destructor, .lookup_prop = String_lookup_prop, - .idx_length = String_idx_length, + .next_prop = String_next_prop, .prop_get = String_prop_get, };