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