Jacek Caban : jscript: Add interpreter support for getters and setters in object initializer.
Alexandre Julliard
julliard at winehq.org
Mon Dec 3 15:28:52 CST 2018
Module: wine
Branch: master
Commit: 0cc68cf82a0414b019a750999c7ca859ad4cea30
URL: https://source.winehq.org/git/wine.git/?a=commit;h=0cc68cf82a0414b019a750999c7ca859ad4cea30
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Nov 30 22:44:40 2018 +0100
jscript: Add interpreter support for getters and setters in object initializer.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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(-)
diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index a498abd..006386a 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 bd4edda..0f9e3a5 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 d0c419a..eb287d5 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 6097f4c..3e81961 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
More information about the wine-cvs
mailing list