Improved iteration over objects indexes in Array functions.
For example, unshift function for object with large length:
var arrayLike = {};
arrayLike.length = 2 ** 53 - 1;
Array.prototype.unshift.call(arrayLike);
Previous, there were several issues with njs_values_hash_test().
1) The function assumed string types of left and right values are identical.
(If current value is a long string it assumed the second value is also
a long string). Long vs short strings collision.
2) The function assumed if hashes are identical value length are equal.
Long vs long string collision.
The fix is to always check value sizes.
In addition, for short strings njs_value_index() calculated hash value including
padding bytes (which values are undefined). It could result in identical
short strings (but with different padding bytes) treated as different strings.
Dmitry Volyntsev [Thu, 29 Aug 2019 16:18:53 +0000 (19:18 +0300)]
Postponing copying of not-configurable PROPERTY_HANDLER properties.
Since df385232d2af a shared property is copied to object hash on the
first access. It simplified changing of configurable shared properties.
Since 50fded8ccee5 Array.prototype functions treat empty array hash as a
sign that array instance is simple (without property getters and
non-numerical properties) to iterate over array values optimally.
Accessing "length" property made a copy in array hash. As a result next
iterations over array became not optimized.
The fix is to postpone making a mutable copy of not-configurable
NJS_PROPERTY_HANDLER properties until they are really required to change.
Dmitry Volyntsev [Thu, 15 Aug 2019 16:22:01 +0000 (19:22 +0300)]
Fixed module importing using require().
Previously, require() did not make a mutable copy of imported module.
As a result, cloned VMs could change a shared module object making
module.object->hash inconsistent.
Before 04d7a5d93ae6, the problem manifested itself only in "PROP GET"
operations, for example, using "require('fs').renameSync", because
njs_value_property() makes a mutable copy of shared methods in
module.object->hash.
After 04d7a5d93ae6, "METHOD CALL" operations, such as
"require('fs').renameSync()", now have the same problem as in "PROP
GET".
Importing modules using "import" statement is not affected, because
for it "OBJECT COPY" instruction is generated, which makes a mutable
copy of imported module object.
The fix is to make a mutable copy of a shared module in require().
hongzhidao [Sun, 4 Aug 2019 08:06:30 +0000 (04:06 -0400)]
Fixed njs_builtin_match().
Previously native functions were identified by comparing pointers to
njs_function_t. This is not correct because njs_function_t maybe copied
from shared prototypes. Instead pointers to native functions should be
compared.
Previously njs_arg() returned expression of type (const njs_value_t *).
This caused a lot of casts when calling functions and forced to declared
const njs_value_t * variables.
Currently njs_ret_t is used in 2 different cases: as a jump offset for
bytecode and as a return value for ordinary functions. The second case
is quite similar with njs_int_t (and is often confused with).
1) Splitting this two cases into different types to avoid
confusion with njs_int_t.
2) Renaming njs_ret_t to njs_jump_off_t to better reflect its
purpose.
1) all source files are moved to src directory.
2) nxt files are renamed with "njs" prefix.
3) some files are renamed to avoid collisions:
nxt_array.c -> njs_arr.c
nxt_array.h -> njs_arr.h
nxt_string.h -> njs_str.h
nxt_time.c -> njs_time.c
nxt_time.h -> njs_time.h
njs_time.c -> njs_timer.c
njs_time.h -> njs_timer.c
njs_core.h -> njs_main.h
4) C tests are moved to src/test dir.
5) Other tests are moved to test dir.
6) Some structs are renamed to avoid collisions:
nxt_array_t -> njs_arr_t
nxt_string_t -> njs_str_t
appropriate functions and macros are also renamed.
7) all macros, functions and other identifiers with "NXT_" and "nxt_"
prefixes are renamed to corresponding "NJS_" or "njs_" prefix.
Fixed String.fromCodePoint(), broken after 0b82f1c9268c.
As it turned out, fromCodePoint() has shared the same handler with
fromCharCode(), but according to the specification these functions
have different semantics. As a result, before 0b82f1c9268c both
functions had behaviour of fromCodePoint(), while after the change
they had behaviour of fromCharCode().
So, the fix is to revert back the code used before the change,
but only for fromCodePoint().
Fixed String.toLowerCase() and String.toUpperCase().
Previously these functions didn't took into account that the size of
a string may change during case transformation resulting in buffer
underflow or overflow.