njs_vmcode_prop_set_t *code;
if (njs_is_primitive(object)) {
- njs_exception_type_error(vm, NULL, NULL);
+ njs_exception_type_error(vm, "property set on primitive %s type",
+ njs_type_string(object->type));
return NXT_ERROR;
}
case NJS_PRIMITIVE_VALUE:
case NJS_STRING_VALUE:
- njs_exception_type_error(vm, NULL, NULL);
+ njs_exception_type_error(vm, "property in on a primitive value", NULL);
return NXT_ERROR;
break;
default: /* NJS_VOID, NJS_NULL. */
- njs_exception_type_error(vm, NULL, NULL);
+ if (nxt_fast_path(njs_is_primitive(property))) {
+
+ ret = njs_primitive_value_to_string(vm, &pq->value, property);
+
+ if (nxt_fast_path(ret == NXT_OK)) {
+ njs_string_get(&pq->value, &pq->lhq.key);
+ njs_exception_type_error(vm,
+ "cannot get property '%.*s' of undefined",
+ (int) pq->lhq.key.length,
+ pq->lhq.key.start);
+ return NXT_ERROR;
+ }
+ }
+
+ njs_exception_type_error(vm,
+ "cannot get property 'unknown' of undefined", NULL);
+
return NXT_ERROR;
}
nxt_lvlhsh_query_t lhq;
if (!njs_is_function(constructor)) {
- njs_exception_type_error(vm, NULL, NULL);
+ njs_exception_type_error(vm, "right argument is not a function", NULL);
return NXT_ERROR;
}
}
}
- njs_exception_type_error(vm, NULL, NULL);
+ njs_exception_type_error(vm, "object is not callable", NULL);
return NXT_ERROR;
}
pq.query = NJS_PROPERTY_QUERY_GET;
- switch (njs_property_query(vm, &pq, object, name)) {
+ ret = njs_property_query(vm, &pq, object, name);
+
+ switch (ret) {
case NXT_OK:
prop = pq.lhq.value;
ret = nxt_lvlhsh_find(&ext->hash, &pq.lhq);
if (nxt_slow_path(ret != NXT_OK)) {
- goto type_error;
+ njs_exception_type_error(vm,
+ "cannot find property '%.*s' of an external object",
+ (int) pq.lhq.key.length, pq.lhq.key.start);
+ return NXT_ERROR;
+
}
ext = pq.lhq.value;
if (nxt_slow_path(ext->type != NJS_EXTERN_METHOD)) {
- goto type_error;
+ njs_exception_type_error(vm,
+ "method '%.*s' of an external object is not callable",
+ (int) pq.lhq.key.length, pq.lhq.key.start);
+ return NXT_ERROR;
}
this.data.u.data = vm->external[ext->object];
break;
default:
- goto type_error;
+ njs_exception_internal_error(vm, "method '%.*s' query failed:%d",
+ (int) pq.lhq.key.length, pq.lhq.key.start,
+ ret);
+ return NXT_ERROR;
}
if (nxt_fast_path(ret == NXT_OK)) {
}
return ret;
-
-type_error:
-
- njs_exception_type_error(vm, NULL, NULL);
-
- return NXT_ERROR;
}
type_error:
- njs_exception_type_error(vm, NULL, NULL);
+ njs_exception_type_error(vm, "cannot convert %s to %s",
+ njs_type_string(args->type),
+ njs_arg_type_string(*args_types));
return NXT_ERROR;
}
+const char *
+njs_type_string(njs_value_type_t type)
+{
+ switch (type) {
+ case NJS_NULL:
+ return "null";
+
+ case NJS_VOID:
+ return "void";
+
+ case NJS_BOOLEAN:
+ return "boolean";
+
+ case NJS_NUMBER:
+ return "number";
+
+ case NJS_STRING:
+ return "string";
+
+ case NJS_EXTERNAL:
+ return "external";
+
+ case NJS_INVALID:
+ return "invalid";
+
+ case NJS_OBJECT:
+ return "object";
+
+ case NJS_ARRAY:
+ return "array";
+
+ case NJS_OBJECT_BOOLEAN:
+ return "object boolean";
+
+ case NJS_OBJECT_NUMBER:
+ return "object number";
+
+ case NJS_OBJECT_STRING:
+ return "object string";
+
+ case NJS_FUNCTION:
+ return "function";
+
+ case NJS_REGEXP:
+ return "regexp";
+
+ case NJS_DATE:
+ return "date";
+
+ case NJS_OBJECT_ERROR:
+ return "error";
+
+ case NJS_OBJECT_EVAL_ERROR:
+ return "eval error";
+
+ case NJS_OBJECT_INTERNAL_ERROR:
+ return "internal error";
+
+ case NJS_OBJECT_RANGE_ERROR:
+ return "range error";
+
+ case NJS_OBJECT_REF_ERROR:
+ return "reference error";
+
+ case NJS_OBJECT_SYNTAX_ERROR:
+ return "syntax error";
+
+ case NJS_OBJECT_TYPE_ERROR:
+ return "type error";
+
+ case NJS_OBJECT_URI_ERROR:
+ return "uri error";
+
+ default:
+ return NULL;
+ }
+}
+
+
+const char *
+njs_arg_type_string(uint8_t arg)
+{
+ switch (arg) {
+ case NJS_SKIP_ARG:
+ return "skip";
+
+ case NJS_NUMBER_ARG:
+ return "number";
+
+ case NJS_INTEGER_ARG:
+ return "integer";
+
+ case NJS_STRING_ARG:
+ return "string";
+
+ case NJS_OBJECT_ARG:
+ return "object";
+
+ case NJS_STRING_OBJECT_ARG:
+ return "string object";
+
+ case NJS_FUNCTION_ARG:
+ return "function";
+
+ case NJS_REGEXP_ARG:
+ return "regexp";
+
+ case NJS_DATE_ARG:
+ return "regexp";
+
+ default:
+ return "unknown";
+ }
+}
+
+
njs_ret_t
njs_vmcode_return(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval)
{
if (!njs_is_primitive(retval)) {
for ( ;; ) {
- njs_exception_type_error(vm, NULL, NULL);
ret = NXT_ERROR;
if (njs_is_object(value) && vm->top_frame->trap_tries < 2) {
}
}
+ if (ret == NXT_ERROR) {
+ njs_exception_type_error(vm, "cannot evaluate an object's "
+ "value", NULL);
+ }
+
return ret;
}
}
nxt_string("undefined") },
{ nxt_string("var a = {}; a.b.c"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot get property 'c' of undefined") },
{ nxt_string("'a'.b = 1"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: property set on primitive string type") },
{ nxt_string("var a = {}; a.b = 1; a.b"),
nxt_string("1") },
nxt_string("3") },
{ nxt_string("var a = undefined; a.b++; a.b"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot get property 'b' of undefined") },
{ nxt_string("var a = null; a.b++; a.b"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot get property 'b' of undefined") },
{ nxt_string("var a = true; a.b++; a.b"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: property set on primitive boolean type") },
{ nxt_string("var a = 1; a.b++; a.b"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: property set on primitive number type") },
{ nxt_string("var n = 1, o = { p: n += 1 }; o.p"),
nxt_string("2") },
nxt_string("2 1") },
{ nxt_string("var a = 2; a.b = 1; var c = a.b++; a +' '+ a.b +' '+ c"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: property set on primitive number type") },
{ nxt_string("var x = { a: 1 }; x.a"),
nxt_string("1") },
nxt_string("SyntaxError: Unexpected token \";\" in 1") },
{ nxt_string("var x = { a: 1, b: x.a }"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot get property 'a' of undefined") },
{ nxt_string("var a = { b: 2 }; a.b += 1"),
nxt_string("3") },
nxt_string("false") },
{ nxt_string("var a = 1; 1 in a"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: property in on a primitive value") },
{ nxt_string("var a = true; 1 in a"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: property in on a primitive value") },
{ nxt_string("var n = { toString: function() { return 'a' } };"
"var o = { a: 5 }; o[n]"),
{ nxt_string("var a = [];"
"a.reduce(function(p, v, i, a) { return p + v })"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: invalid index") },
{ nxt_string("var a = [];"
"a.reduce(function(p, v, i, a) { return p + v }, 10)"),
{ nxt_string("var a = [,,];"
"a.reduce(function(p, v, i, a) { return p + v })"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: invalid index") },
{ nxt_string("var a = [,,];"
"a.reduce(function(p, v, i, a) { return p + v }, 10)"),
{ nxt_string("var a = [];"
"a.reduceRight(function(p, v, i, a) { return p + v })"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: invalid index") },
{ nxt_string("var a = [];"
"a.reduceRight(function(p, v, i, a) { return p + v }, 10)"),
{ nxt_string("var a = [,,];"
"a.reduceRight(function(p, v, i, a) { return p + v })"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: invalid index") },
{ nxt_string("var a = [,,];"
"a.reduceRight(function(p, v, i, a) { return p + v }, 10)"),
nxt_string("abc") },
{ nxt_string("String.prototype.toString.call(1)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: unexpected value type:number") },
{ nxt_string("'abc'.valueOf()"),
nxt_string("abc") },
{ nxt_string("var r = { toString: function() { return /45/ } };"
"'123456'.search(r)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot evaluate an object's value") },
{ nxt_string("var r = { toString: function() { return /34/ },"
" valueOf: function() { return 45 } };"
{ nxt_string("var r = { toString: function() { return /45/ } };"
"'123456'.match(r)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot evaluate an object's value") },
{ nxt_string("var r = { toString: function() { return /34/ },"
" valueOf: function() { return 45 } };"
nxt_string("OKundefined") },
{ nxt_string("var a = 1; a()"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: object is not callable") },
{ nxt_string("var o = {a:1}; o.a()"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: object is not callable") },
{ nxt_string("(function(){})()"),
nxt_string("undefined") },
nxt_string("5") },
{ nxt_string("var f = function(a) { return this + a }; f.apply(5, 1)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: second argument is not an array") },
{ nxt_string("var f = function(a, b) { return this + a + b };"
"f.apply(5, [1, 2])"),
nxt_string("[object Function]") },
{ nxt_string("''.concat.call()"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: 'this' argument is null or undefined") },
{ nxt_string("''.concat.call('a', 'b', 'c')"),
nxt_string("abc") },
nxt_string("ab,cd") },
{ nxt_string("''.concat.apply()"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: 'this' argument is null or undefined") },
{ nxt_string("''.concat.apply('a')"),
nxt_string("a") },
{ nxt_string("''.concat.apply('a', 'b')"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: second argument is not an array") },
{ nxt_string("''.concat.apply('a', [ 'b', 'c' ])"),
nxt_string("abc") },
nxt_string("1552553") },
{ nxt_string("[].join.call()"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot convert void to object") },
{ nxt_string("[].slice.call()"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot convert void to object") },
{ nxt_string("function f(a) {} ; var a = f; var b = f; a === b"),
nxt_string("true") },
nxt_string("01") },
{ nxt_string("var concat = ''.concat; concat(1,2,3)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: 'this' argument is null or undefined") },
{ nxt_string("var concat = ''.concat; concat.call(1,2,3)"),
nxt_string("123") },
nxt_string("object") },
{ nxt_string("new decodeURI('%00')"),
- nxt_string("TypeError")},
+ nxt_string("TypeError: object is not callable")},
{ nxt_string("new ''.toString"),
- nxt_string("TypeError")},
+ nxt_string("TypeError: object is not callable")},
{ nxt_string("function F() { return Number }"
"var o = new (F())(5);"
nxt_string("true") },
{ nxt_string("[0].map(RegExp().toString)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: 'this' argument is not a regexp") },
/* Non-standard ECMA-262 features. */
nxt_string("o:OK") },
{ nxt_string("var o = { toString: function() { return [1] } }; o"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot evaluate an object's value") },
{ nxt_string("var o = { toString: function() { return [1] } }; 'o:' + o"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot evaluate an object's value") },
{ nxt_string("var a = { valueOf: function() { return '3' } };"
"var b = { toString: function() { return 10 - a + 'OK' } };"
nxt_string("true") },
{ nxt_string("[] instanceof []"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: right argument is not a function") },
{ nxt_string("[] instanceof Array"),
nxt_string("true") },
{ nxt_string("var o = Object.create(null); '__proto__' in o"),
nxt_string("false") },
+ { nxt_string("Object.create()"),
+ nxt_string("TypeError: too few arguments") },
+
{ nxt_string("var o = {a:1, b:2, c:3};"
"Object.keys(o)"),
nxt_string("a,b,c") },
{ nxt_string("var a = [,6,,3]; a.one = 7; Object.keys(a)"),
nxt_string("1,3,one") },
+ { nxt_string("Object.keys()"),
+ nxt_string("TypeError: cannot convert null argument to object") },
+
{ nxt_string("Object.keys('a')"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot convert string argument to object") },
{ nxt_string("Object.keys(1)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot convert number argument to object") },
{ nxt_string("var o = {}; Object.defineProperty(o, 'a', {}); o.a"),
nxt_string("undefined") },
nxt_string("2") },
{ nxt_string("var o = {}; Object.defineProperty()"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot convert null argument to object") },
{ nxt_string("var o = {}; Object.defineProperty(o)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: descriptor is not an object") },
{ nxt_string("var o = Object.defineProperties({}, {a:{value:1}}); o.a"),
nxt_string("1") },
nxt_string("1") },
{ nxt_string("Object.defineProperties(1, {})"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot convert number argument to object") },
{ nxt_string("Object.defineProperties({}, 1)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: descriptor is not an object") },
{ nxt_string("var o = {a:1}; o.hasOwnProperty('a')"),
nxt_string("true") },
nxt_string("true") },
{ nxt_string("Object.getPrototypeOf(1)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot convert number argument to object") },
{ nxt_string("Object.getPrototypeOf('a')"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot convert string argument to object") },
{ nxt_string("var p = {}; var o = Object.create(p);"
"p.isPrototypeOf(o)"),
nxt_string("undefined") },
{ nxt_string("Object.getOwnPropertyDescriptor(1, '0')"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot convert number argument to object") },
{ nxt_string("Object.defineProperty(Object.freeze({}), 'b', {})"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: object is not extensible") },
{ nxt_string("Object.defineProperties(Object.freeze({}), {b:{}})"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: object is not extensible") },
{ nxt_string("Object.freeze()"),
nxt_string("undefined") },
{ nxt_string("var a = Object.freeze([1,2]);"
"Object.defineProperty(a, 'a', {value:1}).a"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: object is not extensible") },
{ nxt_string("var a = [1,2]; a.a = 1; Object.freeze(a);"
"delete a.a; a.a"),
{ nxt_string("var f = Object.freeze(function() {});"
"Object.defineProperty(f, 'a', {value:1}).a"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: object is not extensible") },
{ nxt_string("var f = function() {}; f.a = 1; Object.freeze(f);"
"delete f.a; f.a"),
{ nxt_string("var d = Object.freeze(new Date(''));"
"Object.defineProperty(d, 'a', {value:1}).a"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: object is not extensible") },
{ nxt_string("var d = new Date(''); d.a = 1; Object.freeze(d);"
"delete d.a; d.a"),
{ nxt_string("var r = Object.freeze(new RegExp(''));"
"Object.defineProperty(r, 'a', {value:1}).a"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: object is not extensible") },
{ nxt_string("var r = new RegExp(''); r.a = 1; Object.freeze(r);"
"delete r.a; r.a"),
{ nxt_string("var o = Object.preventExtensions({a:1});"
"Object.defineProperty(o, 'b', {value:1})"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: object is not extensible") },
{ nxt_string("var o = Object.preventExtensions({a:1});"
"Object.defineProperties(o, {b:{value:1}})"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: object is not extensible") },
{ nxt_string("var o = Object.preventExtensions({a:1}); o.a = 2; o.a"),
nxt_string("2") },
nxt_string("true") },
{ nxt_string("[0].map(new Date().getDate)"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot convert void to regexp") },
{ nxt_string("new Date(eval)"),
nxt_string("Invalid Date") },
{ nxt_string("var o = JSON.parse('{\"a\":1}', "
" function(k, v) {return v.a.a;}); o"),
- nxt_string("TypeError") },
+ nxt_string("TypeError: cannot get property 'a' of undefined") },
/* JSON.stringify() */