Jacek Caban : jscript: Support setting accessor property value.
Alexandre Julliard
julliard at winehq.org
Tue May 15 16:25:22 CDT 2018
Module: wine
Branch: master
Commit: ff829f0beb27b42d332a08c9b01ee9e1dcc2f77c
URL: https://source.winehq.org/git/wine.git/?a=commit;h=ff829f0beb27b42d332a08c9b01ee9e1dcc2f77c
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue May 15 13:26:52 2018 +0200
jscript: Support setting accessor property value.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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();
}
More information about the wine-cvs
mailing list