jscript: Properly handle elisions in array literals.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
89da4559ee
commit
d72acebd6c
|
@ -861,29 +861,29 @@ static HRESULT literal_as_bstr(compiler_ctx_t *ctx, literal_t *literal, BSTR *st
|
|||
|
||||
static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expression_t *expr)
|
||||
{
|
||||
unsigned i, elem_cnt = expr->length;
|
||||
unsigned length = 0;
|
||||
array_element_t *iter;
|
||||
unsigned array_instr;
|
||||
HRESULT hres;
|
||||
|
||||
for(iter = expr->element_list; iter; iter = iter->next) {
|
||||
elem_cnt += iter->elision+1;
|
||||
array_instr = push_instr(ctx, OP_carray);
|
||||
|
||||
for(i=0; i < iter->elision; i++) {
|
||||
if(!push_instr(ctx, OP_undefined))
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
for(iter = expr->element_list; iter; iter = iter->next) {
|
||||
length += iter->elision;
|
||||
|
||||
hres = compile_expression(ctx, iter->expr, TRUE);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = push_instr_uint(ctx, OP_carray_set, length);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
length++;
|
||||
}
|
||||
|
||||
for(i=0; i < expr->length; i++) {
|
||||
if(!push_instr(ctx, OP_undefined))
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
return push_instr_uint(ctx, OP_carray, elem_cnt);
|
||||
instr_ptr(ctx, array_instr)->u.arg[0].uint = length + expr->length;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr)
|
||||
|
|
|
@ -1399,8 +1399,6 @@ static HRESULT interp_carray(script_ctx_t *ctx)
|
|||
{
|
||||
const unsigned arg = get_op_uint(ctx, 0);
|
||||
jsdisp_t *array;
|
||||
jsval_t val;
|
||||
unsigned i;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("%u\n", arg);
|
||||
|
@ -1409,20 +1407,27 @@ static HRESULT interp_carray(script_ctx_t *ctx)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
i = arg;
|
||||
while(i--) {
|
||||
val = stack_pop(ctx);
|
||||
hres = jsdisp_propput_idx(array, i, val);
|
||||
jsval_release(val);
|
||||
if(FAILED(hres)) {
|
||||
jsdisp_release(array);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
return stack_push(ctx, jsval_obj(array));
|
||||
}
|
||||
|
||||
static HRESULT interp_carray_set(script_ctx_t *ctx)
|
||||
{
|
||||
const unsigned index = get_op_uint(ctx, 0);
|
||||
jsval_t value, array;
|
||||
HRESULT hres;
|
||||
|
||||
value = stack_pop(ctx);
|
||||
|
||||
TRACE("[%u] = %s\n", index, debugstr_jsval(value));
|
||||
|
||||
array = stack_top(ctx);
|
||||
assert(is_object_instance(array));
|
||||
|
||||
hres = jsdisp_propput_idx(iface_to_jsdisp(get_object(array)), index, value);
|
||||
jsval_release(value);
|
||||
return hres;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 11.1.5 */
|
||||
static HRESULT interp_new_obj(script_ctx_t *ctx)
|
||||
{
|
||||
|
|
|
@ -21,12 +21,13 @@
|
|||
X(and, 1, 0,0) \
|
||||
X(array, 1, 0,0) \
|
||||
X(assign, 1, 0,0) \
|
||||
X(assign_call,1, ARG_UINT, 0) \
|
||||
X(assign_call,1, ARG_UINT, 0) \
|
||||
X(bool, 1, ARG_INT, 0) \
|
||||
X(bneg, 1, 0,0) \
|
||||
X(call, 1, ARG_UINT, ARG_UINT) \
|
||||
X(call_member,1, ARG_UINT, ARG_UINT) \
|
||||
X(carray, 1, ARG_UINT, 0) \
|
||||
X(carray_set, 1, ARG_UINT, 0) \
|
||||
X(case, 0, ARG_ADDR, 0) \
|
||||
X(cnd_nz, 0, ARG_ADDR, 0) \
|
||||
X(cnd_z, 0, ARG_ADDR, 0) \
|
||||
|
|
|
@ -1171,6 +1171,10 @@ ok(tmp["0"] === undefined, "tmp[0] is not undefined");
|
|||
ok(tmp["3"] === 2, "tmp[3] !== 2");
|
||||
ok(tmp["6"] === true, "tmp[6] !== true");
|
||||
ok(tmp[2] === 1, "tmp[2] !== 1");
|
||||
ok(!("0" in tmp), "0 found in array");
|
||||
ok(!("1" in tmp), "1 found in array");
|
||||
ok("2" in tmp, "2 not found in array");
|
||||
ok(!("2" in [1,,,,]), "2 found in [1,,,,]");
|
||||
|
||||
ok([1,].length === 2, "[1,].length !== 2");
|
||||
ok([,,].length === 3, "[,,].length !== 3");
|
||||
|
|
Loading…
Reference in New Issue