static njs_ret_t njs_array_prototype_push(njs_vm_t *vm, njs_param_t *param) { uintptr_t i, nargs; njs_ret_t ret; njs_value_t *args; njs_array_t *array; if (njs_is_array(param->object)) { array = param->object->data.u.array; nargs = param->nargs; if (nargs != 0) { if (nargs > array->size - array->length) { ret = njs_array_realloc(vm, array, 0, array->size + nargs); if (nxt_slow_path(ret != NXT_OK)) { return ret; } } args = param->args; for (i = 0; i < nargs; i++) { /* GC: njs_retain(&args[i]); */ array->start[array->length++] = args[i]; } } njs_number_set(&vm->retval, array->length); } return NXT_OK; }
static njs_ret_t njs_array_prototype_length(njs_vm_t *vm, njs_value_t *array) { njs_number_set(&vm->retval, array->data.u.array->length); njs_release(vm, array); return NXT_OK; }
static njs_ret_t njs_regexp_prototype_last_index(njs_vm_t *vm, njs_value_t *value) { uint32_t index; njs_regexp_t *regexp; njs_string_prop_t string; njs_release(vm, value); regexp = value->data.u.regexp; (void) njs_string_prop(&string, ®exp->string); index = njs_string_index(&string, regexp->last_index); njs_number_set(&vm->retval, index); return NXT_OK; }
static njs_ret_t njs_array_prototype_unshift(njs_vm_t *vm, njs_param_t *param) { uintptr_t nargs; njs_ret_t ret; njs_value_t *args; njs_array_t *array; if (njs_is_array(param->object)) { array = param->object->data.u.array; nargs = param->nargs; if (nargs != 0) { if ((intptr_t) nargs > (array->start - array->data)) { ret = njs_array_realloc(vm, array, nargs, array->size); if (nxt_slow_path(ret != NXT_OK)) { return ret; } } array->length += nargs; args = param->args; do { nargs--; /* GC: njs_retain(&args[nargs]); */ array->start--; array->start[0] = args[nargs]; } while (nargs != 0); } njs_number_set(&vm->retval, array->length); } return NXT_OK; }
static njs_ret_t njs_array_prototype_every(njs_vm_t *vm, njs_param_t *param) { nxt_int_t n; uintptr_t nargs; njs_param_t p; njs_array_t *array; njs_value_t *object, *args, *func, arguments[3]; njs_array_each_t *each; object = param->object; if (!vm->frame->reentrant) { vm->frame->reentrant = 1; if (!njs_is_array(object)) { vm->exception = &njs_exception_type_error; return NXT_ERROR; } array = object->data.u.array; n = njs_array_next(array->start, 0, array->length); each = njs_native_data(vm->frame); each->index = n; each->length = array->length; } else { each = njs_native_data(vm->frame); if (!njs_is_true(&each->retval)) { vm->retval = njs_value_false; return NXT_OK; } } n = each->index; if (n < 0) { vm->retval = njs_value_true; return NXT_OK; } /* GC: array elt, array */ array = object->data.u.array; arguments[0] = array->start[n]; njs_number_set(&arguments[1], n); arguments[2] = *object; each->index = njs_array_next(array->start, ++n, each->length); nargs = param->nargs; args = param->args; p.object = (nargs > 1) ? &args[1] : (njs_value_t *) &njs_value_void; p.args = arguments; p.nargs = 3; p.retval = (njs_index_t) &each->retval; func = (nargs != 0) ? &args[0] : (njs_value_t *) &njs_value_void; vm->current -= sizeof(njs_vmcode_call_t); return njs_function_apply(vm, func, &p); }
static njs_ret_t njs_regexp_exec_result(njs_vm_t *vm, njs_regexp_t *regexp, u_char *string, nxt_regex_match_data_t *match_data, nxt_uint_t utf8) { int *captures; u_char *start; int32_t size, length; njs_ret_t ret; nxt_uint_t i, n; njs_array_t *array; njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; static const njs_value_t njs_string_index = njs_string("index"); static const njs_value_t njs_string_input = njs_string("input"); array = njs_array_alloc(vm, regexp->pattern->ncaptures, 0); if (nxt_slow_path(array == NULL)) { goto fail; } captures = nxt_regex_captures(match_data); for (i = 0; i < regexp->pattern->ncaptures; i++) { n = 2 * i; if (captures[n] != -1) { start = &string[captures[n]]; size = captures[n + 1] - captures[n]; switch (utf8) { case 0: length = 0; break; case 1: length = size; break; default: length = nxt_utf8_length(start, size); break; } ret = njs_regexp_string_create(vm, &array->start[i], start, size, length); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } } else { array->start[i] = njs_value_void; } } prop = njs_object_prop_alloc(vm, &njs_string_index); if (nxt_slow_path(prop == NULL)) { goto fail; } /* TODO: Non UTF-8 position */ njs_number_set(&prop->value, regexp->last_index + captures[0]); if (regexp->pattern->global) { regexp->last_index += captures[1]; } lhq.key_hash = NJS_INDEX_HASH; lhq.key.len = sizeof("index") - 1; lhq.key.data = (u_char *) "index"; lhq.replace = 0; lhq.value = prop; lhq.pool = vm->mem_cache_pool; lhq.proto = &njs_object_hash_proto; ret = nxt_lvlhsh_insert(&array->object.hash, &lhq); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } prop = njs_object_prop_alloc(vm, &njs_string_input); if (nxt_slow_path(prop == NULL)) { goto fail; } njs_string_copy(&prop->value, ®exp->string); lhq.key_hash = NJS_INPUT_HASH; lhq.key.len = sizeof("input") - 1; lhq.key.data = (u_char *) "input"; lhq.value = prop; ret = nxt_lvlhsh_insert(&array->object.hash, &lhq); if (nxt_fast_path(ret == NXT_OK)) { vm->retval.data.u.array = array; vm->retval.type = NJS_ARRAY; vm->retval.data.truth = 1; ret = NXT_OK; goto done; } fail: ret = NXT_ERROR; done: nxt_regex_match_data_free(match_data, vm->regex_context); return ret; }