]> git.kaiwu.me - njs.git/commitdiff
Array.toString() fixed.
authorIgor Sysoev <igor@sysoev.ru>
Fri, 11 Dec 2015 15:41:20 +0000 (18:41 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Fri, 11 Dec 2015 15:41:20 +0000 (18:41 +0300)
njs/njs_array.c
njs/njs_object.c
njs/njs_object.h
njs/test/njs_unit_test.c

index 788907c18cff89bc66160ee1df2a6ca7d76857d8..28d3bab7449775f9815abf99b39da213467fd0e2 100644 (file)
@@ -455,38 +455,33 @@ njs_array_prototype_shift(njs_vm_t *vm, njs_param_t *param)
 }
 
 
+/*
+ * ECMAScript 5.1: try first to use object method "join", then
+ * use the standard built-in method Object.prototype.toString().
+ */
+
 static njs_ret_t
 njs_array_prototype_to_string(njs_vm_t *vm, njs_param_t *param)
 {
-    njs_object_t        *object;
+    njs_value_t         *this;
     njs_object_prop_t   *prop;
     nxt_lvlhsh_query_t  lhq;
 
-    lhq.key_hash = NJS_JOIN_HASH;
-    lhq.key.len = sizeof("join") - 1;
-    lhq.key.data = (u_char *) "join";
-
-    object = param->object->data.u.object;
-
-    prop = njs_object_property(vm, object, &lhq);
+    this = param->object;
 
-    if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) {
-        return njs_function_apply(vm, &prop->value, param);
-    }
-
-    lhq.key_hash = NJS_TO_STRING_HASH;
-    lhq.key.len = sizeof("toString") - 1;
-    lhq.key.data = (u_char *) "toString";
-
-    object = &vm->prototypes[NJS_PROTOTYPE_OBJECT];
+    if (njs_is_object(this)) {
+        lhq.key_hash = NJS_JOIN_HASH;
+        lhq.key.len = sizeof("join") - 1;
+        lhq.key.data = (u_char *) "join";
 
-    prop = njs_object_property(vm, object, &lhq);
+        prop = njs_object_property(vm, this->data.u.object, &lhq);
 
-    if (nxt_fast_path(prop != NULL)) {
-        return njs_function_apply(vm, &prop->value, param);
+        if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) {
+            return njs_function_apply(vm, &prop->value, param);
+        }
     }
 
-    return NXT_ERROR;
+    return njs_object_prototype_to_string(vm, param);
 }
 
 
index a0e37795df1588f75e866883a1976d7095945103..df516615bca1a0490e130d550be31ed04975a16d 100644 (file)
@@ -537,7 +537,7 @@ static const njs_value_t  njs_object_regexp_string =
                                      njs_long_string("[object RegExp]");
 
 
-static njs_ret_t
+njs_ret_t
 njs_object_prototype_to_string(njs_vm_t *vm, njs_param_t *param)
 {
     int32_t       index;
index a645494aca54fda17de90f535423593a4cb80cce..ce18d0149c234885ee7b8f0f2c4044fde1bfedce 100644 (file)
@@ -56,6 +56,7 @@ njs_ret_t njs_object_constructor(njs_vm_t *vm, njs_param_t *param);
 njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name);
 njs_ret_t njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_value_t *value);
 njs_ret_t njs_object_prototype_create(njs_vm_t *vm, njs_value_t *value);
+njs_ret_t njs_object_prototype_to_string(njs_vm_t *vm, njs_param_t *param);
 
 extern const njs_object_init_t  njs_object_constructor_init;
 extern const njs_object_init_t  njs_object_prototype_init;
index a9f50eb9a9c6830281e83a8d698490b04e741622..6af272c18a6a52747b0151564cc401c445cbcbf2 100644 (file)
@@ -1708,7 +1708,19 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("a = []; a.concat([]) +''"),
       nxt_string("") },
 
-    /**/
+    /* Array.toString(). */
+
+    { nxt_string("a = [1,2,3]; a.join = 'NO';"
+                 "Object.prototype.toString = function () { return 'A' }; a"),
+      nxt_string("[object Array]") },
+
+    { nxt_string("Array.prototype.toString.call(1)"),
+      nxt_string("[object Number]") },
+
+    { nxt_string("Array.prototype.toString.call('abc')"),
+      nxt_string("[object String]") },
+
+    /* Empty array elements. */
 
     { nxt_string("[,,]"),
       nxt_string(",") },
@@ -3464,6 +3476,7 @@ njs_unit_test(nxt_bool_t disassemble)
             r.uri.data = (u_char *) "АБВ";
 
             if (njs_vm_run(nvm) == NXT_OK) {
+
                 if (njs_vm_retval(nvm, &s) != NXT_OK) {
                     return NXT_ERROR;
                 }
@@ -3559,6 +3572,7 @@ njs_unit_test_benchmark(nxt_str_t *script, nxt_str_t *result, const char *msg,
         }
 
         if (njs_vm_run(nvm) == NXT_OK) {
+
             if (njs_vm_retval(nvm, &s) != NXT_OK) {
                 return NXT_ERROR;
             }