jscript: Fixup PROTREF props when looking them up.
Convert them to PROP_DELETE if the referenced prop in the prototype chain doesn't exist anymore. Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
58722dfe35
commit
738894a47c
|
@ -60,6 +60,24 @@ struct _dispex_prop_t {
|
|||
int bucket_next;
|
||||
};
|
||||
|
||||
static void fix_protref_prop(jsdisp_t *jsdisp, dispex_prop_t *prop)
|
||||
{
|
||||
DWORD ref;
|
||||
|
||||
if(prop->type != PROP_PROTREF)
|
||||
return;
|
||||
ref = prop->u.ref;
|
||||
|
||||
while((jsdisp = jsdisp->prototype)) {
|
||||
if(ref >= jsdisp->prop_cnt || jsdisp->props[ref].type == PROP_DELETED)
|
||||
break;
|
||||
if(jsdisp->props[ref].type != PROP_PROTREF)
|
||||
return;
|
||||
ref = jsdisp->props[ref].u.ref;
|
||||
}
|
||||
prop->type = PROP_DELETED;
|
||||
}
|
||||
|
||||
static inline DISPID prop_to_id(jsdisp_t *This, dispex_prop_t *prop)
|
||||
{
|
||||
return prop - This->props;
|
||||
|
@ -67,10 +85,11 @@ static inline DISPID prop_to_id(jsdisp_t *This, dispex_prop_t *prop)
|
|||
|
||||
static inline dispex_prop_t *get_prop(jsdisp_t *This, DISPID id)
|
||||
{
|
||||
if(id < 0 || id >= This->prop_cnt || This->props[id].type == PROP_DELETED)
|
||||
if(id < 0 || id >= This->prop_cnt)
|
||||
return NULL;
|
||||
fix_protref_prop(This, &This->props[id]);
|
||||
|
||||
return This->props+id;
|
||||
return This->props[id].type == PROP_DELETED ? NULL : &This->props[id];
|
||||
}
|
||||
|
||||
static inline BOOL is_function_prop(dispex_prop_t *prop)
|
||||
|
@ -284,6 +303,7 @@ static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *n
|
|||
if(prop && prop->type==PROP_DELETED) {
|
||||
del = prop;
|
||||
} else if(prop) {
|
||||
fix_protref_prop(This, prop);
|
||||
*ret = prop;
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -292,7 +312,7 @@ static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *n
|
|||
hres = find_prop_name_prot(This->prototype, hash, name, &prop);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(prop) {
|
||||
if(prop && prop->type != PROP_DELETED) {
|
||||
if(del) {
|
||||
del->type = PROP_PROTREF;
|
||||
del->u.ref = prop - This->prototype->props;
|
||||
|
|
|
@ -1569,6 +1569,8 @@ ok((delete inobj.test1) === true, "delete inobj.test1 returned false");
|
|||
ok(!("test1" in inobj), "test1 is still in inobj after delete");
|
||||
ok((delete inobj.test3) === true, "delete inobj.test3 returned false");
|
||||
ok("test3" in inobj, "test3 is not in inobj after delete");
|
||||
ok((delete forinTestObj.prototype.test3) === true, "delete forinTestObj.prototype.test3 returned false");
|
||||
ok(!("test3" in inobj), "test3 is still in inobj after delete on prototype");
|
||||
|
||||
tmp = new Object();
|
||||
tmp.test = false;
|
||||
|
|
Loading…
Reference in New Issue