Jacek Caban : jscript: Added 'instanceof' keyword implementation.

Alexandre Julliard julliard at winehq.org
Sat Aug 29 11:35:56 CDT 2009


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sat Aug 29 00:01:25 2009 +0200

jscript: Added 'instanceof' keyword implementation.

---

 dlls/jscript/engine.c      |   70 ++++++++++++++++++++++++++++++++++++++++++--
 dlls/jscript/tests/api.js  |   23 ++++++++------
 dlls/jscript/tests/lang.js |   15 +++++++++
 dlls/jscript/tests/run.c   |    2 +
 4 files changed, 97 insertions(+), 13 deletions(-)

diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 8035e78..43b422c 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -1954,10 +1954,74 @@ HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD f
 }
 
 /* ECMA-262 3rd Edition    11.8.6 */
-HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
+static HRESULT instanceof_eval(exec_ctx_t *ctx, VARIANT *inst, VARIANT *objv, jsexcept_t *ei, VARIANT *retv)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    DispatchEx *obj, *iter, *tmp = NULL;
+    VARIANT_BOOL ret = VARIANT_FALSE;
+    BOOL b;
+    VARIANT var;
+    HRESULT hres;
+
+    static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
+
+    if(V_VT(objv) != VT_DISPATCH) {
+        FIXME("throw TypeError\n");
+        return E_FAIL;
+    }
+
+    obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(objv));
+    if(!obj) {
+        FIXME("throw TypeError\n");
+        return E_FAIL;
+    }
+
+    if(is_class(obj, JSCLASS_FUNCTION)) {
+        hres = jsdisp_propget_name(obj, prototypeW, ctx->parser->script->lcid, &var, ei, NULL/*FIXME*/);
+    }else {
+        FIXME("throw TypeError\n");
+        hres = E_FAIL;
+    }
+    jsdisp_release(obj);
+    if(FAILED(hres))
+        return hres;
+
+    if(V_VT(&var) == VT_DISPATCH) {
+        if(V_VT(inst) == VT_DISPATCH)
+            tmp = iface_to_jsdisp((IUnknown*)V_DISPATCH(inst));
+        for(iter = tmp; iter; iter = iter->prototype) {
+            hres = disp_cmp(V_DISPATCH(&var), (IDispatch*)_IDispatchEx_(iter), &b);
+            if(FAILED(hres))
+                break;
+            if(b) {
+                ret = VARIANT_TRUE;
+                break;
+            }
+        }
+
+        if(tmp)
+            jsdisp_release(tmp);
+    }else {
+        FIXME("prototype is not an object\n");
+        hres = E_FAIL;
+    }
+
+    VariantClear(&var);
+    if(FAILED(hres))
+        return hres;
+
+    V_VT(retv) = VT_BOOL;
+    V_BOOL(retv) = ret;
+    return S_OK;
+}
+
+/* ECMA-262 3rd Edition    11.8.6 */
+HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
+{
+    binary_expression_t *expr = (binary_expression_t*)_expr;
+
+    TRACE("\n");
+
+    return binary_expr_eval(ctx, expr, instanceof_eval, ei, ret);
 }
 
 /* ECMA-262 3rd Edition    11.8.7 */
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index efc55a4..a77f31a 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -1376,7 +1376,10 @@ exception_test(function() {eval("while(")}, "SyntaxError", -2146827286);
 exception_test(function() {eval("if(")}, "SyntaxError", -2146827286);
 exception_test(function() {eval("'unterminated")}, "SyntaxError", -2146827273);
 
-function testObjectInherit(obj, ts, tls, vo) {
+function testObjectInherit(obj, constr, ts, tls, vo) {
+    ok(obj instanceof Object, "obj is not instance of Object");
+    ok(obj instanceof constr, "obj is not instance of its constructor");
+
     ok(obj.hasOwnProperty === Object.prototype.hasOwnProperty,
        "obj.hasOwnProperty !== Object.prototype.hasOwnProprty");
     ok(obj.isPrototypeOf === Object.prototype.isPrototypeOf,
@@ -1409,15 +1412,15 @@ function testObjectInherit(obj, ts, tls, vo) {
 }
 
 Object.prototype._test = "test";
-testObjectInherit(new String("test"), false, true, false);
-testObjectInherit(/test/g, false, true, true);
-testObjectInherit(new Number(1), false, false, false);
-testObjectInherit(new Date(), false, false, false);
-testObjectInherit(new Boolean(true), false, true, false);
-testObjectInherit(new Array(), false, false, true);
-testObjectInherit(new Error(), false, true, true);
-testObjectInherit(testObjectInherit, false, true, true);
-testObjectInherit(Math, true, true, true);
+testObjectInherit(new String("test"), String, false, true, false);
+testObjectInherit(/test/g, RegExp, false, true, true);
+testObjectInherit(new Number(1), Number, false, false, false);
+testObjectInherit(new Date(), Date, false, false, false);
+testObjectInherit(new Boolean(true), Boolean, false, true, false);
+testObjectInherit(new Array(), Array, false, false, true);
+testObjectInherit(new Error(), Error, false, true, true);
+testObjectInherit(testObjectInherit, Function, false, true, true);
+testObjectInherit(Math, Object, true, true, true);
 
 function testFunctions(obj, arr) {
     var l;
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index b0e90fc..e3abe27 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -796,6 +796,21 @@ if (true)
     else
         ok(true, "else should be associated with nearest if statement");
 
+function instanceOfTest() {}
+tmp = new instanceOfTest();
+
+ok((tmp instanceof instanceOfTest) === true, "tmp is not instance of instanceOfTest");
+ok((tmp instanceof Object) === true, "tmp is not instance of Object");
+ok((tmp instanceof String) === false, "tmp is instance of String");
+
+instanceOfTest.prototype = new Object();
+ok((tmp instanceof instanceOfTest) === false, "tmp is instance of instanceOfTest");
+ok((tmp instanceof Object) === true, "tmp is not instance of Object");
+
+ok((1 instanceof Object) === false, "1 is instance of Object");
+ok((false instanceof Boolean) === false, "false is instance of Boolean");
+ok(("" instanceof Object) === false, "'' is instance of Object");
+
 ok(isNaN(NaN) === true, "isNaN(NaN) !== true");
 ok(isNaN(0.5) === false, "isNaN(0.5) !== false");
 ok(isNaN(Infinity) === false, "isNaN(Infinity) !== false");
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index 21eccc4..0afb180 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -842,6 +842,8 @@ static void run_tests(void)
 
     parse_script_a("function f() { var testPropGet; }");
 
+    parse_script_a("ok((testObj instanceof Object) === false, 'testObj is instance of Object');");
+
     run_from_res("lang.js");
     run_from_res("api.js");
     run_from_res("regexp.js");




More information about the wine-cvs mailing list