Jacek Caban : jscript: Added logical negation implementation.

Alexandre Julliard julliard at winehq.org
Tue Sep 9 05:50:47 CDT 2008


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Sep  9 01:25:40 2008 +0200

jscript: Added logical negation implementation.

---

 dlls/jscript/engine.c      |   49 +++++++++++++++++++++++++++++++++++++++++--
 dlls/jscript/jscript.h     |    2 +
 dlls/jscript/jsutils.c     |   31 +++++++++++++++++++++++++++
 dlls/jscript/tests/lang.js |    5 ++++
 4 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index b74ca47..f37a8ac 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -86,6 +86,24 @@ static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *e
     return exprval_value(ctx, val, ei, ret);
 }
 
+static HRESULT exprval_to_boolean(script_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, VARIANT_BOOL *b)
+{
+    if(exprval->type != EXPRVAL_VARIANT) {
+        VARIANT val;
+        HRESULT hres;
+
+        hres = exprval_to_value(ctx, exprval, ei, &val);
+        if(FAILED(hres))
+            return hres;
+
+        hres = to_boolean(&val, b);
+        VariantClear(&val);
+        return hres;
+    }
+
+    return to_boolean(&exprval->u.var, b);
+}
+
 static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
 {
     val->type = EXPRVAL_IDREF;
@@ -440,6 +458,15 @@ HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt
     return E_NOTIMPL;
 }
 
+static HRESULT return_bool(exprval_t *ret, DWORD b)
+{
+    ret->type = EXPRVAL_VARIANT;
+    V_VT(&ret->u.var) = VT_BOOL;
+    V_BOOL(&ret->u.var) = b ? VARIANT_TRUE : VARIANT_FALSE;
+
+    return S_OK;
+}
+
 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
 {
     FIXME("\n");
@@ -808,10 +835,26 @@ HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWO
     return E_NOTIMPL;
 }
 
-HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
+/* ECMA-262 3rd Edition    11.4.9 */
+HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    unary_expression_t *expr = (unary_expression_t*)_expr;
+    exprval_t exprval;
+    VARIANT_BOOL b;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    hres = expr_eval(ctx, expr->expression, EXPR_NEWREF, ei, &exprval);
+    if(FAILED(hres))
+        return hres;
+
+    hres = exprval_to_boolean(ctx->parser->script, &exprval, ei, &b);
+    exprval_release(&exprval);
+    if(FAILED(hres))
+        return hres;
+
+    return return_bool(ret, !b);
 }
 
 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 45d7bca..52768a4 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -91,6 +91,8 @@ HRESULT disp_call(IDispatch*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,I
 HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
 HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
 
+HRESULT to_boolean(VARIANT*,VARIANT_BOOL*);
+
 typedef struct named_item_t {
     IDispatch *disp;
     DWORD flags;
diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c
index 00aa58c..c29f673 100644
--- a/dlls/jscript/jsutils.c
+++ b/dlls/jscript/jsutils.c
@@ -132,3 +132,34 @@ void jsheap_free(jsheap_t *heap)
 
     jsheap_init(heap);
 }
+
+/* ECMA-262 3rd Edition    9.2 */
+HRESULT to_boolean(VARIANT *v, VARIANT_BOOL *b)
+{
+    switch(V_VT(v)) {
+    case VT_EMPTY:
+    case VT_NULL:
+        *b = VARIANT_FALSE;
+        break;
+    case VT_I4:
+        *b = V_I4(v) ? VARIANT_TRUE : VARIANT_FALSE;
+        break;
+    case VT_R8:
+        *b = V_R8(v) ? VARIANT_TRUE : VARIANT_FALSE;
+        break;
+    case VT_BSTR:
+        *b = V_BSTR(v) && *V_BSTR(v) ? VARIANT_TRUE : VARIANT_FALSE;
+        break;
+    case VT_DISPATCH:
+        *b = V_DISPATCH(v) ? VARIANT_TRUE : VARIANT_FALSE;
+        break;
+    case VT_BOOL:
+        *b = V_BOOL(v);
+        break;
+    default:
+        FIXME("unimplemented for vt %d\n", V_VT(v));
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index f70bb16..d1ef849 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -17,5 +17,10 @@
  */
 
 ok(true, "true is not true?");
+ok(!false, "!false is not true");
+ok(!undefined, "!undefined is not true");
+ok(!null, "!null is not true");
+ok(!0, "!0 is not true");
+ok(!0.0, "!0.0 is not true");
 
 reportSuccess();




More information about the wine-cvs mailing list