[njs] Fixed [[Prototype]] slot of NativeErrors.
Dmitry Volyntsev
xeioex at nginx.com
Thu Oct 24 13:24:27 UTC 2019
details: https://hg.nginx.org/njs/rev/84cb3fa5d1cc
branches:
changeset: 1200:84cb3fa5d1cc
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Oct 24 16:17:16 2019 +0300
description:
Fixed [[Prototype]] slot of NativeErrors.
diffstat:
src/njs_builtin.c | 86 +++++++++-------
src/test/njs_unit_test.c | 227 ++++++----------------------------------------
2 files changed, 81 insertions(+), 232 deletions(-)
diffs (405 lines):
diff -r a908c2ef62ca -r 84cb3fa5d1cc src/njs_builtin.c
--- a/src/njs_builtin.c Thu Oct 24 16:17:16 2019 +0300
+++ b/src/njs_builtin.c Thu Oct 24 16:17:16 2019 +0300
@@ -318,6 +318,7 @@ njs_builtin_objects_create(njs_vm_t *vm)
for (p = njs_constructor_init; *p != NULL; p++) {
obj = *p;
+ func->object.type = NJS_FUNCTION;
func->object.shared = 0;
func->object.extensible = 1;
func->native = 1;
@@ -351,76 +352,76 @@ njs_prototype_function(njs_vm_t *vm, njs
/*
* Object(),
- * Object.__proto__ -> Function_Prototype,
- * Object_Prototype.__proto__ -> null,
+ * Object.__proto__ -> Function.prototype,
+ * Object.prototype.__proto__ -> null,
* the null value is handled by njs_object_prototype_proto(),
*
* Array(),
- * Array.__proto__ -> Function_Prototype,
- * Array_Prototype.__proto__ -> Object_Prototype,
+ * Array.__proto__ -> Function.prototype,
+ * Array.prototype.__proto__ -> Object.prototype,
*
* Boolean(),
- * Boolean.__proto__ -> Function_Prototype,
- * Boolean_Prototype.__proto__ -> Object_Prototype,
+ * Boolean.__proto__ -> Function.prototype,
+ * Boolean.prototype.__proto__ -> Object.prototype,
*
* Number(),
- * Number.__proto__ -> Function_Prototype,
- * Number_Prototype.__proto__ -> Object_Prototype,
+ * Number.__proto__ -> Function.prototype,
+ * Number.prototype.__proto__ -> Object.prototype,
*
* String(),
- * String.__proto__ -> Function_Prototype,
- * String_Prototype.__proto__ -> Object_Prototype,
+ * String.__proto__ -> Function.prototype,
+ * String.prototype.__proto__ -> Object.prototype,
*
* Function(),
- * Function.__proto__ -> Function_Prototype,
- * Function_Prototype.__proto__ -> Object_Prototype,
+ * Function.__proto__ -> Function.prototype,
+ * Function.prototype.__proto__ -> Object.prototype,
*
* RegExp(),
- * RegExp.__proto__ -> Function_Prototype,
- * RegExp_Prototype.__proto__ -> Object_Prototype,
+ * RegExp.__proto__ -> Function.prototype,
+ * RegExp.prototype.__proto__ -> Object.prototype,
*
* Date(),
- * Date.__proto__ -> Function_Prototype,
- * Date_Prototype.__proto__ -> Object_Prototype,
+ * Date.__proto__ -> Function.prototype,
+ * Date.prototype.__proto__ -> Object.prototype,
*
* Error(),
- * Error.__proto__ -> Function_Prototype,
- * Error_Prototype.__proto__ -> Object_Prototype,
+ * Error.__proto__ -> Function.prototype,
+ * Error.prototype.__proto__ -> Object.prototype,
*
* EvalError(),
- * EvalError.__proto__ -> Function_Prototype,
- * EvalError_Prototype.__proto__ -> Error_Prototype,
+ * EvalError.__proto__ -> Error,
+ * EvalError.prototype.__proto__ -> Error.prototype,
*
* InternalError(),
- * InternalError.__proto__ -> Function_Prototype,
- * InternalError_Prototype.__proto__ -> Error_Prototype,
+ * InternalError.__proto__ -> Error,
+ * InternalError.prototype.__proto__ -> Error.prototype,
*
* RangeError(),
- * RangeError.__proto__ -> Function_Prototype,
- * RangeError_Prototype.__proto__ -> Error_Prototype,
+ * RangeError.__proto__ -> Error,
+ * RangeError.prototype.__proto__ -> Error.prototype,
*
* ReferenceError(),
- * ReferenceError.__proto__ -> Function_Prototype,
- * ReferenceError_Prototype.__proto__ -> Error_Prototype,
+ * ReferenceError.__proto__ -> Error,
+ * ReferenceError.prototype.__proto__ -> Error.prototype,
*
* SyntaxError(),
- * SyntaxError.__proto__ -> Function_Prototype,
- * SyntaxError_Prototype.__proto__ -> Error_Prototype,
+ * SyntaxError.__proto__ -> Error,
+ * SyntaxError.prototype.__proto__ -> Error.prototype,
*
* TypeError(),
- * TypeError.__proto__ -> Function_Prototype,
- * TypeError_Prototype.__proto__ -> Error_Prototype,
+ * TypeError.__proto__ -> Error,
+ * TypeError.prototype.__proto__ -> Error.prototype,
*
* URIError(),
- * URIError.__proto__ -> Function_Prototype,
- * URIError_Prototype.__proto__ -> Error_Prototype,
+ * URIError.__proto__ -> Error,
+ * URIError.prototype.__proto__ -> Error.prototype,
*
* MemoryError(),
- * MemoryError.__proto__ -> Function_Prototype,
- * MemoryError_Prototype.__proto__ -> Error_Prototype,
+ * MemoryError.__proto__ -> Error,
+ * MemoryError.prototype.__proto__ -> Error.prototype,
*
* eval(),
- * eval.__proto__ -> Function_Prototype.
+ * eval.__proto__ -> Function.prototype.
*/
njs_int_t
@@ -429,7 +430,8 @@ njs_builtin_objects_clone(njs_vm_t *vm,
size_t size;
njs_uint_t i;
njs_value_t *values;
- njs_object_t *object_prototype, *function_prototype, *error_prototype;
+ njs_object_t *object_prototype, *function_prototype, *error_prototype,
+ *error_constructor;
/*
* Copy both prototypes and constructors arrays by one memcpy()
@@ -452,14 +454,22 @@ njs_builtin_objects_clone(njs_vm_t *vm,
vm->prototypes[i].object.__proto__ = error_prototype;
}
- function_prototype = &vm->prototypes[NJS_CONSTRUCTOR_FUNCTION].object;
values = vm->scopes[NJS_SCOPE_GLOBAL];
- for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_MAX; i++) {
+ function_prototype = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object;
+
+ for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_EVAL_ERROR; i++) {
njs_set_function(&values[i], &vm->constructors[i]);
vm->constructors[i].object.__proto__ = function_prototype;
}
+ error_constructor = &vm->constructors[NJS_CONSTRUCTOR_ERROR].object;
+
+ for (i = NJS_CONSTRUCTOR_EVAL_ERROR; i < NJS_CONSTRUCTOR_MAX; i++) {
+ njs_set_function(&values[i], &vm->constructors[i]);
+ vm->constructors[i].object.__proto__ = error_constructor;
+ }
+
vm->global_object = vm->shared->objects[0];
vm->global_object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT].object;
vm->global_object.shared = 0;
diff -r a908c2ef62ca -r 84cb3fa5d1cc src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Thu Oct 24 16:17:16 2019 +0300
+++ b/src/test/njs_unit_test.c Thu Oct 24 16:17:16 2019 +0300
@@ -8661,75 +8661,9 @@ static njs_unit_test_t njs_test[] =
"new Error()"),
njs_str("n: m") },
- { njs_str("EvalError('e')"),
- njs_str("EvalError: e") },
-
- { njs_str("InternalError('e')"),
- njs_str("InternalError: e") },
-
- { njs_str("RangeError('e')"),
- njs_str("RangeError: e") },
-
{ njs_str("var e = RangeError('e'); Object.preventExtensions(e);e"),
njs_str("RangeError: e") },
- { njs_str("ReferenceError('e')"),
- njs_str("ReferenceError: e") },
-
- { njs_str("SyntaxError('e')"),
- njs_str("SyntaxError: e") },
-
- { njs_str("TypeError('e')"),
- njs_str("TypeError: e") },
-
- { njs_str("URIError('e')"),
- njs_str("URIError: e") },
-
- { njs_str("MemoryError('e')"),
- njs_str("MemoryError") },
-
- { njs_str("EvalError('e').name + ': ' + EvalError('e').message"),
- njs_str("EvalError: e") },
-
- { njs_str("InternalError('e').name + ': ' + InternalError('e').message"),
- njs_str("InternalError: e") },
-
- { njs_str("RangeError('e').name + ': ' + RangeError('e').message"),
- njs_str("RangeError: e") },
-
- { njs_str("ReferenceError('e').name + ': ' + ReferenceError('e').message"),
- njs_str("ReferenceError: e") },
-
- { njs_str("SyntaxError('e').name + ': ' + SyntaxError('e').message"),
- njs_str("SyntaxError: e") },
-
- { njs_str("TypeError('e').name + ': ' + TypeError('e').message"),
- njs_str("TypeError: e") },
-
- { njs_str("URIError('e').name + ': ' + URIError('e').message"),
- njs_str("URIError: e") },
-
- { njs_str("var e = EvalError('e'); e.name = 'E'; e"),
- njs_str("E: e") },
-
- { njs_str("var e = InternalError('e'); e.name = 'E'; e"),
- njs_str("E: e") },
-
- { njs_str("var e = RangeError('e'); e.name = 'E'; e"),
- njs_str("E: e") },
-
- { njs_str("var e = ReferenceError('e'); e.name = 'E'; e"),
- njs_str("E: e") },
-
- { njs_str("var e = SyntaxError('e'); e.name = 'E'; e"),
- njs_str("E: e") },
-
- { njs_str("var e = TypeError('e'); e.name = 'E'; e"),
- njs_str("E: e") },
-
- { njs_str("var e = URIError('e'); e.name = 'E'; e"),
- njs_str("E: e") },
-
/* Memory object is immutable. */
{ njs_str("var e = MemoryError('e'); e.name = 'E'"),
@@ -8759,134 +8693,39 @@ static njs_unit_test_t njs_test[] =
{ njs_str("MemoryError.prototype.name"),
njs_str("InternalError") },
- { njs_str("EvalError.prototype.message"),
- njs_str("") },
-
- { njs_str("InternalError.prototype.message"),
- njs_str("") },
-
- { njs_str("RangeError.prototype.message"),
- njs_str("") },
-
- { njs_str("ReferenceError.prototype.message"),
- njs_str("") },
-
- { njs_str("SyntaxError.prototype.message"),
- njs_str("") },
-
- { njs_str("TypeError.prototype.message"),
- njs_str("") },
-
- { njs_str("URIError.prototype.message"),
- njs_str("") },
-
- { njs_str("MemoryError.prototype.message"),
- njs_str("") },
-
- { njs_str("EvalError.prototype.constructor == EvalError"),
- njs_str("true") },
-
- { njs_str("RangeError.prototype.constructor == RangeError"),
- njs_str("true") },
-
- { njs_str("ReferenceError.prototype.constructor == ReferenceError"),
- njs_str("true") },
-
- { njs_str("SyntaxError.prototype.constructor == SyntaxError"),
- njs_str("true") },
-
- { njs_str("TypeError.prototype.constructor == TypeError"),
- njs_str("true") },
-
- { njs_str("URIError.prototype.constructor == URIError"),
- njs_str("true") },
-
- { njs_str("EvalError.prototype.hasOwnProperty('constructor')"),
- njs_str("true") },
-
- { njs_str("RangeError.prototype.hasOwnProperty('constructor')"),
- njs_str("true") },
-
- { njs_str("ReferenceError.prototype.hasOwnProperty('constructor')"),
- njs_str("true") },
-
- { njs_str("SyntaxError.prototype.hasOwnProperty('constructor')"),
- njs_str("true") },
-
- { njs_str("TypeError.prototype.hasOwnProperty('constructor')"),
- njs_str("true") },
-
- { njs_str("URIError.prototype.hasOwnProperty('constructor')"),
- njs_str("true") },
-
- { njs_str("EvalError().__proto__ == EvalError.prototype"),
- njs_str("true") },
-
- { njs_str("RangeError().__proto__ == RangeError.prototype"),
- njs_str("true") },
-
- { njs_str("ReferenceError().__proto__ == ReferenceError.prototype"),
- njs_str("true") },
-
- { njs_str("SyntaxError().__proto__ == SyntaxError.prototype"),
- njs_str("true") },
-
- { njs_str("TypeError().__proto__ == TypeError.prototype"),
- njs_str("true") },
-
- { njs_str("URIError().__proto__ == URIError.prototype"),
- njs_str("true") },
-
- { njs_str("EvalError().__proto__.__proto__ == Error.prototype"),
- njs_str("true") },
-
- { njs_str("RangeError().__proto__.__proto__ == Error.prototype"),
- njs_str("true") },
-
- { njs_str("ReferenceError().__proto__.__proto__ == Error.prototype"),
- njs_str("true") },
-
- { njs_str("SyntaxError().__proto__.__proto__ == Error.prototype"),
- njs_str("true") },
-
- { njs_str("TypeError().__proto__.__proto__ == Error.prototype"),
- njs_str("true") },
-
- { njs_str("URIError().__proto__.__proto__ == Error.prototype"),
- njs_str("true") },
-
- { njs_str("MemoryError().__proto__ == MemoryError.prototype"),
- njs_str("true") },
-
- { njs_str("MemoryError().__proto__.__proto__ == Error.prototype"),
- njs_str("true") },
-
- { njs_str("typeof Error()"),
- njs_str("object") },
-
- { njs_str("typeof EvalError()"),
- njs_str("object") },
-
- { njs_str("typeof InternalError()"),
- njs_str("object") },
-
- { njs_str("typeof RangeError()"),
- njs_str("object") },
-
- { njs_str("typeof ReferenceError()"),
- njs_str("object") },
-
- { njs_str("typeof SyntaxError()"),
- njs_str("object") },
-
- { njs_str("typeof TypeError()"),
- njs_str("object") },
-
- { njs_str("typeof URIError()"),
- njs_str("object") },
-
- { njs_str("typeof MemoryError()"),
- njs_str("object") },
+
+ /* NativeErrors. */
+
+ { njs_str(
+ "function isValidNativeError(e) {"
+ " var inst;"
+ " var proto = Object.getPrototypeOf(e) === Error;"
+ " var proto2 = e.__proto__ === Error;"
+ " var iproto = e().__proto__ === e.prototype;"
+ " var iproto2 = e().__proto__.__proto__ === Error.prototype;"
+ " var tpof = typeof e() === 'object';"
+ " var ctor = e.prototype.constructor === e;"
+ " var msg = e.prototype.message === '';"
+ " var name = e('e').toString() === `${e.prototype.name}: e`;"
+ " var name2 = (inst = e('e'), inst.name = 'E', inst.toString() === 'E: e');"
+ " var name3 = (inst = e('e'), inst.name = '', inst.toString() === 'e');"
+ " var name4 = e().toString() === `${e.prototype.name}`;"
+ " var own_proto_ctor = e.prototype.hasOwnProperty('constructor');"
+ ""
+ " return proto && proto2 && iproto && iproto2 "
+ " && tpof && ctor && msg && name && name2 && name3 && name4 "
+ " && own_proto_ctor;"
+ "};"
+ "["
+ " EvalError,"
+ " InternalError,"
+ " RangeError,"
+ " ReferenceError,"
+ " SyntaxError,"
+ " TypeError,"
+ " URIError,"
+ "].every(e => isValidNativeError(e))"),
+ njs_str("true") },
/* Exceptions. */
More information about the nginx-devel
mailing list