Module: wine Branch: master Commit: 0cc68cf82a0414b019a750999c7ca859ad4cea30 URL: https://source.winehq.org/git/wine.git/?a=commit;h=0cc68cf82a0414b019a750999...
Author: Jacek Caban jacek@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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