Module: wine Branch: master Commit: ff829f0beb27b42d332a08c9b01ee9e1dcc2f77c URL: https://source.winehq.org/git/wine.git/?a=commit;h=ff829f0beb27b42d332a08c9b...
Author: Jacek Caban jacek@codeweavers.com Date: Tue May 15 13:26:52 2018 +0200
jscript: Support setting accessor property value.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/jscript/dispex.c | 30 +++++++++++++++++++++--------- dlls/mshtml/tests/es5.js | 20 ++++++++++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index e6835db..9b47368 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -296,15 +296,12 @@ static HRESULT find_prop_name_prot(jsdisp_t *This, unsigned hash, const WCHAR *n return S_OK; }
-static HRESULT ensure_prop_name(jsdisp_t *This, const WCHAR *name, BOOL search_prot, DWORD create_flags, dispex_prop_t **ret) +static HRESULT ensure_prop_name(jsdisp_t *This, const WCHAR *name, DWORD create_flags, dispex_prop_t **ret) { dispex_prop_t *prop; HRESULT hres;
- if(search_prot) - hres = find_prop_name_prot(This, string_hash(name), name, &prop); - else - hres = find_prop_name(This, string_hash(name), name, &prop); + hres = find_prop_name_prot(This, string_hash(name), name, &prop); if(SUCCEEDED(hres) && (!prop || prop->type == PROP_DELETED)) { TRACE("creating prop %s flags %x\n", debugstr_w(name), create_flags);
@@ -495,6 +492,18 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val) { HRESULT hres;
+ if(prop->type == PROP_PROTREF) { + dispex_prop_t *prop_iter = prop; + jsdisp_t *prototype_iter = This; + + do { + prototype_iter = prototype_iter->prototype; + prop_iter = prototype_iter->props + prop_iter->u.ref; + } while(prop_iter->type == PROP_PROTREF); + + if(prop_iter->type == PROP_ACCESSOR) + prop = prop_iter; + }
switch(prop->type) { case PROP_BUILTIN: @@ -516,8 +525,11 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val) jsval_release(prop->u.val); break; case PROP_ACCESSOR: - FIXME("not supported for accessor properties\n"); - return E_NOTIMPL; + if(!prop->u.accessor.setter) { + TRACE("no setter\n"); + return S_OK; + } + return jsdisp_call_value(prop->u.accessor.setter, to_disp(This), DISPATCH_METHOD, 1, &val, NULL); case PROP_IDX: if(!This->builtin_info->idx_put) { TRACE("no put_idx\n"); @@ -1079,7 +1091,7 @@ HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID * HRESULT hres;
if(flags & fdexNameEnsure) - hres = ensure_prop_name(jsdisp, name, TRUE, PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE, + hres = ensure_prop_name(jsdisp, name, PROPF_ENUMERABLE | PROPF_CONFIGURABLE | PROPF_WRITABLE, &prop); else hres = find_prop_name_prot(jsdisp, string_hash(name), name, &prop); @@ -1343,7 +1355,7 @@ HRESULT jsdisp_propput(jsdisp_t *obj, const WCHAR *name, DWORD flags, jsval_t va dispex_prop_t *prop; HRESULT hres;
- hres = ensure_prop_name(obj, name, FALSE, flags, &prop); + hres = ensure_prop_name(obj, name, flags, &prop); if(FAILED(hres)) return hres;
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 4e7b83b..62cf12a 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -258,6 +258,10 @@ function test_defineProperty() { test_accessor_prop_desc(obj, "getsetprop", desc);
ok(obj.getsetprop === 1, "getsetprop = " + obj.getsetprop); + obj.getsetprop = 2; + ok(getsetprop_value === 2, "getsetprop_value = " + getsetprop_value); + test_accessor_prop_desc(obj, "getsetprop", desc); + ok(obj.getsetprop === 2, "getsetprop = " + obj.getsetprop);
Object.defineProperty(obj, "notConf", {writable: true, enumerable: true, configurable: false, value: 1}); test_own_data_prop_desc(obj, "notConf", true, true, false); @@ -395,6 +399,9 @@ function test_defineProperty() { obj = new child(); getsetprop_value = 6; ok(obj.parent_accessor === 6, "parent_accessor = " + obj.parent_accessor); + obj.parent_accessor = 1; + ok(getsetprop_value === 1, "getsetprop_value = " + getsetprop_value); + ok(obj.parent_accessor === 1, "parent_accessor = " + obj.parent_accessor);
ok(Object.getOwnPropertyDescriptor(obj, "parent_accessor") === undefined, "getOwnPropertyDescriptor(parent_accessor) did not return undefined"); @@ -404,6 +411,19 @@ function test_defineProperty() { Object.defineProperty(child.prototype, "parent_accessor", desc); ok(obj.parent_accessor === undefined, "parent_accessor = " + obj.parent_accessor);
+ /* no setter */ + desc = { + get: function() { + ok(this === obj, "this != obj"); + return true; + }, + configurable: true + }; + Object.defineProperty(obj, "no_setter", desc); + test_accessor_prop_desc(obj, "no_setter", desc); + obj.no_setter = false; + ok(obj.no_setter === true, "no_setter = " + obj.no_setter); + next_test(); }