Allowing predefine magic argument for a type constructor.
This allows to write generic constructor functions.
const njs_object_type_init_t njs_array_type_init = {
- .constructor = njs_array_constructor,
- .prototype_props = &njs_array_prototype_init,
+ .constructor = njs_native_ctor(njs_array_constructor, 1, 0),
.constructor_props = &njs_array_constructor_init,
- .value = { .object = { .type = NJS_ARRAY } },
+ .prototype_props = &njs_array_prototype_init,
+ .prototype_value = { .object = { .type = NJS_ARRAY } },
};
const njs_object_type_init_t njs_boolean_type_init = {
- .constructor = njs_boolean_constructor,
- .prototype_props = &njs_boolean_prototype_init,
+ .constructor = njs_native_ctor(njs_boolean_constructor, 1, 0),
.constructor_props = &njs_boolean_constructor_init,
- .value = { .object_value = { .value = njs_value(NJS_BOOLEAN, 0, 0.0),
- .object = { .type = NJS_OBJECT_BOOLEAN } } },
+ .prototype_props = &njs_boolean_prototype_init,
+ .prototype_value = { .object_value = {
+ .value = njs_value(NJS_BOOLEAN, 0, 0.0),
+ .object = { .type = NJS_OBJECT_BOOLEAN } }
+ },
};
prototype = shared->prototypes;
for (i = NJS_OBJ_TYPE_OBJECT; i < NJS_OBJ_TYPE_MAX; i++) {
- prototype[i] = njs_object_type_init[i]->value;
+ prototype[i] = njs_object_type_init[i]->prototype_value;
ret = njs_object_hash_init(vm, &prototype[i].object.shared_hash,
njs_object_type_init[i]->prototype_props);
constructor = shared->constructors;
for (i = NJS_OBJ_TYPE_OBJECT; i < NJS_OBJ_TYPE_MAX; i++) {
- constructor[i].object.type = NJS_FUNCTION;
+ constructor[i] = njs_object_type_init[i]->constructor;
constructor[i].object.shared = 0;
- constructor[i].object.extensible = 1;
- constructor[i].native = 1;
- constructor[i].ctor = 1;
- constructor[i].args_offset = 1;
-
- constructor[i].u.native = njs_object_type_init[i]->constructor;
ret = njs_object_hash_init(vm, &constructor[i].object.shared_hash,
njs_object_type_init[i]->constructor_props);
const njs_object_type_init_t njs_hash_type_init = {
- .constructor = njs_hash_constructor,
- .prototype_props = &njs_hash_prototype_init,
+ .constructor = njs_native_ctor(njs_hash_constructor, 2, 0),
.constructor_props = &njs_hash_constructor_init,
- .value = { .object_value = { .value = njs_value(NJS_DATA, 0, 0.0),
- .object = { .type = NJS_OBJECT } } },
+ .prototype_props = &njs_hash_prototype_init,
+ .prototype_value = { .object_value = { .value = njs_value(NJS_DATA, 0, 0.0),
+ .object = { .type = NJS_OBJECT } } },
};
const njs_object_type_init_t njs_hmac_type_init = {
- .constructor = njs_hmac_constructor,
- .prototype_props = &njs_hmac_prototype_init,
+ .constructor = njs_native_ctor(njs_hmac_constructor, 3, 0),
.constructor_props = &njs_hmac_constructor_init,
- .value = { .object_value = { .value = njs_value(NJS_DATA, 0, 0.0),
- .object = { .type = NJS_OBJECT } } },
+ .prototype_props = &njs_hmac_prototype_init,
+ .prototype_value = { .object_value = { .value = njs_value(NJS_DATA, 0, 0.0),
+ .object = { .type = NJS_OBJECT } } },
};
const njs_object_type_init_t njs_date_type_init = {
- .constructor = njs_date_constructor,
- .prototype_props = &njs_date_prototype_init,
+ .constructor = njs_native_ctor(njs_date_constructor, 7, 0),
.constructor_props = &njs_date_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_date_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
const njs_object_type_init_t njs_error_type_init = {
- .constructor = njs_error_constructor,
- .prototype_props = &njs_error_prototype_init,
+ .constructor = njs_native_ctor(njs_error_constructor, 1, 0),
.constructor_props = &njs_error_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_error_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
const njs_object_type_init_t njs_eval_error_type_init = {
- .constructor = njs_eval_error_constructor,
- .prototype_props = &njs_eval_error_prototype_init,
+ .constructor = njs_native_ctor(njs_eval_error_constructor, 1, 0),
.constructor_props = &njs_eval_error_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_eval_error_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
const njs_object_type_init_t njs_internal_error_type_init = {
- .constructor = njs_internal_error_constructor,
- .prototype_props = &njs_internal_error_prototype_init,
+ .constructor = njs_native_ctor(njs_internal_error_constructor, 1, 0),
.constructor_props = &njs_internal_error_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_internal_error_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
const njs_object_type_init_t njs_memory_error_type_init = {
- .constructor = njs_memory_error_constructor,
- .prototype_props = &njs_internal_error_prototype_init,
+ .constructor = njs_native_ctor(njs_memory_error_constructor, 1, 0),
.constructor_props = &njs_memory_error_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_internal_error_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
const njs_object_type_init_t njs_range_error_type_init = {
- .constructor = njs_range_error_constructor,
- .prototype_props = &njs_range_error_prototype_init,
+ .constructor = njs_native_ctor(njs_range_error_constructor, 1, 0),
.constructor_props = &njs_range_error_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_range_error_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
const njs_object_type_init_t njs_reference_error_type_init = {
- .constructor = njs_reference_error_constructor,
- .prototype_props = &njs_reference_error_prototype_init,
+ .constructor = njs_native_ctor(njs_reference_error_constructor, 1, 0),
.constructor_props = &njs_reference_error_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_reference_error_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
const njs_object_type_init_t njs_syntax_error_type_init = {
- .constructor = njs_syntax_error_constructor,
- .prototype_props = &njs_syntax_error_prototype_init,
+ .constructor = njs_native_ctor(njs_syntax_error_constructor, 1, 0),
.constructor_props = &njs_syntax_error_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_syntax_error_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
const njs_object_type_init_t njs_type_error_type_init = {
- .constructor = njs_type_error_constructor,
- .prototype_props = &njs_type_error_prototype_init,
+ .constructor = njs_native_ctor(njs_type_error_constructor, 1, 0),
.constructor_props = &njs_type_error_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_type_error_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
const njs_object_type_init_t njs_uri_error_type_init = {
- .constructor = njs_uri_error_constructor,
- .prototype_props = &njs_uri_error_prototype_init,
+ .constructor = njs_native_ctor(njs_uri_error_constructor, 1, 0),
.constructor_props = &njs_uri_error_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_uri_error_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
do {
/* GC: retain closure. */
- function->closures[n] = closures[n];
+ njs_function_closures(function)[n] = closures[n];
n++;
} while (n < nesting);
}
njs_inline njs_closure_t **
-njs_function_closures(njs_vm_t *vm, njs_function_t *function)
+njs_function_active_closures(njs_vm_t *vm, njs_function_t *function)
{
- return (function->closure) ? function->closures
- : vm->active_frame->closures;
+ return (function->closure) ? njs_function_closures(function)
+ : njs_frame_closures(vm->active_frame);
}
copy->closure = 1;
- closures = njs_function_closures(vm, function);
+ closures = njs_function_active_closures(vm, function);
n = 0;
do {
/* GC: retain closure. */
- copy->closures[n] = closures[n];
+ njs_function_closures(copy)[n] = closures[n];
n++;
} while (n < nesting);
nesting = lambda->nesting;
if (nesting != 0) {
- closures = njs_function_closures(vm, function);
+ closures = njs_function_active_closures(vm, function);
do {
closure = *closures++;
- frame->closures[n] = closure;
+ njs_frame_closures(frame)[n] = closure;
vm->scopes[NJS_SCOPE_CLOSURE + n] = &closure->u.values;
n++;
} while (size != 0);
}
- frame->closures[n] = closure;
+ njs_frame_closures(frame)[n] = closure;
vm->scopes[NJS_SCOPE_CLOSURE + n] = &closure->u.values;
}
const njs_object_type_init_t njs_function_type_init = {
- .constructor = njs_function_constructor,
- .prototype_props = &njs_function_prototype_init,
+ .constructor = njs_native_ctor(njs_function_constructor, 1, 0),
.constructor_props = &njs_function_constructor_init,
- .value = { .function = { .native = 1,
- .args_offset = 1,
- .u.native = njs_prototype_function,
- .object = { .type = NJS_FUNCTION } } },
+ .prototype_props = &njs_function_prototype_init,
+ .prototype_value = { .function = { .native = 1,
+ .args_offset = 1,
+ .u.native = njs_prototype_function,
+ .object = { .type = NJS_FUNCTION } } },
};
njs_frame_t *previous_active_frame;
njs_value_t *local;
-#if (NJS_SUNC)
- njs_closure_t *closures[1];
-#else
- njs_closure_t *closures[];
-#endif
+
+#define njs_frame_closures(frame) \
+ ((njs_closure_t **) ((u_char *) frame + sizeof(njs_frame_t)))
};
const njs_object_type_init_t njs_number_type_init = {
- .constructor = njs_number_constructor,
- .prototype_props = &njs_number_prototype_init,
+ .constructor = njs_native_ctor(njs_number_constructor, 1, 0),
.constructor_props = &njs_number_constructor_init,
- .value = { .object_value = { .value = njs_value(NJS_NUMBER, 0, 0.0),
- .object = { .type = NJS_OBJECT_NUMBER } } },
+ .prototype_props = &njs_number_prototype_init,
+ .prototype_value = { .object_value = {
+ .value = njs_value(NJS_NUMBER, 0, 0.0),
+ .object = { .type = NJS_OBJECT_NUMBER } }
+ },
};
const njs_object_type_init_t njs_obj_type_init = {
- .constructor = njs_object_constructor,
- .prototype_props = &njs_object_prototype_init,
+ .constructor = njs_native_ctor(njs_object_constructor, 1, 0),
.constructor_props = &njs_object_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_object_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
const njs_object_type_init_t njs_regexp_type_init = {
- .constructor = njs_regexp_constructor,
- .prototype_props = &njs_regexp_prototype_init,
+ .constructor = njs_native_ctor(njs_regexp_constructor, 2, 0),
.constructor_props = &njs_regexp_constructor_init,
- .value = { .object = { .type = NJS_REGEXP } },
+ .prototype_props = &njs_regexp_prototype_init,
+ .prototype_value = { .object = { .type = NJS_REGEXP } },
};
const njs_object_type_init_t njs_string_type_init = {
- .constructor = njs_string_constructor,
- .prototype_props = &njs_string_prototype_init,
+ .constructor = njs_native_ctor(njs_string_constructor, 1, 0),
.constructor_props = &njs_string_constructor_init,
- .value = { .object_value = { .value = njs_string(""),
- .object = { .type = NJS_OBJECT_STRING } } },
+ .prototype_props = &njs_string_prototype_init,
+ .prototype_value = { .object_value = {
+ .value = njs_string(""),
+ .object = { .type = NJS_OBJECT_STRING } }
+ },
};
const njs_object_type_init_t njs_symbol_type_init = {
- .constructor = njs_symbol_constructor,
- .prototype_props = &njs_symbol_prototype_init,
+ .constructor = njs_native_ctor(njs_symbol_constructor, 0, 0),
.constructor_props = &njs_symbol_constructor_init,
- .value = { .object = { .type = NJS_OBJECT } },
+ .prototype_props = &njs_symbol_prototype_init,
+ .prototype_value = { .object = { .type = NJS_OBJECT } },
};
uint8_t args_offset;
uint8_t args_count:5;
+
+ /*
+ * If "closure" is true njs_closure_t[] is available right after the
+ * njs_function_t and njs_function_closures() may be used to access it.
+ */
+
+#define njs_function_closures(function) \
+ ((njs_closure_t **) ((u_char *) function + sizeof(njs_function_t)))
+
uint8_t closure:1;
uint8_t native:1;
uint8_t ctor:1;
} u;
njs_value_t *bound;
-#if (NJS_SUNC)
- njs_closure_t *closures[1];
-#else
- njs_closure_t *closures[];
-#endif
};
typedef struct {
- njs_function_native_t constructor;
- const njs_object_init_t *prototype_props;
+ njs_function_t constructor;
const njs_object_init_t *constructor_props;
- njs_object_prototype_t value;
+ const njs_object_init_t *prototype_props;
+ njs_object_prototype_t prototype_value;
} njs_object_type_init_t;
}
-#define _njs_native_function(_function, _args_count, _magic) { \
+#define _njs_function(_function, _args_count, _ctor, _magic) { \
+ .native = 1, \
+ .magic = _magic, \
+ .args_count = _args_count, \
+ .ctor = _ctor, \
+ .args_offset = 1, \
+ .u.native = _function, \
+ .object = { .type = NJS_FUNCTION, \
+ .shared = 1, \
+ .extensible = 1 }, \
+}
+
+
+#define _njs_native_function(_func, _args, _ctor, _magic) { \
.data = { \
.type = NJS_FUNCTION, \
.truth = 1, \
- .u.function = & (njs_function_t) { \
- .native = 1, \
- .magic = _magic, \
- .args_count = _args_count, \
- .args_offset = 1, \
- .u.native = _function, \
- .object = { .type = NJS_FUNCTION, \
- .shared = 1, \
- .extensible = 1 }, \
- } \
+ .u.function = & (njs_function_t) _njs_function(_func, _args, \
+ _ctor, _magic) \
} \
}
#define njs_native_function(_function, _args_count) \
- _njs_native_function(_function, _args_count, 0)
+ _njs_native_function(_function, _args_count, 0, 0)
#define njs_native_function2(_function, _args_count, _magic) \
- _njs_native_function(_function, _args_count, _magic)
+ _njs_native_function(_function, _args_count, 0, _magic)
+
+
+#define njs_native_ctor(_function, _args_count, _magic) \
+ _njs_function(_function, _args_count, 1, _magic)
#define njs_prop_handler(_handler) { \
{
njs_uint_t n, nesting;
njs_value_t *args;
+ njs_closure_t **closures;
njs_function_t *function;
vm->top_frame = previous;
function = frame->native.function;
nesting = (function != NULL) ? function->u.lambda->nesting : 0;
+ closures = njs_frame_closures(frame);
for (n = 0; n <= nesting; n++) {
- vm->scopes[NJS_SCOPE_CLOSURE + n] = &frame->closures[n]->u.values;
+ vm->scopes[NJS_SCOPE_CLOSURE + n] = &closures[n]->u.values;
}
while (n < NJS_MAX_NESTING) {
code = (njs_vmcode_function_t *) pc;
lambda = code->lambda;
- function = njs_function_alloc(vm, lambda, vm->active_frame->closures, 0);
+ function = njs_function_alloc(vm, lambda,
+ njs_frame_closures(vm->active_frame), 0);
if (njs_slow_path(function == NULL)) {
return NJS_ERROR;
}