diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 1b7ae50843d..2cd4ad5025a 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -740,8 +740,15 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc return hres; } -static HRESULT delete_prop(dispex_prop_t *prop) +static HRESULT delete_prop(dispex_prop_t *prop, BOOL *ret) { + if(prop->flags & PROPF_DONTDELETE) { + *ret = FALSE; + return S_OK; + } + + *ret = TRUE; /* FIXME: not exactly right */ + if(prop->type == PROP_JSVAL) { jsval_release(prop->u.val); prop->type = PROP_DELETED; @@ -753,6 +760,7 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bst { jsdisp_t *This = impl_from_IDispatchEx(iface); dispex_prop_t *prop; + BOOL b; HRESULT hres; TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex); @@ -768,13 +776,14 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bst return S_OK; } - return delete_prop(prop); + return delete_prop(prop, &b); } static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id) { jsdisp_t *This = impl_from_IDispatchEx(iface); dispex_prop_t *prop; + BOOL b; TRACE("(%p)->(%x)\n", This, id); @@ -784,7 +793,7 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID return DISP_E_MEMBERNOTFOUND; } - return delete_prop(prop); + return delete_prop(prop, &b); } static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) @@ -1266,18 +1275,23 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W return hres; } -HRESULT jsdisp_propput_name(jsdisp_t *obj, const WCHAR *name, jsval_t val) +HRESULT jsdisp_propput(jsdisp_t *obj, const WCHAR *name, DWORD flags, jsval_t val) { dispex_prop_t *prop; HRESULT hres; - hres = ensure_prop_name(obj, name, FALSE, PROPF_ENUM, &prop); + hres = ensure_prop_name(obj, name, FALSE, flags, &prop); if(FAILED(hres)) return hres; return prop_put(obj, prop, val, NULL); } +HRESULT jsdisp_propput_name(jsdisp_t *obj, const WCHAR *name, jsval_t val) +{ + return jsdisp_propput(obj, name, PROPF_ENUM, val); +} + HRESULT jsdisp_propput_const(jsdisp_t *obj, const WCHAR *name, jsval_t val) { dispex_prop_t *prop; @@ -1292,14 +1306,7 @@ HRESULT jsdisp_propput_const(jsdisp_t *obj, const WCHAR *name, jsval_t val) HRESULT jsdisp_propput_dontenum(jsdisp_t *obj, const WCHAR *name, jsval_t val) { - dispex_prop_t *prop; - HRESULT hres; - - hres = ensure_prop_name(obj, name, FALSE, 0, &prop); - if(FAILED(hres)) - return hres; - - return prop_put(obj, prop, val, NULL); + return jsdisp_propput(obj, name, 0, val); } HRESULT jsdisp_propput_idx(jsdisp_t *obj, DWORD idx, jsval_t val) @@ -1451,6 +1458,7 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx) static const WCHAR formatW[] = {'%','d',0}; WCHAR buf[12]; dispex_prop_t *prop; + BOOL b; HRESULT hres; sprintfW(buf, formatW, idx); @@ -1459,7 +1467,7 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx) if(FAILED(hres) || !prop) return hres; - return delete_prop(prop); + return delete_prop(prop, &b); } HRESULT disp_delete(IDispatch *disp, DISPID id, BOOL *ret) @@ -1472,10 +1480,9 @@ HRESULT disp_delete(IDispatch *disp, DISPID id, BOOL *ret) if(jsdisp) { dispex_prop_t *prop; - *ret = TRUE; prop = get_prop(jsdisp, id); if(prop) - hres = delete_prop(prop); + hres = delete_prop(prop, ret); else hres = DISP_E_MEMBERNOTFOUND; @@ -1508,10 +1515,9 @@ HRESULT disp_delete_name(script_ctx_t *ctx, IDispatch *disp, jsstr_t *name, BOOL if(jsdisp) { dispex_prop_t *prop; - *ret = TRUE; hres = find_prop_name(jsdisp, string_hash(name->str), name->str, &prop); if(prop) - hres = delete_prop(prop); + hres = delete_prop(prop, ret); else hres = DISP_E_MEMBERNOTFOUND; diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 329bec2aef0..5c7f9b5dc0d 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -220,7 +220,7 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis return hres; } - hres = jsdisp_propput_name(var_disp, argumentsW, jsval_obj(arg_disp)); + hres = jsdisp_propput(var_disp, argumentsW, PROPF_DONTDELETE, jsval_obj(arg_disp)); if(SUCCEEDED(hres)) { hres = scope_push(function->scope_chain, var_disp, to_disp(var_disp), &scope); if(SUCCEEDED(hres)) { diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 69ac417c4f3..5bffc2131fa 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -95,11 +95,12 @@ typedef struct jsdisp_t jsdisp_t; extern HINSTANCE jscript_hinstance DECLSPEC_HIDDEN; -#define PROPF_ARGMASK 0x00ff -#define PROPF_METHOD 0x0100 -#define PROPF_ENUM 0x0200 -#define PROPF_CONSTR 0x0400 -#define PROPF_CONST 0x0800 +#define PROPF_ARGMASK 0x00ff +#define PROPF_METHOD 0x0100 +#define PROPF_ENUM 0x0200 +#define PROPF_CONSTR 0x0400 +#define PROPF_CONST 0x0800 +#define PROPF_DONTDELETE 0x1000 /* NOTE: Keep in sync with names in Object.toString implementation */ typedef enum { @@ -268,6 +269,7 @@ HRESULT jsdisp_call_name(jsdisp_t*,const WCHAR*,WORD,unsigned,jsval_t*,jsval_t*) HRESULT disp_propget(script_ctx_t*,IDispatch*,DISPID,jsval_t*) DECLSPEC_HIDDEN; HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,jsval_t) DECLSPEC_HIDDEN; HRESULT jsdisp_propget(jsdisp_t*,DISPID,jsval_t*) DECLSPEC_HIDDEN; +HRESULT jsdisp_propput(jsdisp_t*,const WCHAR*,DWORD,jsval_t) DECLSPEC_HIDDEN; HRESULT jsdisp_propput_name(jsdisp_t*,const WCHAR*,jsval_t) DECLSPEC_HIDDEN; HRESULT jsdisp_propput_const(jsdisp_t*,const WCHAR*,jsval_t) DECLSPEC_HIDDEN; HRESULT jsdisp_propput_dontenum(jsdisp_t*,const WCHAR*,jsval_t) DECLSPEC_HIDDEN; diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index fa3d6d2aca7..92292a42993 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -86,6 +86,10 @@ function testFunc1(x, y) { ok(this === test, "this !== test"); eval('ok(this === test, "this !== test");'); + tmp = delete arguments; + ok(tmp === false, "arguments deleted"); + ok(typeof(arguments) === "object", "typeof(arguments) = " + typeof(arguments)); + return true; }