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>
This commit is contained in:
parent
56be97fd5d
commit
0cc68cf82a
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue