Jacek Caban : jscript: Added '===' expression implementation.
Alexandre Julliard
julliard at winehq.org
Tue Sep 9 05:50:47 CDT 2008
Module: wine
Branch: master
Commit: c3938073dad90bcbd762768b2731bb8fa11b5456
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c3938073dad90bcbd762768b2731bb8fa11b5456
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Sep 9 01:26:20 2008 +0200
jscript: Added '===' expression implementation.
---
dlls/jscript/engine.c | 140 +++++++++++++++++++++++++++++++++++++++++++-
dlls/jscript/tests/lang.js | 9 +++
2 files changed, 146 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index f9f9cd6..8f66b3d 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -194,6 +194,97 @@ static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept
return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
}
+static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
+{
+ IObjectIdentity *identity;
+ IUnknown *unk1, *unk2;
+ HRESULT hres;
+
+ if(disp1 == disp2) {
+ *ret = TRUE;
+ return S_OK;
+ }
+
+ hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
+ if(FAILED(hres))
+ return hres;
+
+ hres = IDispatch_QueryInterface(disp2, &IID_IUnknown, (void**)&unk2);
+ if(FAILED(hres)) {
+ IUnknown_Release(unk1);
+ return hres;
+ }
+
+ if(unk1 == unk2) {
+ *ret = TRUE;
+ }else {
+ hres = IUnknown_QueryInterface(unk1, &IID_IObjectIdentity, (void**)&identity);
+ if(SUCCEEDED(hres)) {
+ hres = IObjectIdentity_IsEqualObject(identity, unk2);
+ IObjectIdentity_Release(identity);
+ *ret = hres == S_OK;
+ }else {
+ *ret = FALSE;
+ }
+ }
+
+ IUnknown_Release(unk1);
+ IUnknown_Release(unk2);
+ return S_OK;
+}
+
+static inline BOOL is_num_vt(enum VARENUM vt)
+{
+ return vt == VT_I4 || vt == VT_R8;
+}
+
+static inline DOUBLE num_val(const VARIANT *v)
+{
+ return V_VT(v) == VT_I4 ? V_I4(v) : V_R8(v);
+}
+
+/* ECMA-262 3rd Edition 11.9.6 */
+HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
+{
+ TRACE("\n");
+
+ if(V_VT(lval) != V_VT(rval)) {
+ if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))) {
+ *ret = num_val(lval) == num_val(rval);
+ return S_OK;
+ }
+
+ *ret = FALSE;
+ return S_OK;
+ }
+
+ switch(V_VT(lval)) {
+ case VT_EMPTY:
+ case VT_NULL:
+ *ret = VARIANT_TRUE;
+ break;
+ case VT_I4:
+ *ret = V_I4(lval) == V_I4(rval);
+ break;
+ case VT_R8:
+ *ret = V_R8(lval) == V_R8(rval);
+ break;
+ case VT_BSTR:
+ *ret = !strcmpW(V_BSTR(lval), V_BSTR(rval));
+ break;
+ case VT_DISPATCH:
+ return disp_cmp(V_DISPATCH(lval), V_DISPATCH(rval), ret);
+ case VT_BOOL:
+ *ret = !V_BOOL(lval) == !V_BOOL(rval);
+ break;
+ default:
+ FIXME("unimplemented vt %d\n", V_VT(lval));
+ return E_NOTIMPL;
+ }
+
+ return S_OK;
+}
+
static HRESULT literal_to_var(literal_t *literal, VARIANT *v)
{
V_VT(v) = literal->vt;
@@ -510,6 +601,34 @@ static HRESULT return_bool(exprval_t *ret, DWORD b)
return S_OK;
}
+static HRESULT get_binary_expr_values(exec_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
+{
+ exprval_t exprval;
+ HRESULT hres;
+
+ hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
+ if(FAILED(hres))
+ return hres;
+
+ hres = exprval_to_value(ctx->parser->script, &exprval, ei, lval);
+ exprval_release(&exprval);
+ if(FAILED(hres))
+ return hres;
+
+ hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
+ if(SUCCEEDED(hres)) {
+ hres = exprval_to_value(ctx->parser->script, &exprval, ei, rval);
+ exprval_release(&exprval);
+ }
+
+ if(FAILED(hres)) {
+ VariantClear(lval);
+ return hres;
+ }
+
+ return S_OK;
+}
+
HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
{
FIXME("\n");
@@ -829,10 +948,25 @@ HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags,
return E_NOTIMPL;
}
-HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
+/* ECMA-262 3rd Edition 11.9.4 */
+HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
{
- FIXME("\n");
- return E_NOTIMPL;
+ binary_expression_t *expr = (binary_expression_t*)_expr;
+ VARIANT rval, lval;
+ BOOL b;
+ HRESULT hres;
+
+ TRACE("\n");
+
+ hres = get_binary_expr_values(ctx, expr, ei, &rval, &lval);
+ if(FAILED(hres))
+ return hres;
+
+ hres = equal2_values(&rval, &lval, &b);
+ if(FAILED(hres))
+ return hres;
+
+ return return_bool(ret, b);
}
HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index 3ea4933..61d108f 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -23,6 +23,15 @@ ok(!null, "!null is not true");
ok(!0, "!0 is not true");
ok(!0.0, "!0.0 is not true");
+ok(1 === 1, "1 === 1 is false");
+ok(!(1 === 2), "!(1 === 2) is false");
+ok(1.0 === 1, "1.0 === 1 is false");
+ok("abc" === "abc", "\"abc\" === \"abc\" is false");
+ok(true === true, "true === true is false");
+ok(null === null, "null === null is false");
+ok(undefined === undefined, "undefined === undefined is false");
+ok(!(undefined === null), "!(undefined === null) is false");
+
var trueVar = true;
ok(trueVar, "trueVar is not true");
More information about the wine-cvs
mailing list