diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 593294c313d..1ff5eb3ff0c 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -2028,10 +2028,44 @@ HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD f } /* ECMA-262 3rd Edition 11.8.7 */ -HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +static HRESULT in_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *obj, jsexcept_t *ei, VARIANT *retv) { - FIXME("\n"); - return E_NOTIMPL; + VARIANT_BOOL ret; + DISPID id; + BSTR str; + HRESULT hres; + + if(V_VT(obj) != VT_DISPATCH) { + FIXME("throw TypeError"); + return E_FAIL; + } + + hres = to_string(ctx->parser->script, lval, ei, &str); + if(FAILED(hres)) + return hres; + + hres = disp_get_id(V_DISPATCH(obj), str, 0, &id); + SysFreeString(str); + if(SUCCEEDED(hres)) + ret = VARIANT_TRUE; + else if(hres == DISP_E_UNKNOWNNAME) + ret = VARIANT_FALSE; + else + return hres; + + V_VT(retv) = VT_BOOL; + V_BOOL(retv) = ret; + return S_OK; +} + +/* ECMA-262 3rd Edition 11.8.7 */ +HRESULT in_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, in_eval, ei, ret); } /* ECMA-262 3rd Edition 11.6.1 */ diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 354fdb4c255..ae69e71bf47 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -817,6 +817,17 @@ ok(("" instanceof Object) === false, "'' is instance of Object"); ok(arguments.toString() === "[object Object]", "arguments.toString() = " + arguments.toString()); })(1,2); +obj = new String(); +ok(("length" in obj) === true, "length is not in obj"); +ok(("isPrototypeOf" in obj) === true, "isPrototypeOf is not in obj"); +ok(("abc" in obj) === false, "test is in obj"); +obj.abc = 1; +ok(("abc" in obj) === true, "test is not in obj"); +ok(("1" in obj) === false, "1 is in obj"); + +obj = [1,2,3]; +ok((1 in obj) === true, "1 is not in obj"); + 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 90b022d95d5..786624cc738 100644 --- a/dlls/jscript/tests/run.c +++ b/dlls/jscript/tests/run.c @@ -66,6 +66,8 @@ DEFINE_EXPECT(global_success_i); DEFINE_EXPECT(global_notexists_d); DEFINE_EXPECT(testobj_delete); DEFINE_EXPECT(testobj_value); +DEFINE_EXPECT(testobj_prop_d); +DEFINE_EXPECT(testobj_noprop_d); DEFINE_EXPECT(GetItemInfo_testVal); #define DISPID_GLOBAL_TESTPROPGET 0x1000 @@ -78,6 +80,8 @@ DEFINE_EXPECT(GetItemInfo_testVal); #define DISPID_GLOBAL_NULL_BSTR 0x1007 #define DISPID_GLOBAL_NULL_DISP 0x1008 +#define DISPID_TESTOBJ_PROP 0x2000 + static const WCHAR testW[] = {'t','e','s','t',0}; static const CHAR testA[] = "test"; static const WCHAR test_valW[] = {'t','e','s','t','V','a','l',0}; @@ -194,9 +198,21 @@ static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown return E_NOTIMPL; } -static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) +static HRESULT WINAPI testObj_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { - ok(0, "unexpected call\n"); + if(!strcmp_wa(bstrName, "prop")) { + CHECK_EXPECT(testobj_prop_d); + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + *pid = DISPID_TESTOBJ_PROP; + return S_OK; + } + if(!strcmp_wa(bstrName, "noprop")) { + CHECK_EXPECT(testobj_noprop_d); + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + return DISP_E_UNKNOWNNAME; + } + + ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName)); return E_NOTIMPL; } @@ -243,7 +259,7 @@ static IDispatchExVtbl testObjVtbl = { DispatchEx_GetTypeInfo, DispatchEx_GetIDsOfNames, DispatchEx_Invoke, - DispatchEx_GetDispID, + testObj_GetDispID, testObj_InvokeEx, testObj_DeleteMemberByName, DispatchEx_DeleteMemberByDispID, @@ -884,6 +900,14 @@ static void run_tests(void) parse_script_a("ok((testObj instanceof Object) === false, 'testObj is instance of Object');"); + SET_EXPECT(testobj_prop_d); + parse_script_a("ok(('prop' in testObj) === true, 'prop is not in testObj');"); + CHECK_CALLED(testobj_prop_d); + + SET_EXPECT(testobj_noprop_d); + parse_script_a("ok(('noprop' in testObj) === false, 'noprop is in testObj');"); + CHECK_CALLED(testobj_noprop_d); + SET_EXPECT(testobj_value); parse_script_a("ok(String(testObj) === '1', 'wrong testObj value');"); CHECK_CALLED(testobj_value);