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