From: Igor Sysoev Date: Mon, 11 Apr 2016 11:39:59 +0000 (+0300) Subject: String.fromCharCode() and String.fromCodePoint(). X-Git-Tag: 0.1.0~34 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=b21cdea89406a6afa3ab1b1b38a0a8027d211fb5;p=njs.git String.fromCharCode() and String.fromCodePoint(). --- diff --git a/njs/njs_string.c b/njs/njs_string.c index e863b04e..d7e853c6 100644 --- a/njs/njs_string.c +++ b/njs/njs_string.c @@ -35,6 +35,8 @@ static nxt_noinline void njs_string_slice_prop(njs_string_prop_t *string, 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_string_constructor_properties[] = .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), + }, }; @@ -1044,6 +1060,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 --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 44ef4d5e..85a00753 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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") },