[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-devel
Subject: [PATCH 4/4] jscript: Add interpreter support for getters and setters in object initializer.
From: Jacek Caban <jacek () codeweavers ! com>
Date: 2018-11-30 21:44:40
Message-ID: 7043e32a-debb-eee5-4e2e-5a1bd10fcd14 () codeweavers ! com
[Download RAW message or body]
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
---
dlls/jscript/compile.c | 9 ++----
dlls/jscript/engine.c | 24 +++++++++++++-
dlls/jscript/engine.h | 2 +-
dlls/mshtml/tests/es5.js | 69 +++++++++++++++++++++++++++++++++++++++-
4 files changed, 95 insertions(+), 9 deletions(-)
["0004-jscript-Add-interpreter-support-for-getters-and-sette.diff" (text/x-patch)]
diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index a498abda01..006386a4e9 100644
--- a/dlls/jscript/compile.c
+++ b/dlls/jscript/compile.c
@@ -889,7 +889,6 @@ static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expressi
static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr)
{
property_definition_t *iter;
- unsigned instr;
BSTR name;
HRESULT hres;
@@ -905,11 +904,9 @@ static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expres
if(FAILED(hres))
return hres;
- instr = push_instr(ctx, OP_obj_prop);
- if(!instr)
- return E_OUTOFMEMORY;
-
- instr_ptr(ctx, instr)->u.arg->bstr = name;
+ hres = push_instr_bstr_uint(ctx, OP_obj_prop, name, iter->type);
+ if(FAILED(hres))
+ return hres;
}
return S_OK;
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index bd4edda10d..0f9e3a5463 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -1445,6 +1445,7 @@ static HRESULT interp_new_obj(script_ctx_t *ctx)
static HRESULT interp_obj_prop(script_ctx_t *ctx)
{
const BSTR name = get_op_bstr(ctx, 0);
+ unsigned type = get_op_uint(ctx, 1);
jsdisp_t *obj;
jsval_t val;
HRESULT hres;
@@ -1456,7 +1457,28 @@ static HRESULT interp_obj_prop(script_ctx_t *ctx)
assert(is_object_instance(stack_top(ctx)));
obj = as_jsdisp(get_object(stack_top(ctx)));
- hres = jsdisp_propput_name(obj, name, val);
+ if(type == PROPERTY_DEFINITION_VALUE) {
+ hres = jsdisp_propput_name(obj, name, val);
+ }else {
+ property_desc_t desc = {PROPF_ENUMERABLE | PROPF_CONFIGURABLE};
+ jsdisp_t *func;
+
+ assert(is_object_instance(val));
+ func = iface_to_jsdisp(get_object(val));
+
+ desc.mask = desc.flags;
+ if(type == PROPERTY_DEFINITION_GETTER) {
+ desc.explicit_getter = TRUE;
+ desc.getter = func;
+ }else {
+ desc.explicit_setter = TRUE;
+ desc.setter = func;
+ }
+
+ hres = jsdisp_define_property(obj, name, &desc);
+ jsdisp_release(func);
+ }
+
jsval_release(val);
return hres;
}
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index d0c419a094..eb287d5167 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -66,7 +66,7 @@
X(new, 1, ARG_UINT, 0) \
X(new_obj, 1, 0,0) \
X(null, 1, 0,0) \
- X(obj_prop, 1, ARG_BSTR, 0) \
+ X(obj_prop, 1, ARG_BSTR, ARG_UINT) \
X(or, 1, 0,0) \
X(pop, 1, ARG_UINT, 0) \
X(pop_except, 0, ARG_ADDR, 0) \
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js
index 6097f4c6e6..3e8196119f 100644
--- a/dlls/mshtml/tests/es5.js
+++ b/dlls/mshtml/tests/es5.js
@@ -149,7 +149,7 @@ function test_identifier_keywords() {
}
function test_own_data_prop_desc(obj, prop, expected_writable, expected_enumerable,
- expected_configurable) {
+ expected_configurable) {
var desc = Object.getOwnPropertyDescriptor(obj, prop);
ok("value" in desc, "value is not in desc");
ok(desc.value === obj[prop], "desc.value = " + desc.value + " expected " + obj[prop]);
@@ -427,6 +427,72 @@ function test_defineProperty() {
next_test();
}
+function test_property_definitions() {
+ var obj, val, i, arr;
+
+ function test_accessor_prop_desc(obj, prop, have_getter, have_setter) {
+ var desc = Object.getOwnPropertyDescriptor(obj, prop);
+ ok(desc.enumerable === true, "desc.enumerable = " + desc.enumerable);
+ ok(desc.configurable === true, "desc.configurable = " + desc.configurable);
+
+ if(have_getter) {
+ ok(typeof(desc.get) === "function", "desc.get = " + desc.get);
+ ok(typeof(desc.get.prototype) === "object", "desc.get.prototype = " + desc.get.prototype);
+ trace("" + desc.get);
+ }else {
+ ok(!("get" in obj), "desc.get = " + desc.get);
+ }
+
+ if(have_setter) {
+ ok(typeof(desc.set) === "function", "desc.set = " + desc.set);
+ ok(typeof(desc.set.prototype) === "object", "desc.set.prototype = " + desc.set.prototype);
+ }else {
+ ok(!("set" in obj), "desc.get = " + desc.get);
+ }
+ }
+
+ obj = {
+ get prop() { return val + 1; },
+ set prop(v) { val = v; }
+ };
+ test_accessor_prop_desc(obj, "prop", true, true);
+ val = 0;
+ ok(obj.prop === 1, "obj.prop = " + obj.prop);
+ obj.prop = 3;
+ ok(val === 3, "val = " + val);
+ ok(obj.prop === 4, "obj.prop = " + obj.prop);
+
+ arr = [];
+ for(i in obj)
+ arr.push(i);
+ ok(arr.join() === "prop", "prop of obj = " + arr.join());
+
+ obj = {
+ set prop(v) { val = v; }
+ };
+ test_accessor_prop_desc(obj, "prop", false, true);
+ val = 1;
+ ok(obj.prop === undefined, "obj.prop = " + obj.prop);
+ obj.prop = 2;
+ ok(val === 2, "val = " + val);
+ ok(obj.prop === undefined, "obj.prop = " + obj.prop);
+
+ obj = {
+ get prop() { return val + 1; },
+ get 0() { return val + 2; }
+ };
+ test_accessor_prop_desc(obj, "prop", true, false);
+ val = 5;
+ ok(obj.prop === 6, "obj.prop = " + obj.prop);
+ obj.prop = 10;
+ ok(val === 5, "val = " + val);
+ ok(obj.prop === 6, "obj.prop = " + obj.prop);
+ test_accessor_prop_desc(obj, "0", true, false);
+ ok(obj[0] === 7, "obj.prop = " + obj[0]);
+
+ next_test();
+}
+
function test_string_trim() {
function test_trim(value, expected) {
var r = String.prototype.trim.call(value);
@@ -513,6 +579,7 @@ var tests = [
test_identifier_keywords,
test_getOwnPropertyDescriptor,
test_defineProperty,
+ test_property_definitions,
test_string_trim,
test_global_properties,
test_string_split
[Attachment #4 (text/plain)]
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic