ext->value.data.truth = 1;
ext->value.data.u.external = ext;
+ if (external->method != NULL) {
+ ext->function = nxt_mem_cache_zalloc(mcp, sizeof(njs_function_t));
+ if (nxt_slow_path(ext->function == NULL)) {
+ return NXT_ERROR;
+ }
+
+ ext->function->native = 1;
+ ext->function->args_offset = 1;
+ ext->function->u.native = external->method;
+ }
+
nxt_lvlhsh_init(&ext->hash);
ext->type = external->type;
ext->get = external->get;
ext->find = external->find;
ext->foreach = external->foreach;
ext->next = external->next;
- ext->method = external->method;
ext->object = object;
ext->data = external->data;
njs_extern_foreach_t foreach;
njs_extern_next_t next;
- njs_extern_method_t method;
+ njs_function_t *function;
uintptr_t object;
uintptr_t data;
njs_value_t *
-njs_function_native_frame(njs_vm_t *vm, njs_native_t native, size_t local_size,
+njs_function_native_frame(njs_vm_t *vm, njs_function_t *function,
njs_vmcode_t *code)
{
size_t size;
njs_value_t *this;
njs_native_frame_t *frame;
- size = NJS_NATIVE_FRAME_SIZE + local_size
+ size = NJS_NATIVE_FRAME_SIZE + function->local_state_size
+ code->nargs * sizeof(njs_value_t);
frame = njs_function_frame_alloc(vm, size);
return NULL;
}
- frame->u.native = native;
- frame->native = 1;
+ frame->u.function = function;
frame->ctor = code->ctor;
- this = (njs_value_t *) ((u_char *) njs_native_data(frame) + local_size);
+ this = (njs_value_t *) ((u_char *) njs_native_data(frame)
+ + function->local_state_size);
frame->arguments = this + 1;
vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = frame->arguments;
}
native_frame->u.function = function;
- native_frame->native = 0;
native_frame->ctor = ctor;
args = (njs_value_t *) ((u_char *) native_frame + NJS_FRAME_SIZE);
union {
njs_function_t *function;
u_char *return_address;
- njs_native_t native;
u_char *restart;
} u;
uint32_t free_size;
- /* Script or native function or method. */
- uint8_t native; /* 1 bit */
-
/* Function is called as constructor with "new" keyword. */
uint8_t ctor; /* 1 bit */
njs_ret_t njs_function_constructor(njs_vm_t *vm, njs_param_t *param);
njs_ret_t njs_function_apply(njs_vm_t *vm, njs_value_t *name,
njs_param_t *param);
-njs_value_t *njs_function_native_frame(njs_vm_t *vm, njs_native_t native,
- size_t local_size, njs_vmcode_t *code);
+njs_value_t *njs_function_native_frame(njs_vm_t *vm, njs_function_t *function,
+ njs_vmcode_t *code);
njs_ret_t njs_function_frame(njs_vm_t *vm, njs_function_t *function,
njs_param_t *param, nxt_bool_t ctor);
njs_ret_t njs_function_call(njs_vm_t *vm, njs_index_t retval);
function = value->data.u.function;
if (function->native) {
- this = njs_function_native_frame(vm, function->u.native, 0,
- &func->code);
+ this = njs_function_native_frame(vm, function, &func->code);
if (nxt_fast_path(this != NULL)) {
*this = njs_value_void;
return ret;
}
- this = njs_function_native_frame(vm, function->u.native,
- function->local_state_size,
- &method->code);
+ this = njs_function_native_frame(vm, function, &method->code);
if (nxt_slow_path(this == NULL)) {
return NXT_ERROR;
}
ext = pq.lhq.value;
if (ext->type == NJS_EXTERN_METHOD) {
- this = njs_function_native_frame(vm, ext->method, 0,
+ this = njs_function_native_frame(vm, ext->function,
&method->code);
if (nxt_slow_path(this == NULL)) {
/* Update code pointer here to store it as return address in call frame. */
vm->current += sizeof(njs_vmcode_function_call_t);
- if (!vm->frame->native) {
+ if (!vm->frame->u.function->native) {
(void) njs_function_call(vm, (njs_index_t) retval);
return 0;
}
param.args = args;
param.this = args - 1;
- ret = vm->frame->u.native(vm, ¶m);
+ ret = vm->frame->u.function->u.native(vm, ¶m);
/*
* A native method can return:
* NXT_OK on method success;