From: Dmitry Volyntsev Date: Mon, 1 Apr 2019 16:11:39 +0000 (+0300) Subject: Refactored function object creation. X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=c43eb4e5c98284fec32372daf7c28a9ac610f86b;p=njs.git Refactored function object creation. --- diff --git a/njs/njs_function.c b/njs/njs_function.c index 9ce1bd39..d3450ed4 100644 --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -14,36 +14,54 @@ static njs_ret_t njs_normalize_args(njs_vm_t *vm, njs_value_t *args, njs_function_t * -njs_function_alloc(njs_vm_t *vm) +njs_function_alloc(njs_vm_t *vm, njs_function_lambda_t *lambda, + njs_closure_t *closures[], nxt_bool_t shared) { + size_t size; + nxt_uint_t n, nesting; njs_function_t *function; - function = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_t)); + nesting = lambda->nesting; + size = sizeof(njs_function_t) + nesting * sizeof(njs_closure_t *); - if (nxt_fast_path(function != NULL)) { - /* - * nxt_mp_zalloc() does also: - * nxt_lvlhsh_init(&function->object.hash); - * function->object.__proto__ = NULL; - */ + function = nxt_mp_zalloc(vm->mem_pool, size); + if (nxt_slow_path(function == NULL)) { + goto fail; + } - function->object.shared_hash = vm->shared->function_prototype_hash; - function->object.type = NJS_FUNCTION; - function->object.shared = 1; - function->object.extensible = 1; - function->args_offset = 1; - function->ctor = 1; - function->u.lambda = nxt_mp_zalloc(vm->mem_pool, - sizeof(njs_function_lambda_t)); - if (nxt_slow_path(function->u.lambda == NULL)) { - njs_memory_error(vm); - return NULL; - } + /* + * nxt_mp_zalloc() does also: + * nxt_lvlhsh_init(&function->object.hash); + * function->object.__proto__ = NULL; + */ - return function; + function->ctor = 1; + function->args_offset = 1; + function->u.lambda = lambda; + + function->object.shared_hash = vm->shared->function_prototype_hash; + function->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object; + function->object.type = NJS_FUNCTION; + function->object.shared = shared; + function->object.extensible = 1; + + if (nesting != 0 && closures != NULL) { + function->closure = 1; + + n = 0; + + do { + /* GC: retain closure. */ + function->closures[n] = closures[n]; + n++; + } while (n < nesting); } + return function; + +fail: + njs_memory_error(vm); return NULL; diff --git a/njs/njs_function.h b/njs/njs_function.h index 9ae86f3d..b099ec1f 100644 --- a/njs/njs_function.h +++ b/njs/njs_function.h @@ -147,7 +147,8 @@ struct njs_frame_s { }; -njs_function_t *njs_function_alloc(njs_vm_t *vm); +njs_function_t *njs_function_alloc(njs_vm_t *vm, njs_function_lambda_t *lambda, + njs_closure_t *closures[], nxt_bool_t shared); njs_function_t *njs_function_value_copy(njs_vm_t *vm, njs_value_t *value); njs_ret_t njs_function_arguments_object_init(njs_vm_t *vm, njs_native_frame_t *frame); diff --git a/njs/njs_parser.c b/njs/njs_parser.c index eff28888..45b9f2c5 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -552,10 +552,23 @@ static njs_function_t * njs_parser_function_alloc(njs_vm_t *vm, njs_parser_t *parser, njs_variable_t *var) { - njs_value_t *value; - njs_function_t *function; + njs_value_t *value; + njs_function_t *function; + njs_function_lambda_t *lambda; + + lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t)); + if (nxt_slow_path(lambda == NULL)) { + njs_memory_error(vm); + return NULL; + } + + /* TODO: + * njs_function_t is used to pass lambda to + * njs_generate_function_declaration() and is not actually needed. + * real njs_function_t is created by njs_vmcode_function() in runtime. + */ - function = njs_function_alloc(vm); + function = njs_function_alloc(vm, lambda, NULL, 1); if (nxt_slow_path(function == NULL)) { return NULL; } diff --git a/njs/njs_vm.c b/njs/njs_vm.c index 0f8b4ed9..aefe678c 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -371,43 +371,18 @@ njs_vmcode_array(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) njs_ret_t njs_vmcode_function(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) { - size_t size; - nxt_uint_t n, nesting; njs_function_t *function; njs_function_lambda_t *lambda; njs_vmcode_function_t *code; code = (njs_vmcode_function_t *) vm->current; lambda = code->lambda; - nesting = lambda->nesting; - size = sizeof(njs_function_t) + nesting * sizeof(njs_closure_t *); - - function = nxt_mp_zalloc(vm->mem_pool, size); + function = njs_function_alloc(vm, lambda, vm->active_frame->closures, 0); if (nxt_slow_path(function == NULL)) { - njs_memory_error(vm); return NXT_ERROR; } - function->u.lambda = lambda; - function->object.shared_hash = vm->shared->function_prototype_hash; - function->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object; - function->object.extensible = 1; - function->args_offset = 1; - function->ctor = 1; - - if (nesting != 0) { - function->closure = 1; - - n = 0; - - do { - /* GC: retain closure. */ - function->closures[n] = vm->active_frame->closures[n]; - n++; - } while (n < nesting); - } - vm->retval.data.u.function = function; vm->retval.type = NJS_FUNCTION; vm->retval.data.truth = 1;