[njs] String.fromCharCode() and String.fromCodePoint().

Igor Sysoev igor at sysoev.ru
Fri Apr 15 14:21:23 UTC 2016


details:   http://hg.nginx.org/njs/rev/51009da8e3d0
branches:  
changeset: 98:51009da8e3d0
user:      Igor Sysoev <igor at sysoev.ru>
date:      Mon Apr 11 14:39:59 2016 +0300
description:
String.fromCharCode() and String.fromCodePoint().

diffstat:

 njs/njs_string.c         |  69 ++++++++++++++++++++++++++++++++++++++++++++++++
 njs/test/njs_unit_test.c |  21 ++++++++++++++
 2 files changed, 90 insertions(+), 0 deletions(-)

diffs (124 lines):

diff -r 24544f647802 -r 51009da8e3d0 njs/njs_string.c
--- a/njs/njs_string.c	Sat Apr 09 12:21:31 2016 +0300
+++ b/njs/njs_string.c	Mon Apr 11 14:39:59 2016 +0300
@@ -35,6 +35,8 @@ static nxt_noinline void njs_string_slic
     njs_slice_prop_t *slice, njs_value_t *args, nxt_uint_t nargs);
 static nxt_noinline void njs_string_slice_args(njs_slice_prop_t *slice,
     njs_value_t *args, nxt_uint_t nargs);
+static njs_ret_t njs_string_prototype_from_char_code(njs_vm_t *vm,
+    njs_value_t *args, nxt_uint_t nargs, njs_index_t unused);
 static nxt_noinline ssize_t njs_string_index_of(njs_vm_t *vm,
     njs_value_t *src, njs_value_t *search_string, size_t index);
 
@@ -305,6 +307,20 @@ static const njs_object_prop_t  njs_stri
         .name = njs_string("prototype"),
         .value = njs_native_getter(njs_object_prototype_create),
     },
+
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("fromCharCode"),
+        .value = njs_native_function(njs_string_prototype_from_char_code, 0, 0),
+    },
+
+
+    /* ECMAScript 6, fromCodePoint(). */
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("fromCodePoint"),
+        .value = njs_native_function(njs_string_prototype_from_char_code, 0, 0),
+    },
 };
 
 
@@ -1045,6 +1061,59 @@ done:
 
 
 static njs_ret_t
+njs_string_prototype_from_char_code(njs_vm_t *vm, njs_value_t *args,
+    nxt_uint_t nargs, njs_index_t unused)
+{
+    u_char      *p;
+    double      num;
+    size_t      size;
+    int32_t     code;
+    nxt_uint_t  i;
+
+    for (i = 1; i < nargs; i++) {
+        if (!njs_is_numeric(&args[i])) {
+            vm->frame->trap_scratch.data.u.value = &args[i];
+            return NJS_TRAP_NUMBER_ARG;
+        }
+    }
+
+    size = 0;
+
+    for (i = 1; i < nargs; i++) {
+        num = args[i].data.u.number;
+        if (njs_is_nan(num)) {
+            goto range_error;
+        }
+
+        code = num;
+
+        if (code != num || code < 0 || code >= 0x110000) {
+            goto range_error;
+        }
+
+        size += nxt_utf8_size(code);
+    }
+
+    p = njs_string_alloc(vm, &vm->retval, size, nargs - 1);
+    if (nxt_slow_path(p == NULL)) {
+        return NXT_ERROR;
+    }
+
+    for (i = 1; i < nargs; i++) {
+        p = nxt_utf8_encode(p, args[i].data.u.number);
+    }
+
+    return NXT_OK;
+
+range_error:
+
+    vm->exception = &njs_exception_range_error;
+
+    return NXT_ERROR;
+}
+
+
+static njs_ret_t
 njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
     njs_index_t unused)
 {
diff -r 24544f647802 -r 51009da8e3d0 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Sat Apr 09 12:21:31 2016 +0300
+++ b/njs/test/njs_unit_test.c	Mon Apr 11 14:39:59 2016 +0300
@@ -2681,6 +2681,27 @@ static njs_unit_test_t  njs_test[] =
                  "    .length"),
       nxt_string("5") },
 
+    { nxt_string("String.fromCharCode('_')"),
+      nxt_string("RangeError") },
+
+    { nxt_string("String.fromCharCode(3.14)"),
+      nxt_string("RangeError") },
+
+    { nxt_string("String.fromCharCode(65, 90)"),
+      nxt_string("AZ") },
+
+    { nxt_string("String.fromCharCode(945, 946, 947)"),
+      nxt_string("αβγ") },
+
+    { nxt_string("(function() {"
+                 "    for (n = 0; n <= 1114111; n++) {"
+                 "        if (String.fromCharCode(n).charCodeAt(0) !== n)"
+                 "            return n;"
+                 "    }"
+                 "    return -1"
+                 "})()"),
+      nxt_string("-1") },
+
     { nxt_string("a = 'abcdef'; function f(a) {"
                  "return a.slice(a.indexOf('cd')) } f(a)"),
       nxt_string("cdef") },


More information about the nginx-devel mailing list