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)
|
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;
|
array_element_t *iter;
|
||||||
|
unsigned array_instr;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
for(iter = expr->element_list; iter; iter = iter->next) {
|
array_instr = push_instr(ctx, OP_carray);
|
||||||
elem_cnt += iter->elision+1;
|
|
||||||
|
|
||||||
for(i=0; i < iter->elision; i++) {
|
for(iter = expr->element_list; iter; iter = iter->next) {
|
||||||
if(!push_instr(ctx, OP_undefined))
|
length += iter->elision;
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
hres = compile_expression(ctx, iter->expr, TRUE);
|
hres = compile_expression(ctx, iter->expr, TRUE);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return 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++) {
|
instr_ptr(ctx, array_instr)->u.arg[0].uint = length + expr->length;
|
||||||
if(!push_instr(ctx, OP_undefined))
|
return S_OK;
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return push_instr_uint(ctx, OP_carray, elem_cnt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr)
|
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);
|
const unsigned arg = get_op_uint(ctx, 0);
|
||||||
jsdisp_t *array;
|
jsdisp_t *array;
|
||||||
jsval_t val;
|
|
||||||
unsigned i;
|
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("%u\n", arg);
|
TRACE("%u\n", arg);
|
||||||
|
@ -1409,20 +1407,27 @@ static HRESULT interp_carray(script_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return 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));
|
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 */
|
/* ECMA-262 3rd Edition 11.1.5 */
|
||||||
static HRESULT interp_new_obj(script_ctx_t *ctx)
|
static HRESULT interp_new_obj(script_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,12 +21,13 @@
|
||||||
X(and, 1, 0,0) \
|
X(and, 1, 0,0) \
|
||||||
X(array, 1, 0,0) \
|
X(array, 1, 0,0) \
|
||||||
X(assign, 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(bool, 1, ARG_INT, 0) \
|
||||||
X(bneg, 1, 0,0) \
|
X(bneg, 1, 0,0) \
|
||||||
X(call, 1, ARG_UINT, ARG_UINT) \
|
X(call, 1, ARG_UINT, ARG_UINT) \
|
||||||
X(call_member,1, ARG_UINT, ARG_UINT) \
|
X(call_member,1, ARG_UINT, ARG_UINT) \
|
||||||
X(carray, 1, ARG_UINT, 0) \
|
X(carray, 1, ARG_UINT, 0) \
|
||||||
|
X(carray_set, 1, ARG_UINT, 0) \
|
||||||
X(case, 0, ARG_ADDR, 0) \
|
X(case, 0, ARG_ADDR, 0) \
|
||||||
X(cnd_nz, 0, ARG_ADDR, 0) \
|
X(cnd_nz, 0, ARG_ADDR, 0) \
|
||||||
X(cnd_z, 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["3"] === 2, "tmp[3] !== 2");
|
||||||
ok(tmp["6"] === true, "tmp[6] !== true");
|
ok(tmp["6"] === true, "tmp[6] !== true");
|
||||||
ok(tmp[2] === 1, "tmp[2] !== 1");
|
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([1,].length === 2, "[1,].length !== 2");
|
||||||
ok([,,].length === 3, "[,,].length !== 3");
|
ok([,,].length === 3, "[,,].length !== 3");
|
||||||
|
|
Loading…
Reference in New Issue