]> git.kaiwu.me - njs.git/commitdiff
Improved object type initialization structure.
authorDmitry Volyntsev <xeioex@nginx.com>
Fri, 6 Dec 2019 11:59:48 +0000 (14:59 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Fri, 6 Dec 2019 11:59:48 +0000 (14:59 +0300)
Allowing predefine magic argument for a type constructor.
This allows to write generic constructor functions.

16 files changed:
src/njs_array.c
src/njs_boolean.c
src/njs_builtin.c
src/njs_crypto.c
src/njs_date.c
src/njs_error.c
src/njs_function.c
src/njs_function.h
src/njs_number.c
src/njs_object.c
src/njs_regexp.c
src/njs_string.c
src/njs_symbol.c
src/njs_value.h
src/njs_vm.c
src/njs_vmcode.c

index a9471ab890160f48e211ef468909b45ddd261c18..00e34a397412854efec19ff78da05260bbbf5560 100644 (file)
@@ -3103,8 +3103,8 @@ const njs_object_init_t  njs_array_instance_init = {
 
 
 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 } },
 };
index a9e6e99a0b106c95481e6b187bdac2c70f010157..6d328fae3ca4f506b73a39912fd35a43fc3a1175 100644 (file)
@@ -166,9 +166,11 @@ const njs_object_init_t  njs_boolean_prototype_init = {
 
 
 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 } }
+                      },
 };
index 2f09385f7db90f525e4b1c4dfc8afbff960f5e8c..e429efa35392abed3ff0b9b487d7267baf4b396f 100644 (file)
@@ -253,7 +253,7 @@ njs_builtin_objects_create(njs_vm_t *vm)
     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);
@@ -270,14 +270,8 @@ njs_builtin_objects_create(njs_vm_t *vm)
     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);
index 322adbd9112f041688d0acaaf26f063f1b9c06b9..e6d665950133da58efd79cf2c721cc2537c899d3 100644 (file)
@@ -386,11 +386,11 @@ const njs_object_init_t  njs_hash_constructor_init = {
 
 
 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 } } },
 };
 
 
@@ -712,11 +712,11 @@ const njs_object_init_t  njs_crypto_object_init = {
 
 
 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 } } },
 };
 
 
index 85e5e6574be9370774a81825b1b18c143d9f9c83..cefe755586bef06ccf91a85f1f5a7e1a324f3b70 100644 (file)
@@ -1835,8 +1835,8 @@ const njs_object_init_t  njs_date_prototype_init = {
 
 
 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 } },
 };
index 8d317959a807f1d5aea7d7aa74c1f24183305f16..433da72c2515aacf275751c61c879d73d5a3fe81 100644 (file)
@@ -899,10 +899,10 @@ const njs_object_init_t  njs_error_prototype_init = {
 
 
 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 } },
 };
 
 
@@ -941,10 +941,10 @@ const njs_object_init_t  njs_eval_error_prototype_init = {
 
 
 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 } },
 };
 
 
@@ -1003,18 +1003,18 @@ const njs_object_init_t  njs_internal_error_prototype_init = {
 
 
 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 } },
 };
 
 
@@ -1053,10 +1053,10 @@ const njs_object_init_t  njs_range_error_prototype_init = {
 
 
 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 } },
 };
 
 
@@ -1095,10 +1095,10 @@ const njs_object_init_t  njs_reference_error_prototype_init = {
 
 
 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 } },
 };
 
 
@@ -1137,10 +1137,10 @@ const njs_object_init_t  njs_syntax_error_prototype_init = {
 
 
 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 } },
 };
 
 
@@ -1179,10 +1179,10 @@ const njs_object_init_t  njs_type_error_prototype_init = {
 
 
 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 } },
 };
 
 
@@ -1221,8 +1221,8 @@ const njs_object_init_t  njs_uri_error_prototype_init = {
 
 
 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 } },
 };
index 79b6dbc82e5ca55741ff825ffd1fa32807652981..46850e25a3b6cbd0011daba153ffdb59c4e52b1b 100644 (file)
@@ -58,7 +58,7 @@ njs_function_alloc(njs_vm_t *vm, njs_function_lambda_t *lambda,
 
         do {
             /* GC: retain closure. */
-            function->closures[n] = closures[n];
+            njs_function_closures(function)[n] = closures[n];
             n++;
         } while (n < nesting);
     }
@@ -104,10 +104,10 @@ njs_function_value_copy(njs_vm_t *vm, njs_value_t *value)
 
 
 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);
 }
 
 
@@ -185,13 +185,13 @@ njs_function_copy(njs_vm_t *vm, njs_function_t *function)
 
     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);
 
@@ -596,11 +596,11 @@ njs_function_lambda_call(njs_vm_t *vm)
     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++;
@@ -633,7 +633,7 @@ njs_function_lambda_call(njs_vm_t *vm)
             } while (size != 0);
         }
 
-        frame->closures[n] = closure;
+        njs_frame_closures(frame)[n] = closure;
         vm->scopes[NJS_SCOPE_CLOSURE + n] = &closure->u.values;
     }
 
@@ -1351,11 +1351,11 @@ njs_prototype_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 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 } } },
 };
index 57443015bd51092488d09bfa0980f45938caed20..a659a4528f476e88bfc3e03d1af3dbb9cb9d7123 100644 (file)
@@ -90,11 +90,9 @@ struct njs_frame_s {
     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)))
 };
 
 
index 60a850c776484c8cec7e354cc239e745f2ec17ce..c737023aa62478577b5d20d411d952cc46200e39 100644 (file)
@@ -1123,9 +1123,11 @@ njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 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 } }
+                      },
 };
index 10f7d569a62347fb1fe58ed684dfb3e0c9fa3cd8..5585b516844966df030c6046a9bca141d1619a46 100644 (file)
@@ -2670,8 +2670,8 @@ njs_object_length(njs_vm_t *vm, njs_value_t *value, uint32_t *length)
 
 
 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 } },
 };
index bce96dd5a44011da760b67e42d4d57db3ea49160..acec442294d6d91a1b78bdc343ea79815f9d09cf 100644 (file)
@@ -1341,8 +1341,8 @@ const njs_object_init_t  njs_regexp_prototype_init = {
 
 
 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 } },
 };
index 48c7bb643d1b307d338b6e6460ed7872f6275e25..8b4818a6bb3cda502528adefe7cbcb170dbae233 100644 (file)
@@ -5276,9 +5276,11 @@ njs_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime)
 
 
 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 } }
+                       },
 };
index ce94dfd931f77c6e57c35b8c78b702c3ca6915de..8d29ec56c8d39656164dba74ea8200c11d7e417b 100644 (file)
@@ -441,8 +441,8 @@ const njs_object_init_t  njs_symbol_prototype_init = {
 
 
 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 } },
 };
index 77790ba402151d8d3414f51ae7dbec136798ad93..4651fa0dc39d4bc459c66272adebbb5e163ed22e 100644 (file)
@@ -239,6 +239,15 @@ struct njs_function_s {
     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;
@@ -252,11 +261,6 @@ struct njs_function_s {
     } u;
 
     njs_value_t                       *bound;
-#if (NJS_SUNC)
-    njs_closure_t                     *closures[1];
-#else
-    njs_closure_t                     *closures[];
-#endif
 };
 
 
@@ -289,10 +293,10 @@ typedef union {
 
 
 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;
 
 
@@ -411,30 +415,39 @@ typedef struct {
 }
 
 
-#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) {                                          \
index ea3a72dc7c3177d27ef8e7958f3d4bd755794f39..42f7a222db8c02089b50b1d955895b382f25469e 100644 (file)
@@ -339,6 +339,7 @@ njs_vm_scopes_restore(njs_vm_t *vm, njs_frame_t *frame,
 {
     njs_uint_t      n, nesting;
     njs_value_t     *args;
+    njs_closure_t   **closures;
     njs_function_t  *function;
 
     vm->top_frame = previous;
@@ -373,9 +374,10 @@ njs_vm_scopes_restore(njs_vm_t *vm, njs_frame_t *frame,
     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) {
index 4cddea08e17e38566d0057c9584e8ba0d676762b..5fdbcf5fd96dd70c70c0f3e41f96227bf02903bb 100644 (file)
@@ -1002,7 +1002,8 @@ njs_vmcode_function(njs_vm_t *vm, u_char *pc)
     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;
     }