Jacek Caban : jscript: Use bytecode for delete on array expression implementation.

Alexandre Julliard julliard at winehq.org
Wed Nov 30 14:19:20 CST 2011


Module: wine
Branch: master
Commit: facc2189d298ad0a76844c178fd2609e2fc7406c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=facc2189d298ad0a76844c178fd2609e2fc7406c

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Nov 30 10:14:22 2011 +0100

jscript: Use bytecode for delete on array expression implementation.

---

 dlls/jscript/compile.c     |   30 +++++++++++++++++++++++++
 dlls/jscript/engine.c      |   52 +++++++++++++++++++++++++++++++++++++++++++-
 dlls/jscript/engine.h      |    1 +
 dlls/jscript/parser.y      |    2 +-
 dlls/jscript/tests/lang.js |    7 ++++++
 5 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index b7abdda..adcd749 100644
--- a/dlls/jscript/compile.c
+++ b/dlls/jscript/compile.c
@@ -301,6 +301,34 @@ static HRESULT compile_interp_fallback(compiler_ctx_t *ctx, expression_t *expr)
     return S_OK;
 }
 
+static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
+{
+    HRESULT hres;
+
+    switch(expr->expression->type) {
+    case EXPR_ARRAY: {
+        array_expression_t *array_expr = (array_expression_t*)expr->expression;
+
+        hres = compile_expression(ctx, array_expr->member_expr);
+        if(FAILED(hres))
+            return hres;
+
+        hres = compile_expression(ctx, array_expr->expression);
+        if(FAILED(hres))
+            return hres;
+
+        if(push_instr(ctx, OP_delete) == -1)
+            return E_OUTOFMEMORY;
+        break;
+    }
+    default:
+        expr->expr.eval = delete_expression_eval;
+        return compile_interp_fallback(ctx, &expr->expr);
+    }
+
+    return S_OK;
+}
+
 static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
 {
     switch(literal->type) {
@@ -352,6 +380,8 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
         return compile_comma_expression(ctx, (binary_expression_t*)expr);
     case EXPR_COND:
         return compile_conditional_expression(ctx, (conditional_expression_t*)expr);
+    case EXPR_DELETE:
+        return compile_delete_expression(ctx, (unary_expression_t*)expr);
     case EXPR_DIV:
         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div);
     case EXPR_EQ:
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 48633cf..6567d68 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -2498,6 +2498,53 @@ HRESULT delete_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD fla
 }
 
 /* ECMA-262 3rd Edition    11.4.2 */
+static HRESULT interp_delete(exec_ctx_t *ctx)
+{
+    VARIANT *obj_var, *name_var;
+    IDispatchEx *dispex;
+    IDispatch *obj;
+    BSTR name;
+    BOOL ret;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    name_var = stack_pop(ctx);
+    obj_var = stack_pop(ctx);
+
+    hres = to_object(ctx->parser->script, obj_var, &obj);
+    VariantClear(obj_var);
+    if(FAILED(hres)) {
+        VariantClear(name_var);
+        return hres;
+    }
+
+    hres = to_string(ctx->parser->script, name_var, &ctx->ei, &name);
+    VariantClear(name_var);
+    if(FAILED(hres)) {
+        IDispatch_Release(obj);
+        return hres;
+    }
+
+    hres = IDispatch_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
+    if(SUCCEEDED(hres)) {
+        hres = IDispatchEx_DeleteMemberByName(dispex, name, make_grfdex(ctx->parser->script, fdexNameCaseSensitive));
+        ret = TRUE;
+        IDispatchEx_Release(dispex);
+    }else {
+        hres = S_OK;
+        ret = FALSE;
+    }
+
+    IDispatch_Release(obj);
+    SysFreeString(name);
+    if(FAILED(hres))
+        return hres;
+
+    return stack_push_bool(ctx, ret);
+}
+
+/* ECMA-262 3rd Edition    11.4.2 */
 static HRESULT interp_void(exec_ctx_t *ctx)
 {
     VARIANT v;
@@ -3469,5 +3516,8 @@ HRESULT compiled_expression_eval(script_ctx_t *ctx, expression_t *expr, DWORD fl
     if(FAILED(hres))
         return hres;
 
-    return (expr->eval = interp_expression_eval)(ctx, expr, flags, ei, ret);
+    if(expr->eval == compiled_expression_eval)
+        expr->eval = interp_expression_eval;
+
+    return expr->eval(ctx, expr, flags, ei, ret);
 }
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 58f12c7..f2af36f 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -45,6 +45,7 @@ typedef struct _func_stack {
     X(add,        1, 0,0)                  \
     X(bool,       1, ARG_INT,    0)        \
     X(bneg,       1, 0,0)                  \
+    X(delete,     1, 0,0)                  \
     X(div,        1, 0,0)                  \
     X(double,     1, ARG_SBL,    0)        \
     X(eq,         1, 0,0)                  \
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y
index 0912107..3fffbe9 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -1318,7 +1318,7 @@ static const expression_eval_t expression_eval_table[] = {
    compiled_expression_eval,
    compiled_expression_eval,
    compiled_expression_eval,
-   delete_expression_eval,
+   compiled_expression_eval,
    compiled_expression_eval,
    typeof_expression_eval,
    compiled_expression_eval,
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index c85907c..4f3d509 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -830,9 +830,16 @@ tmp = new Object();
 tmp.test = false;
 ok((delete tmp.test) === true, "delete returned false");
 ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test));
+ok(!("test" in tmp), "test is still in tmp after delete?");
 for(iter in tmp)
     ok(false, "tmp has prop " + iter);
 
+tmp = new Object();
+tmp.test = false;
+ok((delete tmp["test"]) === true, "delete returned false");
+ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test));
+ok(!("test" in tmp), "test is still in tmp after delete?");
+
 tmp.testWith = true;
 with(tmp)
     ok(testWith === true, "testWith !== true");




More information about the wine-cvs mailing list