From bed34e40830f0936c0dcf2cd43b3bd79f638eb3f Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Mon, 23 Nov 2015 22:36:56 +0300 Subject: [PATCH] "instanceof" fixes. --- njs/njs_vm.c | 59 ++++++++++++++++++++++------------------ njs/test/njs_unit_test.c | 18 ++++++++++++ 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/njs/njs_vm.c b/njs/njs_vm.c index 8f9d99d3..41c973f6 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -1212,45 +1212,52 @@ njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object, const njs_value_t *retval; nxt_lvlhsh_query_t lhq; - /* TODO: test constructor is function or native: TypeError. */ - /* TODO: test object is object: false. */ + if (!njs_is_function(constructor) && !njs_is_native(constructor)) { + vm->exception = &njs_exception_type_error; + return NXT_ERROR; + } retval = &njs_value_false; - lhq.key_hash = NJS_PROTOTYPE_HASH; - lhq.key.len = sizeof("prototype") - 1; - lhq.key.data = (u_char *) "prototype"; + if (njs_is_object(object)) { - prop = njs_object_property(vm, constructor->data.u.object, &lhq); + lhq.key_hash = NJS_PROTOTYPE_HASH; + lhq.key.len = sizeof("prototype") - 1; + lhq.key.data = (u_char *) "prototype"; - if (prop != NULL) { - value = &prop->value; + prop = njs_object_property(vm, constructor->data.u.object, &lhq); - if (prop->type == NJS_NATIVE_GETTER) { - /* STUB: getter should be called by some njs_object_property() */ - ret = prop->value.data.u.getter(vm, constructor); + if (prop != NULL) { + value = &prop->value; - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } + if (prop->type == NJS_NATIVE_GETTER) { + /* + * STUB: getter should be called by some njs_object_property() + */ + ret = prop->value.data.u.getter(vm, constructor); - value = &vm->retval; - } + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } - /* TODO: test prop->value is object. */ + value = &vm->retval; + } - prototype = value->data.u.object; - proto = object->data.u.object; + /* TODO: test prop->value is object. */ - do { - proto = proto->__proto__; + prototype = value->data.u.object; + proto = object->data.u.object; - if (proto == prototype) { - retval = &njs_value_true; - break; - } + do { + proto = proto->__proto__; - } while (proto != NULL); + if (proto == prototype) { + retval = &njs_value_true; + break; + } + + } while (proto != NULL); + } } vm->retval = *retval; diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 67908912..438265aa 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -2601,15 +2601,33 @@ static njs_unit_test_t njs_test[] = { nxt_string("/./.__proto__.test.call(/a{2}/, 'aaa')"), nxt_string("true") }, + { nxt_string("true instanceof Boolean"), + nxt_string("false") }, + + { nxt_string("1 instanceof Number"), + nxt_string("false") }, + + { nxt_string("'' instanceof String"), + nxt_string("false") }, + { nxt_string("({}) instanceof Object"), nxt_string("true") }, + { nxt_string("[] instanceof []"), + nxt_string("TypeError") }, + { nxt_string("[] instanceof Array"), nxt_string("true") }, { nxt_string("[] instanceof Object"), nxt_string("true") }, + { nxt_string("/./ instanceof RegExp"), + nxt_string("true") }, + + { nxt_string("/./ instanceof Object"), + nxt_string("true") }, + { nxt_string("var o = Object(); o"), nxt_string("[object Object]") }, -- 2.47.3