In preparation for host properties support.
From: Jacek Caban jacek@codeweavers.com
--- dlls/jscript/dispex.c | 51 ++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 22 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index a678421f0a3..72af7054570 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -244,6 +244,34 @@ static dispex_prop_t *alloc_protref(jsdisp_t *This, const WCHAR *name, DWORD ref return ret; }
+static HRESULT find_external_prop(jsdisp_t *This, const WCHAR *name, BOOL case_insens, dispex_prop_t **ret) +{ + dispex_prop_t *prop; + + if(This->builtin_info->idx_length) { + const WCHAR *ptr; + unsigned idx = 0; + + for(ptr = name; is_digit(*ptr) && idx < 0x10000; ptr++) + idx = idx*10 + (*ptr-'0'); + if(!*ptr && idx < This->builtin_info->idx_length(This)) { + unsigned flags = PROPF_ENUMERABLE; + if(This->builtin_info->idx_put) + flags |= PROPF_WRITABLE; + prop = alloc_prop(This, name, PROP_IDX, flags); + if(!prop) + return E_OUTOFMEMORY; + + prop->u.idx = idx; + *ret = prop; + return S_OK; + } + } + + *ret = NULL; + return S_OK; +} + static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens, dispex_prop_t **ret) { const builtin_prop_t *builtin; @@ -301,28 +329,7 @@ static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, return S_OK; }
- if(This->builtin_info->idx_length) { - const WCHAR *ptr; - unsigned idx = 0; - - for(ptr = name; is_digit(*ptr) && idx < 0x10000; ptr++) - idx = idx*10 + (*ptr-'0'); - if(!*ptr && idx < This->builtin_info->idx_length(This)) { - unsigned flags = PROPF_ENUMERABLE; - if(This->builtin_info->idx_put) - flags |= PROPF_WRITABLE; - prop = alloc_prop(This, name, PROP_IDX, flags); - if(!prop) - return E_OUTOFMEMORY; - - prop->u.idx = idx; - *ret = prop; - return S_OK; - } - } - - *ret = NULL; - return S_OK; + return find_external_prop(This, name, case_insens, ret); }
static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens, dispex_prop_t **ret)
From: Jacek Caban jacek@codeweavers.com
--- dlls/jscript/dispex.c | 26 +++++++++++++------------- dlls/jscript/engine.c | 8 ++++---- dlls/jscript/function.c | 8 ++++---- dlls/jscript/jscript.h | 4 ++-- dlls/jscript/string.c | 4 ++-- 5 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 72af7054570..ed1cf397927 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -36,7 +36,7 @@ typedef enum { PROP_PROTREF, PROP_ACCESSOR, PROP_DELETED, - PROP_IDX + PROP_EXTERN } prop_type_t;
struct _dispex_prop_t { @@ -49,7 +49,7 @@ struct _dispex_prop_t { jsval_t val; const builtin_prop_t *p; DWORD ref; - unsigned idx; + unsigned id; struct { jsdisp_t *getter; jsdisp_t *setter; @@ -256,13 +256,13 @@ static HRESULT find_external_prop(jsdisp_t *This, const WCHAR *name, BOOL case_i idx = idx*10 + (*ptr-'0'); if(!*ptr && idx < This->builtin_info->idx_length(This)) { unsigned flags = PROPF_ENUMERABLE; - if(This->builtin_info->idx_put) + if(This->builtin_info->prop_put) flags |= PROPF_WRITABLE; - prop = alloc_prop(This, name, PROP_IDX, flags); + prop = alloc_prop(This, name, PROP_EXTERN, flags); if(!prop) return E_OUTOFMEMORY;
- prop->u.idx = idx; + prop->u.id = idx; *ret = prop; return S_OK; } @@ -475,8 +475,8 @@ static HRESULT prop_get(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t *prop, hres = S_OK; } break; - case PROP_IDX: - hres = prop_obj->builtin_info->idx_get(prop_obj, prop->u.idx, r); + case PROP_EXTERN: + hres = prop_obj->builtin_info->prop_get(prop_obj, prop->u.id, r); break; default: ERR("type %d\n", prop->type); @@ -536,12 +536,12 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val) return S_OK; } return jsdisp_call_value(prop->u.accessor.setter, jsval_obj(This), DISPATCH_METHOD, 1, &val, NULL); - case PROP_IDX: - if(!This->builtin_info->idx_put) { - TRACE("no put_idx\n"); + case PROP_EXTERN: + if(!This->builtin_info->prop_put) { + TRACE("no prop_put\n"); return S_OK; } - return This->builtin_info->idx_put(This, prop->u.idx, val); + return This->builtin_info->prop_put(This, prop->u.id, val); default: ERR("type %d\n", prop->type); return E_FAIL; @@ -583,7 +583,7 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t flags, argc, argv, r, caller); } case PROP_ACCESSOR: - case PROP_IDX: { + case PROP_EXTERN: { jsval_t val;
hres = prop_get(This, jsthis ? jsthis : (IDispatch *)&This->IDispatchEx_iface, prop, &val); @@ -2976,7 +2976,7 @@ HRESULT jsdisp_get_own_property(jsdisp_t *obj, const WCHAR *name, BOOL flags_onl switch(prop->type) { case PROP_BUILTIN: case PROP_JSVAL: - case PROP_IDX: + case PROP_EXTERN: desc->mask |= PROPF_WRITABLE; desc->explicit_value = TRUE; if(!flags_only) { diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 60b479fb83b..2e52bb5ed2f 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -485,14 +485,14 @@ static unsigned scope_idx_length(jsdisp_t *dispex) return scope->detached_vars->argc; }
-static HRESULT scope_idx_get(jsdisp_t *dispex, unsigned idx, jsval_t *r) +static HRESULT scope_prop_get(jsdisp_t *dispex, unsigned idx, jsval_t *r) { scope_chain_t *scope = scope_from_dispex(dispex);
return jsval_copy(scope->detached_vars->var[idx], r); }
-static HRESULT scope_idx_put(jsdisp_t *dispex, unsigned idx, jsval_t val) +static HRESULT scope_prop_put(jsdisp_t *dispex, unsigned idx, jsval_t val) { scope_chain_t *scope = scope_from_dispex(dispex); jsval_t copy, *ref; @@ -547,8 +547,8 @@ static const builtin_info_t scope_info = { JSCLASS_NONE, .destructor = scope_destructor, .idx_length = scope_idx_length, - .idx_get = scope_idx_get, - .idx_put = scope_idx_put, + .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 9c339b807f7..7f0779c2aff 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -132,7 +132,7 @@ static jsval_t *get_argument_ref(ArgumentsInstance *arguments, unsigned idx) return arguments->scope->detached_vars->var + idx; }
-static HRESULT Arguments_idx_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r) +static HRESULT Arguments_prop_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r) { ArgumentsInstance *arguments = arguments_from_jsdisp(jsdisp);
@@ -141,7 +141,7 @@ static HRESULT Arguments_idx_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r) return jsval_copy(*get_argument_ref(arguments, idx), r); }
-static HRESULT Arguments_idx_put(jsdisp_t *jsdisp, unsigned idx, jsval_t val) +static HRESULT Arguments_prop_put(jsdisp_t *jsdisp, unsigned idx, jsval_t val) { ArgumentsInstance *arguments = arguments_from_jsdisp(jsdisp); jsval_t copy, *ref; @@ -187,8 +187,8 @@ static const builtin_info_t Arguments_info = { .call = Arguments_value, .destructor = Arguments_destructor, .idx_length = Arguments_idx_length, - .idx_get = Arguments_idx_get, - .idx_put = Arguments_idx_put, + .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 80641731006..7ee6949bdea 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -186,8 +186,8 @@ typedef struct { void (*destructor)(jsdisp_t*); void (*on_put)(jsdisp_t*,const WCHAR*); unsigned (*idx_length)(jsdisp_t*); - HRESULT (*idx_get)(jsdisp_t*,unsigned,jsval_t*); - HRESULT (*idx_put)(jsdisp_t*,unsigned,jsval_t); + 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*); } builtin_info_t;
diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c index ab7497912f2..9e1b7aff11c 100644 --- a/dlls/jscript/string.c +++ b/dlls/jscript/string.c @@ -1515,7 +1515,7 @@ static unsigned String_idx_length(jsdisp_t *jsdisp) return string->dispex.ctx->version < 2 ? 0 : jsstr_length(string->str); }
-static HRESULT String_idx_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r) +static HRESULT String_prop_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r) { StringInstance *string = string_from_jsdisp(jsdisp); jsstr_t *ret; @@ -1584,7 +1584,7 @@ static const builtin_info_t StringInst_info = { .props = StringInst_props, .destructor = String_destructor, .idx_length = String_idx_length, - .idx_get = String_idx_get, + .prop_get = String_prop_get, };
/* ECMA-262 3rd Edition 15.5.3.2 */
From: Jacek Caban jacek@codeweavers.com
And use it in find_external_prop. --- dlls/jscript/dispex.c | 42 +++++++++++++++++++++++++++++------------ dlls/jscript/engine.c | 8 ++++++++ dlls/jscript/function.c | 7 +++++++ dlls/jscript/jscript.h | 8 ++++++++ dlls/jscript/string.c | 29 ++++++++++++++++++++++------ 5 files changed, 76 insertions(+), 18 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index ed1cf397927..0cb2c650407 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -248,21 +248,20 @@ static HRESULT find_external_prop(jsdisp_t *This, const WCHAR *name, BOOL case_i { dispex_prop_t *prop;
- if(This->builtin_info->idx_length) { - const WCHAR *ptr; - unsigned idx = 0; - - for(ptr = name; is_digit(*ptr) && idx < 0x10000; ptr++) - idx = idx*10 + (*ptr-'0'); - if(!*ptr && idx < This->builtin_info->idx_length(This)) { - unsigned flags = PROPF_ENUMERABLE; - if(This->builtin_info->prop_put) - flags |= PROPF_WRITABLE; - prop = alloc_prop(This, name, PROP_EXTERN, flags); + if(This->builtin_info->lookup_prop) { + struct property_info desc; + HRESULT hres; + + hres = This->builtin_info->lookup_prop(This, name, &desc); + if(hres != DISP_E_UNKNOWNNAME) { + if(FAILED(hres)) + return hres; + + prop = alloc_prop(This, name, PROP_EXTERN, desc.flags); if(!prop) return E_OUTOFMEMORY;
- prop->u.id = idx; + prop->u.id = desc.id; *ret = prop; return S_OK; } @@ -398,6 +397,25 @@ static HRESULT ensure_prop_name(jsdisp_t *This, const WCHAR *name, DWORD create_ return hres; }
+HRESULT jsdisp_index_lookup(jsdisp_t *obj, const WCHAR *name, unsigned length, struct property_info *desc) +{ + const WCHAR *ptr; + unsigned idx = 0; + + for(ptr = name; is_digit(*ptr); ptr++) { + idx = idx * 10 + (*ptr - '0'); + if (idx >= length) + return DISP_E_UNKNOWNNAME; + } + if(*ptr) + return DISP_E_UNKNOWNNAME; + desc->id = idx; + 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; diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 2e52bb5ed2f..d20939785fe 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -478,6 +478,13 @@ static void scope_destructor(jsdisp_t *dispex) IDispatch_Release(scope->obj); }
+static HRESULT scope_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, struct property_info *desc) +{ + scope_chain_t *scope = scope_from_dispex(jsdisp); + + 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); @@ -546,6 +553,7 @@ static HRESULT scope_gc_traverse(struct gc_ctx *gc_ctx, enum gc_traverse_op op, 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, diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 7f0779c2aff..5af834769ff 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -117,6 +117,12 @@ static void Arguments_destructor(jsdisp_t *jsdisp) scope_release(arguments->scope); }
+static HRESULT Arguments_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, struct property_info *desc) +{ + ArgumentsInstance *arguments = arguments_from_jsdisp(jsdisp); + return jsdisp_index_lookup(&arguments->jsdisp, name, arguments->argc, desc); +} + static unsigned Arguments_idx_length(jsdisp_t *jsdisp) { ArgumentsInstance *arguments = arguments_from_jsdisp(jsdisp); @@ -186,6 +192,7 @@ static const builtin_info_t Arguments_info = { .class = JSCLASS_ARGUMENTS, .call = Arguments_value, .destructor = Arguments_destructor, + .lookup_prop = Arguments_lookup_prop, .idx_length = Arguments_idx_length, .prop_get = Arguments_prop_get, .prop_put = Arguments_prop_put, diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 7ee6949bdea..a7a9f8cf6d4 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -178,6 +178,12 @@ typedef struct { builtin_setter_t setter; } builtin_prop_t;
+struct property_info +{ + UINT32 id; + UINT32 flags; +}; + typedef struct { jsclass_t class; builtin_invoke_t call; @@ -186,6 +192,7 @@ typedef struct { 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 (*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*); @@ -281,6 +288,7 @@ HRESULT jsdisp_get_id(jsdisp_t*,const WCHAR*,DWORD,DISPID*); 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_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 9e1b7aff11c..f5f01adf871 100644 --- a/dlls/jscript/string.c +++ b/dlls/jscript/string.c @@ -1501,6 +1501,22 @@ static void String_destructor(jsdisp_t *dispex) jsstr_release(This->str); }
+static HRESULT String_lookup_prop(jsdisp_t *jsdisp, const WCHAR *name, 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. + */ + if(string->dispex.ctx->version < 2) + return DISP_E_UNKNOWNNAME; + + return jsdisp_index_lookup(&string->dispex, name, jsstr_length(string->str), desc); +} + static unsigned String_idx_length(jsdisp_t *jsdisp) { StringInstance *string = string_from_jsdisp(jsdisp); @@ -1579,12 +1595,13 @@ static const builtin_prop_t StringInst_props[] = { };
static const builtin_info_t StringInst_info = { - .class = JSCLASS_STRING, - .props_cnt = ARRAY_SIZE(StringInst_props), - .props = StringInst_props, - .destructor = String_destructor, - .idx_length = String_idx_length, - .prop_get = String_prop_get, + .class = JSCLASS_STRING, + .props_cnt = ARRAY_SIZE(StringInst_props), + .props = StringInst_props, + .destructor = String_destructor, + .lookup_prop = String_lookup_prop, + .idx_length = String_idx_length, + .prop_get = String_prop_get, };
/* ECMA-262 3rd Edition 15.5.3.2 */
From: Jacek Caban jacek@codeweavers.com
--- dlls/jscript/dispex.c | 45 +++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 17 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 0cb2c650407..ae81accb1b2 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -244,6 +244,30 @@ static dispex_prop_t *alloc_protref(jsdisp_t *This, const WCHAR *name, DWORD ref return ret; }
+static dispex_prop_t *lookup_dispex_prop(jsdisp_t *obj, unsigned hash, const WCHAR *name, BOOL case_insens) +{ + unsigned bucket, pos, prev = ~0; + + bucket = get_props_idx(obj, hash); + pos = obj->props[bucket].bucket_head; + while(pos != ~0) { + if(case_insens ? !wcsicmp(name, obj->props[pos].name) : !wcscmp(name, obj->props[pos].name)) { + if(prev != ~0) { + obj->props[prev].bucket_next = obj->props[pos].bucket_next; + obj->props[pos].bucket_next = obj->props[bucket].bucket_head; + obj->props[bucket].bucket_head = pos; + } + + return &obj->props[pos]; + } + + prev = pos; + pos = obj->props[pos].bucket_next; + } + + return NULL; +} + static HRESULT find_external_prop(jsdisp_t *This, const WCHAR *name, BOOL case_insens, dispex_prop_t **ret) { dispex_prop_t *prop; @@ -274,26 +298,13 @@ static HRESULT find_external_prop(jsdisp_t *This, const WCHAR *name, BOOL case_i static HRESULT find_prop_name(jsdisp_t *This, unsigned hash, const WCHAR *name, BOOL case_insens, dispex_prop_t **ret) { const builtin_prop_t *builtin; - unsigned bucket, pos, prev = ~0; dispex_prop_t *prop; HRESULT hres;
- bucket = get_props_idx(This, hash); - pos = This->props[bucket].bucket_head; - while(pos != ~0) { - if(case_insens ? !wcsicmp(name, This->props[pos].name) : !wcscmp(name, This->props[pos].name)) { - if(prev != ~0) { - This->props[prev].bucket_next = This->props[pos].bucket_next; - This->props[pos].bucket_next = This->props[bucket].bucket_head; - This->props[bucket].bucket_head = pos; - } - - *ret = &This->props[pos]; - return S_OK; - } - - prev = pos; - pos = This->props[pos].bucket_next; + prop = lookup_dispex_prop(This, hash, name, case_insens); + if(prop) { + *ret = prop; + return S_OK; }
builtin = find_builtin_prop(This, name, case_insens);
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, };
From: Jacek Caban jacek@codeweavers.com
Based on patch by Gabriel Ivăncescu. --- dlls/jscript/dispex.c | 15 ++------------- dlls/jscript/error.c | 15 +++++++++++++++ dlls/jscript/jscript.h | 1 + 3 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 81fdc3d4799..e45e22f3a44 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -2496,19 +2496,8 @@ static HRESULT disp_invoke(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD f hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, params, r, &ei, &err); }
- if(hres == DISP_E_EXCEPTION) { - TRACE("DISP_E_EXCEPTION: %08lx %s %s\n", ei.scode, debugstr_w(ei.bstrSource), debugstr_w(ei.bstrDescription)); - reset_ei(ctx->ei); - ctx->ei->error = (SUCCEEDED(ei.scode) || ei.scode == DISP_E_EXCEPTION) ? E_FAIL : ei.scode; - if(ei.bstrSource) - ctx->ei->source = jsstr_alloc_len(ei.bstrSource, SysStringLen(ei.bstrSource)); - if(ei.bstrDescription) - ctx->ei->message = jsstr_alloc_len(ei.bstrDescription, SysStringLen(ei.bstrDescription)); - SysFreeString(ei.bstrSource); - SysFreeString(ei.bstrDescription); - SysFreeString(ei.bstrHelpFile); - } - + if(hres == DISP_E_EXCEPTION) + handle_dispatch_exception(ctx, &ei); return hres; }
diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c index e1f04aef38c..a3388ee9a27 100644 --- a/dlls/jscript/error.c +++ b/dlls/jscript/error.c @@ -402,6 +402,21 @@ HRESULT throw_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str) return DISP_E_EXCEPTION; }
+void handle_dispatch_exception(script_ctx_t *ctx, EXCEPINFO *ei) +{ + TRACE("%08lx %s %s\n", ei->scode, debugstr_w(ei->bstrSource), debugstr_w(ei->bstrDescription)); + + reset_ei(ctx->ei); + ctx->ei->error = (SUCCEEDED(ei->scode) || ei->scode == DISP_E_EXCEPTION) ? E_FAIL : ei->scode; + if(ei->bstrSource) + ctx->ei->source = jsstr_alloc_len(ei->bstrSource, SysStringLen(ei->bstrSource)); + if(ei->bstrDescription) + ctx->ei->message = jsstr_alloc_len(ei->bstrDescription, SysStringLen(ei->bstrDescription)); + SysFreeString(ei->bstrSource); + SysFreeString(ei->bstrDescription); + SysFreeString(ei->bstrHelpFile); +} + void set_error_location(jsexcept_t *ei, bytecode_t *code, unsigned loc, unsigned source_id, jsstr_t *line) { if(is_jscript_error(ei->error)) { diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 5adf2a2590a..e091e7acd90 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -312,6 +312,7 @@ struct _function_code_t *Function_get_code(jsdisp_t*);
HRESULT throw_error(script_ctx_t*,HRESULT,const WCHAR*); jsdisp_t *create_builtin_error(script_ctx_t *ctx); +void handle_dispatch_exception(script_ctx_t *ctx, EXCEPINFO *ei);
HRESULT create_object(script_ctx_t*,jsdisp_t*,jsdisp_t**); HRESULT create_math(script_ctx_t*,jsdisp_t**);
From: Jacek Caban jacek@codeweavers.com
--- dlls/jscript/dispex.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index e45e22f3a44..8813f6bb71a 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -608,7 +608,7 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t case PROP_BUILTIN: return JS_E_FUNCTION_EXPECTED; case PROP_PROTREF: - return invoke_prop_func(This->prototype, jsthis ? jsthis : (IDispatch *)&This->IDispatchEx_iface, + return invoke_prop_func(This->prototype, jsthis ? jsthis : to_disp(This), This->prototype->props+prop->u.ref, flags, argc, argv, r, caller); case PROP_JSVAL: { if(!is_object_instance(prop->u.val)) { @@ -619,20 +619,20 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t TRACE("call %s %p\n", debugstr_w(prop->name), get_object(prop->u.val));
return disp_call_value_with_caller(This->ctx, get_object(prop->u.val), - jsval_disp(jsthis ? jsthis : (IDispatch*)&This->IDispatchEx_iface), + jsval_disp(jsthis ? jsthis : to_disp(This)), flags, argc, argv, r, caller); } case PROP_ACCESSOR: case PROP_EXTERN: { jsval_t val;
- hres = prop_get(This, jsthis ? jsthis : (IDispatch *)&This->IDispatchEx_iface, prop, &val); + hres = prop_get(This, jsthis ? jsthis : to_disp(This), prop, &val); if(FAILED(hres)) return hres;
if(is_object_instance(val)) { hres = disp_call_value_with_caller(This->ctx, get_object(val), - jsval_disp(jsthis ? jsthis : (IDispatch*)&This->IDispatchEx_iface), + jsval_disp(jsthis ? jsthis : to_disp(This)), flags, argc, argv, r, caller); }else { FIXME("invoke %s\n", debugstr_jsval(val));
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=146876
Your paranoid android.
=== debian11 (build log) ===
error: patch failed: dlls/jscript/dispex.c:2496 error: patch failed: dlls/jscript/error.c:402 error: patch failed: dlls/jscript/jscript.h:312 Task: Patch failed to apply
=== debian11b (build log) ===
error: patch failed: dlls/jscript/dispex.c:2496 error: patch failed: dlls/jscript/error.c:402 error: patch failed: dlls/jscript/jscript.h:312 Task: Patch failed to apply
It's hard to say without seeing the rest, but are you sure this is going to end up with indexed props not having allocated props (PROP_EXTERN)? I mean that was one of the goals for Typed Arrays, even for enumerating.
On Mon Jul 8 18:36:54 2024 +0000, Gabriel Ivăncescu wrote:
It's hard to say without seeing the rest, but are you sure this is going to end up with indexed props not having allocated props (PROP_EXTERN)? I mean that was one of the goals for Typed Arrays, even for enumerating. Specifically I am talking about needing `next_prop`, or is that temporary?
Since we're returning the information needed to handle the property without relying on `dispex_prop_t`, it's a step in that direction (although I didn't actually try to implement that part).