Jacek Caban : jscript: Properly handle elisions in array literals.
Alexandre Julliard
julliard at winehq.org
Fri Mar 2 12:16:45 CST 2018
Module: wine
Branch: master
Commit: d72acebd6c8176f4e00c79c0f199082221caf4e3
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d72acebd6c8176f4e00c79c0f199082221caf4e3
Author: Jacek Caban <jacek at codeweavers.com>
Date: Thu Mar 1 23:58:38 2018 +0100
jscript: Properly handle elisions in array literals.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/jscript/compile.c | 24 ++++++++++++------------
dlls/jscript/engine.c | 31 ++++++++++++++++++-------------
dlls/jscript/engine.h | 3 ++-
dlls/jscript/tests/lang.js | 4 ++++
4 files changed, 36 insertions(+), 26 deletions(-)
diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index 8691595..6e6be91 100644
--- a/dlls/jscript/compile.c
+++ b/dlls/jscript/compile.c
@@ -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;
- }
- for(i=0; i < expr->length; i++) {
- if(!push_instr(ctx, OP_undefined))
- return E_OUTOFMEMORY;
+ hres = push_instr_uint(ctx, OP_carray_set, length);
+ if(FAILED(hres))
+ return hres;
+
+ length++;
}
- 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)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 8092159..6b4aae3 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -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)
{
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 121a2c2..31f6b1c 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -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) \
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index aba6dda..ef4c316 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -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");
More information about the wine-cvs
mailing list