]> git.kaiwu.me - njs.git/commitdiff
Object to primitive value convertion traps have been fixed.
authorIgor Sysoev <igor@sysoev.ru>
Sun, 27 Dec 2015 12:26:08 +0000 (15:26 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Sun, 27 Dec 2015 12:26:08 +0000 (15:26 +0300)
njs/njs_vm.c
njs/test/njs_unit_test.c

index c1f98b79c56a96a2c4a0b73380e75ed0fbd525d4..a72102f1d1c3645fca15a7fbee047519b109c6b8 100644 (file)
@@ -2563,6 +2563,15 @@ njs_vm_trap(njs_vm_t *vm, nxt_uint_t trap, njs_value_t *value1,
 
     frame->ctor = 0;
 
+    /*
+     * The values[0] is scratch value for results of "valueOf" and
+     * "toString" methods.  The values[1] and values[2] are original
+     * operand values which will be replaced with primitive values
+     * returned by "valueOf" or "toString" methods.  The scratch value
+     * is stored separately to preserve the original operand values for
+     * the second method call if the first method call will return
+     * non-primitive value.
+     */
     values = njs_native_data(frame);
     njs_set_invalid(&values[0]);
     values[2] = *value2;
@@ -2695,7 +2704,7 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint)
     if (!njs_is_primitive(value)) {
         retval = njs_native_data(vm->frame);
 
-        if (!njs_is_valid(retval)) {
+        if (!njs_is_primitive(retval)) {
 
             for ( ;; ) {
                 vm->exception = &njs_exception_type_error;
@@ -2710,6 +2719,12 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint)
                     prop = njs_object_property(vm, value->data.u.object, &lhq);
 
                     if (nxt_fast_path(prop != NULL)) {
+
+                        if (!njs_is_function(&prop->value)) {
+                            /* Try the second method. */
+                            continue;
+                        }
+
                         param.this = value;
                         param.retval = (njs_index_t) retval;
                         param.args = NULL;
index 3cfb91e0620a171ad5b9ef4fa7636c19c8ecf6b5..31f6a105a2962bf21551d91094c20ca2ee83189a 100644 (file)
@@ -91,6 +91,28 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("\n +1"),
       nxt_string("1") },
 
+    /* An object "valueOf/toString" methods. */
+
+    { nxt_string("var a = { valueOf: function() { return 1 } };    +a"),
+      nxt_string("1") },
+
+    { nxt_string("var a = { valueOf: function() { return '1' } };  +a"),
+      nxt_string("1") },
+
+    { nxt_string("var a = { valueOf: 2,"
+                 "          toString: function() { return '1' } }; +a"),
+      nxt_string("1") },
+
+    { nxt_string("var a = { valueOf: function() { return [] },"
+                 "          toString: function() { return '1' } }; +a"),
+      nxt_string("1") },
+
+    { nxt_string("var a = { toString: function() { return 'a' } };"
+                 "var b = { toString: function() { return a+'b' } }; '0'+b"),
+      nxt_string("0ab") },
+
+    /**/
+
     { nxt_string("1 + undefined"),
       nxt_string("NaN") },