Jacek Caban : jscript: Add Object.freeze implementation.

Alexandre Julliard julliard at winehq.org
Thu Apr 1 16:09:30 CDT 2021


Module: wine
Branch: master
Commit: 0d3634b3ffb1fe4d58a883244c9ab74b370f8aa1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=0d3634b3ffb1fe4d58a883244c9ab74b370f8aa1

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Apr  1 18:19:09 2021 +0200

jscript: Add Object.freeze implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/jscript/dispex.c    | 13 +++++++++++++
 dlls/jscript/jscript.h   |  1 +
 dlls/jscript/object.c    | 24 ++++++++++++++++++++++++
 dlls/mshtml/tests/es5.js | 41 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 79 insertions(+)

diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 9b11f607791..57f5d09daee 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -2628,6 +2628,19 @@ HRESULT jsdisp_define_data_property(jsdisp_t *obj, const WCHAR *name, unsigned f
     return jsdisp_define_property(obj, name, &prop_desc);
 }
 
+void jsdisp_freeze(jsdisp_t *obj)
+{
+    unsigned int i;
+
+    for(i = 0; i < obj->prop_cnt; i++) {
+        if(obj->props[i].type == PROP_JSVAL)
+            obj->props[i].flags &= ~PROPF_WRITABLE;
+        obj->props[i].flags &= ~PROPF_CONFIGURABLE;
+    }
+
+    obj->extensible = FALSE;
+}
+
 HRESULT jsdisp_get_prop_name(jsdisp_t *obj, DISPID id, jsstr_t **r)
 {
     dispex_prop_t *prop = get_prop(obj, id);
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 750158aabd9..d4ebb3246dd 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -317,6 +317,7 @@ HRESULT jsdisp_define_property(jsdisp_t*,const WCHAR*,property_desc_t*) DECLSPEC
 HRESULT jsdisp_define_data_property(jsdisp_t*,const WCHAR*,unsigned,jsval_t) DECLSPEC_HIDDEN;
 HRESULT jsdisp_next_prop(jsdisp_t*,DISPID,BOOL,DISPID*) DECLSPEC_HIDDEN;
 HRESULT jsdisp_get_prop_name(jsdisp_t*,DISPID,jsstr_t**);
+void jsdisp_freeze(jsdisp_t*) DECLSPEC_HIDDEN;
 
 HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
         jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c
index 8ff040853ef..3dcfd297a9b 100644
--- a/dlls/jscript/object.c
+++ b/dlls/jscript/object.c
@@ -693,6 +693,29 @@ static HRESULT Object_preventExtensions(script_ctx_t *ctx, vdisp_t *jsthis, WORD
     return S_OK;
 }
 
+static HRESULT Object_freeze(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc,
+                             jsval_t *argv, jsval_t *r)
+{
+    jsdisp_t *obj;
+
+    if(!argc || !is_object_instance(argv[0]) || !get_object(argv[0])) {
+        WARN("argument is not an object\n");
+        return JS_E_OBJECT_EXPECTED;
+    }
+
+    TRACE("(%s)\n", debugstr_jsval(argv[0]));
+
+    obj = to_jsdisp(get_object(argv[0]));
+    if(!obj) {
+        FIXME("Non-JS object\n");
+        return E_NOTIMPL;
+    }
+
+    jsdisp_freeze(obj);
+    if(r) *r = jsval_obj(jsdisp_addref(obj));
+    return S_OK;
+}
+
 static HRESULT Object_isExtensible(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
 {
     jsdisp_t *obj;
@@ -718,6 +741,7 @@ static const builtin_prop_t ObjectConstr_props[] = {
     {L"create",                   Object_create,                      PROPF_ES5|PROPF_METHOD|2},
     {L"defineProperties",         Object_defineProperties,            PROPF_ES5|PROPF_METHOD|2},
     {L"defineProperty",           Object_defineProperty,              PROPF_ES5|PROPF_METHOD|2},
+    {L"freeze",                   Object_freeze,                      PROPF_ES5|PROPF_METHOD|1},
     {L"getOwnPropertyDescriptor", Object_getOwnPropertyDescriptor,    PROPF_ES5|PROPF_METHOD|2},
     {L"getPrototypeOf",           Object_getPrototypeOf,              PROPF_ES5|PROPF_METHOD|1},
     {L"isExtensible",             Object_isExtensible,                PROPF_ES5|PROPF_METHOD|1},
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js
index 5851278e983..ae73d435456 100644
--- a/dlls/mshtml/tests/es5.js
+++ b/dlls/mshtml/tests/es5.js
@@ -983,6 +983,47 @@ sync_test("preventExtensions", function() {
     ok(Object.isExtensible.length === 1, "Object.isExtensible.length = " + Object.isExtensible.length);
 });
 
+sync_test("freeze", function() {
+    ok(Object.freeze.length === 1, "Object.freeze.length = " + Object.freeze.length);
+    try {
+        Object.freeze(1);
+        ok(false, "exception expected");
+    }catch(e) {
+        ok(e.name === "TypeError", "got " + e.name + " exception");
+    }
+
+    function f() {}
+
+    var o = {}, r;
+    o.prop = 1;
+    o.func = f;
+    Object.defineProperty(o, "accprop", {
+        get: function() {
+            return r;
+        },
+        set: function(v) {
+            r = v;
+        }
+    });
+
+    test_own_data_prop_desc(o, "prop", true, true, true);
+    r = Object.freeze(o);
+    ok(r === o, "r != o");
+    test_own_data_prop_desc(o, "prop", false, true, false);
+    test_own_data_prop_desc(o, "func", false, true, false);
+    ok(!Object.isExtensible(o), "o is still extensible");
+    o.prop = false;
+    o.func = false;
+    ok(o.prop === 1, "o.prop = " + o.prop);
+    ok(o.func === f, "o.func = " + o.func);
+
+    r = 1;
+    o.accprop = 2;
+    ok(r === 2, "r = " + r);
+    r = 3;
+    ok(o.accprop === 3, "o.accprop = " + o.accprop);
+});
+
 sync_test("head_setter", function() {
     document.head = "";
     ok(typeof(document.head) === "object", "typeof(document.head) = " + typeof(document.head));




More information about the wine-cvs mailing list