njs_ret_t njs_object_prototype_create(njs_vm_t *vm, njs_value_t *value) { int32_t index; nxt_int_t ret; njs_function_t *function; njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; static const njs_value_t prototype = njs_string("prototype"); function = value->data.u.function; index = function - vm->functions; if (index < 0 && index > NJS_PROTOTYPE_MAX) { vm->retval = njs_value_void; return NXT_OK; } prop = njs_object_prop_alloc(vm, &prototype); if (nxt_slow_path(prop == NULL)) { return NXT_ERROR; } prop->value.data.u.object = &vm->prototypes[index]; prop->value.type = NJS_OBJECT; prop->value.data.truth = 1; prop->enumerable = 0; prop->writable = 0; prop->configurable = 0; lhq.value = prop; lhq.key_hash = NJS_PROTOTYPE_HASH; lhq.key.len = sizeof("prototype") - 1; lhq.key.data = (u_char *) "prototype"; lhq.replace = 0; lhq.pool = vm->mem_cache_pool; lhq.proto = &njs_object_hash_proto; ret = nxt_lvlhsh_insert(&function->object.hash, &lhq); if (nxt_fast_path(ret == NXT_OK)) { vm->retval = prop->value; } /* TODO: exception NXT_ERROR. */ return ret; }
} } vm->retval.type = NJS_ARRAY; vm->retval.data.truth = 1; return NXT_OK; } return NXT_ERROR; } static const njs_object_prop_t njs_array_function_properties[] = { { njs_string("Array"), njs_string("name"), NJS_PROPERTY, 0, 0, 0, }, { njs_value(NJS_NUMBER, 1, 1.0), njs_string("length"), NJS_PROPERTY, 0, 0, 0, }, { njs_getter(njs_object_prototype_create_prototype), njs_string("prototype"), NJS_NATIVE_GETTER, 0, 0, 0, }, }; nxt_int_t njs_array_function_hash(njs_vm_t *vm, nxt_lvlhsh_t *hash)
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; }
uint32_t size; u_char buf[NJS_EXCEPTION_BUF_LENGTH]; size = snprintf((char *) buf, NJS_EXCEPTION_BUF_LENGTH, "RegExpError: %s", vm->regex_context->error); return njs_vm_throw_exception(vm, buf, size); } static const njs_object_prop_t njs_regexp_constructor_properties[] = { /* RegExp.name == "RegExp". */ { .type = NJS_PROPERTY, .name = njs_string("name"), .value = njs_string("RegExp"), }, /* RegExp.length == 2. */ { .type = NJS_PROPERTY, .name = njs_string("length"), .value = njs_value(NJS_NUMBER, 1, 2.0), }, /* RegExp.prototype. */ { .type = NJS_NATIVE_GETTER, .name = njs_string("prototype"), .value = njs_native_getter(njs_object_prototype_create),
static njs_ret_t njs_object_prototype_create_constructor(njs_vm_t *vm, njs_value_t *value) { int32_t index; nxt_int_t ret; njs_value_t *constructor; njs_object_t *prototype; njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; static const njs_value_t constructor_string = njs_string("constructor"); if (njs_is_object(value)) { prototype = value->data.u.object; do { index = prototype - vm->prototypes; if (index >= 0 && index < NJS_PROTOTYPE_MAX) { goto found; } prototype = prototype->__proto__; } while (prototype != NULL); nxt_thread_log_alert("prototype not found"); return NXT_ERROR; } else { index = njs_primitive_prototype_index(value->type); prototype = &vm->prototypes[index]; } found: prop = njs_object_prop_alloc(vm, &constructor_string); if (nxt_slow_path(prop == NULL)) { return NXT_ERROR; } /* GC */ constructor = &vm->scopes[NJS_SCOPE_GLOBAL][index]; prop->value = *constructor; prop->enumerable = 0; lhq.value = prop; lhq.key_hash = NJS_CONSTRUCTOR_HASH; lhq.key.len = sizeof("constructor") - 1; lhq.key.data = (u_char *) "constructor"; lhq.replace = 0; lhq.pool = vm->mem_cache_pool; lhq.proto = &njs_object_hash_proto; ret = nxt_lvlhsh_insert(&prototype->hash, &lhq); if (nxt_fast_path(ret == NXT_OK)) { vm->retval = *constructor; } return ret; }
ret = nxt_lvlhsh_insert(&function->object.hash, &lhq); if (nxt_fast_path(ret == NXT_OK)) { vm->retval = prop->value; } /* TODO: exception NXT_ERROR. */ return ret; } static const njs_object_prop_t njs_object_constructor_properties[] = { /* Object.name == "name". */ { njs_string("Object"), njs_string("name"), NJS_PROPERTY, 0, 0, 0, }, /* Object.length == 1. */ { njs_value(NJS_NUMBER, 1, 1.0), njs_string("length"), NJS_PROPERTY, 0, 0, 0, }, /* Object.prototype. */ { njs_native_getter(njs_object_prototype_create), njs_string("prototype"), NJS_NATIVE_GETTER, 0, 0, 0, }, /* Object.create(). */ { njs_native_function(njs_object_create, 0),