]> git.kaiwu.me - njs.git/commitdiff
MemoryError reimplemented without its own prototype.
authorDmitry Volyntsev <xeioex@nginx.com>
Mon, 20 Nov 2017 16:24:58 +0000 (19:24 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Mon, 20 Nov 2017 16:24:58 +0000 (19:24 +0300)
MemoryError is a special preallocated immutable object.  Its value type
is NJS_OBJECT_INTERNAL_ERROR. Initially the object had its own prototype
object.  It introduced inconsistency between value types and prototype
types, because some routines (for example, njs_object_prototype_to_string())
expect them to be pairwise aligned.

njs/njs_builtin.c
njs/njs_error.c
njs/njs_error.h
njs/njs_vm.h
njs/test/njs_unit_test.c

index fa9378a2c37dbaf0fc69033a291b8f61df159720..d04570a9b9b4abe086f4b0581b7e37b3523ca782 100644 (file)
@@ -78,7 +78,6 @@ const njs_object_init_t  *njs_prototype_init[] = {
     &njs_syntax_error_prototype_init,
     &njs_type_error_prototype_init,
     &njs_uri_error_prototype_init,
-    &njs_memory_error_prototype_init,
 };
 
 
index 1061326e24d5431ddae4eda45797df1c670e8abe..5d9650e98b9b4f49125dc53dc9bf5e195edaa122 100644 (file)
@@ -498,7 +498,7 @@ njs_set_memory_error(njs_vm_t *vm)
 
     nxt_lvlhsh_init(&object->hash);
     nxt_lvlhsh_init(&object->shared_hash);
-    object->__proto__ = &prototypes[NJS_PROTOTYPE_MEMORY_ERROR].object;
+    object->__proto__ = &prototypes[NJS_PROTOTYPE_INTERNAL_ERROR].object;
     object->type = NJS_OBJECT_INTERNAL_ERROR;
     object->shared = 1;
 
@@ -532,6 +532,30 @@ njs_memory_error_constructor(njs_vm_t *vm, njs_value_t *args,
 }
 
 
+static njs_ret_t
+njs_memory_error_prototype_create(njs_vm_t *vm, njs_value_t *value)
+{
+    int32_t         index;
+    njs_value_t     *proto;
+    njs_function_t  *function;
+
+    /* MemoryError has no its own prototype. */
+
+    index = NJS_PROTOTYPE_INTERNAL_ERROR;
+
+    function = value->data.u.function;
+    proto = njs_property_prototype_create(vm, &function->object.hash,
+                                          &vm->prototypes[index].object);
+    if (proto == NULL) {
+        proto = (njs_value_t *) &njs_value_void;
+    }
+
+    vm->retval = *proto;
+
+    return NXT_OK;
+}
+
+
 static const njs_object_prop_t  njs_memory_error_constructor_properties[] =
 {
     /* MemoryError.name == "MemoryError". */
@@ -552,7 +576,7 @@ static const njs_object_prop_t  njs_memory_error_constructor_properties[] =
     {
         .type = NJS_NATIVE_GETTER,
         .name = njs_string("prototype"),
-        .value = njs_native_getter(njs_object_prototype_create),
+        .value = njs_native_getter(njs_memory_error_prototype_create),
     },
 };
 
@@ -701,6 +725,26 @@ const njs_object_init_t  njs_eval_error_prototype_init = {
 };
 
 
+static njs_ret_t
+njs_internal_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
+    nxt_uint_t nargs, njs_index_t unused)
+{
+    if (nargs >= 1 && njs_is_object(&args[0])) {
+
+        /* MemoryError is a nonextensible internal error. */
+        if (!args[0].data.u.object->extensible) {
+            static const njs_value_t name = njs_string("MemoryError");
+
+            vm->retval = name;
+
+            return NJS_OK;
+        }
+    }
+
+    return njs_error_prototype_to_string(vm, args, nargs, unused);
+}
+
+
 static const njs_object_prop_t  njs_internal_error_prototype_properties[] =
 {
     {
@@ -708,6 +752,13 @@ static const njs_object_prop_t  njs_internal_error_prototype_properties[] =
         .name = njs_string("name"),
         .value = njs_string("InternalError"),
     },
+
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("toString"),
+        .value = njs_native_function(njs_internal_error_prototype_to_string,
+                                     0, 0),
+    },
 };
 
 
@@ -801,51 +852,3 @@ const njs_object_init_t  njs_uri_error_prototype_init = {
     njs_uri_error_prototype_properties,
     nxt_nitems(njs_uri_error_prototype_properties),
 };
-
-
-static njs_ret_t
-njs_memory_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
-    nxt_uint_t nargs, njs_index_t unused)
-{
-    static const njs_value_t  name = njs_string("MemoryError");
-
-    vm->retval = name;
-
-    return NJS_OK;
-}
-
-
-static const njs_object_prop_t  njs_memory_error_prototype_properties[] =
-{
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_string("name"),
-        .value = njs_string("MemoryError"),
-    },
-
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_string("message"),
-        .value = njs_string(""),
-    },
-
-    {
-        .type = NJS_METHOD,
-        .name = njs_string("valueOf"),
-        .value = njs_native_function(njs_error_prototype_value_of, 0, 0),
-    },
-
-    {
-        .type = NJS_METHOD,
-        .name = njs_string("toString"),
-        .value = njs_native_function(njs_memory_error_prototype_to_string,
-                                     0, 0),
-    },
-};
-
-
-const njs_object_init_t  njs_memory_error_prototype_init = {
-    nxt_string("MemoryError"),
-    njs_memory_error_prototype_properties,
-    nxt_nitems(njs_memory_error_prototype_properties),
-};
index 6179a8d6e9e7e51cb6206a8e87b43ff58411393f..4a204fcc89ef0793360d80a887f921919d5ecaad 100644 (file)
@@ -71,7 +71,6 @@ extern const njs_object_init_t  njs_ref_error_prototype_init;
 extern const njs_object_init_t  njs_syntax_error_prototype_init;
 extern const njs_object_init_t  njs_type_error_prototype_init;
 extern const njs_object_init_t  njs_uri_error_prototype_init;
-extern const njs_object_init_t  njs_memory_error_prototype_init;
 
 
 #endif /* _NJS_BOOLEAN_H_INCLUDED_ */
index 76abbf0792c38da50eede1161b6263071995ea4f..bbd9442fc54f6973cb1471be587ea8393b79a7ae 100644 (file)
@@ -799,8 +799,7 @@ enum njs_prototypes_e {
     NJS_PROTOTYPE_SYNTAX_ERROR,
     NJS_PROTOTYPE_TYPE_ERROR,
     NJS_PROTOTYPE_URI_ERROR,
-    NJS_PROTOTYPE_MEMORY_ERROR,
-#define NJS_PROTOTYPE_MAX      (NJS_PROTOTYPE_MEMORY_ERROR + 1)
+#define NJS_PROTOTYPE_MAX      (NJS_PROTOTYPE_URI_ERROR + 1)
 };
 
 
@@ -833,7 +832,8 @@ enum njs_constructor_e {
     NJS_CONSTRUCTOR_SYNTAX_ERROR =   NJS_PROTOTYPE_SYNTAX_ERROR,
     NJS_CONSTRUCTOR_TYPE_ERROR =     NJS_PROTOTYPE_TYPE_ERROR,
     NJS_CONSTRUCTOR_URI_ERROR =      NJS_PROTOTYPE_URI_ERROR,
-    NJS_CONSTRUCTOR_MEMORY_ERROR =   NJS_PROTOTYPE_MEMORY_ERROR,
+    /* MemoryError has no its own prototype. */
+    NJS_CONSTRUCTOR_MEMORY_ERROR,
 #define NJS_CONSTRUCTOR_MAX    (NJS_CONSTRUCTOR_MEMORY_ERROR + 1)
 };
 
@@ -975,8 +975,7 @@ struct njs_vm_s {
 
     /*
      * MemoryError is statically allocated immutable Error object
-     * with the generic type NJS_OBJECT_INTERNAL_ERROR but its own prototype
-     * object NJS_PROTOTYPE_MEMORY_ERROR.
+     * with the generic type NJS_OBJECT_INTERNAL_ERROR.
      */
     njs_object_t             memory_error_object;
 
index c2fb830f4de03b05811c7374ac8a7161af3955aa..ec77f07005c0f175fcf02ba853d9122310fc9574 100644 (file)
@@ -5291,9 +5291,6 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("URIError('e').name + ': ' + URIError('e').message"),
       nxt_string("URIError: e") },
 
-    { nxt_string("MemoryError('e').name + ': ' + MemoryError('e').message"),
-      nxt_string("MemoryError: ") },
-
     { nxt_string("var e = EvalError('e'); e.name = 'E'; e"),
       nxt_string("E: e") },
 
@@ -5342,7 +5339,7 @@ static njs_unit_test_t  njs_test[] =
       nxt_string("URIError") },
 
     { nxt_string("MemoryError.prototype.name"),
-      nxt_string("MemoryError") },
+      nxt_string("InternalError") },
 
     { nxt_string("EvalError.prototype.message"),
       nxt_string("") },