jscript: Added 'instanceof' keyword implementation.
This commit is contained in:
parent
b71aaadbd2
commit
2a457fb701
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue