Compare commits
138 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e8bc7a2b93 | |||
| 8f39d90f7c | |||
| 7518b7bfe6 | |||
| f0e432c9b9 | |||
| 84a56efd4f | |||
| fc2a2f94fd | |||
| 9e323cdcd6 | |||
| ede1957932 | |||
| 6f515f079e | |||
| 848a9854c3 | |||
| 7dc2d1dcd7 | |||
| eb97860509 | |||
| 0f754ff33c | |||
| 3e23a3b62f | |||
| e54666b448 | |||
| b206d60842 | |||
| 466dc903fb | |||
| c17da4f33b | |||
| cfaecc6698 | |||
| 2180d979b7 | |||
| 6a848a36fd | |||
| cd7720ee08 | |||
| 64774d30ae | |||
| 21e17a1412 | |||
| 5ed8647b9e | |||
| 2096fba571 | |||
| c3bb516e4a | |||
| c3510fc03d | |||
| f1883b9e7d | |||
| 2a89eec98b | |||
| f5e3faeaff | |||
| 32962f067e | |||
| 07c7eb8a20 | |||
| 32c74fff22 | |||
| fbca37fde6 | |||
| 195b0d3c3a | |||
| e9664b78cd | |||
| 3763ac8371 | |||
| f7391a94ae | |||
| 26626947c0 | |||
| 57abd26c33 | |||
| a8fb4eee1e | |||
| 711b06d018 | |||
| 0121b2bbcf | |||
| 4eae760180 | |||
| 2b3faf683d | |||
| 9ab4872244 | |||
| 97a0febaff | |||
| 8f7565db5f | |||
| 137dd8d1f5 | |||
| 35a3df3f28 | |||
| f2013fcb1a | |||
| 5c7df1cb2d | |||
| 053b05f185 | |||
| 25b81c106c | |||
| a7c654617d | |||
| 1acbf83d1a | |||
| 6c03e0f0af | |||
| b1115fbcfc | |||
| dc44b8b933 | |||
| c05686b668 | |||
| 40e63d1207 | |||
| 0eae2f6207 | |||
| 62f8d7c885 | |||
| 4452e79204 | |||
| 8d9788d1b5 | |||
| aa8832a985 | |||
| 436fcbb4b7 | |||
| 62025cfa41 | |||
| 87441635e1 | |||
| 83c44d20b3 | |||
| 17e63e892a | |||
| 9f85d21578 | |||
| 951d7e6842 | |||
| 6e79bb148e | |||
| 376cfea47e | |||
| 57de923770 | |||
| fc30f003ba | |||
| f3d3c34c30 | |||
| fbde788d1f | |||
| 6221b670d1 | |||
| 83459c1fac | |||
| c04fe24253 | |||
| 9fbd0cce6c | |||
| e04bbdfff4 | |||
| c79659d3b2 | |||
| 3111d0e0f2 | |||
| 115ad9a41c | |||
| 2933947534 | |||
| 5d51fe8f27 | |||
| 91818bea93 | |||
| 1b84a17dc7 | |||
| 57f389dcf4 | |||
| 96edec1a62 | |||
| 086c4ebf13 | |||
| 142f79ce05 | |||
| 4afcc709b8 | |||
| 24196b69da | |||
| 1c4cfe3e20 | |||
| 8bccbbf08f | |||
| 1088273bc3 | |||
| 3e661c0c5a | |||
| a315a6534e | |||
| 14e4476084 | |||
| e79059c94b | |||
| 91e87fe34f | |||
| 952fb23e0e | |||
| 29758101a3 | |||
| ea77a79461 | |||
| 3ba6adcc71 | |||
| 2f1908f894 | |||
| c6a4a86257 | |||
| f0578b2c25 | |||
| e3c1451d42 | |||
| 5fa0a690eb | |||
| 26d48c3e28 | |||
| 744a64c6fd | |||
| ee1da14577 | |||
| d0435e1db0 | |||
| 47f2f0ea8b | |||
| 97e348528a | |||
| fd075322fb | |||
| b47c36ad18 | |||
| 3af0079a0e | |||
| 996459714c | |||
| ddd48b30f0 | |||
| d29364c34e | |||
| 77237960a7 | |||
| 3c69dfab2c | |||
| 54a5a650aa | |||
| ff2e75ed2e | |||
| a834288096 | |||
| 566e81451e | |||
| 3b7475b01d | |||
| dec9dbc926 | |||
| 14a9a1a1f0 | |||
| 9c7511221f | |||
| 051febfed7 |
+19
-39
@@ -20,9 +20,9 @@ matrix:
|
||||
apt:
|
||||
packages: [doxygen, cppcheck, vera++]
|
||||
|
||||
- name: "Linux/x86-64 Build & Correctness Tests"
|
||||
- name: "Linux/x86-64 Build, Correctness & Debugger Tests"
|
||||
env:
|
||||
- OPTS="--quiet --jerry-tests --jerry-test-suite"
|
||||
- OPTS="--quiet --jerry-tests --jerry-test-suite --jerry-debugger"
|
||||
|
||||
- name: "Linux/x86 (cpointer-32bit) Build & Correctness Tests"
|
||||
env:
|
||||
@@ -55,22 +55,14 @@ matrix:
|
||||
apt:
|
||||
packages: [gcc-multilib]
|
||||
|
||||
- name: "Unit Tests"
|
||||
env:
|
||||
- OPTS="--unittests"
|
||||
|
||||
- name: "Unit Tests (INIT_FINI)"
|
||||
env:
|
||||
- OPTS="--unittests --buildoptions=--cmake-param=-DFEATURE_INIT_FINI=ON"
|
||||
|
||||
- name: "Debugger Tests"
|
||||
env:
|
||||
- OPTS="--jerry-debugger"
|
||||
|
||||
- name: "Conformance Tests"
|
||||
env:
|
||||
- OPTS="--test262"
|
||||
|
||||
- name: "Unit Tests"
|
||||
env:
|
||||
- OPTS="--unittests"
|
||||
|
||||
- name: "ASAN Tests"
|
||||
env:
|
||||
# Skipping maximum stack usage related tests due to 'detect_stack_use_after_return=1' ASAN option.
|
||||
@@ -95,7 +87,7 @@ matrix:
|
||||
sources: ubuntu-toolchain-r-test
|
||||
packages: [gcc-5, gcc-5-multilib]
|
||||
|
||||
- name: "Coverity Scan"
|
||||
- name: "Coverity Scan & SonarQube"
|
||||
env:
|
||||
# Declaration of the encrypted COVERITY_SCAN_TOKEN, created via the
|
||||
# "travis encrypt" command using the project repo's public key.
|
||||
@@ -108,24 +100,14 @@ matrix:
|
||||
notification_email: rsipka.uszeged@partner.samsung.com
|
||||
build_command: "tools/build.py --clean"
|
||||
branch_pattern: master
|
||||
script: skip # Changed to nop, Coverity Scan has already built the project by the time 'script' stage is reached.
|
||||
|
||||
- name: "SonarQube"
|
||||
addons:
|
||||
sonarcloud:
|
||||
organization: "jerryscript-project"
|
||||
# Coverity Scan has already built the project by the time 'script' stage is reached.
|
||||
script: tools/check-sonarqube.sh
|
||||
cache:
|
||||
directories:
|
||||
- '${HOME}/.sonar/cache'
|
||||
|
||||
- name: "ESP8266 Build Test"
|
||||
install: make -f ./targets/esp8266/Makefile.travis install-noapt
|
||||
script: make -f ./targets/esp8266/Makefile.travis script
|
||||
addons:
|
||||
apt:
|
||||
packages: [wget]
|
||||
|
||||
- name: "Mbed OS 5/K64F Build Test"
|
||||
addons:
|
||||
apt:
|
||||
@@ -137,6 +119,13 @@ matrix:
|
||||
install: make -f ./targets/mbedos5/Makefile.travis install
|
||||
script: make -f ./targets/mbedos5/Makefile.travis script
|
||||
|
||||
- name: "Zephyr/Arduino 101 Build Test"
|
||||
install: make -f ./targets/zephyr/Makefile.travis install-noapt
|
||||
script: make -f ./targets/zephyr/Makefile.travis script
|
||||
addons:
|
||||
apt:
|
||||
packages: [gperf, dfu-util, device-tree-compiler, python3-ply, python3-pip]
|
||||
|
||||
- name: "NuttX/STM32F4 Build Test"
|
||||
install: make -f targets/nuttx-stm32f4/Makefile.travis install-noapt
|
||||
script: make -f targets/nuttx-stm32f4/Makefile.travis script
|
||||
@@ -154,21 +143,12 @@ matrix:
|
||||
- sourceline: ppa:team-gcc-arm-embedded/ppa
|
||||
packages: [clang-3.9, gcc-arm-embedded, gcc-multilib]
|
||||
|
||||
- name: "Tizen RT/Artik053 Build Test"
|
||||
- name: "ESP8266 Build Test"
|
||||
install: make -f ./targets/esp8266/Makefile.travis install-noapt
|
||||
script: make -f ./targets/esp8266/Makefile.travis script
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: ppa:team-gcc-arm-embedded/ppa
|
||||
packages: [gcc-arm-embedded, genromfs]
|
||||
install: make -f ./targets/tizenrt-artik053/Makefile.travis install
|
||||
script: make -f ./targets/tizenrt-artik053/Makefile.travis script
|
||||
|
||||
- name: "Zephyr/Arduino 101 Build Test"
|
||||
install: make -f ./targets/zephyr/Makefile.travis install-noapt
|
||||
script: make -f ./targets/zephyr/Makefile.travis script
|
||||
addons:
|
||||
apt:
|
||||
packages: [gperf, dfu-util, device-tree-compiler, python3-ply, python3-pip]
|
||||
packages: [wget]
|
||||
|
||||
fast_finish: true
|
||||
|
||||
|
||||
+7
-1
@@ -100,6 +100,12 @@ if(USING_MSVC)
|
||||
set(ENABLE_STRIP_MESSAGE " (FORCED BY COMPILER)")
|
||||
endif()
|
||||
|
||||
if(CYGWIN)
|
||||
set(ENABLE_LTO OFF)
|
||||
|
||||
set(ENABLE_LTO_MESSAGE " (FORCED BY PLATFORM)")
|
||||
endif()
|
||||
|
||||
# Status messages
|
||||
message(STATUS "CMAKE_BUILD_TYPE " ${CMAKE_BUILD_TYPE})
|
||||
message(STATUS "CMAKE_C_COMPILER_ID " ${CMAKE_C_COMPILER_ID})
|
||||
@@ -179,7 +185,7 @@ if("${PLATFORM}" STREQUAL "DARWIN")
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Sqc <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup")
|
||||
elseif(USING_GCC OR USING_CLANG)
|
||||
elseif(NOT CYGWIN AND (USING_GCC OR USING_CLANG))
|
||||
jerry_add_link_flags(-Wl,-z,noexecstack)
|
||||
endif()
|
||||
|
||||
|
||||
+4
-1
@@ -92,7 +92,10 @@ commit_msg_filepath = sys.argv[1]
|
||||
with open(commit_msg_filepath, "r+") as f:
|
||||
content = f.read()
|
||||
f.seek(0, 0)
|
||||
f.write("%s\n\nJerryScript-DCO-1.0-Signed-off-by: <Your Name> <Your Email>" % content)
|
||||
if "Signed-off-by" not in content:
|
||||
f.write("\n\nJerryScript-DCO-1.0-Signed-off-by: <Your Name> <Your Email>\n%s" % content)
|
||||
else:
|
||||
f.write(content)
|
||||
```
|
||||
|
||||
Please refer [Git Hooks](http://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) for more information.
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# Copyright JS Foundation and other contributors, http://js.foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(CMAKE_SYSTEM_NAME TizenRT)
|
||||
set(CMAKE_SYSTEM_PROCESSOR armv7l)
|
||||
set(CMAKE_SYSTEM_VERSION ARTIK053)
|
||||
|
||||
set(FLAGS_COMMON_ARCH -mcpu=cortex-r4 -mthumb -mfpu=vfpv3
|
||||
-fno-builtin -fno-strict-aliasing -fomit-frame-pointer -fno-strength-reduce
|
||||
-Wall -Werror -Wshadow -Wno-error=conversion)
|
||||
|
||||
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
|
||||
set(CMAKE_C_COMPILER_WORKS TRUE)
|
||||
@@ -194,7 +194,22 @@ The default value is 512.
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_GLOBAL_HEAP_SIZE=(int)` |
|
||||
| CMake: | `--DJERRY_GLOBAL_HEAP_SIZE=(int)` |
|
||||
| Python: | `--heap-size=(int)` |
|
||||
| Python: | `--mem-heap=(int)` |
|
||||
|
||||
### Garbage collection limit
|
||||
|
||||
This option can be used to adjust the maximum allowed heap usage increase until triggering the next garbage collection, in bytes.
|
||||
When the total allocated memory size reaches the current gc limit, garbage collection will be triggered to try and reduce clutter from unreachable objects.
|
||||
If the total allocated memory can't be reduced below the current limit, then the limit will be increased by the amount specified via this option.
|
||||
Similarly, when the total allocated memory goes well below the current gc limit, the limit is reduced by this amount.
|
||||
The default value is 1/32 of the total heap size, but not greater than 8192 bytes.
|
||||
A value of 0 will use the default value.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_GC_LIMIT=(int)` |
|
||||
| CMake: | `-DJERRY_GC_LIMIT=(int)` |
|
||||
| Python: | `--gc-limit=(int)` |
|
||||
|
||||
### Stack limit
|
||||
|
||||
|
||||
+20
-13
@@ -224,6 +224,7 @@ for the item by default, and if the `init_cb` field is not NULL, it will be call
|
||||
an additional custom initializer. The `deinit_cb` (if non-`NULL`) is called during a call to `jerry_cleanup ()` to run
|
||||
any custom deinitialization *before* the VM has been fully cleaned up. The `finalize_cb` (if non-`NULL`) is also called
|
||||
during a call to `jerry_cleanup ()` to run any custom deinitialization *after* the VM has been fully cleaned up.
|
||||
If bytes_needed field is 0, no buffer is allocated for the manager, callback functions are called with NULL pointer.
|
||||
|
||||
**Prototype**
|
||||
|
||||
@@ -440,6 +441,9 @@ typedef jerry_value_t (*jerry_external_handler_t) (const jerry_value_t function_
|
||||
|
||||
Native free callback of an object. It is used in `jerry_object_native_info_t` and for external Array buffers.
|
||||
|
||||
*Note*:
|
||||
- This callback method **must not** call any JerryScript API methods.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
@@ -2790,7 +2794,7 @@ main (void)
|
||||
|
||||
// Read the string into a byte buffer.
|
||||
jerry_size_t string_size = jerry_get_string_size (value);
|
||||
jerry_char_t *string_buffer_p = (jerry_char_t *) malloc (sizeof (jerry_char_t) * string_size);
|
||||
jerry_char_t *string_buffer_p = (jerry_char_t *) malloc (sizeof (jerry_char_t) * (string_size + 1));
|
||||
|
||||
jerry_size_t copied_bytes = jerry_string_to_char_buffer (value, string_buffer_p, string_size);
|
||||
string_buffer_p[copied_bytes] = '\0';
|
||||
@@ -5541,7 +5545,8 @@ jerry_set_prototype (const jerry_value_t obj_val,
|
||||
**Summary**
|
||||
|
||||
Get native pointer by the given type information.
|
||||
The pointer and the type information are previously associated with the object by jerry_set_object_native_pointer.
|
||||
The pointer and the type information are previously associated with the object by
|
||||
[jerry_set_object_native_pointer](#jerry_set_object_native_pointer).
|
||||
|
||||
*Note*: `out_native_pointer_p` can be NULL, and it means the
|
||||
caller doesn't want to get the native_pointer.
|
||||
@@ -5748,15 +5753,15 @@ main (void)
|
||||
**Summary**
|
||||
|
||||
Set native pointer and an optional type information for the specified object.
|
||||
You can get them by calling jerry_get_object_native_pointer later.
|
||||
You can get them by calling [jerry_get_object_native_pointer](#jerry_get_object_native_pointer) later.
|
||||
|
||||
*Note*: If native pointer was already set for the object, its value is updated.
|
||||
|
||||
*Note*: If a non-NULL free callback is specified in the native type information,
|
||||
it will be called by the garbage collector when the object is freed.
|
||||
This callback **must not** invoke API functions.
|
||||
The type info always overwrites the previous value, so passing
|
||||
a NULL value deletes the current type info.
|
||||
*Notes*:
|
||||
- If a native pointer was already set for the object with the same type information, its value is updated.
|
||||
- If a non-NULL free callback is specified in the native type information,
|
||||
it will be called by the garbage collector when the object is freed.
|
||||
- If the object is only referenced via the "global" object (or one of it's "child"),
|
||||
the free callback will be invoked during the execution of `jerry_cleanup`.
|
||||
- The free callback **must not** invoke API functions.
|
||||
|
||||
**Prototype**
|
||||
|
||||
@@ -5791,10 +5796,12 @@ best-practice example.
|
||||
**Summary**
|
||||
|
||||
Delete the native pointer of the specified object associated with the given native type info.
|
||||
You can get them by calling jerry_get_object_native_pointer later.
|
||||
|
||||
*Note*:
|
||||
*Notes*:
|
||||
- If the specified object has no matching native pointer for the given native type info the operation has no effect.
|
||||
- The method does not invoke the free callback specified in the type info.
|
||||
If the native pointer should be freed then one must get the native pointer first and invoke the free callback manually
|
||||
before calling this method.
|
||||
- This operation cannot throw an exception.
|
||||
|
||||
**Prototype**
|
||||
@@ -6424,7 +6431,7 @@ jerry_create_context (uint32_t heap_size,
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="compile")
|
||||
[doctest]: # (test="compile", name="02.API-REFERENCE-create-context.c")
|
||||
|
||||
```c
|
||||
#include <stdlib.h>
|
||||
|
||||
+24
-11
@@ -634,14 +634,21 @@ print_value (const jerry_value_t jsvalue)
|
||||
/* String value */
|
||||
else if (jerry_value_is_string (value))
|
||||
{
|
||||
jerry_char_t str_buf_p[256];
|
||||
|
||||
/* Determining required buffer size */
|
||||
jerry_size_t req_sz = jerry_get_string_size (value);
|
||||
jerry_char_t str_buf_p[req_sz + 1];
|
||||
|
||||
jerry_string_to_char_buffer (value, str_buf_p, req_sz);
|
||||
str_buf_p[req_sz] = '\0';
|
||||
|
||||
printf ("%s", (const char *) str_buf_p);
|
||||
if (req_sz <= 255)
|
||||
{
|
||||
jerry_string_to_char_buffer (value, str_buf_p, req_sz);
|
||||
str_buf_p[req_sz] = '\0';
|
||||
printf ("%s", (const char *) str_buf_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("error: buffer isn't big enough");
|
||||
}
|
||||
}
|
||||
/* Object reference */
|
||||
else if (jerry_value_is_object (value))
|
||||
@@ -721,14 +728,21 @@ print_value (const jerry_value_t jsvalue)
|
||||
/* String value */
|
||||
else if (jerry_value_is_string (value))
|
||||
{
|
||||
jerry_char_t str_buf_p[256];
|
||||
|
||||
/* Determining required buffer size */
|
||||
jerry_size_t req_sz = jerry_get_string_size (value);
|
||||
jerry_char_t str_buf_p[req_sz + 1];
|
||||
|
||||
jerry_string_to_char_buffer (value, str_buf_p, req_sz);
|
||||
str_buf_p[req_sz] = '\0';
|
||||
|
||||
printf ("%s", (const char *) str_buf_p);
|
||||
if (req_sz <= 255)
|
||||
{
|
||||
jerry_string_to_char_buffer (value, str_buf_p, req_sz);
|
||||
str_buf_p[req_sz] = '\0';
|
||||
printf ("%s", (const char *) str_buf_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("error: buffer isn't big enough");
|
||||
}
|
||||
}
|
||||
/* Object reference */
|
||||
else if (jerry_value_is_object (value))
|
||||
@@ -737,7 +751,6 @@ print_value (const jerry_value_t jsvalue)
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
|
||||
jerry_release_value (value);
|
||||
}
|
||||
|
||||
|
||||
+26
-3
@@ -83,10 +83,14 @@ information.
|
||||
void jerry_port_print_char (char c);
|
||||
```
|
||||
|
||||
### ES2015 Module system helper functions
|
||||
### ES2015 Module system
|
||||
|
||||
The module system requires two specific functions for opening and closing files.
|
||||
It also requires a platform specific way of normalizing file paths.
|
||||
The port API provides functions that can be used by the module system to open
|
||||
and close source files, and normalize file paths.
|
||||
The `jerry_port_get_native_module` port function can be used to provide native
|
||||
modules to the engine. This function will be called when an import/export
|
||||
statement is encountered with an unknown module specifier, which embedders can
|
||||
use to supply native module objects based on the module name argument.
|
||||
|
||||
```c
|
||||
/**
|
||||
@@ -126,6 +130,25 @@ jerry_port_normalize_path (const char *in_path_p, /**< input file path */
|
||||
// write to out_buf_p the normalized path
|
||||
// return length of written path
|
||||
} /* jerry_port_normalize_path */
|
||||
|
||||
/**
|
||||
* Get the module object of a native module.
|
||||
*
|
||||
* Note:
|
||||
* This port function is called by jerry-core when ES2015_MODULE_SYSTEM
|
||||
* is enabled.
|
||||
*
|
||||
* @param name String value of the module specifier.
|
||||
*
|
||||
* @return Undefined, if 'name' is not a native module
|
||||
* jerry_value_t containing the module object, otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_port_get_native_module (jerry_value_t name) /**< module specifier */
|
||||
{
|
||||
(void) name;
|
||||
return jerry_create_undefined ();
|
||||
}
|
||||
```
|
||||
|
||||
## Date
|
||||
|
||||
+3
-1
@@ -310,8 +310,10 @@ wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resource nam
|
||||
size_t resource_name_size, /**< size of resource name */
|
||||
const jerry_char_t *source_p, /**< source code */
|
||||
size_t source_size, /**< source code size */
|
||||
void *user_p __attribute__((unused))) /**< user pointer */
|
||||
void *user_p /**< user pointer */)
|
||||
{
|
||||
(void) user_p;
|
||||
|
||||
jerry_value_t ret_val = jerry_parse (resource_name_p,
|
||||
resource_name_size,
|
||||
source_p,
|
||||
|
||||
@@ -421,6 +421,9 @@ For example usage see [jerryx_set_properties](#jerryx_set_properties).
|
||||
|
||||
Hard assert for scripts. The routine calls `jerry_port_fatal` on assertion failure.
|
||||
|
||||
If the `JERRY_FEATURE_LINE_INFO` runtime feature is enabled (build option: `JERRY_LINE_INFO`)
|
||||
a backtrace is also printed out.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
|
||||
@@ -12,7 +12,7 @@ using the `__cleanup__` variable attribute. For other compilers, no support has
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="compile")
|
||||
[doctest]: # (test="compile", name="11.EXT-REFERENCE-AUTORELEASE.c")
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
|
||||
@@ -37,7 +37,8 @@ resolved using the native JerryScript module resolver `jerryx_module_native_reso
|
||||
`jerryx_module_resolve()`. Native modules are registered during application startup and by calling `dlopen()` by means
|
||||
of library constructors, support for which can be turned on using the `FEATURE_INIT_FINI` build flag. In the absence of
|
||||
such a flag, the module registration and unregistration functions are exposed as global symbols which can be called
|
||||
explicitly.
|
||||
explicitly. Note: `FEATURE_INIT_FINI` build flag isn't supported on Windows, because Microsoft Visual C/C++ Compiler
|
||||
doesn't support library constructors and destructors.
|
||||
|
||||
## jerryx_module_resolve
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
The module system allows users to write import and export statements in scripts, which can be used to separate the logic of the application into custom modules.
|
||||
The standard's relevant part can be found [here](https://www.ecma-international.org/ecma-262/6.0/#sec-modules).
|
||||
Embedders wishing to use native builtin modules with ES6 imports can use the [Port API](05.PORT-API.md#es2015-module-system) to do so.
|
||||
|
||||
## General
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ set(JERRY_SYSTEM_ALLOCATOR OFF CACHE BOOL "Enable system allocato
|
||||
set(JERRY_VALGRIND OFF CACHE BOOL "Enable Valgrind support?")
|
||||
set(JERRY_VM_EXEC_STOP OFF CACHE BOOL "Enable VM execution stopping?")
|
||||
set(JERRY_GLOBAL_HEAP_SIZE "(512)" CACHE STRING "Size of memory heap, in kilobytes")
|
||||
set(JERRY_GC_LIMIT "(0)" CACHE STRING "Heap usage limit to trigger garbage collection")
|
||||
set(JERRY_STACK_LIMIT "(0)" CACHE STRING "Maximum stack usage size, in kilobytes")
|
||||
|
||||
# Option overrides
|
||||
@@ -101,6 +102,7 @@ message(STATUS "JERRY_SYSTEM_ALLOCATOR " ${JERRY_SYSTEM_ALLOCATOR})
|
||||
message(STATUS "JERRY_VALGRIND " ${JERRY_VALGRIND})
|
||||
message(STATUS "JERRY_VM_EXEC_STOP " ${JERRY_VM_EXEC_STOP})
|
||||
message(STATUS "JERRY_GLOBAL_HEAP_SIZE " ${JERRY_GLOBAL_HEAP_SIZE})
|
||||
message(STATUS "JERRY_GC_LIMIT " ${JERRY_GC_LIMIT})
|
||||
message(STATUS "JERRY_STACK_LIMIT " ${JERRY_STACK_LIMIT})
|
||||
|
||||
# Include directories
|
||||
@@ -204,6 +206,11 @@ if(DEFINED JERRY_ATTR_GLOBAL_HEAP)
|
||||
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ATTR_GLOBAL_HEAP=${JERRY_ATTR_GLOBAL_HEAP})
|
||||
endif()
|
||||
|
||||
# Memory usage limit for triggering garbage collection
|
||||
if(JERRY_GC_LIMIT)
|
||||
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_GC_LIMIT=${JERRY_GC_LIMIT})
|
||||
endif()
|
||||
|
||||
# Helper macro to set 0/1 switch as Jerry Defines
|
||||
macro(jerry_add_define01 NAME)
|
||||
if(${NAME})
|
||||
|
||||
@@ -179,7 +179,7 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
|
||||
|
||||
globals_p->snapshot_buffer_write_offset += sizeof (ecma_compiled_code_t);
|
||||
|
||||
ecma_value_t pattern = ((re_compiled_code_t *) compiled_code_p)->pattern;
|
||||
ecma_value_t pattern = ((re_compiled_code_t *) compiled_code_p)->source;
|
||||
ecma_string_t *pattern_string_p = ecma_get_string_from_value (pattern);
|
||||
|
||||
ecma_length_t pattern_size = 0;
|
||||
@@ -795,7 +795,7 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr
|
||||
|
||||
if (!(generate_snapshot_opts & JERRY_SNAPSHOT_SAVE_STATIC))
|
||||
{
|
||||
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
|
||||
ecma_collection_t *lit_pool_p = ecma_new_collection ();
|
||||
|
||||
ecma_save_literals_add_compiled_code (bytecode_data_p, lit_pool_p);
|
||||
|
||||
@@ -1048,7 +1048,7 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
|
||||
static void
|
||||
scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
|
||||
const uint8_t *buffer_end_p, /**< snapshot buffer end */
|
||||
ecma_collection_header_t *lit_pool_p, /**< list of known values */
|
||||
ecma_collection_t *lit_pool_p, /**< list of known values */
|
||||
const uint8_t *literal_base_p) /**< start of literal data */
|
||||
{
|
||||
JERRY_ASSERT (buffer_end_p > buffer_p);
|
||||
@@ -1225,14 +1225,14 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
return 0;
|
||||
}
|
||||
|
||||
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
|
||||
ecma_collection_t *lit_pool_p = ecma_new_collection ();
|
||||
|
||||
for (uint32_t i = 0; i < number_of_snapshots; i++)
|
||||
{
|
||||
if (inp_buffer_sizes_p[i] < sizeof (jerry_snapshot_header_t))
|
||||
{
|
||||
*error_p = "invalid snapshot file";
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1243,7 +1243,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
|| !snapshot_check_global_flags (header_p->global_flags))
|
||||
{
|
||||
*error_p = "invalid snapshot version or unsupported features present";
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1271,7 +1271,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|
||||
if (functions_size >= out_buffer_size)
|
||||
{
|
||||
*error_p = "output buffer is too small";
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1615,21 +1615,21 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
|
||||
JERRY_ASSERT ((header_p->lit_table_offset % sizeof (uint32_t)) == 0);
|
||||
const uint8_t *literal_base_p = snapshot_data_p + header_p->lit_table_offset;
|
||||
|
||||
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
|
||||
ecma_collection_t *lit_pool_p = ecma_new_collection ();
|
||||
scan_snapshot_functions (snapshot_data_p + header_p->func_offsets[0],
|
||||
literal_base_p,
|
||||
lit_pool_p,
|
||||
literal_base_p);
|
||||
|
||||
lit_utf8_size_t literal_count = 0;
|
||||
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
ecma_value_t *buffer_p = lit_pool_p->buffer_p;
|
||||
|
||||
/* Count the valid and non-magic identifiers in the list. */
|
||||
while (iterator_p != NULL)
|
||||
for (uint32_t i = 0; i < lit_pool_p->item_count; i++)
|
||||
{
|
||||
if (ecma_is_value_string (*iterator_p))
|
||||
if (ecma_is_value_string (buffer_p[i]))
|
||||
{
|
||||
ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p);
|
||||
ecma_string_t *literal_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* NOTE:
|
||||
* We don't save a literal (in C format) which isn't a valid
|
||||
@@ -1643,13 +1643,11 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
|
||||
literal_count++;
|
||||
}
|
||||
}
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
if (literal_count == 0)
|
||||
{
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1659,13 +1657,14 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
|
||||
JMEM_DEFINE_LOCAL_ARRAY (literal_array, literal_count, ecma_string_t *);
|
||||
lit_utf8_size_t literal_idx = 0;
|
||||
|
||||
iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
buffer_p = lit_pool_p->buffer_p;
|
||||
|
||||
while (iterator_p != NULL)
|
||||
/* Count the valid and non-magic identifiers in the list. */
|
||||
for (uint32_t i = 0; i < lit_pool_p->item_count; i++)
|
||||
{
|
||||
if (ecma_is_value_string (*iterator_p))
|
||||
if (ecma_is_value_string (buffer_p[i]))
|
||||
{
|
||||
ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p);
|
||||
ecma_string_t *literal_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* NOTE:
|
||||
* We don't save a literal (in C format) which isn't a valid
|
||||
@@ -1679,11 +1678,9 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
|
||||
literal_array[literal_idx++] = literal_p;
|
||||
}
|
||||
}
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
|
||||
/* Sort the strings by size at first, then lexicographically. */
|
||||
jerry_save_literals_sort (literal_array, literal_count);
|
||||
|
||||
+93
-62
@@ -206,7 +206,8 @@ jerry_cleanup (void)
|
||||
{
|
||||
if (this_p->manager_p->deinit_cb)
|
||||
{
|
||||
this_p->manager_p->deinit_cb (JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p));
|
||||
void *data = (this_p->manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p) : NULL;
|
||||
this_p->manager_p->deinit_cb (data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +224,8 @@ jerry_cleanup (void)
|
||||
next_p = this_p->next_p;
|
||||
if (this_p->manager_p->finalize_cb)
|
||||
{
|
||||
this_p->manager_p->finalize_cb (JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p));
|
||||
void *data = (this_p->manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p) : NULL;
|
||||
this_p->manager_p->finalize_cb (data);
|
||||
}
|
||||
jmem_heap_free_block (this_p, sizeof (jerry_context_data_header_t) + this_p->manager_p->bytes_needed);
|
||||
}
|
||||
@@ -249,7 +251,7 @@ jerry_get_context_data (const jerry_context_data_manager_t *manager_p)
|
||||
{
|
||||
if (item_p->manager_p == manager_p)
|
||||
{
|
||||
return JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p);
|
||||
return (manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p) : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,9 +259,13 @@ jerry_get_context_data (const jerry_context_data_manager_t *manager_p)
|
||||
item_p->manager_p = manager_p;
|
||||
item_p->next_p = JERRY_CONTEXT (context_data_p);
|
||||
JERRY_CONTEXT (context_data_p) = item_p;
|
||||
ret = JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p);
|
||||
|
||||
memset (ret, 0, manager_p->bytes_needed);
|
||||
if (manager_p->bytes_needed > 0)
|
||||
{
|
||||
ret = JERRY_CONTEXT_DATA_HEADER_USER_DATA (item_p);
|
||||
memset (ret, 0, manager_p->bytes_needed);
|
||||
}
|
||||
|
||||
if (manager_p->init_cb)
|
||||
{
|
||||
manager_p->init_cb (ret);
|
||||
@@ -2204,16 +2210,22 @@ jerry_define_own_property (const jerry_value_t obj_val, /**< object value */
|
||||
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
|
||||
prop_desc.is_enumerable_defined = ECMA_BOOL_TO_BITFIELD (prop_desc_p->is_enumerable_defined);
|
||||
prop_desc.is_enumerable = ECMA_BOOL_TO_BITFIELD (prop_desc_p->is_enumerable_defined ? prop_desc_p->is_enumerable
|
||||
: false);
|
||||
uint32_t flags = ECMA_PROP_NO_OPTS;
|
||||
|
||||
prop_desc.is_configurable_defined = ECMA_BOOL_TO_BITFIELD (prop_desc_p->is_configurable_defined);
|
||||
prop_desc.is_configurable = ECMA_BOOL_TO_BITFIELD (prop_desc_p->is_configurable_defined ? prop_desc_p->is_configurable
|
||||
: false);
|
||||
if (prop_desc_p->is_enumerable_defined)
|
||||
{
|
||||
flags |= (uint32_t) (ECMA_PROP_IS_ENUMERABLE_DEFINED | (prop_desc_p->is_enumerable ? ECMA_PROP_IS_ENUMERABLE
|
||||
: ECMA_PROP_NO_OPTS));
|
||||
}
|
||||
|
||||
if (prop_desc_p->is_configurable_defined)
|
||||
{
|
||||
flags |= (uint32_t) (ECMA_PROP_IS_CONFIGURABLE_DEFINED | (prop_desc_p->is_enumerable ? ECMA_PROP_IS_CONFIGURABLE
|
||||
: ECMA_PROP_NO_OPTS));
|
||||
}
|
||||
|
||||
/* Copy data property info. */
|
||||
prop_desc.is_value_defined = ECMA_BOOL_TO_BITFIELD (prop_desc_p->is_value_defined);
|
||||
flags |= (prop_desc_p->is_value_defined ? ECMA_PROP_IS_VALUE_DEFINED : ECMA_PROP_NO_OPTS);
|
||||
|
||||
if (prop_desc_p->is_value_defined)
|
||||
{
|
||||
@@ -2225,15 +2237,17 @@ jerry_define_own_property (const jerry_value_t obj_val, /**< object value */
|
||||
prop_desc.value = prop_desc_p->value;
|
||||
}
|
||||
|
||||
prop_desc.is_writable_defined = ECMA_BOOL_TO_BITFIELD (prop_desc_p->is_writable_defined);
|
||||
prop_desc.is_writable = ECMA_BOOL_TO_BITFIELD (prop_desc_p->is_writable_defined ? prop_desc_p->is_writable
|
||||
: false);
|
||||
if (prop_desc_p->is_writable_defined)
|
||||
{
|
||||
flags |= (uint32_t) (ECMA_PROP_IS_WRITABLE_DEFINED | (prop_desc_p->is_writable ? ECMA_PROP_IS_WRITABLE
|
||||
: ECMA_PROP_NO_OPTS));
|
||||
}
|
||||
|
||||
/* Copy accessor property info. */
|
||||
if (prop_desc_p->is_get_defined)
|
||||
{
|
||||
ecma_value_t getter = prop_desc_p->getter;
|
||||
prop_desc.is_get_defined = true;
|
||||
flags |= ECMA_PROP_IS_GET_DEFINED;
|
||||
|
||||
if (ecma_is_value_error_reference (getter))
|
||||
{
|
||||
@@ -2253,7 +2267,7 @@ jerry_define_own_property (const jerry_value_t obj_val, /**< object value */
|
||||
if (prop_desc_p->is_set_defined)
|
||||
{
|
||||
ecma_value_t setter = prop_desc_p->setter;
|
||||
prop_desc.is_set_defined = true;
|
||||
flags |= ECMA_PROP_IS_SET_DEFINED;
|
||||
|
||||
if (ecma_is_value_error_reference (setter))
|
||||
{
|
||||
@@ -2270,10 +2284,11 @@ jerry_define_own_property (const jerry_value_t obj_val, /**< object value */
|
||||
}
|
||||
}
|
||||
|
||||
prop_desc.flags |= (uint16_t) (flags | ECMA_PROP_IS_THROW);
|
||||
|
||||
return ecma_op_object_define_own_property (ecma_get_object_from_value (obj_val),
|
||||
ecma_get_prop_name_from_value (prop_name_val),
|
||||
&prop_desc,
|
||||
true);
|
||||
&prop_desc);
|
||||
} /* jerry_define_own_property */
|
||||
|
||||
/**
|
||||
@@ -2305,27 +2320,27 @@ jerry_get_own_property_descriptor (const jerry_value_t obj_val, /**< object val
|
||||
}
|
||||
|
||||
prop_desc_p->is_configurable_defined = true;
|
||||
prop_desc_p->is_configurable = prop_desc.is_configurable;
|
||||
prop_desc_p->is_configurable = (prop_desc.flags & ECMA_PROP_IS_CONFIGURABLE) != 0;
|
||||
prop_desc_p->is_enumerable_defined = true;
|
||||
prop_desc_p->is_enumerable = prop_desc.is_enumerable;
|
||||
prop_desc_p->is_enumerable = (prop_desc.flags & ECMA_PROP_IS_ENUMERABLE) != 0;
|
||||
|
||||
prop_desc_p->is_writable_defined = prop_desc.is_writable_defined;
|
||||
prop_desc_p->is_writable = prop_desc.is_writable_defined ? prop_desc.is_writable : false;
|
||||
prop_desc_p->is_writable_defined = (prop_desc.flags & ECMA_PROP_IS_WRITABLE_DEFINED) != 0;
|
||||
prop_desc_p->is_writable = prop_desc_p->is_writable_defined ? (prop_desc.flags & ECMA_PROP_IS_WRITABLE) != 0 : false;
|
||||
|
||||
prop_desc_p->is_value_defined = prop_desc.is_value_defined;
|
||||
prop_desc_p->is_get_defined = prop_desc.is_get_defined;
|
||||
prop_desc_p->is_set_defined = prop_desc.is_set_defined;
|
||||
prop_desc_p->is_value_defined = (prop_desc.flags & ECMA_PROP_IS_VALUE_DEFINED) != 0;
|
||||
prop_desc_p->is_get_defined = (prop_desc.flags & ECMA_PROP_IS_GET_DEFINED) != 0;
|
||||
prop_desc_p->is_set_defined = (prop_desc.flags & ECMA_PROP_IS_SET_DEFINED) != 0;
|
||||
|
||||
prop_desc_p->value = ECMA_VALUE_UNDEFINED;
|
||||
prop_desc_p->getter = ECMA_VALUE_UNDEFINED;
|
||||
prop_desc_p->setter = ECMA_VALUE_UNDEFINED;
|
||||
|
||||
if (prop_desc.is_value_defined)
|
||||
if (prop_desc_p->is_value_defined)
|
||||
{
|
||||
prop_desc_p->value = prop_desc.value;
|
||||
}
|
||||
|
||||
if (prop_desc.is_get_defined)
|
||||
if (prop_desc_p->is_get_defined)
|
||||
{
|
||||
if (prop_desc.get_p != NULL)
|
||||
{
|
||||
@@ -2337,7 +2352,7 @@ jerry_get_own_property_descriptor (const jerry_value_t obj_val, /**< object val
|
||||
}
|
||||
}
|
||||
|
||||
if (prop_desc.is_set_defined)
|
||||
if (prop_desc_p->is_set_defined)
|
||||
{
|
||||
if (prop_desc.set_p != NULL)
|
||||
{
|
||||
@@ -2519,13 +2534,15 @@ jerry_get_prototype (const jerry_value_t obj_val) /**< object value */
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
|
||||
}
|
||||
|
||||
ecma_object_t *proto_obj_p = ecma_get_object_prototype (ecma_get_object_from_value (obj_val));
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
|
||||
|
||||
if (proto_obj_p == NULL)
|
||||
if (obj_p->u2.prototype_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return ECMA_VALUE_NULL;
|
||||
}
|
||||
|
||||
ecma_object_t *proto_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_p->u2.prototype_cp);
|
||||
|
||||
return ecma_make_object_value (proto_obj_p);
|
||||
} /* jerry_get_prototype */
|
||||
|
||||
@@ -2547,15 +2564,15 @@ jerry_set_prototype (const jerry_value_t obj_val, /**< object value */
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
|
||||
}
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_val);
|
||||
|
||||
if (ecma_is_value_null (proto_obj_val))
|
||||
{
|
||||
ECMA_SET_POINTER (ecma_get_object_from_value (obj_val)->prototype_or_outer_reference_cp, NULL);
|
||||
obj_p->u2.prototype_cp = JMEM_CP_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_SET_POINTER (ecma_get_object_from_value (obj_val)->prototype_or_outer_reference_cp,
|
||||
ecma_get_object_from_value (proto_obj_val));
|
||||
ECMA_SET_NON_NULL_POINTER (obj_p->u2.prototype_cp, ecma_get_object_from_value (proto_obj_val));
|
||||
}
|
||||
|
||||
return ECMA_VALUE_TRUE;
|
||||
@@ -2575,15 +2592,19 @@ jerry_objects_foreach (jerry_objects_foreach_t foreach_p, /**< function pointer
|
||||
|
||||
JERRY_ASSERT (foreach_p != NULL);
|
||||
|
||||
for (ecma_object_t *iter_p = JERRY_CONTEXT (ecma_gc_objects_p);
|
||||
iter_p != NULL;
|
||||
iter_p = ECMA_GET_POINTER (ecma_object_t, iter_p->gc_next_cp))
|
||||
jmem_cpointer_t iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp);
|
||||
|
||||
while (iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_object_t *iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, iter_cp);
|
||||
|
||||
if (!ecma_is_lexical_environment (iter_p)
|
||||
&& !foreach_p (ecma_make_object_value (iter_p), user_data_p))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
iter_cp = iter_p->gc_next_cp;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -2609,10 +2630,13 @@ jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_i
|
||||
|
||||
ecma_native_pointer_t *native_pointer_p;
|
||||
|
||||
for (ecma_object_t *iter_p = JERRY_CONTEXT (ecma_gc_objects_p);
|
||||
iter_p != NULL;
|
||||
iter_p = ECMA_GET_POINTER (ecma_object_t, iter_p->gc_next_cp))
|
||||
|
||||
jmem_cpointer_t iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp);
|
||||
|
||||
while (iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_object_t *iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, iter_cp);
|
||||
|
||||
if (!ecma_is_lexical_environment (iter_p))
|
||||
{
|
||||
native_pointer_p = ecma_get_native_pointer_value (iter_p, (void *) native_info_p);
|
||||
@@ -2622,6 +2646,8 @@ jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_i
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
iter_cp = iter_p->gc_next_cp;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -2745,16 +2771,16 @@ jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
|
||||
ecma_collection_header_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (names_p);
|
||||
ecma_collection_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
|
||||
ecma_value_t *buffer_p = names_p->buffer_p;
|
||||
|
||||
ecma_value_t property_value = ECMA_VALUE_EMPTY;
|
||||
|
||||
bool continuous = true;
|
||||
|
||||
while (continuous && ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; continuous && (i < names_p->item_count); i++)
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
property_value = ecma_op_object_get (object_p, property_name_p);
|
||||
|
||||
@@ -2763,13 +2789,11 @@ jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */
|
||||
break;
|
||||
}
|
||||
|
||||
continuous = foreach_p (*ecma_value_p, property_value, user_data_p);
|
||||
continuous = foreach_p (buffer_p[i], property_value, user_data_p);
|
||||
ecma_free_value (property_value);
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (names_p, 0);
|
||||
ecma_collection_free (names_p);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (property_value))
|
||||
{
|
||||
@@ -3402,7 +3426,7 @@ typedef struct
|
||||
{
|
||||
jerry_typedarray_type_t api_type; /**< api type */
|
||||
ecma_builtin_id_t prototype_id; /**< prototype ID */
|
||||
lit_magic_string_id_t lit_id; /**< literal ID */
|
||||
ecma_typedarray_type_t id; /**< typedArray ID */
|
||||
uint8_t element_size_shift; /**< element size shift */
|
||||
} jerry_typedarray_mapping_t;
|
||||
|
||||
@@ -3413,7 +3437,7 @@ static jerry_typedarray_mapping_t jerry_typedarray_mappings[] =
|
||||
{
|
||||
#define TYPEDARRAY_ENTRY(NAME, LIT_NAME, SIZE_SHIFT) \
|
||||
{ JERRY_TYPEDARRAY_ ## NAME, ECMA_BUILTIN_ID_ ## NAME ## ARRAY_PROTOTYPE, \
|
||||
LIT_MAGIC_STRING_ ## LIT_NAME ## _ARRAY_UL, SIZE_SHIFT }
|
||||
ECMA_ ## LIT_NAME ## _ARRAY, SIZE_SHIFT }
|
||||
|
||||
TYPEDARRAY_ENTRY (UINT8, UINT8, 0),
|
||||
TYPEDARRAY_ENTRY (UINT8CLAMPED, UINT8_CLAMPED, 0),
|
||||
@@ -3431,7 +3455,7 @@ static jerry_typedarray_mapping_t jerry_typedarray_mappings[] =
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to get the TypedArray prototype, literal id, and element size shift
|
||||
* Helper function to get the TypedArray prototype, typedArray id, and element size shift
|
||||
* information.
|
||||
*
|
||||
* @return true - if the TypedArray information was found
|
||||
@@ -3440,11 +3464,11 @@ static jerry_typedarray_mapping_t jerry_typedarray_mappings[] =
|
||||
static bool
|
||||
jerry_typedarray_find_by_type (jerry_typedarray_type_t type_name, /**< type of the TypedArray */
|
||||
ecma_builtin_id_t *prototype_id, /**< [out] found prototype object id */
|
||||
lit_magic_string_id_t *lit_id, /**< [out] found literal id */
|
||||
ecma_typedarray_type_t *id, /**< [out] found typedArray id */
|
||||
uint8_t *element_size_shift) /**< [out] found element size shift value */
|
||||
{
|
||||
JERRY_ASSERT (prototype_id != NULL);
|
||||
JERRY_ASSERT (lit_id != NULL);
|
||||
JERRY_ASSERT (id != NULL);
|
||||
JERRY_ASSERT (element_size_shift != NULL);
|
||||
|
||||
for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++)
|
||||
@@ -3452,7 +3476,7 @@ jerry_typedarray_find_by_type (jerry_typedarray_type_t type_name, /**< type of t
|
||||
if (type_name == jerry_typedarray_mappings[i].api_type)
|
||||
{
|
||||
*prototype_id = jerry_typedarray_mappings[i].prototype_id;
|
||||
*lit_id = jerry_typedarray_mappings[i].lit_id;
|
||||
*id = jerry_typedarray_mappings[i].id;
|
||||
*element_size_shift = jerry_typedarray_mappings[i].element_size_shift;
|
||||
return true;
|
||||
}
|
||||
@@ -3481,10 +3505,10 @@ jerry_create_typedarray (jerry_typedarray_type_t type_name, /**< type of TypedAr
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
|
||||
ecma_builtin_id_t prototype_id = 0;
|
||||
lit_magic_string_id_t lit_id = 0;
|
||||
ecma_typedarray_type_t id = 0;
|
||||
uint8_t element_size_shift = 0;
|
||||
|
||||
if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &lit_id, &element_size_shift))
|
||||
if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &id, &element_size_shift))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray.")));
|
||||
}
|
||||
@@ -3494,7 +3518,7 @@ jerry_create_typedarray (jerry_typedarray_type_t type_name, /**< type of TypedAr
|
||||
ecma_value_t array_value = ecma_typedarray_create_object_with_length (length,
|
||||
prototype_obj_p,
|
||||
element_size_shift,
|
||||
lit_id);
|
||||
id);
|
||||
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (array_value));
|
||||
|
||||
@@ -3525,10 +3549,10 @@ jerry_create_typedarray_for_arraybuffer_sz (jerry_typedarray_type_t type_name, /
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
|
||||
ecma_builtin_id_t prototype_id = 0;
|
||||
lit_magic_string_id_t lit_id = 0;
|
||||
ecma_typedarray_type_t id = 0;
|
||||
uint8_t element_size_shift = 0;
|
||||
|
||||
if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &lit_id, &element_size_shift))
|
||||
if (!jerry_typedarray_find_by_type (type_name, &prototype_id, &id, &element_size_shift))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray.")));
|
||||
}
|
||||
@@ -3546,7 +3570,7 @@ jerry_create_typedarray_for_arraybuffer_sz (jerry_typedarray_type_t type_name, /
|
||||
ecma_make_uint32_value (length)
|
||||
};
|
||||
|
||||
ecma_value_t array_value = ecma_op_create_typedarray (arguments_p, 3, prototype_obj_p, element_size_shift, lit_id);
|
||||
ecma_value_t array_value = ecma_op_create_typedarray (arguments_p, 3, prototype_obj_p, element_size_shift, id);
|
||||
ecma_free_value (arguments_p[1]);
|
||||
ecma_free_value (arguments_p[2]);
|
||||
|
||||
@@ -3574,8 +3598,15 @@ jerry_create_typedarray_for_arraybuffer (jerry_typedarray_type_t type_name, /**<
|
||||
const jerry_value_t arraybuffer) /**< ArrayBuffer to use */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
|
||||
jerry_length_t byteLength = jerry_get_arraybuffer_byte_length (arraybuffer);
|
||||
return jerry_create_typedarray_for_arraybuffer_sz (type_name, arraybuffer, 0, byteLength);
|
||||
#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
|
||||
JERRY_UNUSED (type_name);
|
||||
JERRY_UNUSED (arraybuffer);
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray not supported.")));
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
|
||||
} /* jerry_create_typedarray_for_arraybuffer */
|
||||
|
||||
/**
|
||||
@@ -3596,11 +3627,11 @@ jerry_get_typedarray_type (jerry_value_t value) /**< object to get the TypedArra
|
||||
}
|
||||
|
||||
ecma_object_t *array_p = ecma_get_object_from_value (value);
|
||||
ecma_typedarray_type_t class_type = ecma_get_typedarray_id (array_p);
|
||||
|
||||
lit_magic_string_id_t class_name_id = ecma_object_get_class_name (array_p);
|
||||
for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++)
|
||||
{
|
||||
if (class_name_id == jerry_typedarray_mappings[i].lit_id)
|
||||
if (class_type == jerry_typedarray_mappings[i].id)
|
||||
{
|
||||
return jerry_typedarray_mappings[i].api_type;
|
||||
}
|
||||
|
||||
@@ -207,6 +207,15 @@
|
||||
# define JERRY_GLOBAL_HEAP_SIZE (512)
|
||||
#endif /* !defined (JERRY_GLOBAL_HEAP_SIZE) */
|
||||
|
||||
/**
|
||||
* The allowed heap usage limit until next garbage collection, in bytes.
|
||||
*
|
||||
* If value is 0, the default is 1/32 of JERRY_HEAP_SIZE
|
||||
*/
|
||||
#ifndef JERRY_GC_LIMIT
|
||||
# define JERRY_GC_LIMIT 0
|
||||
#endif /* !defined (JERRY_GC_LIMIT) */
|
||||
|
||||
/**
|
||||
* Maximum stack usage size in kilobytes
|
||||
*
|
||||
@@ -613,6 +622,9 @@
|
||||
#if !defined (JERRY_GLOBAL_HEAP_SIZE) || (JERRY_GLOBAL_HEAP_SIZE <= 0)
|
||||
# error "Invalid value for 'JERRY_GLOBAL_HEAP_SIZE' macro."
|
||||
#endif
|
||||
#if !defined (JERRY_GC_LIMIT) || (JERRY_GC_LIMIT < 0)
|
||||
# error "Invalid value for 'JERRY_GC_LIMIT' macro."
|
||||
#endif
|
||||
#if !defined (JERRY_STACK_LIMIT) || (JERRY_STACK_LIMIT < 0)
|
||||
# error "Invalid value for 'JERRY_STACK_LIMIT' macro."
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "byte-code.h"
|
||||
#include "debugger.h"
|
||||
#include "ecma-array-object.h"
|
||||
#include "ecma-builtin-helpers.h"
|
||||
#include "ecma-conversion.h"
|
||||
#include "ecma-eval.h"
|
||||
@@ -250,7 +251,7 @@ jerry_debugger_send_scope_chain (void)
|
||||
}
|
||||
else if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND)
|
||||
{
|
||||
if (ecma_get_lex_env_outer_reference (lex_env_p) == NULL)
|
||||
if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL)
|
||||
{
|
||||
message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_GLOBAL;
|
||||
break;
|
||||
@@ -261,7 +262,8 @@ jerry_debugger_send_scope_chain (void)
|
||||
}
|
||||
}
|
||||
|
||||
lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
|
||||
JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL);
|
||||
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
|
||||
}
|
||||
|
||||
message_type_p->type = JERRY_DEBUGGER_SCOPE_CHAIN_END;
|
||||
@@ -430,14 +432,14 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer
|
||||
|
||||
while (chain_index != 0)
|
||||
{
|
||||
lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
|
||||
|
||||
if (JERRY_UNLIKELY (lex_env_p == NULL))
|
||||
if (JERRY_UNLIKELY (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL))
|
||||
{
|
||||
jerry_debugger_send_type (JERRY_DEBUGGER_SCOPE_VARIABLES_END);
|
||||
return;
|
||||
}
|
||||
|
||||
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
|
||||
|
||||
if ((ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND)
|
||||
|| (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE))
|
||||
{
|
||||
@@ -445,17 +447,28 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer
|
||||
}
|
||||
}
|
||||
|
||||
ecma_property_header_t *prop_iter_p;
|
||||
jmem_cpointer_t prop_iter_cp;
|
||||
|
||||
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
prop_iter_p = ecma_get_property_list (lex_env_p);
|
||||
prop_iter_cp = lex_env_p->u1.property_list_cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
prop_iter_p = ecma_get_property_list (binding_obj_p);
|
||||
|
||||
if (JERRY_UNLIKELY (ecma_get_object_type (binding_obj_p) == ECMA_OBJECT_TYPE_ARRAY))
|
||||
{
|
||||
ecma_extended_object_t *ext_binding_obj_p = (ecma_extended_object_t *) binding_obj_p;
|
||||
|
||||
if (ext_binding_obj_p->u.array.is_fast_mode)
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (binding_obj_p);
|
||||
}
|
||||
}
|
||||
|
||||
prop_iter_cp = binding_obj_p->u1.property_list_cp;
|
||||
}
|
||||
|
||||
JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_string_t, message_string_p);
|
||||
@@ -463,8 +476,9 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer
|
||||
|
||||
size_t buffer_pos = 0;
|
||||
|
||||
while (prop_iter_p != NULL)
|
||||
while (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
@@ -513,8 +527,7 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer
|
||||
}
|
||||
}
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
|
||||
message_string_p->type = JERRY_DEBUGGER_SCOPE_VARIABLES_END;
|
||||
@@ -1409,10 +1422,16 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /**
|
||||
{
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (exception_obj_value);
|
||||
|
||||
ecma_object_t *prototype_p = ecma_get_object_prototype (object_p);
|
||||
jmem_cpointer_t prototype_cp = object_p->u2.prototype_cp;
|
||||
|
||||
if (prototype_p == NULL
|
||||
|| ecma_get_object_type (prototype_p) != ECMA_OBJECT_TYPE_GENERAL
|
||||
if (prototype_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, prototype_cp);
|
||||
|
||||
if (ecma_get_object_type (prototype_p) != ECMA_OBJECT_TYPE_GENERAL
|
||||
|| !ecma_get_object_is_builtin (prototype_p))
|
||||
{
|
||||
return NULL;
|
||||
|
||||
@@ -24,9 +24,6 @@ JERRY_STATIC_ASSERT (sizeof (ecma_property_value_t) == sizeof (ecma_value_t),
|
||||
JERRY_STATIC_ASSERT (((sizeof (ecma_property_value_t) - 1) & sizeof (ecma_property_value_t)) == 0,
|
||||
size_of_ecma_property_value_t_must_be_power_of_2);
|
||||
|
||||
JERRY_STATIC_ASSERT (sizeof (ecma_string_t) == sizeof (uint64_t),
|
||||
size_of_ecma_string_t_must_be_less_than_or_equal_to_8_bytes);
|
||||
|
||||
JERRY_STATIC_ASSERT (sizeof (ecma_extended_object_t) - sizeof (ecma_object_t) <= sizeof (uint64_t),
|
||||
size_of_ecma_extended_object_part_must_be_less_than_or_equal_to_8_bytes);
|
||||
|
||||
@@ -155,7 +152,35 @@ ecma_dealloc_string (ecma_string_t *string_p) /**< string to be freed */
|
||||
} /* ecma_dealloc_string */
|
||||
|
||||
/**
|
||||
* Allocate memory for string with character data
|
||||
* Allocate memory for extended ecma-string descriptor
|
||||
*
|
||||
* @return pointer to allocated memory
|
||||
*/
|
||||
inline ecma_extended_string_t * JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_alloc_extended_string (void)
|
||||
{
|
||||
#if ENABLED (JERRY_MEM_STATS)
|
||||
jmem_stats_allocate_string_bytes (sizeof (ecma_extended_string_t));
|
||||
#endif /* ENABLED (JERRY_MEM_STATS) */
|
||||
|
||||
return (ecma_extended_string_t *) jmem_heap_alloc_block (sizeof (ecma_extended_string_t));
|
||||
} /* ecma_alloc_extended_string */
|
||||
|
||||
/**
|
||||
* Dealloc memory from extended ecma-string descriptor
|
||||
*/
|
||||
inline void JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_dealloc_extended_string (ecma_extended_string_t *ext_string_p) /**< extended string to be freed */
|
||||
{
|
||||
#if ENABLED (JERRY_MEM_STATS)
|
||||
jmem_stats_free_string_bytes (sizeof (ecma_extended_string_t));
|
||||
#endif /* ENABLED (JERRY_MEM_STATS) */
|
||||
|
||||
jmem_heap_free_block (ext_string_p, sizeof (ecma_extended_string_t));
|
||||
} /* ecma_dealloc_extended_string */
|
||||
|
||||
/**
|
||||
* Allocate memory for an string with character data
|
||||
*
|
||||
* @return pointer to allocated memory
|
||||
*/
|
||||
|
||||
@@ -73,6 +73,18 @@ ecma_string_t *ecma_alloc_string (void);
|
||||
*/
|
||||
void ecma_dealloc_string (ecma_string_t *string_p);
|
||||
|
||||
/**
|
||||
* Allocate memory for extended ecma-string descriptor
|
||||
*
|
||||
* @return pointer to allocated memory
|
||||
*/
|
||||
ecma_extended_string_t *ecma_alloc_extended_string (void);
|
||||
|
||||
/**
|
||||
* Dealloc memory from extended ecma-string descriptor
|
||||
*/
|
||||
void ecma_dealloc_extended_string (ecma_extended_string_t *string_p);
|
||||
|
||||
/**
|
||||
* Allocate memory for string with character data
|
||||
*
|
||||
|
||||
+258
-150
@@ -53,39 +53,13 @@
|
||||
* the object is marked at the first time.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get next object in list of objects with same generation.
|
||||
*
|
||||
* @return pointer to the next ecma-object
|
||||
* NULL - if there is no next ecma-object
|
||||
*/
|
||||
static inline ecma_object_t *
|
||||
ecma_gc_get_object_next (ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
|
||||
return ECMA_GET_POINTER (ecma_object_t, object_p->gc_next_cp);
|
||||
} /* ecma_gc_get_object_next */
|
||||
|
||||
/**
|
||||
* Set next object in list of objects with same generation.
|
||||
*/
|
||||
static inline void
|
||||
ecma_gc_set_object_next (ecma_object_t *object_p, /**< object */
|
||||
ecma_object_t *next_object_p) /**< next object */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
|
||||
ECMA_SET_POINTER (object_p->gc_next_cp, next_object_p);
|
||||
} /* ecma_gc_set_object_next */
|
||||
|
||||
/**
|
||||
* Get visited flag of the object.
|
||||
*
|
||||
* @return true - if visited
|
||||
* false - otherwise
|
||||
*/
|
||||
static inline bool
|
||||
static inline bool JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_gc_is_object_visited (ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
@@ -95,15 +69,25 @@ ecma_gc_is_object_visited (ecma_object_t *object_p) /**< object */
|
||||
|
||||
/**
|
||||
* Set visited flag of the object.
|
||||
* Note: This macro can be inlined for performance critical code paths
|
||||
*/
|
||||
static inline void
|
||||
#define ECMA_GC_SET_OBJECT_VISITED(object_p) \
|
||||
do \
|
||||
{ \
|
||||
if ((object_p)->type_flags_refs < ECMA_OBJECT_REF_ONE) \
|
||||
{ \
|
||||
(object_p)->type_flags_refs |= ECMA_OBJECT_REF_ONE; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Set visited flag of the object.
|
||||
*/
|
||||
static void JERRY_ATTR_NOINLINE
|
||||
ecma_gc_set_object_visited (ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
/* Set reference counter to one if it is zero. */
|
||||
if (object_p->type_flags_refs < ECMA_OBJECT_REF_ONE)
|
||||
{
|
||||
object_p->type_flags_refs |= ECMA_OBJECT_REF_ONE;
|
||||
}
|
||||
ECMA_GC_SET_OBJECT_VISITED (object_p);
|
||||
} /* ecma_gc_set_object_visited */
|
||||
|
||||
/**
|
||||
@@ -120,8 +104,8 @@ ecma_init_gc_info (ecma_object_t *object_p) /**< object */
|
||||
JERRY_ASSERT (object_p->type_flags_refs < ECMA_OBJECT_REF_ONE);
|
||||
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_REF_ONE);
|
||||
|
||||
ecma_gc_set_object_next (object_p, JERRY_CONTEXT (ecma_gc_objects_p));
|
||||
JERRY_CONTEXT (ecma_gc_objects_p) = object_p;
|
||||
object_p->gc_next_cp = JERRY_CONTEXT (ecma_gc_objects_cp);
|
||||
ECMA_SET_NON_NULL_POINTER (JERRY_CONTEXT (ecma_gc_objects_cp), object_p);
|
||||
} /* ecma_init_gc_info */
|
||||
|
||||
/**
|
||||
@@ -153,59 +137,61 @@ ecma_deref_object (ecma_object_t *object_p) /**< object */
|
||||
/**
|
||||
* Mark referenced object from property
|
||||
*/
|
||||
static void
|
||||
ecma_gc_mark_property (ecma_property_pair_t *property_pair_p, /**< property pair */
|
||||
uint32_t index) /**< property index */
|
||||
static inline void JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_gc_mark_properties (ecma_property_pair_t *property_pair_p) /**< property pair */
|
||||
{
|
||||
uint8_t property = property_pair_p->header.types[index];
|
||||
|
||||
switch (ECMA_PROPERTY_GET_TYPE (property))
|
||||
for (uint32_t index = 0; index < ECMA_PROPERTY_PAIR_ITEM_COUNT; index++)
|
||||
{
|
||||
case ECMA_PROPERTY_TYPE_NAMEDDATA:
|
||||
{
|
||||
ecma_value_t value = property_pair_p->values[index].value;
|
||||
uint8_t property = property_pair_p->header.types[index];
|
||||
|
||||
if (ecma_is_value_object (value))
|
||||
switch (ECMA_PROPERTY_GET_TYPE (property))
|
||||
{
|
||||
case ECMA_PROPERTY_TYPE_NAMEDDATA:
|
||||
{
|
||||
ecma_object_t *value_obj_p = ecma_get_object_from_value (value);
|
||||
ecma_value_t value = property_pair_p->values[index].value;
|
||||
|
||||
ecma_gc_set_object_visited (value_obj_p);
|
||||
if (ecma_is_value_object (value))
|
||||
{
|
||||
ecma_object_t *value_obj_p = ecma_get_object_from_value (value);
|
||||
|
||||
ECMA_GC_SET_OBJECT_VISITED (value_obj_p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ECMA_PROPERTY_TYPE_NAMEDACCESSOR:
|
||||
{
|
||||
ecma_property_value_t *accessor_objs_p = property_pair_p->values + index;
|
||||
ecma_object_t *getter_obj_p = ecma_get_named_accessor_property_getter (accessor_objs_p);
|
||||
ecma_object_t *setter_obj_p = ecma_get_named_accessor_property_setter (accessor_objs_p);
|
||||
|
||||
if (getter_obj_p != NULL)
|
||||
case ECMA_PROPERTY_TYPE_NAMEDACCESSOR:
|
||||
{
|
||||
ecma_gc_set_object_visited (getter_obj_p);
|
||||
}
|
||||
ecma_property_value_t *accessor_objs_p = property_pair_p->values + index;
|
||||
|
||||
if (setter_obj_p != NULL)
|
||||
ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (accessor_objs_p);
|
||||
|
||||
if (get_set_pair_p->getter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp));
|
||||
}
|
||||
|
||||
if (get_set_pair_p->setter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->setter_cp));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ECMA_PROPERTY_TYPE_INTERNAL:
|
||||
{
|
||||
ecma_gc_set_object_visited (setter_obj_p);
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_MAGIC
|
||||
&& property_pair_p->names_cp[index] >= LIT_FIRST_INTERNAL_MAGIC_STRING);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ECMA_PROPERTY_TYPE_INTERNAL:
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_MAGIC
|
||||
&& property_pair_p->names_cp[index] >= LIT_FIRST_INTERNAL_MAGIC_STRING);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_SPECIAL);
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_SPECIAL);
|
||||
|
||||
JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_HASHMAP
|
||||
|| property == ECMA_PROPERTY_TYPE_DELETED);
|
||||
break;
|
||||
JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_HASHMAP
|
||||
|| property == ECMA_PROPERTY_TYPE_DELETED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* ecma_gc_mark_property */
|
||||
} /* ecma_gc_mark_properties */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
|
||||
|
||||
@@ -224,21 +210,29 @@ ecma_gc_mark_promise_object (ecma_extended_object_t *ext_object_p) /**< extended
|
||||
}
|
||||
|
||||
/* Mark all reactions. */
|
||||
ecma_value_t *ecma_value_p;
|
||||
ecma_value_p = ecma_collection_iterator_init (((ecma_promise_object_t *) ext_object_p)->fulfill_reactions);
|
||||
ecma_promise_object_t *promise_object_p = (ecma_promise_object_t *) ext_object_p;
|
||||
ecma_collection_t *collection_p = promise_object_p->fulfill_reactions;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
if (collection_p != NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (*ecma_value_p));
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (buffer_p[i]));
|
||||
}
|
||||
}
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_init (((ecma_promise_object_t *) ext_object_p)->reject_reactions);
|
||||
collection_p = promise_object_p->reject_reactions;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
if (collection_p != NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (*ecma_value_p));
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (buffer_p[i]));
|
||||
}
|
||||
}
|
||||
} /* ecma_gc_mark_promise_object */
|
||||
|
||||
@@ -256,24 +250,32 @@ ecma_gc_mark_container_object (ecma_object_t *object_p) /**< object */
|
||||
|
||||
ecma_gc_set_object_visited (internal_obj_p);
|
||||
|
||||
ecma_property_header_t *prop_iter_p = ecma_get_property_list (internal_obj_p);
|
||||
jmem_cpointer_t prop_iter_cp = internal_obj_p->u1.property_list_cp;
|
||||
|
||||
if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
if (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
|
||||
prop_iter_cp);
|
||||
if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
while (prop_iter_p != NULL)
|
||||
while (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
ecma_gc_mark_properties ((ecma_property_pair_t *) prop_iter_p);
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
|
||||
for (uint32_t i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
{
|
||||
ecma_property_t *property_p = (ecma_property_t *) (prop_iter_p->types + i);
|
||||
ecma_gc_mark_property ((ecma_property_pair_t *) prop_iter_p, i);
|
||||
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_PTR)
|
||||
{
|
||||
@@ -282,7 +284,7 @@ ecma_gc_mark_container_object (ecma_object_t *object_p) /**< object */
|
||||
|
||||
if (ECMA_STRING_GET_CONTAINER (prop_name_p) == ECMA_STRING_CONTAINER_MAP_KEY)
|
||||
{
|
||||
ecma_value_t key_arg = prop_name_p->u.value;
|
||||
ecma_value_t key_arg = ((ecma_extended_string_t *) prop_name_p)->u.value;
|
||||
|
||||
if (ecma_is_value_object (key_arg))
|
||||
{
|
||||
@@ -292,8 +294,7 @@ ecma_gc_mark_container_object (ecma_object_t *object_p) /**< object */
|
||||
}
|
||||
}
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
} /* ecma_gc_mark_container_object */
|
||||
|
||||
@@ -310,10 +311,11 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
|
||||
if (ecma_is_lexical_environment (object_p))
|
||||
{
|
||||
ecma_object_t *lex_env_p = ecma_get_lex_env_outer_reference (object_p);
|
||||
if (lex_env_p != NULL)
|
||||
jmem_cpointer_t outer_lex_env_cp = object_p->u2.outer_reference_cp;
|
||||
|
||||
if (outer_lex_env_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (lex_env_p);
|
||||
ECMA_GC_SET_OBJECT_VISITED (ECMA_GET_NON_NULL_POINTER (ecma_object_t, outer_lex_env_cp));
|
||||
}
|
||||
|
||||
if (ecma_get_lex_env_type (object_p) != ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
@@ -326,10 +328,11 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_object_t *proto_p = ecma_get_object_prototype (object_p);
|
||||
if (proto_p != NULL)
|
||||
jmem_cpointer_t proto_cp = object_p->u2.prototype_cp;
|
||||
|
||||
if (proto_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_gc_set_object_visited (proto_p);
|
||||
ECMA_GC_SET_OBJECT_VISITED (ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp));
|
||||
}
|
||||
|
||||
switch (ecma_get_object_type (object_p))
|
||||
@@ -422,6 +425,31 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
|
||||
break;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_ARRAY:
|
||||
{
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (ext_object_p->u.array.is_fast_mode)
|
||||
{
|
||||
if (object_p->u1.property_list_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
|
||||
for (uint32_t i = 0; i < ext_object_p->u.array.length; i++)
|
||||
{
|
||||
if (ecma_is_value_object (values_p[i]))
|
||||
{
|
||||
ECMA_GC_SET_OBJECT_VISITED (ecma_get_object_from_value (values_p[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
{
|
||||
ecma_extended_object_t *ext_function_p = (ecma_extended_object_t *) object_p;
|
||||
@@ -463,7 +491,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
{
|
||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
ecma_gc_set_object_visited (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
ECMA_GC_SET_OBJECT_VISITED (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
ext_func_p->u.function.scope_cp));
|
||||
}
|
||||
break;
|
||||
@@ -490,23 +518,27 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
}
|
||||
}
|
||||
|
||||
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
|
||||
jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp;
|
||||
|
||||
if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
if (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
while (prop_iter_p != NULL)
|
||||
while (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
ecma_gc_mark_property ((ecma_property_pair_t *) prop_iter_p, 0);
|
||||
ecma_gc_mark_property ((ecma_property_pair_t *) prop_iter_p, 1);
|
||||
ecma_gc_mark_properties ((ecma_property_pair_t *) prop_iter_p);
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
} /* ecma_gc_mark */
|
||||
|
||||
@@ -552,6 +584,37 @@ ecma_gc_free_native_pointer (ecma_property_t *property_p) /**< property */
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
} /* ecma_gc_free_native_pointer */
|
||||
|
||||
/**
|
||||
* Free specified fast access mode array object.
|
||||
*/
|
||||
static void
|
||||
ecma_free_fast_access_array (ecma_object_t *object_p) /**< fast access mode array object to free */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
JERRY_ASSERT (ext_object_p->u.array.is_fast_mode);
|
||||
|
||||
const uint32_t aligned_length = ECMA_FAST_ARRAY_ALIGN_LENGTH (ext_object_p->u.array.length);
|
||||
|
||||
if (object_p->u1.property_list_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
|
||||
for (uint32_t i = 0; i < aligned_length; i++)
|
||||
{
|
||||
ecma_free_value_if_not_object (values_p[i]);
|
||||
}
|
||||
|
||||
jmem_heap_free_block (values_p, aligned_length * sizeof (ecma_value_t));
|
||||
}
|
||||
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_gc_objects_number) > 0);
|
||||
JERRY_CONTEXT (ecma_gc_objects_number)--;
|
||||
|
||||
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t));
|
||||
} /* ecma_free_fast_access_array */
|
||||
|
||||
/**
|
||||
* Free specified object.
|
||||
*/
|
||||
@@ -567,16 +630,35 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
if (obj_is_not_lex_env
|
||||
|| ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
|
||||
|
||||
if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
if (obj_is_not_lex_env && ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY)
|
||||
{
|
||||
ecma_property_hashmap_free (object_p);
|
||||
prop_iter_p = ecma_get_property_list (object_p);
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (ext_object_p->u.array.is_fast_mode)
|
||||
{
|
||||
ecma_free_fast_access_array (object_p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (prop_iter_p != NULL)
|
||||
jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp;
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
if (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
|
||||
prop_iter_cp);
|
||||
if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
ecma_property_hashmap_free (object_p);
|
||||
prop_iter_cp = object_p->u1.property_list_cp;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
while (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
/* Both cannot be deleted. */
|
||||
@@ -591,8 +673,8 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
jmem_cpointer_t name_cp = prop_pair_p->names_cp[i];
|
||||
|
||||
/* Call the native's free callback. */
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC
|
||||
&& (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER))
|
||||
if (JERRY_UNLIKELY (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC
|
||||
&& (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER)))
|
||||
{
|
||||
ecma_gc_free_native_pointer (property_p);
|
||||
}
|
||||
@@ -603,8 +685,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
}
|
||||
}
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
|
||||
ecma_dealloc_property_pair (prop_pair_p);
|
||||
}
|
||||
@@ -705,10 +786,8 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
case LIT_MAGIC_STRING_PROMISE_UL:
|
||||
{
|
||||
ecma_free_value_if_not_object (ext_object_p->u.class_prop.u.value);
|
||||
ecma_free_values_collection (((ecma_promise_object_t *) object_p)->fulfill_reactions,
|
||||
ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_free_values_collection (((ecma_promise_object_t *) object_p)->reject_reactions,
|
||||
ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_collection_free_if_not_object (((ecma_promise_object_t *) object_p)->fulfill_reactions);
|
||||
ecma_collection_free_if_not_object (((ecma_promise_object_t *) object_p)->reject_reactions);
|
||||
ecma_dealloc_extended_object (object_p, sizeof (ecma_promise_object_t));
|
||||
return;
|
||||
}
|
||||
@@ -907,9 +986,12 @@ ecma_gc_run (void)
|
||||
{
|
||||
JERRY_CONTEXT (ecma_gc_new_objects) = 0;
|
||||
|
||||
ecma_object_t black_list_head;
|
||||
black_list_head.gc_next_cp = JMEM_CP_NULL;
|
||||
ecma_object_t *black_end_p = &black_list_head;
|
||||
|
||||
ecma_object_t white_gray_list_head;
|
||||
ecma_gc_set_object_next (&white_gray_list_head, JERRY_CONTEXT (ecma_gc_objects_p));
|
||||
jmem_cpointer_t black_objects_cp = JMEM_CP_NULL;
|
||||
white_gray_list_head.gc_next_cp = JERRY_CONTEXT (ecma_gc_objects_cp);
|
||||
|
||||
ecma_object_t *obj_prev_p = &white_gray_list_head;
|
||||
jmem_cpointer_t obj_iter_cp = obj_prev_p->gc_next_cp;
|
||||
@@ -922,15 +1004,15 @@ ecma_gc_run (void)
|
||||
const jmem_cpointer_t obj_next_cp = obj_iter_p->gc_next_cp;
|
||||
|
||||
JERRY_ASSERT (obj_prev_p == NULL
|
||||
|| ecma_gc_get_object_next (obj_prev_p) == obj_iter_p);
|
||||
|| ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_prev_p->gc_next_cp) == obj_iter_p);
|
||||
|
||||
if (ecma_gc_is_object_visited (obj_iter_p))
|
||||
{
|
||||
/* Moving the object to list of marked objects. */
|
||||
obj_prev_p->gc_next_cp = obj_next_cp;
|
||||
|
||||
obj_iter_p->gc_next_cp = black_objects_cp;
|
||||
black_objects_cp = obj_iter_cp;
|
||||
black_end_p->gc_next_cp = obj_iter_cp;
|
||||
black_end_p = obj_iter_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -940,14 +1022,16 @@ ecma_gc_run (void)
|
||||
obj_iter_cp = obj_next_cp;
|
||||
}
|
||||
|
||||
ecma_object_t *first_root_object_p = JMEM_CP_GET_POINTER (ecma_object_t, black_objects_cp);
|
||||
black_end_p->gc_next_cp = JMEM_CP_NULL;
|
||||
ecma_object_t *const last_root_object_p = black_end_p;
|
||||
|
||||
/* Mark root objects. */
|
||||
obj_iter_p = first_root_object_p;
|
||||
while (obj_iter_p != NULL)
|
||||
obj_iter_cp = black_list_head.gc_next_cp;
|
||||
while (obj_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
obj_iter_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp);
|
||||
ecma_gc_mark (obj_iter_p);
|
||||
obj_iter_p = ecma_gc_get_object_next (obj_iter_p);
|
||||
obj_iter_cp = obj_iter_p->gc_next_cp;
|
||||
}
|
||||
|
||||
/* Mark non-root objects. */
|
||||
@@ -966,15 +1050,15 @@ ecma_gc_run (void)
|
||||
const jmem_cpointer_t obj_next_cp = obj_iter_p->gc_next_cp;
|
||||
|
||||
JERRY_ASSERT (obj_prev_p == NULL
|
||||
|| ecma_gc_get_object_next (obj_prev_p) == obj_iter_p);
|
||||
|| ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_prev_p->gc_next_cp) == obj_iter_p);
|
||||
|
||||
if (ecma_gc_is_object_visited (obj_iter_p))
|
||||
{
|
||||
/* Moving the object to list of marked objects */
|
||||
obj_prev_p->gc_next_cp = obj_next_cp;
|
||||
|
||||
obj_iter_p->gc_next_cp = black_objects_cp;
|
||||
black_objects_cp = obj_iter_cp;
|
||||
black_end_p->gc_next_cp = obj_iter_cp;
|
||||
black_end_p = obj_iter_p;
|
||||
|
||||
ecma_gc_mark (obj_iter_p);
|
||||
marked_anything_during_current_iteration = true;
|
||||
@@ -989,32 +1073,37 @@ ecma_gc_run (void)
|
||||
}
|
||||
while (marked_anything_during_current_iteration);
|
||||
|
||||
/* Sweep objects that are currently unmarked. */
|
||||
obj_iter_p = ecma_gc_get_object_next (&white_gray_list_head);
|
||||
black_end_p->gc_next_cp = JMEM_CP_NULL;
|
||||
|
||||
while (obj_iter_p != NULL)
|
||||
/* Sweep objects that are currently unmarked. */
|
||||
obj_iter_cp = white_gray_list_head.gc_next_cp;
|
||||
|
||||
while (obj_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_object_t *obj_next_p = ecma_gc_get_object_next (obj_iter_p);
|
||||
obj_iter_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp);
|
||||
const jmem_cpointer_t obj_next_cp = obj_iter_p->gc_next_cp;
|
||||
|
||||
JERRY_ASSERT (!ecma_gc_is_object_visited (obj_iter_p));
|
||||
|
||||
ecma_gc_free_object (obj_iter_p);
|
||||
obj_iter_p = obj_next_p;
|
||||
obj_iter_cp = obj_next_cp;
|
||||
}
|
||||
|
||||
/* Reset the reference counter of non-root black objects. */
|
||||
obj_iter_p = JMEM_CP_GET_POINTER (ecma_object_t, black_objects_cp);
|
||||
JERRY_CONTEXT (ecma_gc_objects_p) = obj_iter_p;
|
||||
obj_iter_cp = last_root_object_p->gc_next_cp;
|
||||
|
||||
while (obj_iter_p != first_root_object_p)
|
||||
while (obj_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
/* The reference counter must be 1. */
|
||||
obj_iter_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp);
|
||||
ecma_deref_object (obj_iter_p);
|
||||
JERRY_ASSERT (obj_iter_p->type_flags_refs < ECMA_OBJECT_REF_ONE);
|
||||
|
||||
obj_iter_p = ecma_gc_get_object_next (obj_iter_p);
|
||||
obj_iter_cp = obj_iter_p->gc_next_cp;
|
||||
}
|
||||
|
||||
JERRY_CONTEXT (ecma_gc_objects_cp) = black_list_head.gc_next_cp;
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_REGEXP)
|
||||
/* Free RegExp bytecodes stored in cache */
|
||||
re_cache_gc_run ();
|
||||
@@ -1077,23 +1166,42 @@ ecma_free_unused_memory (jmem_pressure_t pressure) /**< current pressure */
|
||||
|
||||
ecma_gc_run ();
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
/* Free hashmaps of remaining objects. */
|
||||
ecma_object_t *obj_iter_p = JERRY_CONTEXT (ecma_gc_objects_p);
|
||||
while (obj_iter_p != NULL)
|
||||
jmem_cpointer_t obj_iter_cp = JERRY_CONTEXT (ecma_gc_objects_cp);
|
||||
|
||||
while (obj_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_object_t *obj_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp);
|
||||
|
||||
if (!ecma_is_lexical_environment (obj_iter_p)
|
||||
|| ecma_get_lex_env_type (obj_iter_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_iter_p);
|
||||
|
||||
if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
if (!ecma_is_lexical_environment (obj_iter_p)
|
||||
&& ecma_get_object_type (obj_iter_p) == ECMA_OBJECT_TYPE_ARRAY
|
||||
&& ((ecma_extended_object_t *) obj_iter_p)->u.array.is_fast_mode)
|
||||
{
|
||||
ecma_property_hashmap_free (obj_iter_p);
|
||||
obj_iter_cp = obj_iter_p->gc_next_cp;
|
||||
continue;
|
||||
}
|
||||
|
||||
jmem_cpointer_t prop_iter_cp = obj_iter_p->u1.property_list_cp;
|
||||
|
||||
if (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
|
||||
if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
ecma_property_hashmap_free (obj_iter_p);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
obj_iter_p = ecma_gc_get_object_next (obj_iter_p);
|
||||
obj_iter_cp = obj_iter_p->gc_next_cp;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
jmem_pools_collect_empty ();
|
||||
return;
|
||||
|
||||
+303
-111
@@ -76,7 +76,6 @@ typedef enum
|
||||
ECMA_TYPE_SYMBOL = 4, /**< pointer to description of a symbol */
|
||||
ECMA_TYPE_DIRECT_STRING = 5, /**< directly encoded string values */
|
||||
ECMA_TYPE_ERROR = 7, /**< pointer to description of an error reference (only supported by C API) */
|
||||
ECMA_TYPE_POINTER = ECMA_TYPE_ERROR, /**< a generic aligned pointer */
|
||||
ECMA_TYPE_SNAPSHOT_OFFSET = ECMA_TYPE_ERROR, /**< offset to a snapshot number/string */
|
||||
ECMA_TYPE___MAX = ECMA_TYPE_ERROR /** highest value for ecma types */
|
||||
} ecma_type_t;
|
||||
@@ -331,6 +330,8 @@ typedef enum
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|
||||
ECMA_LIST_SYMBOLS = (1 << 3), /**< list symbol properties only */
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
|
||||
ECMA_LIST_CONVERT_FAST_ARRAYS = (1 << 4), /**< after listing the properties convert
|
||||
* the fast access mode array back to normal array */
|
||||
} ecma_list_properties_options_t;
|
||||
|
||||
/**
|
||||
@@ -494,8 +495,8 @@ typedef struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jmem_cpointer_t getter_p; /**< pointer to getter object */
|
||||
jmem_cpointer_t setter_p; /**< pointer to setter object */
|
||||
jmem_cpointer_t getter_cp; /**< compressed pointer to getter object */
|
||||
jmem_cpointer_t setter_cp; /**< compressed pointer to setter object */
|
||||
} ecma_getter_setter_pointers_t;
|
||||
|
||||
/**
|
||||
@@ -564,11 +565,6 @@ typedef struct
|
||||
#define ECMA_PROPERTY_VALUE_PTR(property_p) \
|
||||
((ecma_property_value_t *) ECMA_PROPERTY_VALUE_DATA_PTR (property_p))
|
||||
|
||||
/**
|
||||
* Depth limit for property search (maximum prototype chain depth).
|
||||
*/
|
||||
#define ECMA_PROPERTY_SEARCH_DEPTH_LIMIT 128
|
||||
|
||||
/**
|
||||
* Property reference. It contains the value pointer
|
||||
* for real, and the value itself for virtual properties.
|
||||
@@ -744,10 +740,19 @@ typedef struct
|
||||
jmem_cpointer_t gc_next_cp;
|
||||
|
||||
/** compressed pointer to property list or bound object */
|
||||
jmem_cpointer_t property_list_or_bound_object_cp;
|
||||
union
|
||||
{
|
||||
jmem_cpointer_t property_list_cp; /**< compressed pointer to object's
|
||||
* or declerative lexical environments's property list */
|
||||
jmem_cpointer_t bound_object_cp; /**< compressed pointer to lexical environments's the bound object */
|
||||
} u1;
|
||||
|
||||
/** object prototype or outer reference */
|
||||
jmem_cpointer_t prototype_or_outer_reference_cp;
|
||||
union
|
||||
{
|
||||
jmem_cpointer_t prototype_cp; /**< compressed pointer to the object's prototype */
|
||||
jmem_cpointer_t outer_reference_cp; /**< compressed pointer to the lexical environments's outer reference */
|
||||
} u2;
|
||||
} ecma_object_t;
|
||||
|
||||
/**
|
||||
@@ -818,6 +823,9 @@ typedef struct
|
||||
{
|
||||
uint32_t length; /**< length property value */
|
||||
ecma_property_t length_prop; /**< length property */
|
||||
bool is_fast_mode; /**< true - if the array is a fast access mode array
|
||||
* false - otherwise */
|
||||
uint8_t hole_count; /**< Number of array holes in a fast access mode array */
|
||||
} array;
|
||||
|
||||
/**
|
||||
@@ -827,12 +835,12 @@ typedef struct
|
||||
{
|
||||
uint8_t type; /**< pseudo array type, e.g. Arguments, TypedArray, ArrayIterator */
|
||||
uint8_t extra_info; /**< extra information about the object.
|
||||
* e.g. element_width_shift for typed arrays,
|
||||
* e.g. the specific builtin id for typed arrays,
|
||||
* [[IterationKind]] property for %Iterator% */
|
||||
union
|
||||
{
|
||||
uint16_t length; /**< for arguments: length of names */
|
||||
uint16_t class_id; /**< for typedarray: the specific class name */
|
||||
uint16_t class_id; /**< for typedarray: the specific class name id */
|
||||
uint16_t iterator_index; /**< for %Iterator%: [[%Iterator%NextIndex]] property */
|
||||
} u1;
|
||||
union
|
||||
@@ -865,6 +873,19 @@ typedef struct
|
||||
ecma_built_in_props_t built_in; /**< built-in object part */
|
||||
} ecma_extended_built_in_object_t;
|
||||
|
||||
/**
|
||||
* Alignment for the fast access mode array length.
|
||||
* The real length is aligned up for allocating the underlying buffer.
|
||||
*/
|
||||
#define ECMA_FAST_ARRAY_ALIGNMENT (8)
|
||||
|
||||
/**
|
||||
* Align the length of the fast mode array to get the allocated size of the underlying buffer
|
||||
*/
|
||||
#define ECMA_FAST_ARRAY_ALIGN_LENGTH(length) \
|
||||
(uint32_t) ((((length)) + ECMA_FAST_ARRAY_ALIGNMENT - 1) / ECMA_FAST_ARRAY_ALIGNMENT * ECMA_FAST_ARRAY_ALIGNMENT)
|
||||
|
||||
|
||||
/**
|
||||
* Compiled byte code data.
|
||||
*/
|
||||
@@ -931,6 +952,23 @@ typedef struct
|
||||
} ecma_map_object_t;
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ECMA_PROP_NO_OPTS = (0), /** empty property descriptor */
|
||||
ECMA_PROP_IS_GET_DEFINED = (1 << 0), /** Is [[Get]] defined? */
|
||||
ECMA_PROP_IS_SET_DEFINED = (1 << 1), /** Is [[Set]] defined? */
|
||||
|
||||
ECMA_PROP_IS_CONFIGURABLE = (1 << 2), /** [[Configurable]] */
|
||||
ECMA_PROP_IS_ENUMERABLE = (1 << 3), /** [[Enumerable]] */
|
||||
ECMA_PROP_IS_WRITABLE = (1 << 4), /** [[Writable]] */
|
||||
ECMA_PROP_IS_THROW = (1 << 5), /** Flag that controls failure handling */
|
||||
|
||||
ECMA_PROP_IS_VALUE_DEFINED = (1 << 6), /** Is [[Value]] defined? */
|
||||
ECMA_PROP_IS_CONFIGURABLE_DEFINED = (1 << 7), /** Is [[Configurable]] defined? */
|
||||
ECMA_PROP_IS_ENUMERABLE_DEFINED = (1 << 8), /** Is [[Enumerable]] defined? */
|
||||
ECMA_PROP_IS_WRITABLE_DEFINED = (1 << 9), /** Is [[Writable]] defined? */
|
||||
} ecma_property_descriptor_status_flags_t;
|
||||
|
||||
/**
|
||||
* Description of ECMA property descriptor
|
||||
*
|
||||
@@ -939,35 +977,13 @@ typedef struct
|
||||
* Note:
|
||||
* If a component of descriptor is undefined then corresponding
|
||||
* field should contain it's default value.
|
||||
* The struct members must be in this order or keep in sync with ecma_property_flags_t and ECMA_IS_THROW flag.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** Is [[Value]] defined? */
|
||||
unsigned int is_value_defined : 1;
|
||||
|
||||
/** Is [[Get]] defined? */
|
||||
unsigned int is_get_defined : 1;
|
||||
|
||||
/** Is [[Set]] defined? */
|
||||
unsigned int is_set_defined : 1;
|
||||
|
||||
/** Is [[Writable]] defined? */
|
||||
unsigned int is_writable_defined : 1;
|
||||
|
||||
/** [[Writable]] */
|
||||
unsigned int is_writable : 1;
|
||||
|
||||
/** Is [[Enumerable]] defined? */
|
||||
unsigned int is_enumerable_defined : 1;
|
||||
|
||||
/** [[Enumerable]] */
|
||||
unsigned int is_enumerable : 1;
|
||||
|
||||
/** Is [[Configurable]] defined? */
|
||||
unsigned int is_configurable_defined : 1;
|
||||
|
||||
/** [[Configurable]] */
|
||||
unsigned int is_configurable : 1;
|
||||
/** any combination of ecma_property_descriptor_status_flags_t bits */
|
||||
uint16_t flags;
|
||||
|
||||
/** [[Value]] */
|
||||
ecma_value_t value;
|
||||
@@ -979,12 +995,44 @@ typedef struct
|
||||
ecma_object_t *set_p;
|
||||
} ecma_property_descriptor_t;
|
||||
|
||||
/**
|
||||
* Bitfield which represents a namedata property options in an ecma_property_descriptor_t
|
||||
* Attributes:
|
||||
* - is_get_defined, is_set_defined : false
|
||||
* - is_configurable, is_writable, is_enumerable : undefined (false)
|
||||
* - is_throw : undefined (false)
|
||||
* - is_value_defined : true
|
||||
* - is_configurable_defined, is_writable_defined, is_enumerable_defined : true
|
||||
*/
|
||||
#define ECMA_NAME_DATA_PROPERTY_DESCRIPTOR_BITS 0x3c0
|
||||
|
||||
/**
|
||||
* Bitmask to get a the physical property flags from an ecma_property_descriptor
|
||||
*/
|
||||
#define ECMA_PROPERTY_FLAGS_MASK 0x1c
|
||||
|
||||
/**
|
||||
* Flag that controls failure handling during defining property
|
||||
*
|
||||
* Note: This flags represents the [[DefineOwnProperty]] (P, Desc, Throw) 3rd argument
|
||||
*/
|
||||
#define ECMA_IS_THROW (1 << 5)
|
||||
|
||||
#if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
/**
|
||||
* Description of an ecma-number
|
||||
*/
|
||||
typedef float ecma_number_t;
|
||||
|
||||
/**
|
||||
* It makes possible to read/write an ecma_number_t as uint32_t without strict aliasing rule violation.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
ecma_number_t as_ecma_number_t;
|
||||
uint32_t as_uint32_t;
|
||||
} ecma_number_accessor_t;
|
||||
|
||||
#define DOUBLE_TO_ECMA_NUMBER_T(value) (ecma_number_t) (value)
|
||||
|
||||
/**
|
||||
@@ -1021,6 +1069,15 @@ typedef float ecma_number_t;
|
||||
*/
|
||||
typedef double ecma_number_t;
|
||||
|
||||
/**
|
||||
* It makes possible to read/write an ecma_number_t as uint64_t without strict aliasing rule violation.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
ecma_number_t as_ecma_number_t;
|
||||
uint64_t as_uint64_t;
|
||||
} ecma_number_accessor_t;
|
||||
|
||||
#define DOUBLE_TO_ECMA_NUMBER_T(value) value
|
||||
|
||||
/**
|
||||
@@ -1105,7 +1162,22 @@ typedef double ecma_number_t;
|
||||
*/
|
||||
# define ECMA_NUMBER_MIN_VALUE ((ecma_number_t) 5e-324)
|
||||
#endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN)
|
||||
/**
|
||||
* Number.EPSILON
|
||||
*
|
||||
* See also: ECMA_262 v6, 20.1.2.1
|
||||
*/
|
||||
# define ECMA_NUMBER_EPSILON ((ecma_number_t) 2.2204460492503130808472633361816e-16)
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN)
|
||||
/**
|
||||
* Number.MAX_SAFE_INTEGER
|
||||
*
|
||||
* See also: ECMA_262 v6, 20.1.2.1
|
||||
*/
|
||||
# define ECMA_NUMBER_MAX_SAFE_INTEGER ((ecma_number_t) 0x1FFFFFFFFFFFFF)
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
|
||||
/**
|
||||
* Euler number
|
||||
*/
|
||||
@@ -1161,57 +1233,36 @@ typedef double ecma_number_t;
|
||||
*/
|
||||
#define ECMA_STRING_NOT_ARRAY_INDEX UINT32_MAX
|
||||
|
||||
/*
|
||||
* Ecma-collection: a growable list of ecma-values. Currently the list is
|
||||
* a chain list, where appending new items at the end is cheap operation.
|
||||
*
|
||||
* Enumerating elements is also cheap, since each page is terminated by a
|
||||
* special ecma-value: collection-type. This type has a pointer to the next
|
||||
* chunk. The last chunk is terminated by a NULL pointer. There when the
|
||||
* next value is requested from the iterator it simply checks the next
|
||||
* memory location. If it is not a collection-type value, it returns with
|
||||
* the value. Otherwise it gets the start address of the next chunk, and
|
||||
* return the value there.
|
||||
*
|
||||
* The collection-type value is always the last item of a collection chunk,
|
||||
* even if the chunk is not completely filled with values (this is only true
|
||||
* for the last chunk). Each chunk must have at least one non collection-type
|
||||
* value as well.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Collection flags.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_COLLECTION_NO_REF_OBJECTS = (1u << 0), /**< do not increase the refcount of objects */
|
||||
ECMA_COLLECTION_NO_COPY = (1u << 1), /**< do not copy values */
|
||||
} ecma_collection_flag_t;
|
||||
|
||||
/**
|
||||
* Description of a collection's header.
|
||||
* Ecma-collection: a growable list of ecma-values.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jmem_cpointer_t first_chunk_cp; /**< compressed pointer to first chunk with collection's data */
|
||||
jmem_cpointer_t last_chunk_cp; /**< compressed pointer to last chunk with collection's data */
|
||||
ecma_length_t item_count; /**< number of items in the collection */
|
||||
} ecma_collection_header_t;
|
||||
uint32_t item_count; /**< number of items in the collection */
|
||||
uint32_t capacity; /**< number of items can be stored in the underlying buffer */
|
||||
ecma_value_t *buffer_p; /**< underlying data buffer */
|
||||
} ecma_collection_t;
|
||||
|
||||
/**
|
||||
* Maximum number of items stored by a collection chunk (excluding the last collection-type value).
|
||||
* Initial capacity of an ecma-collection
|
||||
*/
|
||||
#define ECMA_COLLECTION_CHUNK_ITEMS 5
|
||||
#define ECMA_COLLECTION_INITIAL_CAPACITY 4
|
||||
|
||||
/**
|
||||
* Collection chunk item.
|
||||
* Ecma-collenction grow factor when the collection underlying buffer need to be reallocated
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_value_t items[ECMA_COLLECTION_CHUNK_ITEMS + 1]; /**< ecma-value list, where the last value is a special
|
||||
* collection-type value which points to the next chunk,
|
||||
* so the chunk area is enlarged by one for this value */
|
||||
} ecma_collection_chunk_t;
|
||||
#define ECMA_COLLECTION_GROW_FACTOR (ECMA_COLLECTION_INITIAL_CAPACITY * 2)
|
||||
|
||||
/**
|
||||
* Compute the total allocated size of the collection based on it's capacity
|
||||
*/
|
||||
#define ECMA_COLLECTION_ALLOCATED_SIZE(capacity) \
|
||||
(uint32_t) (sizeof (ecma_collection_t) + (capacity * sizeof (ecma_value_t)))
|
||||
|
||||
/**
|
||||
* Initial allocated size of an ecma-collection
|
||||
*/
|
||||
#define ECMA_COLLECTION_INITIAL_SIZE ECMA_COLLECTION_ALLOCATED_SIZE (ECMA_COLLECTION_INITIAL_CAPACITY)
|
||||
|
||||
/**
|
||||
* Direct string types (2 bit).
|
||||
@@ -1250,6 +1301,14 @@ typedef enum
|
||||
#define ECMA_CREATE_DIRECT_STRING(type, value) \
|
||||
((uintptr_t) (ECMA_TYPE_DIRECT_STRING | ((type) << ECMA_VALUE_SHIFT) | (value) << ECMA_DIRECT_STRING_SHIFT))
|
||||
|
||||
/**
|
||||
* Create an ecma direct string from the given number.
|
||||
*
|
||||
* Note: the given number must be less or equal than ECMA_DIRECT_STRING_MAX_IMM
|
||||
*/
|
||||
#define ECMA_CREATE_DIRECT_UINT32_STRING(uint32_number) \
|
||||
((ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_UINT, (uintptr_t) uint32_number))
|
||||
|
||||
/**
|
||||
* Checks whether the string is direct.
|
||||
*/
|
||||
@@ -1286,8 +1345,10 @@ typedef enum
|
||||
(((uintptr_t) (string_p)) >> ECMA_DIRECT_STRING_SHIFT)
|
||||
|
||||
/**
|
||||
* Identifier for ecma-string's actual data container
|
||||
* Maximum number of bytes that a long-utf8-string is able to store
|
||||
*/
|
||||
#define ECMA_STRING_SIZE_LIMIT UINT32_MAX
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ECMA_STRING_CONTAINER_HEAP_UTF8_STRING, /**< actual data is on the heap as an utf-8 (cesu8) string
|
||||
@@ -1296,17 +1357,15 @@ typedef enum
|
||||
* maximum size is 2^32. */
|
||||
ECMA_STRING_CONTAINER_UINT32_IN_DESC, /**< actual data is UInt32-represeneted Number
|
||||
stored locally in the string's descriptor */
|
||||
ECMA_STRING_CONTAINER_HEAP_ASCII_STRING, /**< actual data is on the heap as an ASCII string
|
||||
* maximum size is 2^16. */
|
||||
ECMA_STRING_CONTAINER_MAGIC_STRING_EX, /**< the ecma-string is equal to one of external magic strings */
|
||||
|
||||
ECMA_STRING_CONTAINER_SYMBOL, /**< the ecma-string is a symbol */
|
||||
|
||||
ECMA_STRING_CONTAINER_MAP_KEY, /**< the ecma-string is a map key string */
|
||||
|
||||
ECMA_STRING_LITERAL_NUMBER, /**< a literal number which is used solely by the literal storage
|
||||
* so no string processing function supports this type except
|
||||
* the ecma_deref_ecma_string function. */
|
||||
|
||||
ECMA_STRING_CONTAINER__MAX = ECMA_STRING_LITERAL_NUMBER /**< maximum value */
|
||||
ECMA_STRING_CONTAINER__MAX = ECMA_STRING_CONTAINER_MAP_KEY /**< maximum value */
|
||||
} ecma_string_container_t;
|
||||
|
||||
/**
|
||||
@@ -1317,12 +1376,29 @@ typedef enum
|
||||
/**
|
||||
* Value for increasing or decreasing the reference counter.
|
||||
*/
|
||||
#define ECMA_STRING_REF_ONE (1u << 3)
|
||||
#define ECMA_STRING_REF_ONE (1u << 4)
|
||||
|
||||
/**
|
||||
* Maximum value of the reference counter (8191).
|
||||
* Maximum value of the reference counter (4294967280).
|
||||
*/
|
||||
#define ECMA_STRING_MAX_REF (0x1fffu << 3)
|
||||
#define ECMA_STRING_MAX_REF (0xFFFFFFF0)
|
||||
|
||||
/**
|
||||
* Flag that identifies that the string is static which means it is stored in JERRY_CONTEXT (string_list_cp)
|
||||
*/
|
||||
#define ECMA_STATIC_STRING_FLAG (1 << 3)
|
||||
|
||||
/**
|
||||
* Set an ecma-string as static string
|
||||
*/
|
||||
#define ECMA_SET_STRING_AS_STATIC(string_p) \
|
||||
(string_p)->refs_and_container |= ECMA_STATIC_STRING_FLAG
|
||||
|
||||
/**
|
||||
* Checks whether the ecma-string is static string
|
||||
*/
|
||||
#define ECMA_STRING_IS_STATIC(string_p) \
|
||||
((string_p)->refs_and_container & ECMA_STATIC_STRING_FLAG)
|
||||
|
||||
/**
|
||||
* Returns with the container type of a string.
|
||||
@@ -1334,7 +1410,7 @@ typedef enum
|
||||
* Checks whether the reference counter is 1.
|
||||
*/
|
||||
#define ECMA_STRING_IS_REF_EQUALS_TO_ONE(string_desc_p) \
|
||||
(((string_desc_p)->refs_and_container >> 3) == 1)
|
||||
(((string_desc_p)->refs_and_container >> 4) == 1)
|
||||
|
||||
/**
|
||||
* ECMA string-value descriptor
|
||||
@@ -1342,43 +1418,107 @@ typedef enum
|
||||
typedef struct
|
||||
{
|
||||
/** Reference counter for the string */
|
||||
uint16_t refs_and_container;
|
||||
|
||||
/** Hash of the string (calculated from two last characters of the string) */
|
||||
lit_string_hash_t hash;
|
||||
uint32_t refs_and_container;
|
||||
|
||||
/**
|
||||
* Actual data or identifier of it's place in container (depending on 'container' field)
|
||||
*/
|
||||
union
|
||||
{
|
||||
/**
|
||||
* Actual data of an utf-8 string type
|
||||
*/
|
||||
struct
|
||||
{
|
||||
uint16_t size; /**< size of this utf-8 string in bytes */
|
||||
uint16_t length; /**< length of this utf-8 string in characters */
|
||||
} utf8_string;
|
||||
|
||||
lit_utf8_size_t long_utf8_string_size; /**< size of this long utf-8 string in bytes */
|
||||
uint32_t uint32_number; /**< uint32-represented number placed locally in the descriptor */
|
||||
lit_string_hash_t hash; /**< hash of the ASCII/UTF8 string */
|
||||
uint32_t magic_string_ex_id; /**< identifier of an external magic string (lit_magic_string_ex_id_t) */
|
||||
ecma_value_t lit_number; /**< number (see ECMA_STRING_LITERAL_NUMBER) */
|
||||
uint32_t common_uint32_field; /**< for zeroing and comparison in some cases */
|
||||
ecma_value_t symbol_descriptor; /**< symbol descriptor string-value */
|
||||
ecma_value_t value; /**< original key value corresponds to the map key string */
|
||||
uint32_t uint32_number; /**< uint32-represented number placed locally in the descriptor */
|
||||
} u;
|
||||
} ecma_string_t;
|
||||
|
||||
/**
|
||||
* Long ECMA string-value descriptor
|
||||
* ECMA ASCII string-value descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_string_t header; /**< string header */
|
||||
lit_utf8_size_t long_utf8_string_length; /**< length of this long utf-8 string in bytes */
|
||||
} ecma_long_string_t;
|
||||
uint16_t size; /**< size of this ASCII string in bytes */
|
||||
} ecma_ascii_string_t;
|
||||
|
||||
/**
|
||||
* ECMA long UTF8 string-value descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_string_t header; /**< string header */
|
||||
uint16_t size; /**< size of this utf-8 string in bytes */
|
||||
uint16_t length; /**< length of this utf-8 string in bytes */
|
||||
} ecma_utf8_string_t;
|
||||
|
||||
/**
|
||||
* ECMA UTF8 string-value descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_string_t header; /**< string header */
|
||||
lit_utf8_size_t size; /**< size of this long utf-8 string in bytes */
|
||||
lit_utf8_size_t length; /**< length of this long utf-8 string in bytes */
|
||||
} ecma_long_utf8_string_t;
|
||||
|
||||
/**
|
||||
* Get the start position of the string buffer of an ecma ASCII string
|
||||
*/
|
||||
#define ECMA_ASCII_STRING_GET_BUFFER(string_p) \
|
||||
((lit_utf8_byte_t *) ((lit_utf8_byte_t *) (string_p) + sizeof (ecma_ascii_string_t)))
|
||||
|
||||
/**
|
||||
* Get the start position of the string buffer of an ecma UTF8 string
|
||||
*/
|
||||
#define ECMA_UTF8_STRING_GET_BUFFER(string_p) \
|
||||
((lit_utf8_byte_t *) ((lit_utf8_byte_t *) (string_p) + sizeof (ecma_utf8_string_t)))
|
||||
|
||||
/**
|
||||
* Get the start position of the string buffer of an ecma long UTF8 string
|
||||
*/
|
||||
#define ECMA_LONG_UTF8_STRING_GET_BUFFER(string_p) \
|
||||
((lit_utf8_byte_t *) ((lit_utf8_byte_t *) (string_p) + sizeof (ecma_long_utf8_string_t)))
|
||||
|
||||
/**
|
||||
* ECMA extended string-value descriptor
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_string_t header; /**< string header */
|
||||
|
||||
union
|
||||
{
|
||||
ecma_value_t symbol_descriptor; /**< symbol descriptor string-value */
|
||||
ecma_value_t value; /**< original key value corresponds to the map key string */
|
||||
} u;
|
||||
} ecma_extended_string_t;
|
||||
|
||||
/**
|
||||
* String builder header
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
lit_utf8_size_t current_size; /**< size of the data in the buffer */
|
||||
} ecma_stringbuilder_header_t;
|
||||
|
||||
/**
|
||||
* Get pointer to the beginning of the stored string in the string builder
|
||||
*/
|
||||
#define ECMA_STRINGBUILDER_STRING_PTR(header_p) \
|
||||
((lit_utf8_byte_t *) (((lit_utf8_byte_t *) header_p) + sizeof (ecma_ascii_string_t)))
|
||||
|
||||
/**
|
||||
* Get the size of the stored string in the string builder
|
||||
*/
|
||||
#define ECMA_STRINGBUILDER_STRING_SIZE(header_p) \
|
||||
((lit_utf8_size_t) (header_p->current_size - sizeof (ecma_ascii_string_t)))
|
||||
|
||||
/**
|
||||
* String builder handle
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_stringbuilder_header_t *header_p; /**< pointer to header */
|
||||
} ecma_stringbuilder_t;
|
||||
|
||||
/**
|
||||
* Abort flag for error reference.
|
||||
@@ -1434,6 +1574,15 @@ typedef struct
|
||||
jmem_cpointer_t values[ECMA_LIT_STORAGE_VALUE_COUNT]; /**< list of values */
|
||||
} ecma_lit_storage_item_t;
|
||||
|
||||
/**
|
||||
* Number storage item
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jmem_cpointer_t next_cp; /**< cpointer ot next item */
|
||||
jmem_cpointer_t values[ECMA_LIT_STORAGE_VALUE_COUNT]; /**< list of values */
|
||||
} ecma_number_storage_item_t;
|
||||
|
||||
#if ENABLED (JERRY_LCACHE)
|
||||
/**
|
||||
* Container of an LCache entry identifier
|
||||
@@ -1470,6 +1619,32 @@ typedef struct
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
|
||||
|
||||
/**
|
||||
* Function callback descriptor of a %TypedArray% object getter
|
||||
*/
|
||||
typedef ecma_number_t (*ecma_typedarray_getter_fn_t)(lit_utf8_byte_t *src);
|
||||
|
||||
/**
|
||||
* Function callback descriptor of a %TypedArray% object setter
|
||||
*/
|
||||
typedef void (*ecma_typedarray_setter_fn_t)(lit_utf8_byte_t *src, ecma_number_t value);
|
||||
|
||||
/**
|
||||
* Builtin id for the different types of TypedArray's
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_INT8_ARRAY, /**< Int8Array */
|
||||
ECMA_UINT8_ARRAY, /**< Uint8Array */
|
||||
ECMA_UINT8_CLAMPED_ARRAY, /**< Uint8ClampedArray */
|
||||
ECMA_INT16_ARRAY, /**< Int16Array */
|
||||
ECMA_UINT16_ARRAY, /**< Uint16Array */
|
||||
ECMA_INT32_ARRAY, /**< Int32Array */
|
||||
ECMA_UINT32_ARRAY, /**< Uint32Array */
|
||||
ECMA_FLOAT32_ARRAY, /**< Float32Array */
|
||||
ECMA_FLOAT64_ARRAY, /**< Float64Array */
|
||||
} ecma_typedarray_type_t;
|
||||
|
||||
/**
|
||||
* Extra information for ArrayBuffers.
|
||||
*/
|
||||
@@ -1509,6 +1684,23 @@ typedef struct
|
||||
ecma_length_t array_length; /**< the array length */
|
||||
} ecma_extended_typedarray_object_t;
|
||||
|
||||
/**
|
||||
* General structure for query %TypedArray% object's properties.
|
||||
**/
|
||||
typedef struct
|
||||
{
|
||||
ecma_object_t *array_buffer_p; /**< pointer to the typedArray's [[ViewedArrayBuffer]] internal slot */
|
||||
lit_utf8_byte_t *buffer_p; /**< pointer to the underlying raw data buffer.
|
||||
* Note:
|
||||
* - This address is increased by the [ByteOffset]] internal property.
|
||||
* - This address must be used during indexed read/write operation. */
|
||||
ecma_typedarray_type_t id; /**< [[TypedArrayName]] internal slot */
|
||||
uint32_t length; /**< [[ByteLength]] internal slot */
|
||||
ecma_length_t offset; /**< [[ByteOffset]] internal slot. */
|
||||
uint8_t shift; /**< the element size shift in the typedArray */
|
||||
uint8_t element_size; /**< element size based on [[TypedArrayName]] in Table 49 */
|
||||
} ecma_typedarray_info_t;
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmahelpers Helpers for operations with ECMA data types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate a collection of ecma values.
|
||||
*
|
||||
* @return pointer to the collection
|
||||
*/
|
||||
ecma_collection_t *
|
||||
ecma_new_collection (void)
|
||||
{
|
||||
ecma_collection_t *collection_p;
|
||||
collection_p = (ecma_collection_t *) jmem_heap_alloc_block (sizeof (ecma_collection_t));
|
||||
|
||||
collection_p->item_count = 0;
|
||||
collection_p->capacity = ECMA_COLLECTION_INITIAL_CAPACITY;
|
||||
const uint32_t size = ECMA_COLLECTION_ALLOCATED_SIZE (ECMA_COLLECTION_INITIAL_CAPACITY);
|
||||
collection_p->buffer_p = (ecma_value_t *) jmem_heap_alloc_block (size);
|
||||
|
||||
return collection_p;
|
||||
} /* ecma_new_collection */
|
||||
|
||||
/**
|
||||
* Deallocate a collection of ecma values without freeing it's values
|
||||
*/
|
||||
inline void JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_collection_destroy (ecma_collection_t *collection_p) /**< value collection */
|
||||
{
|
||||
JERRY_ASSERT (collection_p != NULL);
|
||||
|
||||
jmem_heap_free_block (collection_p->buffer_p, ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity));
|
||||
jmem_heap_free_block (collection_p, sizeof (ecma_collection_t));
|
||||
} /* ecma_collection_destroy */
|
||||
|
||||
/**
|
||||
* Free the object collection elements and deallocate the collection
|
||||
*/
|
||||
void
|
||||
ecma_collection_free_objects (ecma_collection_t *collection_p) /**< value collection */
|
||||
{
|
||||
JERRY_ASSERT (collection_p != NULL);
|
||||
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
if (ecma_is_value_object (buffer_p[i]))
|
||||
{
|
||||
ecma_deref_object (ecma_get_object_from_value (buffer_p[i]));
|
||||
}
|
||||
}
|
||||
|
||||
ecma_collection_destroy (collection_p);
|
||||
} /* ecma_collection_free_objects */
|
||||
|
||||
/**
|
||||
* Free the non-object collection elements and deallocate the collection
|
||||
*/
|
||||
void
|
||||
ecma_collection_free_if_not_object (ecma_collection_t *collection_p) /**< value collection */
|
||||
{
|
||||
JERRY_ASSERT (collection_p != NULL);
|
||||
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_free_value_if_not_object (buffer_p[i]);
|
||||
}
|
||||
|
||||
ecma_collection_destroy (collection_p);
|
||||
} /* ecma_collection_free_if_not_object */
|
||||
|
||||
/**
|
||||
* Free the collection elements and deallocate the collection
|
||||
*/
|
||||
void
|
||||
ecma_collection_free (ecma_collection_t *collection_p) /**< value collection */
|
||||
{
|
||||
JERRY_ASSERT (collection_p != NULL);
|
||||
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_free_value (buffer_p[i]);
|
||||
}
|
||||
|
||||
ecma_collection_destroy (collection_p);
|
||||
} /* ecma_collection_free */
|
||||
|
||||
/**
|
||||
* Append new value to ecma values collection
|
||||
*
|
||||
* Note: The reference count of the values are not increased
|
||||
*/
|
||||
void
|
||||
ecma_collection_push_back (ecma_collection_t *collection_p, /**< value collection */
|
||||
ecma_value_t value) /**< ecma value to append */
|
||||
{
|
||||
JERRY_ASSERT (collection_p != NULL);
|
||||
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
if (JERRY_LIKELY (collection_p->item_count < collection_p->capacity))
|
||||
{
|
||||
buffer_p[collection_p->item_count++] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t new_capacity = collection_p->capacity + ECMA_COLLECTION_GROW_FACTOR;
|
||||
const uint32_t old_size = ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity);
|
||||
const uint32_t new_size = ECMA_COLLECTION_ALLOCATED_SIZE (new_capacity);
|
||||
|
||||
buffer_p = jmem_heap_realloc_block (buffer_p, old_size, new_size);
|
||||
buffer_p[collection_p->item_count++] = value;
|
||||
collection_p->capacity = new_capacity;
|
||||
|
||||
collection_p->buffer_p = buffer_p;
|
||||
} /* ecma_collection_push_back */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
@@ -299,57 +299,25 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
|
||||
return ECMA_NUMBER_ZERO;
|
||||
}
|
||||
|
||||
const lit_utf8_byte_t *str_curr_p = str_p;
|
||||
const lit_utf8_byte_t *str_end_p = str_p + str_size;
|
||||
ecma_char_t code_unit;
|
||||
ecma_string_trim_helper (&str_p, &str_size);
|
||||
const lit_utf8_byte_t *end_p = str_p + (str_size - 1);
|
||||
|
||||
while (str_curr_p < str_end_p)
|
||||
{
|
||||
code_unit = lit_utf8_peek_next (str_curr_p);
|
||||
if (lit_char_is_white_space (code_unit) || lit_char_is_line_terminator (code_unit))
|
||||
{
|
||||
lit_utf8_incr (&str_curr_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const lit_utf8_byte_t *begin_p = str_curr_p;
|
||||
str_curr_p = (lit_utf8_byte_t *) str_end_p;
|
||||
|
||||
while (str_curr_p > str_p)
|
||||
{
|
||||
code_unit = lit_utf8_peek_prev (str_curr_p);
|
||||
if (lit_char_is_white_space (code_unit) || lit_char_is_line_terminator (code_unit))
|
||||
{
|
||||
lit_utf8_decr (&str_curr_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const lit_utf8_byte_t *end_p = str_curr_p - 1;
|
||||
|
||||
if (begin_p > end_p)
|
||||
if (str_size < 1)
|
||||
{
|
||||
return ECMA_NUMBER_ZERO;
|
||||
}
|
||||
|
||||
if ((end_p >= begin_p + 2)
|
||||
&& begin_p[0] == LIT_CHAR_0
|
||||
&& (begin_p[1] == LIT_CHAR_LOWERCASE_X
|
||||
|| begin_p[1] == LIT_CHAR_UPPERCASE_X))
|
||||
if ((end_p >= str_p + 2)
|
||||
&& str_p[0] == LIT_CHAR_0
|
||||
&& (str_p[1] == LIT_CHAR_LOWERCASE_X
|
||||
|| str_p[1] == LIT_CHAR_UPPERCASE_X))
|
||||
{
|
||||
/* Hex literal handling */
|
||||
begin_p += 2;
|
||||
str_p += 2;
|
||||
|
||||
ecma_number_t num = ECMA_NUMBER_ZERO;
|
||||
|
||||
for (const lit_utf8_byte_t * iter_p = begin_p;
|
||||
for (const lit_utf8_byte_t * iter_p = str_p;
|
||||
iter_p <= end_p;
|
||||
iter_p++)
|
||||
{
|
||||
@@ -383,18 +351,18 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
|
||||
|
||||
bool sign = false; /* positive */
|
||||
|
||||
if (*begin_p == LIT_CHAR_PLUS)
|
||||
if (*str_p == LIT_CHAR_PLUS)
|
||||
{
|
||||
begin_p++;
|
||||
str_p++;
|
||||
}
|
||||
else if (*begin_p == LIT_CHAR_MINUS)
|
||||
else if (*str_p == LIT_CHAR_MINUS)
|
||||
{
|
||||
sign = true; /* negative */
|
||||
|
||||
begin_p++;
|
||||
str_p++;
|
||||
}
|
||||
|
||||
if (begin_p > end_p)
|
||||
if (str_p > end_p)
|
||||
{
|
||||
return ecma_number_make_nan ();
|
||||
}
|
||||
@@ -404,7 +372,7 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
|
||||
|
||||
JERRY_ASSERT (strlen ((const char *) infinity_zt_str_p) == 8);
|
||||
|
||||
if ((end_p - begin_p) == (8 - 1) && memcmp (infinity_zt_str_p, begin_p, 8) == 0)
|
||||
if ((end_p - str_p) == (8 - 1) && memcmp (infinity_zt_str_p, str_p, 8) == 0)
|
||||
{
|
||||
return ecma_number_make_infinity (sign);
|
||||
}
|
||||
@@ -415,15 +383,15 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
|
||||
bool digit_seen = false;
|
||||
|
||||
/* Parsing digits before dot (or before end of digits part if there is no dot in number) */
|
||||
while (begin_p <= end_p)
|
||||
while (str_p <= end_p)
|
||||
{
|
||||
int32_t digit_value;
|
||||
|
||||
if (*begin_p >= LIT_CHAR_0
|
||||
&& *begin_p <= LIT_CHAR_9)
|
||||
if (*str_p >= LIT_CHAR_0
|
||||
&& *str_p <= LIT_CHAR_9)
|
||||
{
|
||||
digit_seen = true;
|
||||
digit_value = (*begin_p - LIT_CHAR_0);
|
||||
digit_value = (*str_p - LIT_CHAR_0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -443,29 +411,29 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
|
||||
}
|
||||
}
|
||||
|
||||
begin_p++;
|
||||
str_p++;
|
||||
}
|
||||
|
||||
if (begin_p <= end_p
|
||||
&& *begin_p == LIT_CHAR_DOT)
|
||||
if (str_p <= end_p
|
||||
&& *str_p == LIT_CHAR_DOT)
|
||||
{
|
||||
begin_p++;
|
||||
str_p++;
|
||||
|
||||
if (!digit_seen && begin_p > end_p)
|
||||
if (!digit_seen && str_p > end_p)
|
||||
{
|
||||
return ecma_number_make_nan ();
|
||||
}
|
||||
|
||||
/* Parsing number's part that is placed after dot */
|
||||
while (begin_p <= end_p)
|
||||
while (str_p <= end_p)
|
||||
{
|
||||
int32_t digit_value;
|
||||
|
||||
if (*begin_p >= LIT_CHAR_0
|
||||
&& *begin_p <= LIT_CHAR_9)
|
||||
if (*str_p >= LIT_CHAR_0
|
||||
&& *str_p <= LIT_CHAR_9)
|
||||
{
|
||||
digit_seen = true;
|
||||
digit_value = (*begin_p - LIT_CHAR_0);
|
||||
digit_value = (*str_p - LIT_CHAR_0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -483,7 +451,7 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
|
||||
e--;
|
||||
}
|
||||
|
||||
begin_p++;
|
||||
str_p++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,40 +459,40 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
|
||||
int32_t e_in_lit = 0;
|
||||
bool e_in_lit_sign = false;
|
||||
|
||||
if (begin_p <= end_p
|
||||
&& (*begin_p == LIT_CHAR_LOWERCASE_E
|
||||
|| *begin_p == LIT_CHAR_UPPERCASE_E))
|
||||
if (str_p <= end_p
|
||||
&& (*str_p == LIT_CHAR_LOWERCASE_E
|
||||
|| *str_p == LIT_CHAR_UPPERCASE_E))
|
||||
{
|
||||
begin_p++;
|
||||
str_p++;
|
||||
|
||||
if (!digit_seen || begin_p > end_p)
|
||||
if (!digit_seen || str_p > end_p)
|
||||
{
|
||||
return ecma_number_make_nan ();
|
||||
}
|
||||
|
||||
if (*begin_p == LIT_CHAR_PLUS)
|
||||
if (*str_p == LIT_CHAR_PLUS)
|
||||
{
|
||||
begin_p++;
|
||||
str_p++;
|
||||
}
|
||||
else if (*begin_p == LIT_CHAR_MINUS)
|
||||
else if (*str_p == LIT_CHAR_MINUS)
|
||||
{
|
||||
e_in_lit_sign = true;
|
||||
begin_p++;
|
||||
str_p++;
|
||||
}
|
||||
|
||||
if (begin_p > end_p)
|
||||
if (str_p > end_p)
|
||||
{
|
||||
return ecma_number_make_nan ();
|
||||
}
|
||||
|
||||
while (begin_p <= end_p)
|
||||
while (str_p <= end_p)
|
||||
{
|
||||
int32_t digit_value;
|
||||
|
||||
if (*begin_p >= LIT_CHAR_0
|
||||
&& *begin_p <= LIT_CHAR_9)
|
||||
if (*str_p >= LIT_CHAR_0
|
||||
&& *str_p <= LIT_CHAR_9)
|
||||
{
|
||||
digit_value = (*begin_p - LIT_CHAR_0);
|
||||
digit_value = (*str_p - LIT_CHAR_0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -543,7 +511,7 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
|
||||
return sign ? -ECMA_NUMBER_ZERO : ECMA_NUMBER_ZERO;
|
||||
}
|
||||
|
||||
begin_p++;
|
||||
str_p++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,12 +537,12 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
|
||||
e_sign = false;
|
||||
}
|
||||
|
||||
if (begin_p <= end_p)
|
||||
if (str_p <= end_p)
|
||||
{
|
||||
return ecma_number_make_nan ();
|
||||
}
|
||||
|
||||
JERRY_ASSERT (begin_p == end_p + 1);
|
||||
JERRY_ASSERT (str_p == end_p + 1);
|
||||
|
||||
if (fraction_uint64 == 0)
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-array-object.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-helpers.h"
|
||||
@@ -37,6 +38,13 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create
|
||||
void *info_p) /**< native pointer's type info */
|
||||
{
|
||||
ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
|
||||
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY
|
||||
&& ((ecma_extended_object_t *) obj_p)->u.array.is_fast_mode)
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (obj_p);
|
||||
}
|
||||
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
|
||||
|
||||
bool is_new = (property_p == NULL);
|
||||
@@ -107,6 +115,13 @@ ecma_native_pointer_t *
|
||||
ecma_get_native_pointer_value (ecma_object_t *obj_p, /**< object to get property value from */
|
||||
void *info_p) /**< native pointer's type info */
|
||||
{
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY
|
||||
&& ((ecma_extended_object_t *) obj_p)->u.array.is_fast_mode)
|
||||
{
|
||||
/* Fast access mode array can not have native pointer properties */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
|
||||
|
||||
@@ -149,6 +164,13 @@ bool
|
||||
ecma_delete_native_pointer_property (ecma_object_t *obj_p, /**< object to delete property from */
|
||||
void *info_p) /**< native pointer's type info */
|
||||
{
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY
|
||||
&& ((ecma_extended_object_t *) obj_p)->u.array.is_fast_mode)
|
||||
{
|
||||
/* Fast access mode array can not have native pointer properties */
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
|
||||
|
||||
|
||||
@@ -58,15 +58,9 @@ ecma_number_pack (bool sign, /**< sign */
|
||||
(biased_exp << ECMA_NUMBER_FRACTION_WIDTH) |
|
||||
((uint32_t) fraction));
|
||||
|
||||
union
|
||||
{
|
||||
uint32_t u32_value;
|
||||
ecma_number_t float_value;
|
||||
} u;
|
||||
|
||||
u.u32_value = packed_value;
|
||||
|
||||
return u.float_value;
|
||||
ecma_number_accessor_t u;
|
||||
u.as_uint32_t = packed_value;
|
||||
return u.as_ecma_number_t;
|
||||
} /* ecma_number_pack */
|
||||
|
||||
/**
|
||||
@@ -78,15 +72,9 @@ ecma_number_unpack (ecma_number_t num, /**< ecma-number */
|
||||
uint32_t *biased_exp_p, /**< [out] biased exponent (optional) */
|
||||
uint64_t *fraction_p) /**< [out] fraction (optional) */
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t u32_value;
|
||||
ecma_number_t float_value;
|
||||
} u;
|
||||
|
||||
u.float_value = num;
|
||||
|
||||
uint32_t packed_value = u.u32_value;
|
||||
ecma_number_accessor_t u;
|
||||
u.as_ecma_number_t = num;
|
||||
uint32_t packed_value = u.as_uint32_t;
|
||||
|
||||
if (sign_p != NULL)
|
||||
{
|
||||
@@ -133,15 +121,9 @@ ecma_number_pack (bool sign, /**< sign */
|
||||
JERRY_ASSERT ((biased_exp & ~((1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1)) == 0);
|
||||
JERRY_ASSERT ((fraction & ~((1ull << ECMA_NUMBER_FRACTION_WIDTH) - 1)) == 0);
|
||||
|
||||
union
|
||||
{
|
||||
uint64_t u64_value;
|
||||
ecma_number_t float_value;
|
||||
} u;
|
||||
|
||||
u.u64_value = packed_value;
|
||||
|
||||
return u.float_value;
|
||||
ecma_number_accessor_t u;
|
||||
u.as_uint64_t = packed_value;
|
||||
return u.as_ecma_number_t;
|
||||
} /* ecma_number_pack */
|
||||
|
||||
/**
|
||||
@@ -153,14 +135,9 @@ ecma_number_unpack (ecma_number_t num, /**< ecma-number */
|
||||
uint32_t *biased_exp_p, /**< [out] biased exponent (optional) */
|
||||
uint64_t *fraction_p) /**< [out] fraction (optional) */
|
||||
{
|
||||
union
|
||||
{
|
||||
uint64_t u64_value;
|
||||
ecma_number_t float_value;
|
||||
} u;
|
||||
u.float_value = num;
|
||||
|
||||
uint64_t packed_value = u.u64_value;
|
||||
ecma_number_accessor_t u;
|
||||
u.as_ecma_number_t = num;
|
||||
uint64_t packed_value = u.as_uint64_t;
|
||||
|
||||
if (sign_p != NULL)
|
||||
{
|
||||
@@ -240,7 +217,7 @@ ecma_number_get_sign_field (ecma_number_t num) /**< ecma-number */
|
||||
fraction is filled with anything but not all zero bits,
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool JERRY_ATTR_ALWAYS_INLINE
|
||||
extern inline bool JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_number_is_nan (ecma_number_t num) /**< ecma-number */
|
||||
{
|
||||
bool is_nan = (num != num);
|
||||
@@ -267,9 +244,14 @@ ecma_number_is_nan (ecma_number_t num) /**< ecma-number */
|
||||
ecma_number_t
|
||||
ecma_number_make_nan (void)
|
||||
{
|
||||
return ecma_number_pack (false,
|
||||
(1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1u,
|
||||
1u);
|
||||
/* IEEE754 QNaN = sign bit: 0, exponent: all 1 bits, fraction: 1....0 */
|
||||
ecma_number_accessor_t f;
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
f.as_uint64_t = 0x7ff8000000000000ull; /* double QNaN, same as the C99 nan("") returns. */
|
||||
#else /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
f.as_uint32_t = 0x7fc00000u; /* float QNaN, same as the C99 nanf("") returns. */
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
return f.as_ecma_number_t;
|
||||
} /* ecma_number_make_nan */
|
||||
|
||||
/**
|
||||
@@ -282,9 +264,14 @@ ecma_number_t
|
||||
ecma_number_make_infinity (bool sign) /**< true - for negative Infinity,
|
||||
false - for positive Infinity */
|
||||
{
|
||||
return ecma_number_pack (sign,
|
||||
(1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1u,
|
||||
0u);
|
||||
/* IEEE754 INF = sign bit: sign, exponent: all 1 bits, fraction: 0....0 */
|
||||
ecma_number_accessor_t f;
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
f.as_uint64_t = sign ? 0xfff0000000000000ull : 0x7ff0000000000000ull;
|
||||
#else /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
f.as_uint32_t = sign ? 0xff800000u : 0x7f800000u;
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
return f.as_ecma_number_t;
|
||||
} /* ecma_number_make_infinity */
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -289,7 +289,7 @@ ecma_is_value_float_number (ecma_value_t value) /**< ecma value */
|
||||
* @return true - if the value contains ecma-number value,
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
|
||||
extern inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_is_value_number (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
return (ecma_is_value_integer_number (value)
|
||||
@@ -305,7 +305,7 @@ JERRY_STATIC_ASSERT ((ECMA_TYPE_STRING | 0x4) == ECMA_TYPE_DIRECT_STRING,
|
||||
* @return true - if the value contains ecma-string value,
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
|
||||
extern inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_is_value_string (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
return ((value & (ECMA_VALUE_TYPE_MASK - 0x4)) == ECMA_TYPE_STRING);
|
||||
@@ -389,18 +389,6 @@ ecma_is_value_error_reference (ecma_value_t value) /**< ecma value */
|
||||
return (ecma_get_value_type_field (value) == ECMA_TYPE_ERROR);
|
||||
} /* ecma_is_value_error_reference */
|
||||
|
||||
/**
|
||||
* Check if the value is an aligned pointer.
|
||||
*
|
||||
* @return true - if the value contains an aligned pointer,
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_is_value_pointer (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
return (ecma_get_value_type_field (value) == ECMA_TYPE_POINTER);
|
||||
} /* ecma_is_value_pointer */
|
||||
|
||||
/**
|
||||
* Debug assertion that specified value's type is one of ECMA-defined
|
||||
* script-visible types, i.e.: undefined, null, boolean, number, string, object.
|
||||
@@ -459,12 +447,23 @@ ecma_create_float_number (ecma_number_t ecma_number) /**< value of the float num
|
||||
return ecma_pointer_to_ecma_value (ecma_num_p) | ECMA_TYPE_FLOAT;
|
||||
} /* ecma_create_float_number */
|
||||
|
||||
/**
|
||||
* Encode float number without checks.
|
||||
*
|
||||
* @return ecma-value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_make_float_value (ecma_number_t *ecma_num_p) /**< pointer to the float number */
|
||||
{
|
||||
return ecma_pointer_to_ecma_value (ecma_num_p) | ECMA_TYPE_FLOAT;
|
||||
} /* ecma_make_float_value */
|
||||
|
||||
/**
|
||||
* Create a new NaN value.
|
||||
*
|
||||
* @return ecma-value
|
||||
*/
|
||||
inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
|
||||
extern inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_make_nan_value (void)
|
||||
{
|
||||
return ecma_create_float_number (ecma_number_make_nan ());
|
||||
@@ -478,26 +477,12 @@ ecma_make_nan_value (void)
|
||||
static inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_is_number_equal_to_positive_zero (ecma_number_t ecma_number) /**< number */
|
||||
{
|
||||
ecma_number_accessor_t u;
|
||||
u.as_ecma_number_t = ecma_number;
|
||||
#if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
union
|
||||
{
|
||||
uint32_t u32_value;
|
||||
ecma_number_t float_value;
|
||||
} u;
|
||||
|
||||
u.float_value = ecma_number;
|
||||
|
||||
return u.u32_value == 0;
|
||||
return u.as_uint32_t == 0;
|
||||
#else /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
union
|
||||
{
|
||||
uint64_t u64_value;
|
||||
ecma_number_t float_value;
|
||||
} u;
|
||||
|
||||
u.float_value = ecma_number;
|
||||
|
||||
return u.u64_value == 0;
|
||||
return u.as_uint64_t == 0;
|
||||
#endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
} /* ecma_is_number_equal_to_positive_zero */
|
||||
|
||||
@@ -647,29 +632,6 @@ ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p) /**<
|
||||
return ecma_pointer_to_ecma_value (error_ref_p) | ECMA_TYPE_ERROR;
|
||||
} /* ecma_make_error_reference_value */
|
||||
|
||||
/**
|
||||
* Create an ecma value from an aligned pointer
|
||||
*
|
||||
* @return ecma-value representation of the aligned pointer
|
||||
*/
|
||||
inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_make_pointer_value (const void *any_p) /**< any aligned pointer */
|
||||
{
|
||||
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
|
||||
|
||||
uintptr_t uint_ptr = (uintptr_t) any_p;
|
||||
JERRY_ASSERT ((uint_ptr & ECMA_VALUE_TYPE_MASK) == 0);
|
||||
return ((ecma_value_t) uint_ptr) | ECMA_TYPE_POINTER;
|
||||
|
||||
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
|
||||
jmem_cpointer_t ptr_cp;
|
||||
ECMA_SET_POINTER (ptr_cp, any_p);
|
||||
return (((ecma_value_t) ptr_cp) << ECMA_VALUE_SHIFT) | ECMA_TYPE_POINTER;
|
||||
|
||||
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
} /* ecma_make_pointer_value */
|
||||
|
||||
/**
|
||||
* Get integer value from an integer ecma value
|
||||
*
|
||||
@@ -696,6 +658,19 @@ ecma_get_float_from_value (ecma_value_t value) /**< ecma value */
|
||||
return *(ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
|
||||
} /* ecma_get_float_from_value */
|
||||
|
||||
/**
|
||||
* Get floating point value pointer from an ecma value
|
||||
*
|
||||
* @return floating point value
|
||||
*/
|
||||
inline ecma_number_t * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_get_pointer_from_float_value (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);
|
||||
|
||||
return (ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
|
||||
} /* ecma_get_pointer_from_float_value */
|
||||
|
||||
/**
|
||||
* Get floating point value from an ecma value
|
||||
*
|
||||
@@ -789,23 +764,6 @@ ecma_get_error_reference_from_value (ecma_value_t value) /**< ecma value */
|
||||
return (ecma_error_reference_t *) ecma_get_pointer_from_ecma_value (value);
|
||||
} /* ecma_get_error_reference_from_value */
|
||||
|
||||
/**
|
||||
* Get an aligned pointer from an ecma value
|
||||
*
|
||||
* @return pointer value
|
||||
*/
|
||||
inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_get_pointer_from_value (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_POINTER);
|
||||
|
||||
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
|
||||
return (void *) (uintptr_t) ((value) & ~ECMA_VALUE_TYPE_MASK);
|
||||
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
return ECMA_GET_POINTER (void, value >> ECMA_VALUE_SHIFT);
|
||||
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
} /* ecma_get_pointer_from_value */
|
||||
|
||||
/**
|
||||
* Invert a boolean value
|
||||
*
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmahelpers Helpers for operations with ECMA data types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The type of ecma error and ecma collection chunk must be the same.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (ECMA_TYPE_ERROR == ECMA_TYPE_POINTER,
|
||||
ecma_type_error_must_be_the_same_as_ecma_type_pointer);
|
||||
|
||||
/**
|
||||
* Allocate a collection of ecma values.
|
||||
*
|
||||
* @return pointer to the collection's header
|
||||
*/
|
||||
ecma_collection_header_t *
|
||||
ecma_new_values_collection (void)
|
||||
{
|
||||
ecma_collection_header_t *header_p;
|
||||
header_p = (ecma_collection_header_t *) jmem_pools_alloc (sizeof (ecma_collection_header_t));
|
||||
|
||||
header_p->item_count = 0;
|
||||
header_p->first_chunk_cp = ECMA_NULL_POINTER;
|
||||
header_p->last_chunk_cp = ECMA_NULL_POINTER;
|
||||
|
||||
return header_p;
|
||||
} /* ecma_new_values_collection */
|
||||
|
||||
/**
|
||||
* Free the collection of ecma values.
|
||||
*/
|
||||
void
|
||||
ecma_free_values_collection (ecma_collection_header_t *header_p, /**< collection's header */
|
||||
uint32_t flags) /**< combination of ecma_collection_flag_t flags */
|
||||
{
|
||||
ecma_collection_chunk_t *chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t,
|
||||
header_p->first_chunk_cp);
|
||||
|
||||
jmem_pools_free (header_p, sizeof (ecma_collection_header_t));
|
||||
|
||||
if (chunk_p == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
ecma_value_t *item_p = chunk_p->items;
|
||||
|
||||
JERRY_ASSERT (!ecma_is_value_pointer (*item_p));
|
||||
|
||||
do
|
||||
{
|
||||
if (!(flags & ECMA_COLLECTION_NO_COPY)
|
||||
&& (!ecma_is_value_object (*item_p)
|
||||
|| !(flags & ECMA_COLLECTION_NO_REF_OBJECTS)))
|
||||
{
|
||||
ecma_free_value (*item_p);
|
||||
}
|
||||
|
||||
item_p++;
|
||||
}
|
||||
while (!ecma_is_value_pointer (*item_p));
|
||||
|
||||
ecma_collection_chunk_t *next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (*item_p);
|
||||
|
||||
jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t));
|
||||
|
||||
chunk_p = next_chunk_p;
|
||||
}
|
||||
while (chunk_p != NULL);
|
||||
} /* ecma_free_values_collection */
|
||||
|
||||
/**
|
||||
* Append new value to ecma values collection
|
||||
*/
|
||||
void
|
||||
ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< collection's header */
|
||||
ecma_value_t value, /**< ecma value to append */
|
||||
uint32_t flags) /**< combination of ecma_collection_flag_t flags */
|
||||
{
|
||||
ecma_length_t item_index;
|
||||
ecma_collection_chunk_t *chunk_p;
|
||||
|
||||
if (JERRY_UNLIKELY (header_p->item_count == 0))
|
||||
{
|
||||
item_index = 0;
|
||||
chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t));
|
||||
|
||||
ECMA_SET_POINTER (header_p->first_chunk_cp, chunk_p);
|
||||
header_p->last_chunk_cp = header_p->first_chunk_cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
item_index = header_p->item_count % ECMA_COLLECTION_CHUNK_ITEMS;
|
||||
|
||||
chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
|
||||
header_p->last_chunk_cp);
|
||||
|
||||
if (JERRY_UNLIKELY (item_index == 0))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_pointer (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS])
|
||||
&& ecma_get_pointer_from_value (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS]) == NULL);
|
||||
|
||||
ecma_collection_chunk_t *next_chunk_p;
|
||||
next_chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t));
|
||||
|
||||
chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS] = ecma_make_pointer_value ((void *) next_chunk_p);
|
||||
ECMA_SET_POINTER (header_p->last_chunk_cp, next_chunk_p);
|
||||
|
||||
chunk_p = next_chunk_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_pointer (chunk_p->items[item_index])
|
||||
&& ecma_get_pointer_from_value (chunk_p->items[item_index]) == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & ECMA_COLLECTION_NO_COPY)
|
||||
&& (!ecma_is_value_object (value)
|
||||
|| !(flags & ECMA_COLLECTION_NO_REF_OBJECTS)))
|
||||
{
|
||||
value = ecma_copy_value (value);
|
||||
}
|
||||
|
||||
chunk_p->items[item_index] = value;
|
||||
chunk_p->items[item_index + 1] = ecma_make_pointer_value (NULL);
|
||||
header_p->item_count++;
|
||||
} /* ecma_append_to_values_collection */
|
||||
|
||||
/**
|
||||
* Initialize new collection iterator for the collection
|
||||
*
|
||||
* @return pointer to the first item
|
||||
*/
|
||||
ecma_value_t *
|
||||
ecma_collection_iterator_init (ecma_collection_header_t *header_p) /**< header of collection */
|
||||
{
|
||||
if (JERRY_UNLIKELY (!header_p || header_p->item_count == 0))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ecma_collection_chunk_t *chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
|
||||
header_p->first_chunk_cp);
|
||||
|
||||
return chunk_p->items;
|
||||
} /* ecma_collection_iterator_init */
|
||||
|
||||
/**
|
||||
* Move collection iterator to next element if there is any.
|
||||
*
|
||||
* @return pointer to the next item
|
||||
*/
|
||||
ecma_value_t *
|
||||
ecma_collection_iterator_next (ecma_value_t *ecma_value_p) /**< current value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_value_p != NULL);
|
||||
|
||||
ecma_value_p++;
|
||||
|
||||
if (JERRY_UNLIKELY (ecma_is_value_pointer (*ecma_value_p)))
|
||||
{
|
||||
ecma_value_p = ((ecma_collection_chunk_t *) ecma_get_pointer_from_value (*ecma_value_p))->items;
|
||||
|
||||
JERRY_ASSERT (ecma_value_p == NULL || !ecma_is_value_pointer (*ecma_value_p));
|
||||
return ecma_value_p;
|
||||
}
|
||||
|
||||
return ecma_value_p;
|
||||
} /* ecma_collection_iterator_next */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
+140
-328
@@ -89,10 +89,9 @@ ecma_create_object (ecma_object_t *prototype_object_p, /**< pointer to prototybe
|
||||
|
||||
ecma_init_gc_info (new_object_p);
|
||||
|
||||
new_object_p->property_list_or_bound_object_cp = JMEM_CP_NULL;
|
||||
new_object_p->u1.property_list_cp = JMEM_CP_NULL;
|
||||
|
||||
ECMA_SET_POINTER (new_object_p->prototype_or_outer_reference_cp,
|
||||
prototype_object_p);
|
||||
ECMA_SET_POINTER (new_object_p->u2.prototype_cp, prototype_object_p);
|
||||
|
||||
return new_object_p;
|
||||
} /* ecma_create_object */
|
||||
@@ -117,10 +116,9 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer
|
||||
|
||||
ecma_init_gc_info (new_lexical_environment_p);
|
||||
|
||||
new_lexical_environment_p->property_list_or_bound_object_cp = JMEM_CP_NULL;
|
||||
new_lexical_environment_p->u1.property_list_cp = JMEM_CP_NULL;
|
||||
|
||||
ECMA_SET_POINTER (new_lexical_environment_p->prototype_or_outer_reference_cp,
|
||||
outer_lexical_environment_p);
|
||||
ECMA_SET_POINTER (new_lexical_environment_p->u2.outer_reference_cp, outer_lexical_environment_p);
|
||||
|
||||
return new_lexical_environment_p;
|
||||
} /* ecma_create_decl_lex_env */
|
||||
@@ -156,11 +154,10 @@ ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< out
|
||||
|
||||
ecma_init_gc_info (new_lexical_environment_p);
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (new_lexical_environment_p->property_list_or_bound_object_cp,
|
||||
ECMA_SET_NON_NULL_POINTER (new_lexical_environment_p->u1.bound_object_cp,
|
||||
binding_obj_p);
|
||||
|
||||
ECMA_SET_POINTER (new_lexical_environment_p->prototype_or_outer_reference_cp,
|
||||
outer_lexical_environment_p);
|
||||
ECMA_SET_POINTER (new_lexical_environment_p->u2.outer_reference_cp, outer_lexical_environment_p);
|
||||
|
||||
return new_lexical_environment_p;
|
||||
} /* ecma_create_object_lex_env */
|
||||
@@ -230,22 +227,6 @@ ecma_get_object_type (const ecma_object_t *object_p) /**< object */
|
||||
return (ecma_object_type_t) (object_p->type_flags_refs & ECMA_OBJECT_TYPE_MASK);
|
||||
} /* ecma_get_object_type */
|
||||
|
||||
/**
|
||||
* Get object's prototype.
|
||||
*
|
||||
* @return pointer to the prototype object
|
||||
* NULL if there is no prototype
|
||||
*/
|
||||
inline ecma_object_t *JERRY_ATTR_PURE
|
||||
ecma_get_object_prototype (const ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (object_p));
|
||||
|
||||
return ECMA_GET_POINTER (ecma_object_t,
|
||||
object_p->prototype_or_outer_reference_cp);
|
||||
} /* ecma_get_object_prototype */
|
||||
|
||||
/**
|
||||
* Check if the object is a built-in object
|
||||
*
|
||||
@@ -317,40 +298,6 @@ ecma_get_lex_env_type (const ecma_object_t *object_p) /**< lexical environment *
|
||||
return (ecma_lexical_environment_type_t) (object_p->type_flags_refs & ECMA_OBJECT_TYPE_MASK);
|
||||
} /* ecma_get_lex_env_type */
|
||||
|
||||
/**
|
||||
* Get outer reference of lexical environment.
|
||||
*
|
||||
* @return pointer to the outer reference
|
||||
*/
|
||||
inline ecma_object_t *JERRY_ATTR_PURE
|
||||
ecma_get_lex_env_outer_reference (const ecma_object_t *object_p) /**< lexical environment */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
JERRY_ASSERT (ecma_is_lexical_environment (object_p));
|
||||
|
||||
return ECMA_GET_POINTER (ecma_object_t,
|
||||
object_p->prototype_or_outer_reference_cp);
|
||||
} /* ecma_get_lex_env_outer_reference */
|
||||
|
||||
/**
|
||||
* Get object's/lexical environment's property list.
|
||||
*
|
||||
* See also:
|
||||
* ecma_op_object_get_property_names
|
||||
*
|
||||
* @return pointer to the head of the property list
|
||||
*/
|
||||
inline ecma_property_header_t *JERRY_ATTR_PURE
|
||||
ecma_get_property_list (const ecma_object_t *object_p) /**< object or lexical environment */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
JERRY_ASSERT (!ecma_is_lexical_environment (object_p)
|
||||
|| ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
|
||||
|
||||
return ECMA_GET_POINTER (ecma_property_header_t,
|
||||
object_p->property_list_or_bound_object_cp);
|
||||
} /* ecma_get_property_list */
|
||||
|
||||
/**
|
||||
* Get lexical environment's bound object.
|
||||
*
|
||||
@@ -368,8 +315,7 @@ ecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-boun
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
#endif /* ENABLED (JERRY_ES2015_CLASS) */
|
||||
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_object_t,
|
||||
object_p->property_list_or_bound_object_cp);
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u1.bound_object_cp);
|
||||
} /* ecma_get_lex_env_binding_object */
|
||||
|
||||
/**
|
||||
@@ -387,14 +333,18 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
|
||||
* if this field is non-NULL */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);
|
||||
JERRY_ASSERT (name_p != NULL);
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
|
||||
jmem_cpointer_t *property_list_head_p = &object_p->property_list_or_bound_object_cp;
|
||||
jmem_cpointer_t *property_list_head_p = &object_p->u1.property_list_cp;
|
||||
|
||||
if (*property_list_head_p != ECMA_NULL_POINTER)
|
||||
{
|
||||
/* If the first entry is free (deleted), it is reused. */
|
||||
ecma_property_header_t *first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
|
||||
*property_list_head_p);
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
bool has_hashmap = false;
|
||||
|
||||
if (first_property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
@@ -404,6 +354,7 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
|
||||
*property_list_head_p);
|
||||
has_hashmap = true;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (first_property_p));
|
||||
|
||||
@@ -411,19 +362,10 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
|
||||
{
|
||||
ecma_property_pair_t *first_property_pair_p = (ecma_property_pair_t *) first_property_p;
|
||||
|
||||
if (name_p == NULL)
|
||||
{
|
||||
first_property_pair_p->names_cp[0] = ECMA_NULL_POINTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_property_t name_type;
|
||||
first_property_pair_p->names_cp[0] = ecma_string_to_property_name (name_p,
|
||||
&name_type);
|
||||
type_and_flags = (ecma_property_t) (type_and_flags | name_type);
|
||||
}
|
||||
|
||||
first_property_p->types[0] = type_and_flags;
|
||||
ecma_property_t name_type;
|
||||
first_property_pair_p->names_cp[0] = ecma_string_to_property_name (name_p,
|
||||
&name_type);
|
||||
first_property_p->types[0] = (ecma_property_t) (type_and_flags | name_type);
|
||||
|
||||
ecma_property_t *property_p = first_property_p->types + 0;
|
||||
|
||||
@@ -436,18 +378,20 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
first_property_pair_p->values[0] = value;
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
/* The property must be fully initialized before ecma_property_hashmap_insert
|
||||
* is called, because the insert operation may reallocate the hashmap, and
|
||||
* that triggers garbage collection which scans all properties of all objects.
|
||||
* A not fully initialized but queued property may cause a crash. */
|
||||
|
||||
if (has_hashmap && name_p != NULL)
|
||||
if (has_hashmap)
|
||||
{
|
||||
ecma_property_hashmap_insert (object_p,
|
||||
name_p,
|
||||
first_property_pair_p,
|
||||
0);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
return first_property_pair_p->values + 0;
|
||||
}
|
||||
@@ -458,7 +402,8 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
/* Need to query property_list_head_p again and recheck the existennce
|
||||
* of property hasmap, because ecma_alloc_property_pair may delete them. */
|
||||
property_list_head_p = &object_p->property_list_or_bound_object_cp;
|
||||
property_list_head_p = &object_p->u1.property_list_cp;
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
bool has_hashmap = false;
|
||||
|
||||
if (*property_list_head_p != ECMA_NULL_POINTER)
|
||||
@@ -472,25 +417,18 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
|
||||
has_hashmap = true;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
/* Just copy the previous value (no need to decompress, compress). */
|
||||
first_property_pair_p->header.next_property_cp = *property_list_head_p;
|
||||
first_property_pair_p->header.types[0] = ECMA_PROPERTY_TYPE_DELETED;
|
||||
first_property_pair_p->names_cp[0] = LIT_INTERNAL_MAGIC_STRING_DELETED;
|
||||
|
||||
if (name_p == NULL)
|
||||
{
|
||||
first_property_pair_p->names_cp[1] = ECMA_NULL_POINTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_property_t name_type;
|
||||
first_property_pair_p->names_cp[1] = ecma_string_to_property_name (name_p,
|
||||
&name_type);
|
||||
type_and_flags = (ecma_property_t) (type_and_flags | name_type);
|
||||
}
|
||||
ecma_property_t name_type;
|
||||
first_property_pair_p->names_cp[1] = ecma_string_to_property_name (name_p,
|
||||
&name_type);
|
||||
|
||||
first_property_pair_p->header.types[1] = type_and_flags;
|
||||
first_property_pair_p->header.types[1] = (ecma_property_t) (type_and_flags | name_type);
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (*property_list_head_p, &first_property_pair_p->header);
|
||||
|
||||
@@ -505,15 +443,17 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
first_property_pair_p->values[1] = value;
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
/* See the comment before the other ecma_property_hashmap_insert above. */
|
||||
|
||||
if (has_hashmap && name_p != NULL)
|
||||
if (has_hashmap)
|
||||
{
|
||||
ecma_property_hashmap_insert (object_p,
|
||||
name_p,
|
||||
first_property_pair_p,
|
||||
1);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
return first_property_pair_p->values + 1;
|
||||
} /* ecma_create_property */
|
||||
@@ -532,6 +472,9 @@ ecma_create_named_data_property (ecma_object_t *object_p, /**< object */
|
||||
* if this field is non-NULL */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL && name_p != NULL);
|
||||
JERRY_ASSERT (ecma_is_lexical_environment (object_p)
|
||||
|| ecma_get_object_type (object_p) != ECMA_OBJECT_TYPE_ARRAY
|
||||
|| !((ecma_extended_object_t *) object_p)->u.array.is_fast_mode);
|
||||
JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL);
|
||||
JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE) == 0);
|
||||
|
||||
@@ -558,6 +501,9 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */
|
||||
* if this field is non-NULL */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL && name_p != NULL);
|
||||
JERRY_ASSERT (ecma_is_lexical_environment (object_p)
|
||||
|| ecma_get_object_type (object_p) != ECMA_OBJECT_TYPE_ARRAY
|
||||
|| !((ecma_extended_object_t *) object_p)->u.array.is_fast_mode);
|
||||
JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL);
|
||||
JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE) == 0);
|
||||
|
||||
@@ -567,12 +513,12 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */
|
||||
#if ENABLED (JERRY_CPOINTER_32_BIT)
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
getter_setter_pair_p = jmem_pools_alloc (sizeof (ecma_getter_setter_pointers_t));
|
||||
ECMA_SET_POINTER (getter_setter_pair_p->getter_p, get_p);
|
||||
ECMA_SET_POINTER (getter_setter_pair_p->setter_p, set_p);
|
||||
ECMA_SET_POINTER (value.getter_setter_pair_cp, getter_setter_pair_p);
|
||||
ECMA_SET_POINTER (getter_setter_pair_p->getter_cp, get_p);
|
||||
ECMA_SET_POINTER (getter_setter_pair_p->setter_cp, set_p);
|
||||
ECMA_SET_NON_NULL_POINTER (value.getter_setter_pair_cp, getter_setter_pair_p);
|
||||
#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
ECMA_SET_POINTER (value.getter_setter_pair.getter_p, get_p);
|
||||
ECMA_SET_POINTER (value.getter_setter_pair.setter_p, set_p);
|
||||
ECMA_SET_POINTER (value.getter_setter_pair.getter_cp, get_p);
|
||||
ECMA_SET_POINTER (value.getter_setter_pair.setter_cp, set_p);
|
||||
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
|
||||
return ecma_create_property (object_p, name_p, type_and_flags, value, out_prop_p);
|
||||
@@ -590,6 +536,9 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
{
|
||||
JERRY_ASSERT (obj_p != NULL);
|
||||
JERRY_ASSERT (name_p != NULL);
|
||||
JERRY_ASSERT (ecma_is_lexical_environment (obj_p)
|
||||
|| ecma_get_object_type (obj_p) != ECMA_OBJECT_TYPE_ARRAY
|
||||
|| !((ecma_extended_object_t *) obj_p)->u.array.is_fast_mode);
|
||||
|
||||
ecma_property_t *property_p = NULL;
|
||||
|
||||
@@ -601,31 +550,34 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
}
|
||||
#endif /* ENABLED (JERRY_LCACHE) */
|
||||
|
||||
ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_p);
|
||||
jmem_cpointer_t prop_iter_cp = obj_p->u1.property_list_cp;
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
if (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
jmem_cpointer_t property_real_name_cp;
|
||||
property_p = ecma_property_hashmap_find ((ecma_property_hashmap_t *) prop_iter_p,
|
||||
name_p,
|
||||
&property_real_name_cp);
|
||||
|
||||
#if ENABLED (JERRY_LCACHE)
|
||||
if (property_p != NULL
|
||||
&& !ecma_is_property_lcached (property_p))
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
|
||||
prop_iter_cp);
|
||||
if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
ecma_lcache_insert (obj_p, property_real_name_cp, property_p);
|
||||
}
|
||||
jmem_cpointer_t property_real_name_cp;
|
||||
property_p = ecma_property_hashmap_find ((ecma_property_hashmap_t *) prop_iter_p,
|
||||
name_p,
|
||||
&property_real_name_cp);
|
||||
#if ENABLED (JERRY_LCACHE)
|
||||
if (property_p != NULL
|
||||
&& !ecma_is_property_lcached (property_p))
|
||||
{
|
||||
ecma_lcache_insert (obj_p, property_real_name_cp, property_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_LCACHE) */
|
||||
|
||||
return property_p;
|
||||
return property_p;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
uint32_t steps = 0;
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
jmem_cpointer_t property_name_cp = ECMA_NULL_POINTER;
|
||||
|
||||
if (ECMA_IS_DIRECT_STRING (name_p))
|
||||
@@ -635,8 +587,11 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
|
||||
JERRY_ASSERT (prop_name_type > 0);
|
||||
|
||||
while (prop_iter_p != NULL)
|
||||
while (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
|
||||
prop_iter_cp);
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
@@ -659,16 +614,19 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
break;
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
steps++;
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (prop_iter_p != NULL)
|
||||
while (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
|
||||
prop_iter_cp);
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
@@ -697,17 +655,19 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
steps++;
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
if (steps >= (ECMA_PROPERTY_HASMAP_MINIMUM_SIZE / 2))
|
||||
{
|
||||
ecma_property_hashmap_create (obj_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
#if ENABLED (JERRY_LCACHE)
|
||||
if (property_p != NULL
|
||||
@@ -735,6 +695,9 @@ ecma_get_named_data_property (ecma_object_t *obj_p, /**< object to find property
|
||||
{
|
||||
JERRY_ASSERT (obj_p != NULL);
|
||||
JERRY_ASSERT (name_p != NULL);
|
||||
JERRY_ASSERT (ecma_is_lexical_environment (obj_p)
|
||||
|| ecma_get_object_type (obj_p) != ECMA_OBJECT_TYPE_ARRAY
|
||||
|| !((ecma_extended_object_t *) obj_p)->u.array.is_fast_mode);
|
||||
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
|
||||
|
||||
@@ -765,8 +728,8 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
|
||||
{
|
||||
#if ENABLED (JERRY_CPOINTER_32_BIT)
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
|
||||
ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp);
|
||||
getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t,
|
||||
ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp);
|
||||
jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
|
||||
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
break;
|
||||
@@ -805,21 +768,32 @@ void
|
||||
ecma_delete_property (ecma_object_t *object_p, /**< object */
|
||||
ecma_property_value_t *prop_value_p) /**< property value reference */
|
||||
{
|
||||
ecma_property_header_t *cur_prop_p = ecma_get_property_list (object_p);
|
||||
jmem_cpointer_t cur_prop_cp = object_p->u1.property_list_cp;
|
||||
|
||||
ecma_property_header_t *prev_prop_p = NULL;
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
ecma_property_hashmap_delete_status hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_NO_HASHMAP;
|
||||
|
||||
if (cur_prop_p != NULL && cur_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
if (cur_prop_cp != JMEM_CP_NULL)
|
||||
{
|
||||
prev_prop_p = cur_prop_p;
|
||||
cur_prop_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
cur_prop_p->next_property_cp);
|
||||
hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP;
|
||||
}
|
||||
ecma_property_header_t *cur_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
|
||||
cur_prop_cp);
|
||||
|
||||
while (true)
|
||||
if (cur_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
prev_prop_p = cur_prop_p;
|
||||
cur_prop_cp = cur_prop_p->next_property_cp;
|
||||
hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
while (cur_prop_cp != JMEM_CP_NULL)
|
||||
{
|
||||
JERRY_ASSERT (cur_prop_p != NULL);
|
||||
ecma_property_header_t *cur_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
|
||||
cur_prop_cp);
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (cur_prop_p));
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) cur_prop_p;
|
||||
@@ -830,12 +804,14 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (cur_prop_p->types[i]) != ECMA_PROPERTY_TYPE_SPECIAL);
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP)
|
||||
{
|
||||
hashmap_status = ecma_property_hashmap_delete (object_p,
|
||||
prop_pair_p->names_cp[i],
|
||||
cur_prop_p->types + i);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
ecma_free_property (object_p, prop_pair_p->names_cp[i], cur_prop_p->types + i);
|
||||
cur_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED;
|
||||
@@ -845,12 +821,14 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
|
||||
|
||||
if (cur_prop_p->types[1 - i] != ECMA_PROPERTY_TYPE_DELETED)
|
||||
{
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
/* The other property is still valid. */
|
||||
if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP)
|
||||
{
|
||||
ecma_property_hashmap_free (object_p);
|
||||
ecma_property_hashmap_create (object_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -858,7 +836,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
|
||||
|
||||
if (prev_prop_p == NULL)
|
||||
{
|
||||
object_p->property_list_or_bound_object_cp = cur_prop_p->next_property_cp;
|
||||
object_p->u1.property_list_cp = cur_prop_p->next_property_cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -867,159 +845,22 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
|
||||
|
||||
ecma_dealloc_property_pair ((ecma_property_pair_t *) cur_prop_p);
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP)
|
||||
{
|
||||
ecma_property_hashmap_free (object_p);
|
||||
ecma_property_hashmap_create (object_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
prev_prop_p = cur_prop_p;
|
||||
cur_prop_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
cur_prop_p->next_property_cp);
|
||||
cur_prop_cp = cur_prop_p->next_property_cp;
|
||||
}
|
||||
} /* ecma_delete_property */
|
||||
|
||||
/**
|
||||
* Low level delete of array items from new_length to old_length
|
||||
*
|
||||
* Note: new_length must be less than old_length
|
||||
*
|
||||
* @return the updated value of new_length
|
||||
*/
|
||||
uint32_t
|
||||
ecma_delete_array_properties (ecma_object_t *object_p, /**< object */
|
||||
uint32_t new_length, /**< new length */
|
||||
uint32_t old_length) /**< old length */
|
||||
{
|
||||
JERRY_ASSERT (new_length < old_length);
|
||||
|
||||
/* First the minimum value of new_length is updated. */
|
||||
ecma_property_header_t *current_prop_p = ecma_get_property_list (object_p);
|
||||
|
||||
if (current_prop_p == NULL)
|
||||
{
|
||||
return new_length;
|
||||
}
|
||||
|
||||
if (current_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
current_prop_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
current_prop_p->next_property_cp);
|
||||
}
|
||||
|
||||
while (current_prop_p != NULL)
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (current_prop_p));
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) current_prop_p;
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
{
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (current_prop_p->types[i])
|
||||
&& !ecma_is_property_configurable (current_prop_p->types[i]))
|
||||
{
|
||||
uint32_t index = ecma_string_get_property_index (current_prop_p->types[i],
|
||||
prop_pair_p->names_cp[i]);
|
||||
|
||||
if (index < old_length && index >= new_length)
|
||||
{
|
||||
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
|
||||
|
||||
new_length = index + 1;
|
||||
|
||||
if (new_length == old_length)
|
||||
{
|
||||
/* Early return. */
|
||||
return new_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current_prop_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
current_prop_p->next_property_cp);
|
||||
}
|
||||
|
||||
/* Second all properties between new_length and old_length are deleted. */
|
||||
current_prop_p = ecma_get_property_list (object_p);
|
||||
ecma_property_header_t *prev_prop_p = NULL;
|
||||
ecma_property_hashmap_delete_status hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_NO_HASHMAP;
|
||||
|
||||
if (current_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
prev_prop_p = current_prop_p;
|
||||
current_prop_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
current_prop_p->next_property_cp);
|
||||
hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP;
|
||||
}
|
||||
|
||||
while (current_prop_p != NULL)
|
||||
{
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) current_prop_p;
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
{
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (current_prop_p->types[i])
|
||||
&& ecma_is_property_configurable (current_prop_p->types[i]))
|
||||
{
|
||||
uint32_t index = ecma_string_get_property_index (current_prop_p->types[i],
|
||||
prop_pair_p->names_cp[i]);
|
||||
|
||||
if (index < old_length && index >= new_length)
|
||||
{
|
||||
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
|
||||
|
||||
if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP)
|
||||
{
|
||||
hashmap_status = ecma_property_hashmap_delete (object_p,
|
||||
prop_pair_p->names_cp[i],
|
||||
current_prop_p->types + i);
|
||||
}
|
||||
|
||||
ecma_free_property (object_p, prop_pair_p->names_cp[i], current_prop_p->types + i);
|
||||
current_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED;
|
||||
prop_pair_p->names_cp[i] = LIT_INTERNAL_MAGIC_STRING_DELETED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (current_prop_p->types[0] == ECMA_PROPERTY_TYPE_DELETED
|
||||
&& current_prop_p->types[1] == ECMA_PROPERTY_TYPE_DELETED)
|
||||
{
|
||||
if (prev_prop_p == NULL)
|
||||
{
|
||||
object_p->property_list_or_bound_object_cp = current_prop_p->next_property_cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_prop_p->next_property_cp = current_prop_p->next_property_cp;
|
||||
}
|
||||
|
||||
ecma_property_header_t *next_prop_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
current_prop_p->next_property_cp);
|
||||
ecma_dealloc_property_pair ((ecma_property_pair_t *) current_prop_p);
|
||||
current_prop_p = next_prop_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_prop_p = current_prop_p;
|
||||
current_prop_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
current_prop_p->next_property_cp);
|
||||
}
|
||||
}
|
||||
|
||||
if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP)
|
||||
{
|
||||
ecma_property_hashmap_free (object_p);
|
||||
ecma_property_hashmap_create (object_p);
|
||||
}
|
||||
|
||||
return new_length;
|
||||
} /* ecma_delete_array_properties */
|
||||
|
||||
/**
|
||||
* Check whether the object contains a property
|
||||
*/
|
||||
@@ -1029,19 +870,20 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec
|
||||
ecma_property_types_t type) /**< expected property type */
|
||||
{
|
||||
#ifndef JERRY_NDEBUG
|
||||
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
|
||||
jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp;
|
||||
JERRY_ASSERT (prop_iter_cp != JMEM_CP_NULL);
|
||||
|
||||
JERRY_ASSERT (prop_iter_p != NULL);
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
|
||||
if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
|
||||
while (true)
|
||||
while (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
JERRY_ASSERT (prop_iter_p != NULL);
|
||||
prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
@@ -1055,8 +897,7 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec
|
||||
}
|
||||
}
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
#else /* JERRY_NDEBUG */
|
||||
JERRY_UNUSED (object_p);
|
||||
@@ -1082,40 +923,19 @@ ecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */
|
||||
} /* ecma_named_data_property_assign_value */
|
||||
|
||||
/**
|
||||
* Get getter of named accessor property
|
||||
* Get named accessor property getter-setter-pair
|
||||
*
|
||||
* @return pointer to object - getter of the property
|
||||
* @return pointer to object's getter-setter pair
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_get_named_accessor_property_getter (const ecma_property_value_t *prop_value_p) /**< property value reference */
|
||||
ecma_getter_setter_pointers_t *
|
||||
ecma_get_named_accessor_property (const ecma_property_value_t *prop_value_p) /**< property value reference */
|
||||
{
|
||||
#if ENABLED (JERRY_CPOINTER_32_BIT)
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
|
||||
prop_value_p->getter_setter_pair_cp);
|
||||
return ECMA_GET_POINTER (ecma_object_t, getter_setter_pair_p->getter_p);
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, prop_value_p->getter_setter_pair_cp);
|
||||
#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
return ECMA_GET_POINTER (ecma_object_t, prop_value_p->getter_setter_pair.getter_p);
|
||||
return (ecma_getter_setter_pointers_t *) &prop_value_p->getter_setter_pair;
|
||||
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
} /* ecma_get_named_accessor_property_getter */
|
||||
|
||||
/**
|
||||
* Get setter of named accessor property
|
||||
*
|
||||
* @return pointer to object - setter of the property
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_get_named_accessor_property_setter (const ecma_property_value_t *prop_value_p) /**< property value reference */
|
||||
{
|
||||
#if ENABLED (JERRY_CPOINTER_32_BIT)
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
|
||||
prop_value_p->getter_setter_pair_cp);
|
||||
return ECMA_GET_POINTER (ecma_object_t, getter_setter_pair_p->setter_p);
|
||||
#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
return ECMA_GET_POINTER (ecma_object_t, prop_value_p->getter_setter_pair.setter_p);
|
||||
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
} /* ecma_get_named_accessor_property_setter */
|
||||
} /* ecma_get_named_accessor_property */
|
||||
|
||||
/**
|
||||
* Set getter of named accessor property
|
||||
@@ -1129,11 +949,11 @@ ecma_set_named_accessor_property_getter (ecma_object_t *object_p, /**< the prope
|
||||
|
||||
#if ENABLED (JERRY_CPOINTER_32_BIT)
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
|
||||
prop_value_p->getter_setter_pair_cp);
|
||||
ECMA_SET_POINTER (getter_setter_pair_p->getter_p, getter_p);
|
||||
getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t,
|
||||
prop_value_p->getter_setter_pair_cp);
|
||||
ECMA_SET_POINTER (getter_setter_pair_p->getter_cp, getter_p);
|
||||
#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
ECMA_SET_POINTER (prop_value_p->getter_setter_pair.getter_p, getter_p);
|
||||
ECMA_SET_POINTER (prop_value_p->getter_setter_pair.getter_cp, getter_p);
|
||||
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
} /* ecma_set_named_accessor_property_getter */
|
||||
|
||||
@@ -1149,11 +969,11 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope
|
||||
|
||||
#if ENABLED (JERRY_CPOINTER_32_BIT)
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
|
||||
prop_value_p->getter_setter_pair_cp);
|
||||
ECMA_SET_POINTER (getter_setter_pair_p->setter_p, setter_p);
|
||||
getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t,
|
||||
prop_value_p->getter_setter_pair_cp);
|
||||
ECMA_SET_POINTER (getter_setter_pair_p->setter_cp, setter_p);
|
||||
#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
ECMA_SET_POINTER (prop_value_p->getter_setter_pair.setter_p, setter_p);
|
||||
ECMA_SET_POINTER (prop_value_p->getter_setter_pair.setter_cp, setter_p);
|
||||
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
} /* ecma_set_named_accessor_property_setter */
|
||||
|
||||
@@ -1314,17 +1134,9 @@ ecma_make_empty_property_descriptor (void)
|
||||
{
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
|
||||
prop_desc.is_value_defined = false;
|
||||
prop_desc.flags = 0;
|
||||
prop_desc.value = ECMA_VALUE_UNDEFINED;
|
||||
prop_desc.is_writable_defined = false;
|
||||
prop_desc.is_writable = false;
|
||||
prop_desc.is_enumerable_defined = false;
|
||||
prop_desc.is_enumerable = false;
|
||||
prop_desc.is_configurable_defined = false;
|
||||
prop_desc.is_configurable = false;
|
||||
prop_desc.is_get_defined = false;
|
||||
prop_desc.get_p = NULL;
|
||||
prop_desc.is_set_defined = false;
|
||||
prop_desc.set_p = NULL;
|
||||
|
||||
return prop_desc;
|
||||
@@ -1337,18 +1149,18 @@ ecma_make_empty_property_descriptor (void)
|
||||
void
|
||||
ecma_free_property_descriptor (ecma_property_descriptor_t *prop_desc_p) /**< property descriptor */
|
||||
{
|
||||
if (prop_desc_p->is_value_defined)
|
||||
if (prop_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
|
||||
{
|
||||
ecma_free_value (prop_desc_p->value);
|
||||
}
|
||||
|
||||
if (prop_desc_p->is_get_defined
|
||||
if ((prop_desc_p->flags & ECMA_PROP_IS_GET_DEFINED)
|
||||
&& prop_desc_p->get_p != NULL)
|
||||
{
|
||||
ecma_deref_object (prop_desc_p->get_p);
|
||||
}
|
||||
|
||||
if (prop_desc_p->is_set_defined
|
||||
if ((prop_desc_p->flags & ECMA_PROP_IS_SET_DEFINED)
|
||||
&& prop_desc_p->set_p != NULL)
|
||||
{
|
||||
ecma_deref_object (prop_desc_p->set_p);
|
||||
@@ -1591,7 +1403,7 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
#if ENABLED (JERRY_BUILTIN_REGEXP)
|
||||
re_compiled_code_t *re_bytecode_p = (re_compiled_code_t *) bytecode_p;
|
||||
|
||||
ecma_deref_ecma_string (ecma_get_string_from_value (re_bytecode_p->pattern));
|
||||
ecma_deref_ecma_string (ecma_get_string_from_value (re_bytecode_p->source));
|
||||
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
|
||||
}
|
||||
|
||||
|
||||
@@ -50,11 +50,17 @@
|
||||
*/
|
||||
#define ECMA_SET_POINTER(field, non_compressed_pointer) JMEM_CP_SET_POINTER (field, non_compressed_pointer)
|
||||
|
||||
/**
|
||||
* Status flags for ecma_string_get_chars function
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_STRING_FLAG_EMPTY = 0,
|
||||
ECMA_STRING_FLAG_IS_ASCII,
|
||||
ECMA_STRING_FLAG_MUST_BE_FREED
|
||||
ECMA_STRING_FLAG_EMPTY = 0, /**< No options are provided. */
|
||||
ECMA_STRING_FLAG_IS_ASCII = (1 << 0), /**< The string contains only ASCII characters. */
|
||||
ECMA_STRING_FLAG_REHASH_NEEDED = (1 << 1), /**< The hash of the string must be recalculated.
|
||||
* For more details see ecma_append_chars_to_string */
|
||||
ECMA_STRING_FLAG_IS_UINT32 = (1 << 2), /**< The string repesents an UINT32 number */
|
||||
ECMA_STRING_FLAG_MUST_BE_FREED = (1 << 3), /**< The returned buffer must be freed */
|
||||
} ecma_string_flag_t;
|
||||
|
||||
/**
|
||||
@@ -65,7 +71,11 @@ typedef enum
|
||||
utf8_str_size) /**< [out] output buffer size */ \
|
||||
lit_utf8_size_t utf8_str_size; \
|
||||
uint8_t utf8_ptr ## flags = ECMA_STRING_FLAG_EMPTY; \
|
||||
const lit_utf8_byte_t *utf8_ptr = ecma_string_get_chars (ecma_str_ptr, &utf8_str_size, &utf8_ptr ## flags);
|
||||
const lit_utf8_byte_t *utf8_ptr = ecma_string_get_chars (ecma_str_ptr, \
|
||||
&utf8_str_size, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
&utf8_ptr ## flags);
|
||||
|
||||
/**
|
||||
* Free the cesu-8 string buffer allocated by 'ECMA_STRING_TO_UTF8_STRING'
|
||||
@@ -174,13 +184,13 @@ bool JERRY_ATTR_CONST ecma_is_value_direct_string (ecma_value_t value);
|
||||
bool JERRY_ATTR_CONST ecma_is_value_non_direct_string (ecma_value_t value);
|
||||
bool JERRY_ATTR_CONST ecma_is_value_object (ecma_value_t value);
|
||||
bool JERRY_ATTR_CONST ecma_is_value_error_reference (ecma_value_t value);
|
||||
bool JERRY_ATTR_CONST ecma_is_value_pointer (ecma_value_t value);
|
||||
|
||||
void ecma_check_value_type_is_spec_defined (ecma_value_t value);
|
||||
|
||||
ecma_value_t JERRY_ATTR_CONST ecma_make_boolean_value (bool boolean_value);
|
||||
ecma_value_t JERRY_ATTR_CONST ecma_make_integer_value (ecma_integer_value_t integer_value);
|
||||
ecma_value_t ecma_make_nan_value (void);
|
||||
ecma_value_t ecma_make_float_value (ecma_number_t *ecma_num_p);
|
||||
ecma_value_t ecma_make_number_value (ecma_number_t ecma_number);
|
||||
ecma_value_t ecma_make_int32_value (int32_t int32_number);
|
||||
ecma_value_t ecma_make_uint32_value (uint32_t uint32_number);
|
||||
@@ -192,9 +202,9 @@ ecma_value_t JERRY_ATTR_PURE ecma_make_prop_name_value (const ecma_string_t *ecm
|
||||
ecma_value_t JERRY_ATTR_PURE ecma_make_magic_string_value (lit_magic_string_id_t id);
|
||||
ecma_value_t JERRY_ATTR_PURE ecma_make_object_value (const ecma_object_t *object_p);
|
||||
ecma_value_t JERRY_ATTR_PURE ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p);
|
||||
ecma_value_t JERRY_ATTR_PURE ecma_make_pointer_value (const void *any_p);
|
||||
ecma_integer_value_t JERRY_ATTR_CONST ecma_get_integer_from_value (ecma_value_t value);
|
||||
ecma_number_t JERRY_ATTR_PURE ecma_get_float_from_value (ecma_value_t value);
|
||||
ecma_number_t * ecma_get_pointer_from_float_value (ecma_value_t value);
|
||||
ecma_number_t JERRY_ATTR_PURE ecma_get_number_from_value (ecma_value_t value);
|
||||
ecma_string_t JERRY_ATTR_PURE *ecma_get_string_from_value (ecma_value_t value);
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|
||||
@@ -203,7 +213,6 @@ ecma_string_t JERRY_ATTR_PURE *ecma_get_symbol_from_value (ecma_value_t value);
|
||||
ecma_string_t JERRY_ATTR_PURE *ecma_get_prop_name_from_value (ecma_value_t value);
|
||||
ecma_object_t JERRY_ATTR_PURE *ecma_get_object_from_value (ecma_value_t value);
|
||||
ecma_error_reference_t JERRY_ATTR_PURE *ecma_get_error_reference_from_value (ecma_value_t value);
|
||||
void * JERRY_ATTR_PURE ecma_get_pointer_from_value (ecma_value_t value);
|
||||
ecma_value_t JERRY_ATTR_CONST ecma_invert_boolean_value (ecma_value_t value);
|
||||
ecma_value_t ecma_copy_value (ecma_value_t value);
|
||||
ecma_value_t ecma_fast_copy_value (ecma_value_t value);
|
||||
@@ -234,6 +243,7 @@ ecma_string_t *ecma_new_ecma_string_from_code_unit (ecma_char_t code_unit);
|
||||
ecma_string_t *ecma_new_ecma_string_from_code_units (ecma_char_t first_code_unit, ecma_char_t second_code_unit);
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
|
||||
ecma_string_t *ecma_new_ecma_string_from_uint32 (uint32_t uint32_number);
|
||||
ecma_string_t *ecma_new_non_direct_string_from_uint32 (uint32_t uint32_number);
|
||||
ecma_string_t *ecma_get_ecma_string_from_uint32 (uint32_t uint32_number);
|
||||
ecma_string_t *ecma_new_ecma_string_from_number (ecma_number_t num);
|
||||
ecma_string_t *ecma_get_magic_string (lit_magic_string_id_t id);
|
||||
@@ -245,6 +255,7 @@ ecma_string_t *ecma_concat_ecma_strings (ecma_string_t *string1_p, ecma_string_t
|
||||
ecma_string_t *ecma_append_magic_string_to_string (ecma_string_t *string1_p, lit_magic_string_id_t string2_id);
|
||||
void ecma_ref_ecma_string (ecma_string_t *string_p);
|
||||
void ecma_deref_ecma_string (ecma_string_t *string_p);
|
||||
void ecma_destroy_ecma_string (ecma_string_t *string_p);
|
||||
ecma_number_t ecma_string_to_number (const ecma_string_t *str_p);
|
||||
uint32_t ecma_string_get_array_index (const ecma_string_t *str_p);
|
||||
|
||||
@@ -270,7 +281,11 @@ ecma_substring_copy_to_utf8_buffer (const ecma_string_t *string_desc_p,
|
||||
lit_utf8_size_t buffer_size);
|
||||
void ecma_string_to_utf8_bytes (const ecma_string_t *string_desc_p, lit_utf8_byte_t *buffer_p,
|
||||
lit_utf8_size_t buffer_size);
|
||||
const lit_utf8_byte_t *ecma_string_get_chars (const ecma_string_t *string_p, lit_utf8_size_t *size_p, uint8_t *flags_p);
|
||||
const lit_utf8_byte_t *ecma_string_get_chars (const ecma_string_t *string_p,
|
||||
lit_utf8_size_t *size_p,
|
||||
lit_utf8_size_t *length_p,
|
||||
lit_utf8_byte_t *uint32_buff_p,
|
||||
uint8_t *flags_p);
|
||||
bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id);
|
||||
bool ecma_string_is_empty (const ecma_string_t *string_p);
|
||||
bool ecma_string_is_length (const ecma_string_t *string_p);
|
||||
@@ -295,8 +310,25 @@ lit_magic_string_id_t ecma_get_string_magic (const ecma_string_t *string_p);
|
||||
|
||||
lit_string_hash_t ecma_string_hash (const ecma_string_t *string_p);
|
||||
ecma_string_t *ecma_string_substr (const ecma_string_t *string_p, ecma_length_t start_pos, ecma_length_t end_pos);
|
||||
void ecma_string_trim_helper (const lit_utf8_byte_t **utf8_str_p,
|
||||
lit_utf8_size_t *utf8_str_size);
|
||||
ecma_string_t *ecma_string_trim (const ecma_string_t *string_p);
|
||||
|
||||
ecma_stringbuilder_t ecma_stringbuilder_create (void);
|
||||
ecma_stringbuilder_t ecma_stringbuilder_create_from (ecma_string_t *string_p);
|
||||
lit_utf8_size_t ecma_stringbuilder_get_size (ecma_stringbuilder_t *builder_p);
|
||||
lit_utf8_byte_t *ecma_stringbuilder_get_data (ecma_stringbuilder_t *builder_p);
|
||||
void ecma_stringbuilder_revert (ecma_stringbuilder_t *builder_p, const lit_utf8_size_t size);
|
||||
void ecma_stringbuilder_append (ecma_stringbuilder_t *builder_p, const ecma_string_t *string_p);
|
||||
void ecma_stringbuilder_append_magic (ecma_stringbuilder_t *builder_p, const lit_magic_string_id_t id);
|
||||
void ecma_stringbuilder_append_raw (ecma_stringbuilder_t *builder_p,
|
||||
const lit_utf8_byte_t *data_p,
|
||||
const lit_utf8_size_t data_size);
|
||||
void ecma_stringbuilder_append_char (ecma_stringbuilder_t *builder_p, const ecma_char_t c);
|
||||
void ecma_stringbuilder_append_byte (ecma_stringbuilder_t *builder_p, const lit_utf8_byte_t);
|
||||
ecma_string_t *ecma_stringbuilder_finalize (ecma_stringbuilder_t *builder_p);
|
||||
void ecma_stringbuilder_destroy (ecma_stringbuilder_t *builder_p);
|
||||
|
||||
/* ecma-helpers-number.c */
|
||||
ecma_number_t ecma_number_make_nan (void);
|
||||
ecma_number_t ecma_number_make_infinity (bool sign);
|
||||
@@ -316,15 +348,13 @@ lit_utf8_size_t ecma_number_to_binary_floating_point_number (ecma_number_t num,
|
||||
lit_utf8_byte_t *out_digits_p,
|
||||
int32_t *out_decimal_exp_p);
|
||||
|
||||
/* ecma-helpers-values-collection.c */
|
||||
ecma_collection_header_t *ecma_new_values_collection (void);
|
||||
void ecma_free_values_collection (ecma_collection_header_t *header_p, uint32_t flags);
|
||||
void ecma_append_to_values_collection (ecma_collection_header_t *header_p, ecma_value_t v, uint32_t flags);
|
||||
|
||||
ecma_value_t *
|
||||
ecma_collection_iterator_init (ecma_collection_header_t *header_p);
|
||||
ecma_value_t *
|
||||
ecma_collection_iterator_next (ecma_value_t *iterator_p);
|
||||
/* ecma-helpers-collection.c */
|
||||
ecma_collection_t *ecma_new_collection (void);
|
||||
void ecma_collection_push_back (ecma_collection_t *collection_p, ecma_value_t value);
|
||||
void ecma_collection_destroy (ecma_collection_t *collection_p);
|
||||
void ecma_collection_free (ecma_collection_t *collection_p);
|
||||
void ecma_collection_free_if_not_object (ecma_collection_t *collection_p);
|
||||
void ecma_collection_free_objects (ecma_collection_t *collection_p);
|
||||
|
||||
/* ecma-helpers.c */
|
||||
ecma_object_t *ecma_create_object (ecma_object_t *prototype_object_p, size_t ext_object_size, ecma_object_type_t type);
|
||||
@@ -335,13 +365,11 @@ bool JERRY_ATTR_PURE ecma_is_lexical_environment (const ecma_object_t *object_p)
|
||||
bool JERRY_ATTR_PURE ecma_get_object_extensible (const ecma_object_t *object_p);
|
||||
void ecma_set_object_extensible (ecma_object_t *object_p, bool is_extensible);
|
||||
ecma_object_type_t JERRY_ATTR_PURE ecma_get_object_type (const ecma_object_t *object_p);
|
||||
ecma_object_t JERRY_ATTR_PURE *ecma_get_object_prototype (const ecma_object_t *object_p);
|
||||
bool JERRY_ATTR_PURE ecma_get_object_is_builtin (const ecma_object_t *object_p);
|
||||
void ecma_set_object_is_builtin (ecma_object_t *object_p);
|
||||
uint8_t ecma_get_object_builtin_id (ecma_object_t *object_p);
|
||||
ecma_lexical_environment_type_t JERRY_ATTR_PURE ecma_get_lex_env_type (const ecma_object_t *object_p);
|
||||
ecma_object_t JERRY_ATTR_PURE *ecma_get_lex_env_outer_reference (const ecma_object_t *object_p);
|
||||
ecma_property_header_t JERRY_ATTR_PURE *ecma_get_property_list (const ecma_object_t *object_p);
|
||||
ecma_object_t JERRY_ATTR_PURE *ecma_get_lex_env_binding_object (const ecma_object_t *object_p);
|
||||
|
||||
ecma_property_value_t *
|
||||
@@ -358,13 +386,12 @@ ecma_get_named_data_property (ecma_object_t *obj_p, ecma_string_t *name_p);
|
||||
void ecma_free_property (ecma_object_t *object_p, jmem_cpointer_t name_cp, ecma_property_t *property_p);
|
||||
|
||||
void ecma_delete_property (ecma_object_t *object_p, ecma_property_value_t *prop_value_p);
|
||||
uint32_t ecma_delete_array_properties (ecma_object_t *object_p, uint32_t new_length, uint32_t old_length);
|
||||
|
||||
void ecma_named_data_property_assign_value (ecma_object_t *obj_p, ecma_property_value_t *prop_value_p,
|
||||
ecma_value_t value);
|
||||
|
||||
ecma_object_t *ecma_get_named_accessor_property_getter (const ecma_property_value_t *prop_value_p);
|
||||
ecma_object_t *ecma_get_named_accessor_property_setter (const ecma_property_value_t *prop_value_p);
|
||||
ecma_getter_setter_pointers_t *
|
||||
ecma_get_named_accessor_property (const ecma_property_value_t *prop_value_p);
|
||||
void ecma_set_named_accessor_property_getter (ecma_object_t *object_p, ecma_property_value_t *prop_value_p,
|
||||
ecma_object_t *getter_p);
|
||||
void ecma_set_named_accessor_property_setter (ecma_object_t *object_p, ecma_property_value_t *prop_value_p,
|
||||
|
||||
@@ -28,10 +28,19 @@
|
||||
|
||||
#if ENABLED (JERRY_LCACHE)
|
||||
|
||||
/**
|
||||
* Bitshift index for calculating hash.
|
||||
*/
|
||||
#if ENABLED (JERRY_CPOINTER_32_BIT)
|
||||
#define ECMA_LCACHE_HASH_BITSHIFT_INDEX (2 * JMEM_ALIGNMENT_LOG)
|
||||
#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
#define ECMA_LCACHE_HASH_BITSHIFT_INDEX 0
|
||||
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
|
||||
/**
|
||||
* Mask for hash bits
|
||||
*/
|
||||
#define ECMA_LCACHE_HASH_MASK (ECMA_LCACHE_HASH_ROWS_COUNT - 1)
|
||||
#define ECMA_LCACHE_HASH_MASK ((ECMA_LCACHE_HASH_ROWS_COUNT - 1) << ECMA_LCACHE_HASH_BITSHIFT_INDEX)
|
||||
|
||||
/**
|
||||
* Bitshift index for creating property identifier
|
||||
@@ -69,15 +78,15 @@ ecma_lcache_row_index (jmem_cpointer_t object_cp, /**< compressed pointer to obj
|
||||
{
|
||||
/* Randomize the property name with the object pointer using a xor operation,
|
||||
* so properties of different objects with the same name can be cached effectively. */
|
||||
return (size_t) ((name_cp ^ object_cp) & ECMA_LCACHE_HASH_MASK);
|
||||
return (size_t) (((name_cp ^ object_cp) & ECMA_LCACHE_HASH_MASK) >> ECMA_LCACHE_HASH_BITSHIFT_INDEX);
|
||||
} /* ecma_lcache_row_index */
|
||||
|
||||
/**
|
||||
* Insert an entry into LCache
|
||||
*/
|
||||
void
|
||||
ecma_lcache_insert (ecma_object_t *object_p, /**< object */
|
||||
jmem_cpointer_t name_cp, /**< property name */
|
||||
ecma_lcache_insert (const ecma_object_t *object_p, /**< object */
|
||||
const jmem_cpointer_t name_cp, /**< property name */
|
||||
ecma_property_t *prop_p) /**< property */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
@@ -91,31 +100,32 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */
|
||||
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
|
||||
|
||||
size_t row_index = ecma_lcache_row_index (object_cp, name_cp);
|
||||
ecma_lcache_hash_entry_t *entries_p = JERRY_CONTEXT (lcache) [row_index];
|
||||
ecma_lcache_hash_entry_t *entry_p = JERRY_CONTEXT (lcache) [row_index];
|
||||
ecma_lcache_hash_entry_t *entry_end_p = entry_p + ECMA_LCACHE_HASH_ROW_LENGTH;
|
||||
|
||||
uint32_t entry_index;
|
||||
for (entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++)
|
||||
do
|
||||
{
|
||||
if (entries_p[entry_index].id == 0)
|
||||
if (entry_p->id == 0)
|
||||
{
|
||||
break;
|
||||
goto insert;
|
||||
}
|
||||
|
||||
entry_p++;
|
||||
}
|
||||
while (entry_p < entry_end_p);
|
||||
|
||||
/* Invalidate the last entry. */
|
||||
ecma_lcache_invalidate_entry (--entry_p);
|
||||
|
||||
/* Shift other entries towards the end. */
|
||||
for (uint32_t i = 0; i < ECMA_LCACHE_HASH_ROW_LENGTH - 1; i++)
|
||||
{
|
||||
entry_p->id = entry_p[-1].id;
|
||||
entry_p->prop_p = entry_p[-1].prop_p;
|
||||
entry_p--;
|
||||
}
|
||||
|
||||
if (entry_index == ECMA_LCACHE_HASH_ROW_LENGTH)
|
||||
{
|
||||
/* Invalidate the last entry. */
|
||||
ecma_lcache_invalidate_entry (entries_p + ECMA_LCACHE_HASH_ROW_LENGTH - 1);
|
||||
|
||||
/* Shift other entries towards the end. */
|
||||
for (uint32_t i = ECMA_LCACHE_HASH_ROW_LENGTH - 1; i > 0; i--)
|
||||
{
|
||||
entries_p[i] = entries_p[i - 1];
|
||||
}
|
||||
entry_index = 0;
|
||||
}
|
||||
|
||||
ecma_lcache_hash_entry_t *entry_p = entries_p + entry_index;
|
||||
insert:
|
||||
entry_p->prop_p = prop_p;
|
||||
entry_p->id = ECMA_LCACHE_CREATE_ID (object_cp, name_cp);
|
||||
|
||||
@@ -129,7 +139,7 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */
|
||||
* NULL otherwise
|
||||
*/
|
||||
inline ecma_property_t * JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
|
||||
ecma_lcache_lookup (const ecma_object_t *object_p, /**< object */
|
||||
const ecma_string_t *prop_name_p) /**< property's name */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
@@ -138,17 +148,16 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
|
||||
jmem_cpointer_t object_cp;
|
||||
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
|
||||
|
||||
ecma_property_t prop_name_type;
|
||||
ecma_property_t prop_name_type = ECMA_DIRECT_STRING_PTR;
|
||||
jmem_cpointer_t prop_name_cp;
|
||||
|
||||
if (ECMA_IS_DIRECT_STRING (prop_name_p))
|
||||
if (JERRY_UNLIKELY (ECMA_IS_DIRECT_STRING (prop_name_p)))
|
||||
{
|
||||
prop_name_type = (ecma_property_t) ECMA_GET_DIRECT_STRING_TYPE (prop_name_p);
|
||||
prop_name_cp = (jmem_cpointer_t) ECMA_GET_DIRECT_STRING_VALUE (prop_name_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_name_type = ECMA_DIRECT_STRING_PTR;
|
||||
ECMA_SET_NON_NULL_POINTER (prop_name_cp, prop_name_p);
|
||||
}
|
||||
|
||||
@@ -156,18 +165,18 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
|
||||
|
||||
ecma_lcache_hash_entry_t *entry_p = JERRY_CONTEXT (lcache) [row_index];
|
||||
ecma_lcache_hash_entry_t *entry_end_p = entry_p + ECMA_LCACHE_HASH_ROW_LENGTH;
|
||||
|
||||
ecma_lcache_hash_entry_id_t id = ECMA_LCACHE_CREATE_ID (object_cp, prop_name_cp);
|
||||
|
||||
while (entry_p < entry_end_p)
|
||||
do
|
||||
{
|
||||
if (entry_p->id == id && ECMA_PROPERTY_GET_NAME_TYPE (*entry_p->prop_p) == prop_name_type)
|
||||
if (entry_p->id == id && JERRY_LIKELY (ECMA_PROPERTY_GET_NAME_TYPE (*entry_p->prop_p) == prop_name_type))
|
||||
{
|
||||
JERRY_ASSERT (entry_p->prop_p != NULL && ecma_is_property_lcached (entry_p->prop_p));
|
||||
return entry_p->prop_p;
|
||||
}
|
||||
entry_p++;
|
||||
}
|
||||
while (entry_p < entry_end_p);
|
||||
|
||||
return NULL;
|
||||
} /* ecma_lcache_lookup */
|
||||
@@ -176,8 +185,8 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
|
||||
* Invalidate LCache entries associated with given object and property name / property
|
||||
*/
|
||||
void
|
||||
ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */
|
||||
jmem_cpointer_t name_cp, /**< property name */
|
||||
ecma_lcache_invalidate (const ecma_object_t *object_p, /**< object */
|
||||
const jmem_cpointer_t name_cp, /**< property name */
|
||||
ecma_property_t *prop_p) /**< property */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
|
||||
@@ -24,10 +24,9 @@
|
||||
*/
|
||||
|
||||
#if ENABLED (JERRY_LCACHE)
|
||||
|
||||
void ecma_lcache_insert (ecma_object_t *object_p, jmem_cpointer_t name_cp, ecma_property_t *prop_p);
|
||||
ecma_property_t *ecma_lcache_lookup (ecma_object_t *object_p, const ecma_string_t *prop_name_p);
|
||||
void ecma_lcache_invalidate (ecma_object_t *object_p, jmem_cpointer_t name_cp, ecma_property_t *prop_p);
|
||||
void ecma_lcache_insert (const ecma_object_t *object_p, const jmem_cpointer_t name_cp, ecma_property_t *prop_p);
|
||||
ecma_property_t *ecma_lcache_lookup (const ecma_object_t *object_p, const ecma_string_t *prop_name_p);
|
||||
void ecma_lcache_invalidate (const ecma_object_t *object_p, const jmem_cpointer_t name_cp, ecma_property_t *prop_p);
|
||||
|
||||
#endif /* ENABLED (JERRY_LCACHE) */
|
||||
|
||||
|
||||
@@ -25,14 +25,46 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|
||||
/**
|
||||
* Free symbol list
|
||||
*/
|
||||
static void
|
||||
ecma_free_symbol_list (jmem_cpointer_t symbol_list_cp) /**< symbol list */
|
||||
{
|
||||
while (symbol_list_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_lit_storage_item_t *symbol_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_lit_storage_item_t, symbol_list_cp);
|
||||
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
{
|
||||
if (symbol_list_p->values[i] != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
symbol_list_p->values[i]);
|
||||
|
||||
JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (string_p));
|
||||
ecma_deref_ecma_string (string_p);
|
||||
}
|
||||
}
|
||||
|
||||
jmem_cpointer_t next_item_cp = symbol_list_p->next_cp;
|
||||
jmem_pools_free (symbol_list_p, sizeof (ecma_lit_storage_item_t));
|
||||
symbol_list_cp = next_item_cp;
|
||||
}
|
||||
} /* ecma_free_symbol_list */
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
|
||||
|
||||
/**
|
||||
* Free string list
|
||||
*/
|
||||
static void
|
||||
ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list */
|
||||
ecma_free_string_list (jmem_cpointer_t string_list_cp) /**< string list */
|
||||
{
|
||||
while (string_list_p != NULL)
|
||||
while (string_list_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_lit_storage_item_t *string_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_lit_storage_item_t, string_list_cp);
|
||||
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
{
|
||||
if (string_list_p->values[i] != JMEM_CP_NULL)
|
||||
@@ -41,16 +73,42 @@ ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list
|
||||
string_list_p->values[i]);
|
||||
|
||||
JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (string_p));
|
||||
ecma_deref_ecma_string (string_p);
|
||||
ecma_destroy_ecma_string (string_p);
|
||||
}
|
||||
}
|
||||
|
||||
ecma_lit_storage_item_t *prev_item = string_list_p;
|
||||
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
|
||||
jmem_pools_free (prev_item, sizeof (ecma_lit_storage_item_t));
|
||||
jmem_cpointer_t next_item_cp = string_list_p->next_cp;
|
||||
jmem_pools_free (string_list_p, sizeof (ecma_lit_storage_item_t));
|
||||
string_list_cp = next_item_cp;
|
||||
}
|
||||
} /* ecma_free_string_list */
|
||||
|
||||
/**
|
||||
* Free number list
|
||||
*/
|
||||
static void
|
||||
ecma_free_number_list (jmem_cpointer_t number_list_cp) /**< string list */
|
||||
{
|
||||
while (number_list_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_number_storage_item_t *number_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_number_storage_item_t,
|
||||
number_list_cp);
|
||||
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
{
|
||||
if (number_list_p->values[i] != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_number_t *num_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_number_t, number_list_p->values[i]);
|
||||
ecma_dealloc_number (num_p);
|
||||
}
|
||||
}
|
||||
|
||||
jmem_cpointer_t next_item_cp = number_list_p->next_cp;
|
||||
jmem_pools_free (number_list_p, sizeof (ecma_number_storage_item_t));
|
||||
number_list_cp = next_item_cp;
|
||||
}
|
||||
} /* ecma_free_number_list */
|
||||
|
||||
/**
|
||||
* Finalize literal storage
|
||||
*/
|
||||
@@ -58,10 +116,10 @@ void
|
||||
ecma_finalize_lit_storage (void)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|
||||
ecma_free_string_list (JERRY_CONTEXT (symbol_list_first_p));
|
||||
ecma_free_symbol_list (JERRY_CONTEXT (symbol_list_first_cp));
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
|
||||
ecma_free_string_list (JERRY_CONTEXT (string_list_first_p));
|
||||
ecma_free_string_list (JERRY_CONTEXT (number_list_first_p));
|
||||
ecma_free_string_list (JERRY_CONTEXT (string_list_first_cp));
|
||||
ecma_free_number_list (JERRY_CONTEXT (number_list_first_cp));
|
||||
} /* ecma_finalize_lit_storage */
|
||||
|
||||
/**
|
||||
@@ -80,11 +138,13 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
|
||||
return ecma_make_string_value (string_p);
|
||||
}
|
||||
|
||||
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
|
||||
jmem_cpointer_t string_list_cp = JERRY_CONTEXT (string_list_first_cp);
|
||||
jmem_cpointer_t *empty_cpointer_p = NULL;
|
||||
|
||||
while (string_list_p != NULL)
|
||||
while (string_list_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_lit_storage_item_t *string_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_lit_storage_item_t, string_list_cp);
|
||||
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
{
|
||||
if (string_list_p->values[i] == JMEM_CP_NULL)
|
||||
@@ -108,9 +168,10 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
|
||||
}
|
||||
}
|
||||
|
||||
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
|
||||
string_list_cp = string_list_p->next_cp;
|
||||
}
|
||||
|
||||
ECMA_SET_STRING_AS_STATIC (string_p);
|
||||
jmem_cpointer_t result;
|
||||
JMEM_CP_SET_NON_NULL_POINTER (result, string_p);
|
||||
|
||||
@@ -129,8 +190,8 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
|
||||
new_item_p->values[i] = JMEM_CP_NULL;
|
||||
}
|
||||
|
||||
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (string_list_first_p));
|
||||
JERRY_CONTEXT (string_list_first_p) = new_item_p;
|
||||
new_item_p->next_cp = JERRY_CONTEXT (string_list_first_cp);
|
||||
JMEM_CP_SET_NON_NULL_POINTER (JERRY_CONTEXT (string_list_first_cp), new_item_p);
|
||||
|
||||
return ecma_make_string_value (string_p);
|
||||
} /* ecma_find_or_create_literal_string */
|
||||
@@ -152,11 +213,14 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_float_number (num));
|
||||
|
||||
ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p);
|
||||
jmem_cpointer_t number_list_cp = JERRY_CONTEXT (number_list_first_cp);
|
||||
jmem_cpointer_t *empty_cpointer_p = NULL;
|
||||
|
||||
while (number_list_p != NULL)
|
||||
while (number_list_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_number_storage_item_t *number_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_number_storage_item_t,
|
||||
number_list_cp);
|
||||
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
{
|
||||
if (number_list_p->values[i] == JMEM_CP_NULL)
|
||||
@@ -168,29 +232,24 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
number_list_p->values[i]);
|
||||
ecma_number_t *number_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_number_t,
|
||||
number_list_p->values[i]);
|
||||
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
|
||||
JERRY_ASSERT (ecma_is_value_float_number (value_p->u.lit_number));
|
||||
|
||||
if (ecma_get_float_from_value (value_p->u.lit_number) == number_arg)
|
||||
if (*number_p == number_arg)
|
||||
{
|
||||
ecma_free_value (num);
|
||||
return value_p->u.lit_number;
|
||||
return ecma_make_float_value (number_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
|
||||
number_list_cp = number_list_p->next_cp;
|
||||
}
|
||||
|
||||
ecma_string_t *string_p = ecma_alloc_string ();
|
||||
string_p->refs_and_container = ECMA_STRING_REF_ONE | ECMA_STRING_LITERAL_NUMBER;
|
||||
string_p->u.lit_number = num;
|
||||
ecma_number_t *num_p = ecma_get_pointer_from_float_value (num);
|
||||
|
||||
jmem_cpointer_t result;
|
||||
JMEM_CP_SET_NON_NULL_POINTER (result, string_p);
|
||||
JMEM_CP_SET_NON_NULL_POINTER (result, num_p);
|
||||
|
||||
if (empty_cpointer_p != NULL)
|
||||
{
|
||||
@@ -198,8 +257,8 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
|
||||
return num;
|
||||
}
|
||||
|
||||
ecma_lit_storage_item_t *new_item_p;
|
||||
new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (sizeof (ecma_lit_storage_item_t));
|
||||
ecma_number_storage_item_t *new_item_p;
|
||||
new_item_p = (ecma_number_storage_item_t *) jmem_pools_alloc (sizeof (ecma_number_storage_item_t));
|
||||
|
||||
new_item_p->values[0] = result;
|
||||
for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
@@ -207,8 +266,8 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
|
||||
new_item_p->values[i] = JMEM_CP_NULL;
|
||||
}
|
||||
|
||||
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (number_list_first_p));
|
||||
JERRY_CONTEXT (number_list_first_p) = new_item_p;
|
||||
new_item_p->next_cp = JERRY_CONTEXT (number_list_first_cp);
|
||||
JMEM_CP_SET_NON_NULL_POINTER (JERRY_CONTEXT (number_list_first_cp), new_item_p);
|
||||
|
||||
return num;
|
||||
} /* ecma_find_or_create_literal_number */
|
||||
@@ -239,7 +298,7 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
|
||||
* Append the value at the end of the appropriate list if it is not present there.
|
||||
*/
|
||||
void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appended */
|
||||
ecma_collection_header_t *lit_pool_p) /**< list of known values */
|
||||
ecma_collection_t *lit_pool_p) /**< list of known values */
|
||||
{
|
||||
/* Unlike direct numbers, direct strings are converted to character literals. */
|
||||
if (!ecma_is_value_string (value) && !ecma_is_value_float_number (value))
|
||||
@@ -247,21 +306,19 @@ void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appen
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
ecma_value_t *buffer_p = lit_pool_p->buffer_p;
|
||||
|
||||
while (iterator_p != NULL)
|
||||
for (uint32_t i = 0; i < lit_pool_p->item_count; i++)
|
||||
{
|
||||
/* Strings / numbers are direct strings or stored in the literal storage.
|
||||
* Therefore direct comparison is enough to find the same strings / numbers. */
|
||||
if (*iterator_p == value)
|
||||
if (buffer_p[i] == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
ecma_append_to_values_collection (lit_pool_p, value, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_push_back (lit_pool_p, value);
|
||||
} /* ecma_save_literals_append_value */
|
||||
|
||||
/**
|
||||
@@ -269,7 +326,7 @@ void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appen
|
||||
*/
|
||||
void
|
||||
ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_p, /**< byte-code data */
|
||||
ecma_collection_header_t *lit_pool_p) /**< list of known values */
|
||||
ecma_collection_t *lit_pool_p) /**< list of known values */
|
||||
{
|
||||
ecma_value_t *literal_p;
|
||||
uint32_t argument_end = 0;
|
||||
@@ -355,7 +412,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list of known values */
|
||||
ecma_save_literals_for_snapshot (ecma_collection_t *lit_pool_p, /**< list of known values */
|
||||
uint32_t *buffer_p, /**< [out] output snapshot buffer */
|
||||
size_t buffer_size, /**< size of the buffer */
|
||||
size_t *in_out_buffer_offset_p, /**< [in,out] write position in the buffer */
|
||||
@@ -378,18 +435,18 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list
|
||||
max_lit_table_size = (UINT32_MAX >> JERRY_SNAPSHOT_LITERAL_SHIFT);
|
||||
}
|
||||
|
||||
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
ecma_value_t *lit_buffer_p = lit_pool_p->buffer_p;
|
||||
|
||||
/* Compute the size of the literal pool. */
|
||||
while (iterator_p != NULL)
|
||||
for (uint32_t i = 0; i < lit_pool_p->item_count; i++)
|
||||
{
|
||||
if (ecma_is_value_float_number (*iterator_p))
|
||||
if (ecma_is_value_float_number (lit_buffer_p[i]))
|
||||
{
|
||||
lit_table_size += (uint32_t) sizeof (ecma_number_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (*iterator_p);
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (lit_buffer_p[i]);
|
||||
|
||||
lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p),
|
||||
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
@@ -398,11 +455,9 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list
|
||||
/* Check whether enough space is available and the maximum size is not reached. */
|
||||
if (lit_table_size > max_lit_table_size)
|
||||
{
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return false;
|
||||
}
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
}
|
||||
|
||||
lit_mem_to_snapshot_id_map_entry_t *map_p;
|
||||
@@ -420,28 +475,28 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list
|
||||
*out_map_p = map_p;
|
||||
*out_map_len_p = total_count;
|
||||
|
||||
iterator_p = ecma_collection_iterator_init (lit_pool_p);
|
||||
lit_buffer_p = lit_pool_p->buffer_p;
|
||||
|
||||
/* Generate literal pool data. */
|
||||
while (iterator_p != NULL)
|
||||
for (uint32_t i = 0; i < lit_pool_p->item_count; i++)
|
||||
{
|
||||
map_p->literal_id = *iterator_p;
|
||||
map_p->literal_id = lit_buffer_p[i];
|
||||
map_p->literal_offset = (literal_offset << JERRY_SNAPSHOT_LITERAL_SHIFT) | ECMA_TYPE_SNAPSHOT_OFFSET;
|
||||
|
||||
ecma_length_t length;
|
||||
|
||||
if (ecma_is_value_float_number (*iterator_p))
|
||||
if (ecma_is_value_float_number (lit_buffer_p[i]))
|
||||
{
|
||||
map_p->literal_offset |= JERRY_SNAPSHOT_LITERAL_IS_NUMBER;
|
||||
|
||||
ecma_number_t num = ecma_get_float_from_value (*iterator_p);
|
||||
ecma_number_t num = ecma_get_float_from_value (lit_buffer_p[i]);
|
||||
memcpy (destination_p, &num, sizeof (ecma_number_t));
|
||||
|
||||
length = JERRY_ALIGNUP (sizeof (ecma_number_t), JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (*iterator_p);
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (lit_buffer_p[i]);
|
||||
length = ecma_string_get_size (string_p);
|
||||
|
||||
*(uint16_t *) destination_p = (uint16_t) length;
|
||||
@@ -455,11 +510,10 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list
|
||||
destination_p += length;
|
||||
literal_offset += length;
|
||||
|
||||
iterator_p = ecma_collection_iterator_next (iterator_p);
|
||||
map_p++;
|
||||
}
|
||||
|
||||
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
|
||||
ecma_collection_destroy (lit_pool_p);
|
||||
return true;
|
||||
} /* ecma_save_literals_for_snapshot */
|
||||
|
||||
|
||||
@@ -44,10 +44,10 @@ ecma_value_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p,
|
||||
ecma_value_t ecma_find_or_create_literal_number (ecma_number_t number_arg);
|
||||
|
||||
#if ENABLED (JERRY_SNAPSHOT_SAVE)
|
||||
void ecma_save_literals_append_value (ecma_value_t value, ecma_collection_header_t *lit_pool_p);
|
||||
void ecma_save_literals_append_value (ecma_value_t value, ecma_collection_t *lit_pool_p);
|
||||
void ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_p,
|
||||
ecma_collection_header_t *lit_pool_p);
|
||||
bool ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, uint32_t *buffer_p, size_t buffer_size,
|
||||
ecma_collection_t *lit_pool_p);
|
||||
bool ecma_save_literals_for_snapshot (ecma_collection_t *lit_pool_p, uint32_t *buffer_p, size_t buffer_size,
|
||||
size_t *in_out_buffer_offset_p, lit_mem_to_snapshot_id_map_entry_t **out_map_p,
|
||||
uint32_t *out_map_len_p);
|
||||
#endif /* ENABLED (JERRY_SNAPSHOT_SAVE) */
|
||||
|
||||
@@ -97,12 +97,13 @@ ecma_module_create_normalized_path (const uint8_t *char_p, /**< module specifier
|
||||
} /* ecma_module_create_normalized_path */
|
||||
|
||||
/**
|
||||
* Checks if we already have a module request in the module list.
|
||||
* Find a module with a specific identifier
|
||||
*
|
||||
* @return pointer to found or newly created module structure
|
||||
* @return pointer to ecma_module_t, if found
|
||||
* NULL, otherwise
|
||||
*/
|
||||
ecma_module_t *
|
||||
ecma_module_find_or_create_module (ecma_string_t * const path_p) /**< module path */
|
||||
ecma_module_find_module (ecma_string_t *const path_p) /**< module identifier */
|
||||
{
|
||||
ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
|
||||
while (current_p != NULL)
|
||||
@@ -114,16 +115,59 @@ ecma_module_find_or_create_module (ecma_string_t * const path_p) /**< module pat
|
||||
current_p = current_p->next_p;
|
||||
}
|
||||
|
||||
current_p = (ecma_module_t *) jmem_heap_alloc_block (sizeof (ecma_module_t));
|
||||
memset (current_p, 0, sizeof (ecma_module_t));
|
||||
|
||||
ecma_ref_ecma_string (path_p);
|
||||
current_p->path_p = path_p;
|
||||
current_p->next_p = JERRY_CONTEXT (ecma_modules_p);
|
||||
JERRY_CONTEXT (ecma_modules_p) = current_p;
|
||||
return current_p;
|
||||
} /* ecma_module_find_module */
|
||||
|
||||
/**
|
||||
* Create a new module
|
||||
*
|
||||
* @return pointer to created module
|
||||
*/
|
||||
static ecma_module_t *
|
||||
ecma_module_create_module (ecma_string_t *const path_p) /**< module identifier */
|
||||
{
|
||||
ecma_module_t *module_p = (ecma_module_t *) jmem_heap_alloc_block (sizeof (ecma_module_t));
|
||||
memset (module_p, 0, sizeof (ecma_module_t));
|
||||
|
||||
module_p->path_p = path_p;
|
||||
module_p->next_p = JERRY_CONTEXT (ecma_modules_p);
|
||||
JERRY_CONTEXT (ecma_modules_p) = module_p;
|
||||
return module_p;
|
||||
} /* ecma_module_create_module */
|
||||
|
||||
/**
|
||||
* Checks if we already have a module request in the module list.
|
||||
*
|
||||
* @return pointer to found or newly created module structure
|
||||
*/
|
||||
ecma_module_t *
|
||||
ecma_module_find_or_create_module (ecma_string_t *const path_p) /**< module path */
|
||||
{
|
||||
ecma_module_t *module_p = ecma_module_find_module (path_p);
|
||||
if (module_p)
|
||||
{
|
||||
ecma_deref_ecma_string (path_p);
|
||||
return module_p;
|
||||
}
|
||||
|
||||
return ecma_module_create_module (path_p);
|
||||
} /* ecma_module_find_or_create_module */
|
||||
|
||||
/**
|
||||
* Create a new native module
|
||||
*
|
||||
* @return pointer to created module
|
||||
*/
|
||||
ecma_module_t *
|
||||
ecma_module_create_native_module (ecma_string_t *const path_p, /**< module identifier */
|
||||
ecma_object_t *const namespace_p) /**< module namespace */
|
||||
{
|
||||
ecma_module_t *module_p = ecma_module_create_module (path_p);
|
||||
module_p->state = ECMA_MODULE_STATE_NATIVE;
|
||||
module_p->namespace_object_p = namespace_p;
|
||||
return module_p;
|
||||
} /* ecma_module_create_native_module */
|
||||
|
||||
/**
|
||||
* Creates a module context.
|
||||
*
|
||||
@@ -274,6 +318,30 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current_module_p->state == ECMA_MODULE_STATE_NATIVE)
|
||||
{
|
||||
ecma_object_t *object_p = current_module_p->namespace_object_p;
|
||||
ecma_value_t prop_value = ecma_op_object_find_own (ecma_make_object_value (object_p),
|
||||
object_p,
|
||||
current_export_name_p);
|
||||
if (ecma_is_value_found (prop_value))
|
||||
{
|
||||
found = true;
|
||||
found_record.module_p = current_module_p;
|
||||
found_record.name_p = current_export_name_p;
|
||||
ecma_free_value (prop_value);
|
||||
}
|
||||
|
||||
if (ecma_compare_ecma_string_to_magic_id (current_export_name_p, LIT_MAGIC_STRING_DEFAULT))
|
||||
{
|
||||
ret_value = ecma_raise_syntax_error (ECMA_ERR_MSG ("No default export in native module."));
|
||||
break;
|
||||
}
|
||||
|
||||
ecma_module_resolve_stack_pop (&stack_p);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (context_p->local_exports_p != NULL)
|
||||
{
|
||||
/* 15.2.1.16.3 / 4 */
|
||||
@@ -645,25 +713,44 @@ ecma_module_connect_imports (void)
|
||||
return ecma_raise_syntax_error (ECMA_ERR_MSG ("Ambiguous import request."));
|
||||
}
|
||||
|
||||
result = ecma_module_evaluate (record.module_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
if (record.module_p->state == ECMA_MODULE_STATE_NATIVE)
|
||||
{
|
||||
return result;
|
||||
ecma_object_t *object_p = record.module_p->namespace_object_p;
|
||||
ecma_value_t prop_value = ecma_op_object_find_own (ecma_make_object_value (object_p),
|
||||
object_p,
|
||||
record.name_p);
|
||||
JERRY_ASSERT (ecma_is_value_found (prop_value));
|
||||
|
||||
ecma_op_create_mutable_binding (local_env_p, import_names_p->local_name_p, true /* is_deletable */);
|
||||
ecma_op_set_mutable_binding (local_env_p,
|
||||
import_names_p->local_name_p,
|
||||
prop_value,
|
||||
false /* is_strict */);
|
||||
|
||||
ecma_free_value (prop_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ecma_module_evaluate (record.module_p);
|
||||
|
||||
ecma_object_t *ref_base_lex_env_p;
|
||||
ecma_value_t prop_value = ecma_op_get_value_lex_env_base (record.module_p->scope_p,
|
||||
&ref_base_lex_env_p,
|
||||
record.name_p);
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
ecma_op_create_mutable_binding (local_env_p, import_names_p->local_name_p, true /* is_deletable */);
|
||||
ecma_op_set_mutable_binding (local_env_p,
|
||||
import_names_p->local_name_p,
|
||||
prop_value,
|
||||
false /* is_strict */);
|
||||
ecma_object_t *ref_base_lex_env_p;
|
||||
ecma_value_t prop_value = ecma_op_get_value_lex_env_base (record.module_p->scope_p,
|
||||
&ref_base_lex_env_p,
|
||||
record.name_p);
|
||||
|
||||
ecma_free_value (prop_value);
|
||||
ecma_op_create_mutable_binding (local_env_p, import_names_p->local_name_p, true /* is_deletable */);
|
||||
ecma_op_set_mutable_binding (local_env_p,
|
||||
import_names_p->local_name_p,
|
||||
prop_value,
|
||||
false /* is_strict */);
|
||||
|
||||
ecma_free_value (prop_value);
|
||||
}
|
||||
}
|
||||
|
||||
import_names_p = import_names_p->next_p;
|
||||
@@ -820,7 +907,7 @@ ecma_module_check_indirect_exports (void)
|
||||
/**
|
||||
* Cleans up a list of module names.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
ecma_module_release_module_names (ecma_module_names_t *module_name_p) /**< first module name */
|
||||
{
|
||||
while (module_name_p != NULL)
|
||||
@@ -838,7 +925,7 @@ ecma_module_release_module_names (ecma_module_names_t *module_name_p) /**< first
|
||||
/**
|
||||
* Cleans up a list of module nodes.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
ecma_module_release_module_nodes (ecma_module_node_t *module_node_p) /**< first module node */
|
||||
{
|
||||
while (module_node_p != NULL)
|
||||
@@ -873,6 +960,17 @@ static void
|
||||
ecma_module_release_module (ecma_module_t *module_p) /**< module */
|
||||
{
|
||||
ecma_deref_ecma_string (module_p->path_p);
|
||||
|
||||
if (module_p->namespace_object_p != NULL)
|
||||
{
|
||||
ecma_deref_object (module_p->namespace_object_p);
|
||||
}
|
||||
|
||||
if (module_p->state == ECMA_MODULE_STATE_NATIVE)
|
||||
{
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (module_p->state >= ECMA_MODULE_STATE_PARSING)
|
||||
{
|
||||
ecma_module_release_module_context (module_p->context_p);
|
||||
@@ -889,11 +987,7 @@ ecma_module_release_module (ecma_module_t *module_p) /**< module */
|
||||
ecma_bytecode_deref (module_p->compiled_code_p);
|
||||
}
|
||||
|
||||
if (module_p->namespace_object_p != NULL)
|
||||
{
|
||||
ecma_deref_object (module_p->namespace_object_p);
|
||||
}
|
||||
|
||||
finished:
|
||||
jmem_heap_free_block (module_p, sizeof (ecma_module_t));
|
||||
} /* ecma_module_release_module */
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ typedef enum
|
||||
ECMA_MODULE_STATE_PARSED = 2, /**< module has been parsed */
|
||||
ECMA_MODULE_STATE_EVALUATING = 3, /**< module is currently being evaluated */
|
||||
ECMA_MODULE_STATE_EVALUATED = 4, /**< module has been evaluated */
|
||||
ECMA_MODULE_STATE_NATIVE = 5, /**< module is native */
|
||||
} ecma_module_state_t;
|
||||
|
||||
/**
|
||||
@@ -116,24 +117,27 @@ typedef struct ecma_module_resolve_stack
|
||||
} ecma_module_resolve_stack_t;
|
||||
|
||||
bool ecma_module_resolve_set_insert (ecma_module_resolve_set_t **set_p,
|
||||
ecma_module_t * const module_p,
|
||||
ecma_string_t * const export_name_p);
|
||||
ecma_module_t *const module_p,
|
||||
ecma_string_t *const export_name_p);
|
||||
void ecma_module_resolve_set_cleanup (ecma_module_resolve_set_t *set_p);
|
||||
|
||||
void ecma_module_resolve_stack_push (ecma_module_resolve_stack_t **stack_p,
|
||||
ecma_module_t * const module_p,
|
||||
ecma_string_t * const export_name_p);
|
||||
ecma_module_t *const module_p,
|
||||
ecma_string_t *const export_name_p);
|
||||
void ecma_module_resolve_stack_pop (ecma_module_resolve_stack_t **stack_p);
|
||||
|
||||
ecma_string_t *ecma_module_create_normalized_path (const uint8_t *char_p,
|
||||
prop_length_t size);
|
||||
ecma_module_t *ecma_module_find_or_create_module (ecma_string_t * const path_p);
|
||||
ecma_module_t *ecma_module_find_module (ecma_string_t *const path_p);
|
||||
ecma_module_t *ecma_module_create_native_module (ecma_string_t *const path_p,
|
||||
ecma_object_t *const namespace_p);
|
||||
ecma_module_t *ecma_module_find_or_create_module (ecma_string_t *const path_p);
|
||||
|
||||
ecma_value_t ecma_module_connect_imports (void);
|
||||
ecma_value_t ecma_module_parse_modules (void);
|
||||
ecma_value_t ecma_module_check_indirect_exports (void);
|
||||
|
||||
void ecma_module_release_module_names (ecma_module_names_t *module_name_p);
|
||||
void ecma_module_release_module_nodes (ecma_module_node_t *module_node_p);
|
||||
void ecma_module_cleanup (void);
|
||||
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
|
||||
|
||||
@@ -65,8 +65,6 @@ static const uint8_t ecma_property_hashmap_steps[ECMA_PROPERTY_HASHMAP_NUMBER_OF
|
||||
#define ECMA_PROPERTY_HASHMAP_SET_BIT(byte_p, index) \
|
||||
((byte_p)[(index) >> 3] = (uint8_t) ((byte_p)[(index) >> 3] | (1 << ((index) & 0x7))))
|
||||
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
/**
|
||||
* Create a new property hashmap for the object.
|
||||
* The object must not have a property hashmap.
|
||||
@@ -74,25 +72,23 @@ static const uint8_t ecma_property_hashmap_steps[ECMA_PROPERTY_HASHMAP_NUMBER_OF
|
||||
void
|
||||
ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
if (JERRY_CONTEXT (ecma_prop_hashmap_alloc_state) != ECMA_PROP_HASHMAP_ALLOC_ON)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
|
||||
jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp;
|
||||
|
||||
if (prop_iter_p == NULL)
|
||||
if (prop_iter_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
uint32_t named_property_count = 0;
|
||||
|
||||
while (prop_iter_p != NULL)
|
||||
while (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
@@ -104,8 +100,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
|
||||
named_property_count++;
|
||||
}
|
||||
}
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
|
||||
if (named_property_count < (ECMA_PROPERTY_HASMAP_MINIMUM_SIZE / 2))
|
||||
@@ -134,8 +129,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
|
||||
memset (hashmap_p, 0, total_size);
|
||||
|
||||
hashmap_p->header.types[0] = ECMA_PROPERTY_TYPE_HASHMAP;
|
||||
hashmap_p->header.types[1] = 0;
|
||||
hashmap_p->header.next_property_cp = object_p->property_list_or_bound_object_cp;
|
||||
hashmap_p->header.next_property_cp = object_p->u1.property_list_cp;
|
||||
hashmap_p->max_property_count = max_property_count;
|
||||
hashmap_p->null_count = max_property_count - named_property_count;
|
||||
hashmap_p->unused_count = max_property_count - named_property_count;
|
||||
@@ -144,21 +138,12 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
|
||||
uint8_t *bits_p = (uint8_t *) (pair_list_p + max_property_count);
|
||||
uint32_t mask = max_property_count - 1;
|
||||
|
||||
uint8_t shift_counter = 0;
|
||||
prop_iter_cp = object_p->u1.property_list_cp;
|
||||
ECMA_SET_NON_NULL_POINTER (object_p->u1.property_list_cp, hashmap_p);
|
||||
|
||||
while (max_property_count > LIT_STRING_HASH_LIMIT)
|
||||
{
|
||||
shift_counter++;
|
||||
max_property_count >>= 1;
|
||||
}
|
||||
|
||||
hashmap_p->header.types[1] = shift_counter;
|
||||
|
||||
prop_iter_p = ecma_get_property_list (object_p);
|
||||
ECMA_SET_POINTER (object_p->property_list_or_bound_object_cp, hashmap_p);
|
||||
|
||||
while (prop_iter_p != NULL)
|
||||
while (prop_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
@@ -174,16 +159,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
|
||||
property_pair_p->names_cp[i]);
|
||||
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
|
||||
|
||||
if (mask < LIT_STRING_HASH_LIMIT)
|
||||
{
|
||||
entry_index &= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry_index <<= shift_counter;
|
||||
JERRY_ASSERT (entry_index <= mask);
|
||||
}
|
||||
|
||||
entry_index &= mask;
|
||||
#ifndef JERRY_NDEBUG
|
||||
/* Because max_property_count (power of 2) and step (a prime
|
||||
* number) are relative primes, all entries of the hasmap are
|
||||
@@ -203,7 +179,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
}
|
||||
|
||||
ECMA_SET_POINTER (pair_list_p[entry_index], property_pair_p);
|
||||
ECMA_SET_NON_NULL_POINTER (pair_list_p[entry_index], property_pair_p);
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
@@ -211,12 +187,8 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
|
||||
}
|
||||
}
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
JERRY_UNUSED (object_p);
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
} /* ecma_property_hashmap_create */
|
||||
|
||||
/**
|
||||
@@ -226,21 +198,20 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
|
||||
void
|
||||
ecma_property_hashmap_free (ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
/* Property hash must be exists and must be the first property. */
|
||||
ecma_property_header_t *property_p = ecma_get_property_list (object_p);
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp != JMEM_CP_NULL);
|
||||
|
||||
JERRY_ASSERT (property_p != NULL && property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP);
|
||||
ecma_property_header_t *property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
|
||||
object_p->u1.property_list_cp);
|
||||
|
||||
JERRY_ASSERT (property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP);
|
||||
|
||||
ecma_property_hashmap_t *hashmap_p = (ecma_property_hashmap_t *) property_p;
|
||||
|
||||
object_p->property_list_or_bound_object_cp = property_p->next_property_cp;
|
||||
object_p->u1.property_list_cp = property_p->next_property_cp;
|
||||
|
||||
jmem_heap_free_block (hashmap_p,
|
||||
ECMA_PROPERTY_HASHMAP_GET_TOTAL_SIZE (hashmap_p->max_property_count));
|
||||
#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
JERRY_UNUSED (object_p);
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
} /* ecma_property_hashmap_free */
|
||||
|
||||
/**
|
||||
@@ -252,9 +223,10 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
|
||||
ecma_property_pair_t *property_pair_p, /**< property pair */
|
||||
int property_index) /**< property index in the pair (0 or 1) */
|
||||
{
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
JERRY_ASSERT (property_pair_p != NULL);
|
||||
|
||||
ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t,
|
||||
object_p->property_list_or_bound_object_cp);
|
||||
object_p->u1.property_list_cp);
|
||||
|
||||
JERRY_ASSERT (hashmap_p->header.types[0] == ECMA_PROPERTY_TYPE_HASHMAP);
|
||||
|
||||
@@ -271,15 +243,8 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
|
||||
uint32_t entry_index = ecma_string_hash (name_p);
|
||||
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
|
||||
uint32_t mask = hashmap_p->max_property_count - 1;
|
||||
entry_index &= mask;
|
||||
|
||||
if (mask < LIT_STRING_HASH_LIMIT)
|
||||
{
|
||||
entry_index &= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry_index <<= hashmap_p->header.types[1];
|
||||
}
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
/* See the comment for this variable in ecma_property_hashmap_create. */
|
||||
@@ -297,7 +262,7 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
}
|
||||
|
||||
ECMA_SET_POINTER (pair_list_p[entry_index], property_pair_p);
|
||||
ECMA_SET_NON_NULL_POINTER (pair_list_p[entry_index], property_pair_p);
|
||||
|
||||
uint8_t *bits_p = (uint8_t *) (pair_list_p + hashmap_p->max_property_count);
|
||||
bits_p += (entry_index >> 3);
|
||||
@@ -322,12 +287,6 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
|
||||
{
|
||||
*bits_p = (uint8_t) ((*bits_p) | mask);
|
||||
}
|
||||
#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
JERRY_UNUSED (object_p);
|
||||
JERRY_UNUSED (name_p);
|
||||
JERRY_UNUSED (property_pair_p);
|
||||
JERRY_UNUSED (property_index);
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
} /* ecma_property_hashmap_insert */
|
||||
|
||||
/**
|
||||
@@ -341,9 +300,8 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
|
||||
jmem_cpointer_t name_cp, /**< property name */
|
||||
ecma_property_t *property_p) /**< property */
|
||||
{
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t,
|
||||
object_p->property_list_or_bound_object_cp);
|
||||
object_p->u1.property_list_cp);
|
||||
|
||||
JERRY_ASSERT (hashmap_p->header.types[0] == ECMA_PROPERTY_TYPE_HASHMAP);
|
||||
|
||||
@@ -361,15 +319,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
|
||||
jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1);
|
||||
uint8_t *bits_p = (uint8_t *) (pair_list_p + hashmap_p->max_property_count);
|
||||
|
||||
if (mask < LIT_STRING_HASH_LIMIT)
|
||||
{
|
||||
entry_index &= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry_index <<= hashmap_p->header.types[1];
|
||||
JERRY_ASSERT (entry_index <= mask);
|
||||
}
|
||||
entry_index &= mask;
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
/* See the comment for this variable in ecma_property_hashmap_create. */
|
||||
@@ -411,16 +361,8 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
|
||||
JERRY_ASSERT (entry_index != start_entry_index);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
}
|
||||
#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
JERRY_UNUSED (object_p);
|
||||
JERRY_UNUSED (name_cp);
|
||||
JERRY_UNUSED (property_p);
|
||||
|
||||
return ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP;
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
} /* ecma_property_hashmap_delete */
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
/**
|
||||
* Find a named property.
|
||||
*
|
||||
@@ -437,11 +379,12 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
|
||||
* from both data collection. The following code checks the property
|
||||
* chain, and sets the property_found variable. */
|
||||
bool property_found = false;
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
hashmap_p->header.next_property_cp);
|
||||
|
||||
while (prop_iter_p != NULL && !property_found)
|
||||
jmem_cpointer_t prop_iter_cp = hashmap_p->header.next_property_cp;
|
||||
|
||||
while (prop_iter_cp != JMEM_CP_NULL && !property_found)
|
||||
{
|
||||
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
@@ -454,14 +397,14 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
|
||||
prop_pair_p->names_cp[i],
|
||||
name_p))
|
||||
{
|
||||
/* Property is found */
|
||||
property_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
prop_iter_cp = prop_iter_p->next_property_cp;
|
||||
}
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
@@ -470,16 +413,7 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
|
||||
uint32_t mask = hashmap_p->max_property_count - 1;
|
||||
jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1);
|
||||
uint8_t *bits_p = (uint8_t *) (pair_list_p + hashmap_p->max_property_count);
|
||||
|
||||
if (mask < LIT_STRING_HASH_LIMIT)
|
||||
{
|
||||
entry_index &= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry_index <<= hashmap_p->header.types[1];
|
||||
JERRY_ASSERT (entry_index <= mask);
|
||||
}
|
||||
entry_index &= mask;
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
/* See the comment for this variable in ecma_property_hashmap_create. */
|
||||
|
||||
@@ -53,6 +53,8 @@ typedef struct
|
||||
*/
|
||||
} ecma_property_hashmap_t;
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
|
||||
/**
|
||||
* Simple ecma values
|
||||
*/
|
||||
@@ -70,7 +72,7 @@ void ecma_property_hashmap_insert (ecma_object_t *object_p, ecma_string_t *name_
|
||||
ecma_property_hashmap_delete_status ecma_property_hashmap_delete (ecma_object_t *object_p, jmem_cpointer_t name_cp,
|
||||
ecma_property_t *property_p);
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
|
||||
ecma_property_t *ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, ecma_string_t *name_p,
|
||||
jmem_cpointer_t *property_real_name_cp);
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -106,7 +106,7 @@ ecma_builtin_arraybuffer_prototype_object_slice (ecma_value_t this_arg, /**< thi
|
||||
arg1,
|
||||
ret_value);
|
||||
|
||||
start = ecma_builtin_helper_array_index_normalize (start_num, len);
|
||||
start = ecma_builtin_helper_array_index_normalize (start_num, len, false);
|
||||
|
||||
if (!ecma_is_value_undefined (arg2))
|
||||
{
|
||||
@@ -114,7 +114,7 @@ ecma_builtin_arraybuffer_prototype_object_slice (ecma_value_t this_arg, /**< thi
|
||||
arg2,
|
||||
ret_value);
|
||||
|
||||
end = ecma_builtin_helper_array_index_normalize (end_num, len);
|
||||
end = ecma_builtin_helper_array_index_normalize (end_num, len, false);
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (end_num);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ enum
|
||||
ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER,
|
||||
ECMA_DATAVIEW_PROTOTYPE_GET_INT8,
|
||||
ECMA_DATAVIEW_PROTOTYPE_GET_UINT8,
|
||||
ECMA_DATAVIEW_PROTOTYPE_GET_UINT8_CLAMPED, /* unused value */
|
||||
ECMA_DATAVIEW_PROTOTYPE_GET_INT16,
|
||||
ECMA_DATAVIEW_PROTOTYPE_GET_UINT16,
|
||||
ECMA_DATAVIEW_PROTOTYPE_GET_INT32,
|
||||
@@ -51,6 +52,7 @@ enum
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
ECMA_DATAVIEW_PROTOTYPE_SET_INT8,
|
||||
ECMA_DATAVIEW_PROTOTYPE_SET_UINT8,
|
||||
ECMA_DATAVIEW_PROTOTYPE_SET_UINT8_CLAMPED, /* unused value */
|
||||
ECMA_DATAVIEW_PROTOTYPE_SET_INT16,
|
||||
ECMA_DATAVIEW_PROTOTYPE_SET_UINT16,
|
||||
ECMA_DATAVIEW_PROTOTYPE_SET_INT32,
|
||||
@@ -75,23 +77,6 @@ enum
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Corresponding typedarray mappings for the {get,set}{[U]int, Float}{8, 16, 32, 64} routines
|
||||
*/
|
||||
static const uint8_t ecma_dataview_type_mapping[] =
|
||||
{
|
||||
ECMA_BUILTIN_ID_INT8ARRAY,
|
||||
ECMA_BUILTIN_ID_UINT8ARRAY,
|
||||
ECMA_BUILTIN_ID_INT16ARRAY,
|
||||
ECMA_BUILTIN_ID_UINT16ARRAY,
|
||||
ECMA_BUILTIN_ID_INT32ARRAY,
|
||||
ECMA_BUILTIN_ID_UINT32ARRAY,
|
||||
ECMA_BUILTIN_ID_FLOAT32ARRAY,
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
ECMA_BUILTIN_ID_FLOAT64ARRAY,
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
};
|
||||
|
||||
/**
|
||||
* The DataView.prototype object's {buffer, byteOffset, byteLength} getters
|
||||
*
|
||||
@@ -168,9 +153,9 @@ ecma_builtin_dataview_prototype_dispatch_routine (uint16_t builtin_routine_id, /
|
||||
case ECMA_DATAVIEW_PROTOTYPE_GET_UINT32:
|
||||
{
|
||||
ecma_value_t little_endian = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_FALSE;
|
||||
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8];
|
||||
ecma_typedarray_type_t id = (ecma_typedarray_type_t) (builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8);
|
||||
|
||||
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, ECMA_VALUE_EMPTY, type);
|
||||
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, ECMA_VALUE_EMPTY, id);
|
||||
}
|
||||
case ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT32:
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
@@ -183,25 +168,25 @@ ecma_builtin_dataview_prototype_dispatch_routine (uint16_t builtin_routine_id, /
|
||||
{
|
||||
ecma_value_t value_to_set = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_UNDEFINED;
|
||||
ecma_value_t little_endian = arguments_number > 2 ? arguments_list_p[2] : ECMA_VALUE_FALSE;
|
||||
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8];
|
||||
ecma_typedarray_type_t id = (ecma_typedarray_type_t) (builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8);
|
||||
|
||||
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, value_to_set, type);
|
||||
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, value_to_set, id);
|
||||
}
|
||||
case ECMA_DATAVIEW_PROTOTYPE_GET_INT8:
|
||||
case ECMA_DATAVIEW_PROTOTYPE_GET_UINT8:
|
||||
{
|
||||
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8];
|
||||
ecma_typedarray_type_t id = (ecma_typedarray_type_t) (builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8);
|
||||
|
||||
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, ECMA_VALUE_EMPTY, type);
|
||||
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, ECMA_VALUE_EMPTY, id);
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (builtin_routine_id == ECMA_DATAVIEW_PROTOTYPE_SET_INT8
|
||||
|| builtin_routine_id == ECMA_DATAVIEW_PROTOTYPE_SET_UINT8);
|
||||
ecma_value_t value_to_set = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_UNDEFINED;
|
||||
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8];
|
||||
ecma_typedarray_type_t id = (ecma_typedarray_type_t) (builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8);
|
||||
|
||||
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, value_to_set, type);
|
||||
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, value_to_set, id);
|
||||
}
|
||||
}
|
||||
} /* ecma_builtin_dataview_prototype_dispatch_routine */
|
||||
|
||||
@@ -199,10 +199,27 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
|
||||
const lit_utf8_byte_t *date_str_end_p = date_start_p + date_start_size;
|
||||
|
||||
/* 1. read year */
|
||||
ecma_number_t year = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 4);
|
||||
|
||||
if (!ecma_number_is_nan (year)
|
||||
&& year >= 0)
|
||||
uint32_t year_digits = 4;
|
||||
bool year_sign = false; /* false: positive, true: negative */
|
||||
if (*date_str_curr_p == '-' || *date_str_curr_p == '+')
|
||||
{
|
||||
year_digits = 6;
|
||||
if (*date_str_curr_p == '-')
|
||||
{
|
||||
year_sign = true;
|
||||
}
|
||||
/* eat up '-' or '+' */
|
||||
date_str_curr_p++;
|
||||
}
|
||||
|
||||
ecma_number_t year = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, year_digits);
|
||||
if (year_sign)
|
||||
{
|
||||
year = -year;
|
||||
}
|
||||
|
||||
if (!ecma_number_is_nan (year))
|
||||
{
|
||||
ecma_number_t month = ECMA_NUMBER_ONE;
|
||||
ecma_number_t day = ECMA_NUMBER_ONE;
|
||||
@@ -260,10 +277,6 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
|
||||
{
|
||||
hours = ecma_number_make_nan ();
|
||||
}
|
||||
else if (hours == 24)
|
||||
{
|
||||
hours = ECMA_NUMBER_ZERO;
|
||||
}
|
||||
|
||||
if (date_str_curr_p < date_str_end_p
|
||||
&& *date_str_curr_p == ':')
|
||||
@@ -307,6 +320,11 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
|
||||
}
|
||||
}
|
||||
|
||||
if (hours == 24 && (minutes != 0 || seconds != 0 || milliseconds != 0))
|
||||
{
|
||||
hours = ecma_number_make_nan ();
|
||||
}
|
||||
|
||||
time = ecma_date_make_time (hours, minutes, seconds, milliseconds);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -111,31 +111,6 @@ ecma_builtin_global_object_eval (ecma_value_t x) /**< routine's first argument *
|
||||
return ecma_op_eval (ecma_get_string_from_value (x), parse_opts);
|
||||
} /* ecma_builtin_global_object_eval */
|
||||
|
||||
/**
|
||||
* Helper function for trimming leading whitespaces
|
||||
* for the Global object's 'parseInt' and 'parseFloat' routines
|
||||
*/
|
||||
static void
|
||||
ecma_builtin_global_remove_leading_white_spaces (const lit_utf8_byte_t **string_curr_p, /**< [in, out] current string
|
||||
* position */
|
||||
const lit_utf8_byte_t *string_end_p, /**< end of the string buffer */
|
||||
const lit_utf8_byte_t **start_p) /**< [in, out] start position of the
|
||||
* trimmed string */
|
||||
{
|
||||
while (*string_curr_p < string_end_p)
|
||||
{
|
||||
ecma_char_t current_char = lit_utf8_read_next (string_curr_p);
|
||||
|
||||
if (!lit_char_is_white_space (current_char)
|
||||
&& !lit_char_is_line_terminator (current_char))
|
||||
{
|
||||
lit_utf8_decr (string_curr_p);
|
||||
*start_p = *string_curr_p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* ecma_builtin_global_remove_leading_white_spaces */
|
||||
|
||||
/**
|
||||
* The Global object's 'parseInt' routine
|
||||
*
|
||||
@@ -158,13 +133,13 @@ ecma_builtin_global_object_parse_int (const lit_utf8_byte_t *string_buff, /**< r
|
||||
}
|
||||
|
||||
const lit_utf8_byte_t *string_curr_p = string_buff;
|
||||
const lit_utf8_byte_t *string_end_p = string_buff + string_buff_size;
|
||||
|
||||
/* 2. Remove leading whitespace. */
|
||||
const lit_utf8_byte_t *start_p = string_end_p;
|
||||
const lit_utf8_byte_t *end_p = start_p;
|
||||
ecma_string_trim_helper (&string_curr_p, &string_buff_size);
|
||||
|
||||
ecma_builtin_global_remove_leading_white_spaces (&string_curr_p, string_end_p, &start_p);
|
||||
const lit_utf8_byte_t *string_end_p = string_curr_p + string_buff_size;
|
||||
const lit_utf8_byte_t *start_p = string_curr_p;
|
||||
const lit_utf8_byte_t *end_p = string_end_p;
|
||||
|
||||
if (string_curr_p >= string_end_p)
|
||||
{
|
||||
@@ -336,14 +311,14 @@ ecma_builtin_global_object_parse_float (const lit_utf8_byte_t *string_buff, /**<
|
||||
}
|
||||
|
||||
const lit_utf8_byte_t *str_curr_p = string_buff;
|
||||
const lit_utf8_byte_t *str_end_p = string_buff + string_buff_size;
|
||||
|
||||
const lit_utf8_byte_t *start_p = str_end_p;
|
||||
/* 2. Remove leading whitespace. */
|
||||
ecma_string_trim_helper (&str_curr_p, &string_buff_size);
|
||||
|
||||
const lit_utf8_byte_t *str_end_p = str_curr_p + string_buff_size;
|
||||
const lit_utf8_byte_t *start_p = str_curr_p;
|
||||
const lit_utf8_byte_t *end_p = str_end_p;
|
||||
|
||||
/* 2. Find first non whitespace char and set starting position. */
|
||||
ecma_builtin_global_remove_leading_white_spaces (&str_curr_p, str_end_p, &start_p);
|
||||
|
||||
bool sign = false;
|
||||
ecma_char_t current;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
*
|
||||
* @return time value for day number
|
||||
*/
|
||||
inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE
|
||||
extern inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_date_day (ecma_number_t time) /**< time value */
|
||||
{
|
||||
JERRY_ASSERT (!ecma_number_is_nan (time));
|
||||
@@ -57,7 +57,7 @@ ecma_date_day (ecma_number_t time) /**< time value */
|
||||
*
|
||||
* @return time value within the day
|
||||
*/
|
||||
inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE
|
||||
extern inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_date_time_within_day (ecma_number_t time) /**< time value */
|
||||
{
|
||||
JERRY_ASSERT (!ecma_number_is_nan (time));
|
||||
@@ -587,7 +587,7 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
const uint32_t date_buffer_length = 34;
|
||||
const uint32_t date_buffer_length = 37;
|
||||
JERRY_VLA (lit_utf8_byte_t, date_buffer, date_buffer_length);
|
||||
|
||||
lit_utf8_byte_t *dest_p = date_buffer;
|
||||
@@ -611,7 +611,32 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
|
||||
case LIT_CHAR_UPPERCASE_Y: /* Year. */
|
||||
{
|
||||
number = (int32_t) ecma_date_year_from_time (datetime_number);
|
||||
number_length = 4;
|
||||
|
||||
if (number >= 100000 || number <= -100000)
|
||||
{
|
||||
number_length = 6;
|
||||
}
|
||||
else if (number >= 10000 || number <= -10000)
|
||||
{
|
||||
number_length = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
number_length = 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LIT_CHAR_LOWERCASE_Y: /* ISO Year: -000001, 0000, 0001, 9999, +012345 */
|
||||
{
|
||||
number = (int32_t) ecma_date_year_from_time (datetime_number);
|
||||
if (0 <= number && number <= 9999)
|
||||
{
|
||||
number_length = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
number_length = 6;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LIT_CHAR_UPPERCASE_M: /* Month. */
|
||||
@@ -723,6 +748,17 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
|
||||
/* Print right aligned number values. */
|
||||
JERRY_ASSERT (number_length > 0);
|
||||
|
||||
if (number < 0)
|
||||
{
|
||||
number = -number;
|
||||
*dest_p++ = '-';
|
||||
}
|
||||
else if (*(format_p - 1) == LIT_CHAR_LOWERCASE_Y && number_length == 6)
|
||||
{
|
||||
/* positive sign is compulsory for extended years */
|
||||
*dest_p++ = '+';
|
||||
}
|
||||
|
||||
dest_p += number_length;
|
||||
lit_utf8_byte_t *buffer_p = dest_p;
|
||||
|
||||
@@ -785,7 +821,7 @@ ecma_date_value_to_utc_string (ecma_number_t datetime_number) /**< datetime */
|
||||
ecma_value_t
|
||||
ecma_date_value_to_iso_string (ecma_number_t datetime_number) /**<datetime */
|
||||
{
|
||||
return ecma_date_to_string_format (datetime_number, "$Y-$O-$DT$h:$m:$s.$iZ");
|
||||
return ecma_date_to_string_format (datetime_number, "$y-$O-$DT$h:$m:$s.$iZ");
|
||||
} /* ecma_date_value_to_iso_string */
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,165 +63,23 @@ ecma_json_has_object_in_stack (ecma_json_occurence_stack_item_t *stack_p, /**< s
|
||||
* @return true, if the string is already in the collection.
|
||||
*/
|
||||
bool
|
||||
ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, /**< collection */
|
||||
ecma_value_t string_value) /**< string value */
|
||||
ecma_has_string_value_in_collection (ecma_collection_t *collection_p, /**< collection */
|
||||
ecma_string_t *string_p) /**< string */
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_string (string_value));
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (string_value);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (collection_p);
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < collection_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *current_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_string_t *current_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
if (ecma_compare_ecma_strings (current_p, string_p))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
return false;
|
||||
} /* ecma_has_string_value_in_collection*/
|
||||
|
||||
/**
|
||||
* Common function to concatenate key-value pairs into an ecma-string.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 15.12.3
|
||||
*
|
||||
* Used by:
|
||||
* - ecma_builtin_helper_json_create_formatted_json step 10.b.ii
|
||||
* - ecma_builtin_helper_json_create_non_formatted_json step 10.a.i
|
||||
*
|
||||
* @return pointer to ecma-string
|
||||
* Returned value must be freed with ecma_deref_ecma_string.
|
||||
*/
|
||||
static ecma_string_t *
|
||||
ecma_builtin_helper_json_create_separated_properties (ecma_collection_header_t *partial_p, /**< key-value pairs*/
|
||||
ecma_string_t *separator_p) /**< separator*/
|
||||
{
|
||||
ecma_string_t *properties_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (partial_p);
|
||||
|
||||
bool first = true;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
{
|
||||
ecma_string_t *current_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
|
||||
if (JERRY_LIKELY (!first))
|
||||
{
|
||||
properties_str_p = ecma_concat_ecma_strings (properties_str_p, separator_p);
|
||||
}
|
||||
|
||||
properties_str_p = ecma_concat_ecma_strings (properties_str_p, current_p);
|
||||
first = false;
|
||||
}
|
||||
|
||||
return properties_str_p;
|
||||
} /* ecma_builtin_helper_json_create_separated_properties */
|
||||
|
||||
/**
|
||||
* Common function to create a formatted JSON string.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 15.12.3
|
||||
*
|
||||
* Used by:
|
||||
* - ecma_builtin_json_object step 10.b
|
||||
* - ecma_builtin_json_array step 10.b
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_builtin_helper_json_create_formatted_json (lit_utf8_byte_t left_bracket, /**< left bracket character */
|
||||
lit_utf8_byte_t right_bracket, /**< right bracket character */
|
||||
ecma_string_t *stepback_p, /**< stepback*/
|
||||
ecma_collection_header_t *partial_p, /**< key-value pairs*/
|
||||
ecma_json_stringify_context_t *context_p) /**< context*/
|
||||
{
|
||||
JERRY_ASSERT (left_bracket < LIT_UTF8_1_BYTE_CODE_POINT_MAX
|
||||
&& right_bracket < LIT_UTF8_1_BYTE_CODE_POINT_MAX);
|
||||
|
||||
/* 10.b.i */
|
||||
lit_utf8_byte_t chars[2] = { LIT_CHAR_COMMA, LIT_CHAR_LF };
|
||||
|
||||
ecma_string_t *separator_p = ecma_new_ecma_string_from_utf8 (chars, 2);
|
||||
|
||||
separator_p = ecma_concat_ecma_strings (separator_p, context_p->indent_str_p);
|
||||
|
||||
/* 10.b.ii */
|
||||
ecma_string_t *properties_str_p = ecma_builtin_helper_json_create_separated_properties (partial_p, separator_p);
|
||||
ecma_deref_ecma_string (separator_p);
|
||||
|
||||
/* 10.b.iii */
|
||||
chars[0] = left_bracket;
|
||||
|
||||
ecma_string_t *final_str_p = ecma_new_ecma_string_from_utf8 (chars, 2);
|
||||
|
||||
final_str_p = ecma_concat_ecma_strings (final_str_p, context_p->indent_str_p);
|
||||
|
||||
final_str_p = ecma_concat_ecma_strings (final_str_p, properties_str_p);
|
||||
ecma_deref_ecma_string (properties_str_p);
|
||||
|
||||
chars[0] = LIT_CHAR_LF;
|
||||
final_str_p = ecma_append_chars_to_string (final_str_p, chars, 1, 1);
|
||||
|
||||
final_str_p = ecma_concat_ecma_strings (final_str_p, stepback_p);
|
||||
|
||||
chars[0] = right_bracket;
|
||||
final_str_p = ecma_append_chars_to_string (final_str_p, chars, 1, 1);
|
||||
|
||||
return ecma_make_string_value (final_str_p);
|
||||
} /* ecma_builtin_helper_json_create_formatted_json */
|
||||
|
||||
/**
|
||||
* Common function to create a non-formatted JSON string.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 15.12.3
|
||||
*
|
||||
* Used by:
|
||||
* - ecma_builtin_json_object step 10.a
|
||||
* - ecma_builtin_json_array step 10.a
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_builtin_helper_json_create_non_formatted_json (lit_utf8_byte_t left_bracket, /**< left bracket character */
|
||||
lit_utf8_byte_t right_bracket, /**< right bracket character */
|
||||
ecma_collection_header_t *partial_p) /**< key-value pairs */
|
||||
{
|
||||
JERRY_ASSERT (left_bracket < LIT_UTF8_1_BYTE_CODE_POINT_MAX
|
||||
&& right_bracket < LIT_UTF8_1_BYTE_CODE_POINT_MAX);
|
||||
|
||||
/* 10.a */
|
||||
ecma_string_t *comma_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR);
|
||||
ecma_string_t *properties_str_p;
|
||||
|
||||
/* 10.a.i */
|
||||
properties_str_p = ecma_builtin_helper_json_create_separated_properties (partial_p, comma_str_p);
|
||||
|
||||
/* 10.a.ii */
|
||||
ecma_string_t *result_str_p = ecma_new_ecma_string_from_code_unit (left_bracket);
|
||||
|
||||
result_str_p = ecma_concat_ecma_strings (result_str_p, properties_str_p);
|
||||
ecma_deref_ecma_string (properties_str_p);
|
||||
|
||||
lit_utf8_byte_t chars[1] = { right_bracket };
|
||||
|
||||
result_str_p = ecma_append_chars_to_string (result_str_p, chars, 1, 1);
|
||||
|
||||
return ecma_make_string_value (result_str_p);
|
||||
} /* ecma_builtin_helper_json_create_non_formatted_json */
|
||||
} /* ecma_has_string_value_in_collection */
|
||||
|
||||
#endif /* ENABLED (JERRY_BUILTIN_JSON) */
|
||||
|
||||
|
||||
@@ -278,32 +278,22 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
||||
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
|
||||
|
||||
uint32_t index = 0;
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, opts);
|
||||
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, opts);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
if (props_p->item_count == 0)
|
||||
{
|
||||
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
|
||||
|
||||
ecma_value_t completion = ecma_builtin_helper_def_prop (new_array_p,
|
||||
index_string_p,
|
||||
*ecma_value_p,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
ecma_deref_ecma_string (index_string_p);
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
|
||||
index++;
|
||||
ecma_collection_destroy (props_p);
|
||||
return new_array;
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
JERRY_ASSERT (((ecma_extended_object_t *) new_array_p)->u.array.is_fast_mode);
|
||||
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
ecma_value_t *values_p = ecma_fast_array_extend (new_array_p, props_p->item_count);
|
||||
|
||||
memcpy (values_p, buffer_p, props_p->item_count * sizeof (ecma_value_t));
|
||||
|
||||
ecma_collection_free_objects (props_p);
|
||||
|
||||
return new_array;
|
||||
} /* ecma_builtin_helper_object_get_properties */
|
||||
@@ -315,7 +305,7 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
|
||||
* If the index is negative, it is used as the offset from the end of the array,
|
||||
* to compute normalized index.
|
||||
* If the index is greater than the length of the array, the normalized index will be the length of the array.
|
||||
*
|
||||
* If is_last_index_of is true, then we use the method in ECMA-262 v6, 22.2.3.16 to compute the normalized index.
|
||||
* See also:
|
||||
* ECMA-262 v5, 15.4.4.10 steps 5-6, 7 (part 2) and 8
|
||||
* ECMA-262 v5, 15.4.4.12 steps 5-6
|
||||
@@ -327,12 +317,15 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
|
||||
* - The Array.prototype.splice routine.
|
||||
* - The Array.prototype.indexOf routine.
|
||||
* - The String.prototype.slice routine.
|
||||
* - The TypedArray.prototype.indexOf routine.
|
||||
* - The TypedArray.prototype.lastIndexOf routine
|
||||
*
|
||||
* @return uint32_t - the normalized value of the index
|
||||
*/
|
||||
uint32_t
|
||||
ecma_builtin_helper_array_index_normalize (ecma_number_t index, /**< index */
|
||||
uint32_t length) /**< array's length */
|
||||
uint32_t length, /**< array's length */
|
||||
bool is_last_index_of) /**< true - normalize for lastIndexOf method*/
|
||||
{
|
||||
uint32_t norm_index;
|
||||
|
||||
@@ -345,7 +338,14 @@ ecma_builtin_helper_array_index_normalize (ecma_number_t index, /**< index */
|
||||
}
|
||||
else if (ecma_number_is_infinity (index))
|
||||
{
|
||||
norm_index = ecma_number_is_negative (index) ? 0 : length;
|
||||
if (is_last_index_of)
|
||||
{
|
||||
norm_index = ecma_number_is_negative (index) ? (uint32_t) -1 : length - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
norm_index = ecma_number_is_negative (index) ? 0 : length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -353,20 +353,27 @@ ecma_builtin_helper_array_index_normalize (ecma_number_t index, /**< index */
|
||||
{
|
||||
ecma_number_t index_neg = -index;
|
||||
|
||||
if (index_neg > length)
|
||||
if (is_last_index_of)
|
||||
{
|
||||
norm_index = 0;
|
||||
norm_index = length - ecma_number_to_uint32 (index_neg);
|
||||
}
|
||||
else
|
||||
{
|
||||
norm_index = length - ecma_number_to_uint32 (index_neg);
|
||||
if (index_neg > length)
|
||||
{
|
||||
norm_index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
norm_index = length - ecma_number_to_uint32 (index_neg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index > length)
|
||||
{
|
||||
norm_index = length;
|
||||
norm_index = is_last_index_of ? length - 1 : length;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -438,8 +445,7 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */
|
||||
ecma_value_t put_comp = ecma_builtin_helper_def_prop (obj_p,
|
||||
new_array_index_string_p,
|
||||
get_value,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (put_comp));
|
||||
ecma_deref_ecma_string (new_array_index_string_p);
|
||||
@@ -464,19 +470,12 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */
|
||||
ecma_value_t put_comp = ecma_builtin_helper_def_prop (obj_p,
|
||||
new_array_index_string_p,
|
||||
value,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
JERRY_ASSERT (ecma_is_value_true (put_comp));
|
||||
|
||||
ecma_deref_ecma_string (new_array_index_string_p);
|
||||
}
|
||||
|
||||
if (ecma_is_value_empty (ret_value))
|
||||
{
|
||||
ret_value = ECMA_VALUE_TRUE;
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_builtin_helper_array_concat_value */
|
||||
|
||||
@@ -795,6 +794,38 @@ ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, /**< index
|
||||
return match_found;
|
||||
} /* ecma_builtin_helper_string_find_index */
|
||||
|
||||
/**
|
||||
* Helper function for using [[DefineOwnProperty]] specialized for indexed property names
|
||||
*
|
||||
* Note: this method falls back to the general ecma_builtin_helper_def_prop
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, /**< object */
|
||||
uint32_t index, /**< property index */
|
||||
ecma_value_t value, /**< value */
|
||||
uint32_t opts) /**< any combination of ecma_property_flag_t bits */
|
||||
{
|
||||
if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM))
|
||||
{
|
||||
return ecma_builtin_helper_def_prop (obj_p,
|
||||
ECMA_CREATE_DIRECT_UINT32_STRING (index),
|
||||
value,
|
||||
opts);
|
||||
}
|
||||
|
||||
ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index);
|
||||
ecma_value_t ret_value = ecma_builtin_helper_def_prop (obj_p,
|
||||
index_str_p,
|
||||
value,
|
||||
opts);
|
||||
ecma_deref_ecma_string (index_str_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_builtin_helper_def_prop_by_index */
|
||||
|
||||
/**
|
||||
* Helper function for using [[DefineOwnProperty]].
|
||||
*
|
||||
@@ -809,27 +840,18 @@ ecma_value_t
|
||||
ecma_builtin_helper_def_prop (ecma_object_t *obj_p, /**< object */
|
||||
ecma_string_t *index_p, /**< index string */
|
||||
ecma_value_t value, /**< value */
|
||||
uint32_t opts, /**< any combination of ecma_property_flag_t bits */
|
||||
bool is_throw) /**< is_throw */
|
||||
uint32_t opts) /**< any combination of ecma_property_flag_t bits
|
||||
* with the optional ECMA_IS_THROW flag */
|
||||
{
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
|
||||
prop_desc.flags = (uint16_t) (ECMA_NAME_DATA_PROPERTY_DESCRIPTOR_BITS | opts);
|
||||
|
||||
prop_desc.is_value_defined = true;
|
||||
prop_desc.value = value;
|
||||
|
||||
prop_desc.is_writable_defined = true;
|
||||
prop_desc.is_writable = (opts & ECMA_PROPERTY_FLAG_WRITABLE) != 0;
|
||||
|
||||
prop_desc.is_enumerable_defined = true;
|
||||
prop_desc.is_enumerable = (opts & ECMA_PROPERTY_FLAG_ENUMERABLE) != 0;
|
||||
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = (opts & ECMA_PROPERTY_FLAG_CONFIGURABLE) != 0;
|
||||
|
||||
return ecma_op_object_define_own_property (obj_p,
|
||||
index_p,
|
||||
&prop_desc,
|
||||
is_throw);
|
||||
&prop_desc);
|
||||
} /* ecma_builtin_helper_def_prop */
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,7 +48,7 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, uint32_t opts);
|
||||
ecma_value_t
|
||||
ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, uint32_t *length_p, ecma_value_t value);
|
||||
uint32_t
|
||||
ecma_builtin_helper_array_index_normalize (ecma_number_t index, uint32_t length);
|
||||
ecma_builtin_helper_array_index_normalize (ecma_number_t index, uint32_t length, bool last_index_of);
|
||||
uint32_t
|
||||
ecma_builtin_helper_string_index_normalize (ecma_number_t index, uint32_t length, bool nan_to_zero);
|
||||
ecma_value_t
|
||||
@@ -58,8 +58,10 @@ bool
|
||||
ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, ecma_string_t *search_str_p, bool first_index,
|
||||
ecma_length_t start_pos, ecma_length_t *ret_index_p);
|
||||
ecma_value_t
|
||||
ecma_builtin_helper_def_prop (ecma_object_t *obj_p, ecma_string_t *index_p, ecma_value_t value,
|
||||
uint32_t opts, bool is_throw);
|
||||
ecma_builtin_helper_def_prop (ecma_object_t *obj_p, ecma_string_t *index_p, ecma_value_t value, uint32_t opts);
|
||||
|
||||
ecma_value_t
|
||||
ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, uint32_t index, ecma_value_t value, uint32_t opts);
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_DATE)
|
||||
|
||||
@@ -151,34 +153,33 @@ typedef struct struct_ecma_json_occurence_stack_item_t
|
||||
typedef struct
|
||||
{
|
||||
/** Collection for property keys. */
|
||||
ecma_collection_header_t *property_list_p;
|
||||
ecma_collection_t *property_list_p;
|
||||
|
||||
/** Collection for traversing objects. */
|
||||
ecma_json_occurence_stack_item_t *occurence_stack_last_p;
|
||||
|
||||
/** The actual indentation text. */
|
||||
ecma_string_t *indent_str_p;
|
||||
ecma_stringbuilder_t indent_builder;
|
||||
|
||||
/** The indentation text. */
|
||||
ecma_string_t *gap_str_p;
|
||||
|
||||
/** The replacer function. */
|
||||
ecma_object_t *replacer_function_p;
|
||||
|
||||
/** Result string builder. */
|
||||
ecma_stringbuilder_t result_builder;
|
||||
} ecma_json_stringify_context_t;
|
||||
|
||||
ecma_value_t ecma_builtin_json_parse_buffer (const lit_utf8_byte_t * str_start_p,
|
||||
lit_utf8_size_t string_size);
|
||||
ecma_value_t ecma_builtin_json_string_from_object (const ecma_value_t arg1);
|
||||
bool ecma_json_has_object_in_stack (ecma_json_occurence_stack_item_t *stack_p, ecma_object_t *object_p);
|
||||
bool ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, ecma_value_t string_value);
|
||||
bool ecma_has_string_value_in_collection (ecma_collection_t *collection_p, ecma_string_t *string_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_builtin_helper_json_create_formatted_json (lit_utf8_byte_t left_bracket, lit_utf8_byte_t right_bracket,
|
||||
ecma_string_t *stepback_p, ecma_collection_header_t *partial_p,
|
||||
ecma_json_stringify_context_t *context_p);
|
||||
ecma_value_t
|
||||
ecma_builtin_helper_json_create_non_formatted_json (lit_utf8_byte_t left_bracket, lit_utf8_byte_t right_bracket,
|
||||
ecma_collection_header_t *partial_p);
|
||||
ecma_collection_t *partial_p);
|
||||
#endif /* ENABLED (JERRY_BUILTIN_JSON) */
|
||||
|
||||
/* ecma-builtin-helper-error.c */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -632,9 +632,9 @@ ecma_builtin_number_prepare_conversion (ecma_number_t *this_num_p, /**< [out] th
|
||||
}
|
||||
|
||||
if (mode == NUMBER_ROUTINE_TO_PRECISION &&
|
||||
(arg_num < 1 || arg_num >= 22))
|
||||
(ecma_number_is_nan (arg_num) || arg_num < 1 || arg_num >= 22))
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Precision digits must be between 0 and 21."));
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Precision digits must be between 1 and 21."));
|
||||
}
|
||||
|
||||
*arg_1_int32_p = ecma_number_to_int32 (arg_num);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-conversion.h"
|
||||
@@ -91,6 +93,134 @@ ecma_builtin_number_dispatch_construct (const ecma_value_t *arguments_list_p, /*
|
||||
}
|
||||
} /* ecma_builtin_number_dispatch_construct */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN)
|
||||
/**
|
||||
* The Number object 'isFinite' routine
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 20.1.2.2
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_number_object_is_finite (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_value_t arg) /**< routine's argument */
|
||||
{
|
||||
JERRY_UNUSED (this_arg);
|
||||
|
||||
if (ecma_is_value_number (arg))
|
||||
{
|
||||
ecma_number_t num = ecma_get_number_from_value (arg);
|
||||
if (!(ecma_number_is_nan (num) || ecma_number_is_infinity (num)))
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
}
|
||||
return ECMA_VALUE_FALSE;
|
||||
} /* ecma_builtin_number_object_is_finite */
|
||||
|
||||
/**
|
||||
* The Number object 'isNan' routine
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 20.1.2.4
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_number_object_is_nan (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_value_t arg) /**< routine's argument */
|
||||
{
|
||||
JERRY_UNUSED (this_arg);
|
||||
|
||||
if (ecma_is_value_number (arg))
|
||||
{
|
||||
ecma_number_t num_val = ecma_get_number_from_value (arg);
|
||||
|
||||
if (ecma_number_is_nan (num_val))
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
}
|
||||
return ECMA_VALUE_FALSE;
|
||||
} /* ecma_builtin_number_object_is_nan */
|
||||
|
||||
/**
|
||||
* The Number object 'isInteger' routine
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 20.1.2.3
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_number_object_is_integer (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_value_t arg) /**< routine's argument */
|
||||
{
|
||||
JERRY_UNUSED (this_arg);
|
||||
if (!ecma_is_value_number (arg))
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
ecma_number_t num = ecma_get_number_from_value (arg);
|
||||
|
||||
if (ecma_number_is_nan (num) || ecma_number_is_infinity (num))
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
ecma_number_t int_num = ecma_number_trunc (num);
|
||||
|
||||
if (int_num != num)
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
return ECMA_VALUE_TRUE;
|
||||
} /* ecma_builtin_number_object_is_integer */
|
||||
|
||||
/**
|
||||
* The Number object 'isSafeInteger' routine
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 20.1.2.3
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_number_object_is_safe_integer (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_value_t arg) /**< routine's argument */
|
||||
{
|
||||
JERRY_UNUSED (this_arg);
|
||||
|
||||
if (!ecma_is_value_number (arg))
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
ecma_number_t num = ecma_get_number_from_value (arg);
|
||||
|
||||
if (ecma_number_is_nan (num) || ecma_number_is_infinity (num))
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
ecma_number_t int_num = ecma_number_trunc (num);
|
||||
|
||||
if (int_num == num && fabs (int_num) <= ECMA_NUMBER_MAX_SAFE_INTEGER)
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
|
||||
return ECMA_VALUE_FALSE;
|
||||
} /* ecma_builtin_number_object_is_safe_integer */
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@@ -64,4 +64,12 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
|
||||
|
||||
#endif /* ENABLED (JERRY_BUILTIN_NUMBER) */
|
||||
|
||||
/* Routine properties:
|
||||
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN)
|
||||
ROUTINE (LIT_MAGIC_STRING_IS_FINITE, ecma_builtin_number_object_is_finite, 1, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_IS_NAN, ecma_builtin_number_object_is_nan, 1, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_IS_INTEGER, ecma_builtin_number_object_is_integer, 1, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_IS_SAFE_INTEGER, ecma_builtin_number_object_is_safe_integer, 1, 1)
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
|
||||
#include "ecma-builtin-helpers-macro-undefs.inc.h"
|
||||
|
||||
@@ -143,10 +143,11 @@ ecma_builtin_object_object_get_prototype_of (ecma_value_t arg) /**< routine's ar
|
||||
}
|
||||
/* 2. */
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
|
||||
ecma_object_t *prototype_p = ecma_get_object_prototype (obj_p);
|
||||
jmem_cpointer_t prototype_cp = obj_p->u2.prototype_cp;
|
||||
|
||||
if (prototype_p)
|
||||
if (prototype_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, prototype_cp);
|
||||
ret_value = ecma_make_object_value (prototype_p);
|
||||
ecma_ref_object (prototype_p);
|
||||
}
|
||||
@@ -184,10 +185,21 @@ ecma_set_prototype_of (ecma_value_t o_value, /**< O */
|
||||
JERRY_ASSERT (ecma_is_value_object (v_value) || ecma_is_value_null (v_value));
|
||||
|
||||
ecma_object_t *o_p = ecma_get_object_from_value (o_value);
|
||||
ecma_object_t *v_p = ecma_is_value_null (v_value) ? NULL : ecma_get_object_from_value (v_value);
|
||||
|
||||
jmem_cpointer_t v_cp;
|
||||
|
||||
if (ecma_is_value_null (v_value))
|
||||
{
|
||||
v_cp = JMEM_CP_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_SET_NON_NULL_POINTER (v_cp, ecma_get_object_from_value (v_value));
|
||||
}
|
||||
|
||||
|
||||
/* 3., 4. */
|
||||
if (v_p == ecma_get_object_prototype (o_p))
|
||||
if (v_cp == o_p->u2.prototype_cp)
|
||||
{
|
||||
ecma_ref_object (o_p);
|
||||
return ecma_make_object_value (o_p);
|
||||
@@ -200,14 +212,10 @@ ecma_set_prototype_of (ecma_value_t o_value, /**< O */
|
||||
}
|
||||
|
||||
/* 6., 7., 8. */
|
||||
ecma_object_t *p_p = v_p;
|
||||
while (true)
|
||||
jmem_cpointer_t p_cp = v_cp;
|
||||
while (p_cp != JMEM_CP_NULL)
|
||||
{
|
||||
/* a. */
|
||||
if (p_p == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
ecma_object_t *p_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, p_cp);
|
||||
|
||||
/* b. */
|
||||
if (p_p == o_p)
|
||||
@@ -219,11 +227,11 @@ ecma_set_prototype_of (ecma_value_t o_value, /**< O */
|
||||
* [[GetPrototypeOf]] internal method */
|
||||
|
||||
/* c.ii. */
|
||||
p_p = ecma_get_object_prototype (p_p);
|
||||
p_cp = p_p->u2.prototype_cp;
|
||||
}
|
||||
|
||||
/* 9. */
|
||||
ECMA_SET_POINTER (o_p->prototype_or_outer_reference_cp, v_p);
|
||||
o_p->u2.prototype_cp = v_cp;
|
||||
|
||||
/* 10. */
|
||||
ecma_ref_object (o_p);
|
||||
@@ -313,14 +321,13 @@ ecma_builtin_object_object_get_own_property_symbols (ecma_object_t *obj_p) /**<
|
||||
static ecma_value_t
|
||||
ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument */
|
||||
{
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 2.a */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
@@ -331,26 +338,26 @@ ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument *
|
||||
}
|
||||
|
||||
/* 2.b */
|
||||
prop_desc.is_configurable = false;
|
||||
prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_CONFIGURABLE;
|
||||
prop_desc.flags |= ECMA_PROP_IS_THROW;
|
||||
|
||||
/* 2.c */
|
||||
ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
&prop_desc,
|
||||
true);
|
||||
&prop_desc);
|
||||
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (define_own_prop_ret))
|
||||
{
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
return define_own_prop_ret;
|
||||
}
|
||||
|
||||
ecma_free_value (define_own_prop_ret);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
/* 3. */
|
||||
ecma_set_object_extensible (obj_p, false);
|
||||
@@ -372,14 +379,13 @@ ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument *
|
||||
static ecma_value_t
|
||||
ecma_builtin_object_object_freeze (ecma_object_t *obj_p) /**< routine's argument */
|
||||
{
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 2.a */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
@@ -390,32 +396,33 @@ ecma_builtin_object_object_freeze (ecma_object_t *obj_p) /**< routine's argument
|
||||
}
|
||||
|
||||
/* 2.b */
|
||||
if (prop_desc.is_writable_defined && prop_desc.is_writable)
|
||||
if ((prop_desc.flags & (ECMA_PROP_IS_WRITABLE_DEFINED | ECMA_PROP_IS_WRITABLE))
|
||||
== (ECMA_PROP_IS_WRITABLE_DEFINED | ECMA_PROP_IS_WRITABLE))
|
||||
{
|
||||
prop_desc.is_writable = false;
|
||||
prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_WRITABLE;
|
||||
}
|
||||
|
||||
/* 2.c */
|
||||
prop_desc.is_configurable = false;
|
||||
prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_CONFIGURABLE;
|
||||
prop_desc.flags |= ECMA_PROP_IS_THROW;
|
||||
|
||||
/* 2.d */
|
||||
ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
&prop_desc,
|
||||
true);
|
||||
&prop_desc);
|
||||
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (define_own_prop_ret))
|
||||
{
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
return define_own_prop_ret;
|
||||
}
|
||||
|
||||
ecma_free_value (define_own_prop_ret);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
/* 3. */
|
||||
ecma_set_object_extensible (obj_p, false);
|
||||
@@ -469,14 +476,13 @@ ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine'
|
||||
ecma_value_t ret_value = ECMA_VALUE_TRUE;
|
||||
|
||||
/* 2. */
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]);
|
||||
|
||||
/* 2.a */
|
||||
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
|
||||
@@ -501,7 +507,7 @@ ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine'
|
||||
}
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_builtin_object_frozen_or_sealed_helper */
|
||||
@@ -588,20 +594,20 @@ ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine
|
||||
|
||||
ecma_object_t *props_p = ecma_get_object_from_value (props);
|
||||
/* 3. */
|
||||
ecma_collection_header_t *prop_names_p = ecma_op_object_get_property_names (props_p, ECMA_LIST_ENUMERABLE);
|
||||
uint32_t property_number = prop_names_p->item_count;
|
||||
ecma_collection_t *prop_names_p = ecma_op_object_get_property_names (props_p, ECMA_LIST_CONVERT_FAST_ARRAYS
|
||||
| ECMA_LIST_ENUMERABLE);
|
||||
ecma_value_t ret_value = ECMA_VALUE_ERROR;
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (prop_names_p);
|
||||
ecma_value_t *buffer_p = prop_names_p->buffer_p;
|
||||
|
||||
/* 4. */
|
||||
JMEM_DEFINE_LOCAL_ARRAY (property_descriptors, property_number, ecma_property_descriptor_t);
|
||||
JMEM_DEFINE_LOCAL_ARRAY (property_descriptors, prop_names_p->item_count, ecma_property_descriptor_t);
|
||||
uint32_t property_descriptor_number = 0;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < prop_names_p->item_count; i++)
|
||||
{
|
||||
/* 5.a */
|
||||
ecma_value_t desc_obj = ecma_op_object_get (props_p, ecma_get_string_from_value (*ecma_value_p));
|
||||
ecma_value_t desc_obj = ecma_op_object_get (props_p, ecma_get_string_from_value (buffer_p[i]));
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (desc_obj))
|
||||
{
|
||||
@@ -612,6 +618,8 @@ ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine
|
||||
ecma_value_t conv_result = ecma_op_to_property_descriptor (desc_obj,
|
||||
&property_descriptors[property_descriptor_number]);
|
||||
|
||||
property_descriptors[property_descriptor_number].flags |= ECMA_PROP_IS_THROW;
|
||||
|
||||
ecma_free_value (desc_obj);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (conv_result))
|
||||
@@ -622,27 +630,22 @@ ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine
|
||||
property_descriptor_number++;
|
||||
|
||||
ecma_free_value (conv_result);
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
/* 6. */
|
||||
ecma_value_p = ecma_collection_iterator_init (prop_names_p);
|
||||
buffer_p = prop_names_p->buffer_p;
|
||||
|
||||
for (uint32_t index = 0; index < property_number; index++)
|
||||
for (uint32_t i = 0; i < prop_names_p->item_count; i++)
|
||||
{
|
||||
ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p,
|
||||
ecma_get_string_from_value (*ecma_value_p),
|
||||
&property_descriptors[index],
|
||||
true);
|
||||
ecma_get_string_from_value (buffer_p[i]),
|
||||
&property_descriptors[i]);
|
||||
if (ECMA_IS_VALUE_ERROR (define_own_prop_ret))
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ecma_free_value (define_own_prop_ret);
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
ecma_ref_object (obj_p);
|
||||
@@ -659,7 +662,7 @@ cleanup:
|
||||
|
||||
JMEM_FINALIZE_LOCAL_ARRAY (property_descriptors);
|
||||
|
||||
ecma_free_values_collection (prop_names_p, 0);
|
||||
ecma_collection_free (prop_names_p);
|
||||
|
||||
ecma_deref_object (props_p);
|
||||
|
||||
@@ -735,10 +738,11 @@ ecma_builtin_object_object_define_property (ecma_object_t *obj_p, /**< routine's
|
||||
return conv_result;
|
||||
}
|
||||
|
||||
prop_desc.flags |= ECMA_PROP_IS_THROW;
|
||||
|
||||
ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p,
|
||||
name_str_p,
|
||||
&prop_desc,
|
||||
true);
|
||||
&prop_desc);
|
||||
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
ecma_free_value (conv_result);
|
||||
@@ -809,13 +813,14 @@ ecma_builtin_object_object_assign (const ecma_value_t arguments_list_p[], /**< a
|
||||
|
||||
/* 5.b.iii */
|
||||
/* TODO: extends this collection if symbols will be supported */
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (from_obj_p, ECMA_LIST_ENUMERABLE);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (from_obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS
|
||||
| ECMA_LIST_ENUMERABLE);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
|
||||
for (uint32_t j = 0; (j < props_p->item_count) && ecma_is_value_empty (ret_value); j++)
|
||||
{
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
|
||||
ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[j]);
|
||||
|
||||
/* 5.c.i-ii */
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
@@ -826,9 +831,9 @@ ecma_builtin_object_object_assign (const ecma_value_t arguments_list_p[], /**< a
|
||||
}
|
||||
|
||||
/* 5.c.iii */
|
||||
if (prop_desc.is_enumerable
|
||||
&& ((prop_desc.is_value_defined && !ecma_is_value_undefined (prop_desc.value))
|
||||
|| prop_desc.is_get_defined))
|
||||
if ((prop_desc.flags & ECMA_PROP_IS_ENUMERABLE)
|
||||
&& (((prop_desc.flags & ECMA_PROP_IS_VALUE_DEFINED) && !ecma_is_value_undefined (prop_desc.value))
|
||||
|| (prop_desc.flags & ECMA_PROP_IS_GET_DEFINED)))
|
||||
{
|
||||
/* 5.c.iii.1 */
|
||||
ecma_value_t prop_value = ecma_op_object_get (from_obj_p, property_name_p);
|
||||
@@ -853,12 +858,10 @@ ecma_builtin_object_object_assign (const ecma_value_t arguments_list_p[], /**< a
|
||||
ecma_free_value (prop_value);
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
}
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
ecma_deref_object (from_obj_p);
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
}
|
||||
|
||||
/* 6. */
|
||||
|
||||
@@ -482,8 +482,7 @@ ecma_builtin_promise_do_all (ecma_value_t array, /**< the array for all */
|
||||
ecma_value_t put_ret = ecma_builtin_helper_def_prop (ecma_get_object_from_value (value_array),
|
||||
index_to_str_p,
|
||||
undefined_val,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false);
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
ecma_deref_ecma_string (index_to_str_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (put_ret))
|
||||
|
||||
@@ -45,6 +45,185 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
/**
|
||||
* Helper function to retrieve the flags associated with a RegExp object
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if 'this' is not a RegExp object
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_flags_helper (ecma_value_t this, /**< this value */
|
||||
uint16_t *flags_p) /**< [out] flags */
|
||||
{
|
||||
if (!ecma_is_value_object (this)
|
||||
|| !ecma_object_class_is (ecma_get_object_from_value (this), LIT_MAGIC_STRING_REGEXP_UL))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type"));
|
||||
}
|
||||
|
||||
ecma_extended_object_t *re_obj_p = (ecma_extended_object_t *) ecma_get_object_from_value (this);
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t,
|
||||
re_obj_p->u.class_prop.u.value);
|
||||
|
||||
if (bc_p != NULL)
|
||||
{
|
||||
*flags_p = bc_p->header.status_flags;
|
||||
}
|
||||
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* ecma_builtin_regexp_prototype_flags_helper */
|
||||
|
||||
/**
|
||||
* The RegExp.prototype object's 'flags' accessor property
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 21.2.5.3
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if 'this' is not a RegExp object
|
||||
* string value - otherwise
|
||||
*
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_get_flags (ecma_value_t this_arg) /**< this argument */
|
||||
{
|
||||
uint16_t flags = RE_FLAG_EMPTY;
|
||||
ecma_value_t ret_value = ecma_builtin_regexp_prototype_flags_helper (this_arg, &flags);
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
ecma_stringbuilder_t result = ecma_stringbuilder_create ();
|
||||
|
||||
if (flags & RE_FLAG_GLOBAL)
|
||||
{
|
||||
ecma_stringbuilder_append_byte (&result, LIT_CHAR_LOWERCASE_G);
|
||||
}
|
||||
|
||||
if (flags & RE_FLAG_IGNORE_CASE)
|
||||
{
|
||||
ecma_stringbuilder_append_byte (&result, LIT_CHAR_LOWERCASE_I);
|
||||
}
|
||||
|
||||
if (flags & RE_FLAG_MULTILINE)
|
||||
{
|
||||
ecma_stringbuilder_append_byte (&result, LIT_CHAR_LOWERCASE_M);
|
||||
}
|
||||
|
||||
return ecma_make_string_value (ecma_stringbuilder_finalize (&result));
|
||||
} /* ecma_builtin_regexp_prototype_get_flags */
|
||||
|
||||
/**
|
||||
* The RegExp.prototype object's 'source' accessor property
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 21.2.5.10
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if 'this' is not a RegExp object
|
||||
* string value - otherwise
|
||||
*
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_get_source (ecma_value_t this_arg) /**< this argument */
|
||||
{
|
||||
if (!ecma_is_value_object (this_arg)
|
||||
|| !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_REGEXP_UL))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type"));
|
||||
}
|
||||
|
||||
ecma_extended_object_t *re_obj_p = (ecma_extended_object_t *) ecma_get_object_from_value (this_arg);
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t,
|
||||
re_obj_p->u.class_prop.u.value);
|
||||
|
||||
if (bc_p != NULL)
|
||||
{
|
||||
ecma_ref_ecma_string (ecma_get_string_from_value (bc_p->source));
|
||||
return bc_p->source;
|
||||
}
|
||||
|
||||
return ecma_make_string_value (ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP));
|
||||
} /* ecma_builtin_regexp_prototype_get_source */
|
||||
|
||||
/**
|
||||
* The RegExp.prototype object's 'global' accessor property
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 21.2.5.4
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if 'this' is not a RegExp object
|
||||
* ECMA_VALUE_TRUE - if 'global' flag is set
|
||||
* ECMA_VALUE_FALSE - otherwise
|
||||
*
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_get_global (ecma_value_t this_arg) /**< this argument */
|
||||
{
|
||||
uint16_t flags = RE_FLAG_EMPTY;
|
||||
ecma_value_t ret_value = ecma_builtin_regexp_prototype_flags_helper (this_arg, &flags);
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
return ecma_make_boolean_value (flags & RE_FLAG_GLOBAL);
|
||||
} /* ecma_builtin_regexp_prototype_get_global */
|
||||
|
||||
/**
|
||||
* The RegExp.prototype object's 'ignoreCase' accessor property
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 21.2.5.5
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if 'this' is not a RegExp object
|
||||
* ECMA_VALUE_TRUE - if 'ignoreCase' flag is set
|
||||
* ECMA_VALUE_FALSE - otherwise
|
||||
*
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_get_ignorecase (ecma_value_t this_arg) /**< this argument */
|
||||
{
|
||||
uint16_t flags = RE_FLAG_EMPTY;
|
||||
ecma_value_t ret_value = ecma_builtin_regexp_prototype_flags_helper (this_arg, &flags);
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
return ecma_make_boolean_value (flags & RE_FLAG_IGNORE_CASE);
|
||||
} /* ecma_builtin_regexp_prototype_get_ignorecase */
|
||||
|
||||
/**
|
||||
* The RegExp.prototype object's 'multiline' accessor property
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 21.2.5.7
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if 'this' is not a RegExp object
|
||||
* ECMA_VALUE_TRUE - if 'multiline' flag is set
|
||||
* ECMA_VALUE_FALSE - otherwise
|
||||
*
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_get_multiline (ecma_value_t this_arg) /**< this argument */
|
||||
{
|
||||
uint16_t flags = RE_FLAG_EMPTY;
|
||||
ecma_value_t ret_value = ecma_builtin_regexp_prototype_flags_helper (this_arg, &flags);
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
return ecma_make_boolean_value (flags & RE_FLAG_MULTILINE);
|
||||
} /* ecma_builtin_regexp_prototype_get_multiline */
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_ANNEXB)
|
||||
|
||||
/**
|
||||
@@ -68,89 +247,40 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
|
||||
/* The builtin RegExp.prototype object does not have [[RegExpMatcher]] internal slot */
|
||||
|| ecma_get_object_from_value (this_arg) == ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type"));
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type"));
|
||||
}
|
||||
|
||||
uint16_t flags = 0;
|
||||
|
||||
if (ecma_is_value_object (pattern_arg)
|
||||
&& ecma_object_class_is (ecma_get_object_from_value (pattern_arg), LIT_MAGIC_STRING_REGEXP_UL))
|
||||
&& ecma_object_class_is (ecma_get_object_from_value (pattern_arg), LIT_MAGIC_STRING_REGEXP_UL)
|
||||
&& ecma_get_object_from_value (pattern_arg) != ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE))
|
||||
{
|
||||
if (!ecma_is_value_undefined (flags_arg))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument of RegExp compile."));
|
||||
}
|
||||
/* Compile from existing RegExp pbject. */
|
||||
ecma_object_t *target_p = ecma_get_object_from_value (pattern_arg);
|
||||
|
||||
/* Get source. */
|
||||
ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE);
|
||||
ecma_value_t source_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
ecma_string_t *pattern_string_p = ecma_get_string_from_value (source_value);
|
||||
|
||||
/* Get flags. */
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL);
|
||||
ecma_value_t global_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (global_value));
|
||||
|
||||
if (ecma_is_value_true (global_value))
|
||||
{
|
||||
flags |= RE_FLAG_GLOBAL;
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument"));
|
||||
}
|
||||
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_IGNORECASE_UL);
|
||||
ecma_value_t ignore_case_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
/* Compile from existing RegExp object. */
|
||||
ecma_extended_object_t *target_p = (ecma_extended_object_t *) ecma_get_object_from_value (pattern_arg);
|
||||
re_compiled_code_t *target_bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t,
|
||||
target_p->u.class_prop.u.value);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (ignore_case_value));
|
||||
ecma_object_t *this_object_p = ecma_get_object_from_value (this_arg);
|
||||
ecma_extended_object_t *current_p = (ecma_extended_object_t *) this_object_p;
|
||||
|
||||
if (ecma_is_value_true (ignore_case_value))
|
||||
{
|
||||
flags |= RE_FLAG_IGNORE_CASE;
|
||||
}
|
||||
re_compiled_code_t *current_bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t,
|
||||
current_p->u.class_prop.u.value);
|
||||
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MULTILINE);
|
||||
ecma_value_t multiline_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (multiline_value));
|
||||
|
||||
if (ecma_is_value_true (multiline_value))
|
||||
{
|
||||
flags |= RE_FLAG_MULTILINE;
|
||||
}
|
||||
|
||||
ecma_value_t obj_this = ecma_op_to_object (this_arg);
|
||||
if (ECMA_IS_VALUE_ERROR (obj_this))
|
||||
{
|
||||
return obj_this;
|
||||
}
|
||||
ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this);
|
||||
|
||||
/* Get bytecode property. */
|
||||
ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.u.value);
|
||||
|
||||
/* TODO: We currently have to re-compile the bytecode, because
|
||||
* we can't copy it without knowing its length. */
|
||||
const re_compiled_code_t *new_bc_p = NULL;
|
||||
ecma_value_t bc_comp = re_compile_bytecode (&new_bc_p, pattern_string_p, flags);
|
||||
/* Should always succeed, since we're compiling from a source that has been compiled previously. */
|
||||
JERRY_ASSERT (ecma_is_value_empty (bc_comp));
|
||||
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
|
||||
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t, *bc_prop_p);
|
||||
|
||||
if (old_bc_p != NULL)
|
||||
{
|
||||
/* Free the old bytecode */
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
}
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (*bc_prop_p, new_bc_p);
|
||||
|
||||
re_initialize_props (this_obj_p, pattern_string_p, flags);
|
||||
ecma_free_value (obj_this);
|
||||
JERRY_ASSERT (current_bc_p != NULL);
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) current_bc_p);
|
||||
|
||||
JERRY_ASSERT (target_bc_p != NULL);
|
||||
ecma_bytecode_ref ((ecma_compiled_code_t *) target_bc_p);
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (current_p->u.class_prop.u.value, target_bc_p);
|
||||
ecma_regexp_initialize_props (this_object_p,
|
||||
ecma_get_string_from_value (target_bc_p->source),
|
||||
target_bc_p->header.status_flags);
|
||||
return ecma_copy_value (this_arg);
|
||||
}
|
||||
|
||||
@@ -175,7 +305,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
|
||||
return flags_str_value;
|
||||
}
|
||||
|
||||
ecma_value_t parsed_flags_val = re_parse_regexp_flags (ecma_get_string_from_value (flags_str_value), &flags);
|
||||
ecma_value_t parsed_flags_val = ecma_regexp_parse_flags (ecma_get_string_from_value (flags_str_value), &flags);
|
||||
ecma_free_value (flags_str_value);
|
||||
if (ECMA_IS_VALUE_ERROR (parsed_flags_val))
|
||||
{
|
||||
@@ -193,26 +323,16 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
|
||||
return bc_val;
|
||||
}
|
||||
|
||||
ecma_value_t obj_this = ecma_op_to_object (this_arg);
|
||||
if (ECMA_IS_VALUE_ERROR (obj_this))
|
||||
{
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
return obj_this;
|
||||
}
|
||||
ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this);
|
||||
ecma_object_t *this_obj_p = ecma_get_object_from_value (this_arg);
|
||||
ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.u.value);
|
||||
|
||||
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t, *bc_prop_p);
|
||||
|
||||
if (old_bc_p != NULL)
|
||||
{
|
||||
/* Free the old bytecode */
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
}
|
||||
JERRY_ASSERT (old_bc_p != NULL);
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (*bc_prop_p, new_bc_p);
|
||||
re_initialize_props (this_obj_p, pattern_string_p, flags);
|
||||
ecma_free_value (obj_this);
|
||||
ecma_regexp_initialize_props (this_obj_p, pattern_string_p, flags);
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
|
||||
return ecma_copy_value (this_arg);
|
||||
@@ -254,26 +374,7 @@ ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */
|
||||
return input_str_value;
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
|
||||
ecma_value_t *bytecode_prop_p = &(((ecma_extended_object_t *) obj_p)->u.class_prop.u.value);
|
||||
|
||||
void *bytecode_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (void, *bytecode_prop_p);
|
||||
|
||||
ecma_value_t ret_value;
|
||||
if (bytecode_p == NULL)
|
||||
{
|
||||
/* Missing bytecode means empty RegExp: '/(?:)/', so always return empty string. */
|
||||
ecma_value_t empty_str_val = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
|
||||
ret_value = ecma_op_create_array_object (&empty_str_val, 1, false);
|
||||
re_set_result_array_properties (ecma_get_object_from_value (ret_value),
|
||||
ecma_get_string_from_value (input_str_value),
|
||||
1,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_regexp_exec_helper (obj_this, input_str_value, false);
|
||||
}
|
||||
ecma_value_t ret_value = ecma_regexp_exec_helper (obj_this, input_str_value, false);
|
||||
|
||||
ecma_free_value (obj_this);
|
||||
ecma_free_value (input_str_value);
|
||||
@@ -296,15 +397,15 @@ static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_test (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_value_t arg) /**< routine's argument */
|
||||
{
|
||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
||||
ecma_value_t result = ecma_builtin_regexp_prototype_exec (this_arg, arg);
|
||||
|
||||
ECMA_TRY_CATCH (match_value,
|
||||
ecma_builtin_regexp_prototype_exec (this_arg, arg),
|
||||
ret_value);
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
ret_value = ecma_make_boolean_value (!ecma_is_value_null (match_value));
|
||||
|
||||
ECMA_FINALIZE (match_value);
|
||||
ecma_value_t ret_value = ecma_make_boolean_value (!ecma_is_value_null (result));
|
||||
ecma_free_value (result);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_builtin_regexp_prototype_test */
|
||||
@@ -321,77 +422,53 @@ ecma_builtin_regexp_prototype_test (ecma_value_t this_arg, /**< this argument */
|
||||
static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argument */
|
||||
{
|
||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
||||
|
||||
if (!ecma_is_value_object (this_arg)
|
||||
|| !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_REGEXP_UL))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type"));
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type"));
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
|
||||
ecma_extended_object_t *re_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t,
|
||||
re_obj_p->u.class_prop.u.value);
|
||||
|
||||
ecma_string_t *source_p;
|
||||
uint16_t flags;
|
||||
|
||||
if (bc_p != NULL)
|
||||
{
|
||||
source_p = ecma_get_string_from_value (bc_p->source);
|
||||
flags = bc_p->header.status_flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_TRY_CATCH (obj_this,
|
||||
ecma_op_to_object (this_arg),
|
||||
ret_value);
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
|
||||
|
||||
/* Get RegExp source from the source property */
|
||||
ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE);
|
||||
ecma_value_t source_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p);
|
||||
|
||||
ecma_string_t *output_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_SLASH_CHAR);
|
||||
ecma_string_t *source_str_p = ecma_get_string_from_value (source_value);
|
||||
output_str_p = ecma_concat_ecma_strings (output_str_p, source_str_p);
|
||||
ecma_deref_ecma_string (source_str_p);
|
||||
|
||||
lit_utf8_byte_t flags[4];
|
||||
lit_utf8_byte_t *flags_p = flags;
|
||||
|
||||
*flags_p++ = LIT_CHAR_SLASH;
|
||||
|
||||
/* Check the global flag */
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL);
|
||||
ecma_value_t global_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (global_value));
|
||||
|
||||
if (ecma_is_value_true (global_value))
|
||||
{
|
||||
*flags_p++ = LIT_CHAR_LOWERCASE_G;
|
||||
}
|
||||
|
||||
/* Check the ignoreCase flag */
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_IGNORECASE_UL);
|
||||
ecma_value_t ignore_case_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (ignore_case_value));
|
||||
|
||||
if (ecma_is_value_true (ignore_case_value))
|
||||
{
|
||||
*flags_p++ = LIT_CHAR_LOWERCASE_I;
|
||||
}
|
||||
|
||||
/* Check the multiline flag */
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MULTILINE);
|
||||
ecma_value_t multiline_value = ecma_op_object_get_own_data_prop (obj_p, magic_string_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (multiline_value));
|
||||
|
||||
if (ecma_is_value_true (multiline_value))
|
||||
{
|
||||
*flags_p++ = LIT_CHAR_LOWERCASE_M;
|
||||
}
|
||||
|
||||
lit_utf8_size_t size = (lit_utf8_size_t) (flags_p - flags);
|
||||
output_str_p = ecma_append_chars_to_string (output_str_p, flags, size, size);
|
||||
|
||||
ret_value = ecma_make_string_value (output_str_p);
|
||||
|
||||
ECMA_FINALIZE (obj_this);
|
||||
source_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
|
||||
flags = RE_FLAG_EMPTY;
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
ecma_stringbuilder_t result = ecma_stringbuilder_create ();
|
||||
ecma_stringbuilder_append_byte (&result, LIT_CHAR_SLASH);
|
||||
ecma_stringbuilder_append (&result, source_p);
|
||||
ecma_stringbuilder_append_byte (&result, LIT_CHAR_SLASH);
|
||||
|
||||
if (flags & RE_FLAG_GLOBAL)
|
||||
{
|
||||
ecma_stringbuilder_append_byte (&result, LIT_CHAR_LOWERCASE_G);
|
||||
}
|
||||
|
||||
if (flags & RE_FLAG_IGNORE_CASE)
|
||||
{
|
||||
ecma_stringbuilder_append_byte (&result, LIT_CHAR_LOWERCASE_I);
|
||||
}
|
||||
|
||||
if (flags & RE_FLAG_MULTILINE)
|
||||
{
|
||||
ecma_stringbuilder_append_byte (&result, LIT_CHAR_LOWERCASE_M);
|
||||
}
|
||||
|
||||
return ecma_make_string_value (ecma_stringbuilder_finalize (&result));
|
||||
} /* ecma_builtin_regexp_prototype_to_string */
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,27 @@ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
|
||||
ECMA_BUILTIN_ID_REGEXP,
|
||||
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_FLAGS,
|
||||
ecma_builtin_regexp_prototype_get_flags,
|
||||
ECMA_PROPERTY_FIXED)
|
||||
|
||||
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_SOURCE,
|
||||
ecma_builtin_regexp_prototype_get_source,
|
||||
ECMA_PROPERTY_FIXED)
|
||||
|
||||
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_GLOBAL,
|
||||
ecma_builtin_regexp_prototype_get_global,
|
||||
ECMA_PROPERTY_FIXED)
|
||||
|
||||
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_IGNORECASE_UL,
|
||||
ecma_builtin_regexp_prototype_get_ignorecase,
|
||||
ECMA_PROPERTY_FIXED)
|
||||
|
||||
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_MULTILINE,
|
||||
ecma_builtin_regexp_prototype_get_multiline,
|
||||
ECMA_PROPERTY_FIXED)
|
||||
#else /* !ENABLED (JERRY_ES2015) */
|
||||
/* ECMA-262 v5, 15.10.7.1 */
|
||||
STRING_VALUE (LIT_MAGIC_STRING_SOURCE,
|
||||
LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP,
|
||||
@@ -45,6 +66,7 @@ SIMPLE_VALUE (LIT_MAGIC_STRING_IGNORECASE_UL,
|
||||
SIMPLE_VALUE (LIT_MAGIC_STRING_MULTILINE,
|
||||
ECMA_VALUE_FALSE,
|
||||
ECMA_PROPERTY_FIXED)
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/* ECMA-262 v5, 15.10.7.5 */
|
||||
NUMBER_VALUE (LIT_MAGIC_STRING_LASTINDEX_UL,
|
||||
|
||||
@@ -110,7 +110,7 @@ ecma_builtin_regexp_dispatch_construct (const ecma_value_t *arguments_list_p, /*
|
||||
|
||||
ecma_string_t *flags_string_p = ecma_get_string_from_value (flags_str_value);
|
||||
JERRY_ASSERT (flags_string_p != NULL);
|
||||
ret_value = re_parse_regexp_flags (flags_string_p, &flags);
|
||||
ret_value = ecma_regexp_parse_flags (flags_string_p, &flags);
|
||||
ecma_free_value (flags_str_value); // implicit frees flags_string_p
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
|
||||
@@ -462,8 +462,7 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_to_string_value, /
|
||||
ecma_value_t completion = ecma_builtin_helper_def_prop (new_array_obj_p,
|
||||
current_index_str_p,
|
||||
match_string_value,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
@@ -1276,7 +1275,7 @@ ecma_builtin_string_prototype_object_slice (ecma_string_t *get_string_val, /**<
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
start = ecma_builtin_helper_array_index_normalize (start_num, len);
|
||||
start = ecma_builtin_helper_array_index_normalize (start_num, len, false);
|
||||
|
||||
/* 5. 7. */
|
||||
if (ecma_is_value_undefined (arg2))
|
||||
@@ -1292,10 +1291,9 @@ ecma_builtin_string_prototype_object_slice (ecma_string_t *get_string_val, /**<
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
end = ecma_builtin_helper_array_index_normalize (end_num, len);
|
||||
end = ecma_builtin_helper_array_index_normalize (end_num, len, false);
|
||||
}
|
||||
|
||||
|
||||
JERRY_ASSERT (start <= len && end <= len);
|
||||
|
||||
/* 8-9. */
|
||||
@@ -1358,8 +1356,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
|
||||
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
|
||||
zero_str_p,
|
||||
this_to_string_val,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (put_comp));
|
||||
|
||||
@@ -1435,8 +1432,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
|
||||
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
|
||||
zero_str_p,
|
||||
this_to_string_val,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (put_comp));
|
||||
ecma_deref_ecma_string (zero_str_p);
|
||||
@@ -1510,34 +1506,38 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
|
||||
ecma_object_t *match_obj_p = ecma_get_object_from_value (match_result);
|
||||
ecma_string_t *zero_str_p = ecma_get_ecma_string_from_uint32 (0);
|
||||
ecma_string_t *magic_index_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INDEX);
|
||||
ecma_property_value_t *index_prop_value_p;
|
||||
ecma_value_t index_prop_value;
|
||||
|
||||
if (separator_is_regexp)
|
||||
{
|
||||
index_prop_value_p = ecma_get_named_data_property (match_obj_p, magic_index_str_p);
|
||||
JERRY_ASSERT (ecma_get_object_type (match_obj_p) != ECMA_OBJECT_TYPE_ARRAY
|
||||
|| !((ecma_extended_object_t *) match_obj_p)->u.array.is_fast_mode);
|
||||
|
||||
ecma_property_value_t *index_prop_value_p = ecma_get_named_data_property (match_obj_p, magic_index_str_p);
|
||||
ecma_number_t index_num = ecma_get_number_from_value (index_prop_value_p->value);
|
||||
ecma_value_assign_number (&index_prop_value_p->value, index_num + (ecma_number_t) curr_pos);
|
||||
index_prop_value = index_prop_value_p->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t opts = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW;
|
||||
ecma_string_t *separator_str_p = ecma_get_string_from_value (separator);
|
||||
|
||||
ecma_value_t put_comp = ecma_builtin_helper_def_prop (match_obj_p,
|
||||
zero_str_p,
|
||||
ecma_make_string_value (separator_str_p),
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
true); /* Failure handling */
|
||||
opts);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (put_comp));
|
||||
|
||||
index_prop_value_p = ecma_create_named_data_property (match_obj_p,
|
||||
magic_index_str_p,
|
||||
ECMA_PROPERTY_FLAG_WRITABLE,
|
||||
NULL);
|
||||
index_prop_value = ecma_make_uint32_value (curr_pos);
|
||||
|
||||
ecma_named_data_property_assign_value (match_obj_p,
|
||||
index_prop_value_p,
|
||||
ecma_make_uint32_value (curr_pos));
|
||||
put_comp = ecma_builtin_helper_def_prop (match_obj_p,
|
||||
magic_index_str_p,
|
||||
index_prop_value,
|
||||
ECMA_PROPERTY_FLAG_WRITABLE);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (put_comp));
|
||||
}
|
||||
|
||||
ecma_value_t match_comp_value = ecma_op_object_get (match_obj_p, zero_str_p);
|
||||
@@ -1550,7 +1550,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
|
||||
|
||||
ecma_free_value (match_comp_value);
|
||||
|
||||
ecma_number_t index_num = ecma_get_number_from_value (index_prop_value_p->value);
|
||||
ecma_number_t index_num = ecma_get_number_from_value (index_prop_value);
|
||||
JERRY_ASSERT (index_num >= 0);
|
||||
|
||||
|
||||
@@ -1571,8 +1571,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
|
||||
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
|
||||
array_length_str_p,
|
||||
ecma_make_string_value (substr_str_p),
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (put_comp));
|
||||
|
||||
@@ -1616,8 +1615,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
|
||||
put_comp = ecma_builtin_helper_def_prop (new_array_p,
|
||||
new_array_idx_str_p,
|
||||
match_comp_value,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (put_comp));
|
||||
|
||||
@@ -1662,8 +1660,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
|
||||
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
|
||||
array_length_string_p,
|
||||
ecma_make_string_value (substr_str_p),
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (put_comp));
|
||||
|
||||
@@ -1886,43 +1883,49 @@ ecma_builtin_string_prototype_object_trim (ecma_string_t *original_string_p) /**
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_string_prototype_object_repeat (ecma_string_t *original_string_p, /**< this argument */
|
||||
ecma_value_t count) /**< times to repeat */
|
||||
ecma_value_t repeat) /**< times to repeat */
|
||||
{
|
||||
ecma_string_t *ret_string_p;
|
||||
|
||||
/* 4 */
|
||||
ecma_number_t length_number;
|
||||
ecma_value_t length_value = ecma_get_number (count, &length_number);
|
||||
ecma_number_t count_number;
|
||||
ecma_value_t count_value = ecma_get_number (repeat, &count_number);
|
||||
|
||||
/* 5 */
|
||||
if (ECMA_IS_VALUE_ERROR (length_value))
|
||||
if (ECMA_IS_VALUE_ERROR (count_value))
|
||||
{
|
||||
return length_value;
|
||||
return count_value;
|
||||
}
|
||||
|
||||
int32_t length = ecma_number_to_int32 (length_number);
|
||||
int32_t repeat_count = ecma_number_to_int32 (count_number);
|
||||
|
||||
bool isNan = ecma_number_is_nan (length_number);
|
||||
bool isNan = ecma_number_is_nan (count_number);
|
||||
|
||||
/* 6, 7 */
|
||||
if (length_number < 0 || (!isNan && ecma_number_is_infinity (length_number)))
|
||||
if (count_number < 0 || (!isNan && ecma_number_is_infinity (count_number)))
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid count value"));
|
||||
}
|
||||
|
||||
if (length == 0 || isNan)
|
||||
lit_utf8_size_t size = ecma_string_get_size (original_string_p);
|
||||
|
||||
if (repeat_count == 0 || size == 0 || isNan)
|
||||
{
|
||||
return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
|
||||
}
|
||||
|
||||
lit_utf8_size_t size = ecma_string_get_utf8_size (original_string_p);
|
||||
lit_utf8_size_t total_size = size * (lit_utf8_size_t) length;
|
||||
if ((uint32_t) repeat_count >= (ECMA_STRING_SIZE_LIMIT / size))
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid string length"));
|
||||
}
|
||||
|
||||
lit_utf8_size_t total_size = size * (lit_utf8_size_t) repeat_count;
|
||||
|
||||
JMEM_DEFINE_LOCAL_ARRAY (str_buffer, total_size, lit_utf8_byte_t);
|
||||
|
||||
lit_utf8_byte_t *buffer_ptr = str_buffer;
|
||||
|
||||
for (int32_t n = 0; n < length; n++)
|
||||
for (int32_t n = 0; n < repeat_count; n++)
|
||||
{
|
||||
buffer_ptr += ecma_string_copy_to_cesu8_buffer (original_string_p, buffer_ptr,
|
||||
(lit_utf8_size_t) (size));
|
||||
|
||||
@@ -102,11 +102,14 @@ ecma_builtin_symbol_for_helper (ecma_value_t value_to_find) /**< symbol or ecma-
|
||||
string_p = ecma_get_symbol_from_value (value_to_find);
|
||||
}
|
||||
|
||||
ecma_lit_storage_item_t *symbol_list_p = JERRY_CONTEXT (symbol_list_first_p);
|
||||
jmem_cpointer_t symbol_list_cp = JERRY_CONTEXT (symbol_list_first_cp);
|
||||
jmem_cpointer_t *empty_cpointer_p = NULL;
|
||||
|
||||
while (symbol_list_p != NULL)
|
||||
while (symbol_list_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_lit_storage_item_t *symbol_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_lit_storage_item_t,
|
||||
symbol_list_cp);
|
||||
|
||||
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
|
||||
{
|
||||
if (symbol_list_p->values[i] != JMEM_CP_NULL)
|
||||
@@ -145,7 +148,7 @@ ecma_builtin_symbol_for_helper (ecma_value_t value_to_find) /**< symbol or ecma-
|
||||
}
|
||||
}
|
||||
|
||||
symbol_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, symbol_list_p->next_cp);
|
||||
symbol_list_cp = symbol_list_p->next_cp;
|
||||
}
|
||||
|
||||
if (!is_for)
|
||||
@@ -175,8 +178,8 @@ ecma_builtin_symbol_for_helper (ecma_value_t value_to_find) /**< symbol or ecma-
|
||||
new_item_p->values[i] = JMEM_CP_NULL;
|
||||
}
|
||||
|
||||
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (symbol_list_first_p));
|
||||
JERRY_CONTEXT (symbol_list_first_p) = new_item_p;
|
||||
new_item_p->next_cp = JERRY_CONTEXT (symbol_list_first_cp);
|
||||
JMEM_CP_SET_NON_NULL_POINTER (JERRY_CONTEXT (symbol_list_first_cp), new_item_p);
|
||||
|
||||
return ecma_copy_value (ecma_make_symbol_value (new_symbol_p));
|
||||
} /* ecma_builtin_symbol_for_helper */
|
||||
|
||||
@@ -48,6 +48,10 @@ typedef enum
|
||||
{
|
||||
ECMA_BUILTIN_NUMBER_MAX = 256, /**< value of ECMA_NUMBER_MAX_VALUE */
|
||||
ECMA_BUILTIN_NUMBER_MIN, /**< value of ECMA_NUMBER_MIN_VALUE */
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN)
|
||||
ECMA_BUILTIN_NUMBER_EPSILON, /**< value of ECMA_NUMBER_EPSILON */
|
||||
ECMA_BUILTIN_NUMBER_MAX_SAFE_INTEGER, /**< value of ECMA_NUMBER_MAX_SAFE_INTEGER */
|
||||
#endif /* ENABLED (JERRY_BUILTIN_NUMBER) */
|
||||
ECMA_BUILTIN_NUMBER_E, /**< value of ECMA_NUMBER_E */
|
||||
ECMA_BUILTIN_NUMBER_PI, /**< value of ECMA_NUMBER_PI */
|
||||
ECMA_BUILTIN_NUMBER_LN10, /**< value of ECMA_NUMBER_LN10 */
|
||||
|
||||
@@ -276,7 +276,9 @@ ecma_builtin_is (ecma_object_t *obj_p, /**< pointer to an object */
|
||||
|
||||
/* If a built-in object is not instantiated, its value is NULL,
|
||||
hence it cannot be equal to a valid object. */
|
||||
return (obj_p == JERRY_CONTEXT (ecma_builtin_objects)[builtin_id]);
|
||||
jmem_cpointer_t builtin_cp = JERRY_CONTEXT (ecma_builtin_objects)[builtin_id];
|
||||
|
||||
return (builtin_cp != JMEM_CP_NULL && (obj_p == ECMA_GET_NON_NULL_POINTER (ecma_object_t, builtin_cp)));
|
||||
} /* ecma_builtin_is */
|
||||
|
||||
/**
|
||||
@@ -292,12 +294,12 @@ ecma_builtin_get (ecma_builtin_id_t builtin_id) /**< id of built-in to check on
|
||||
{
|
||||
JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT);
|
||||
|
||||
if (JERRY_UNLIKELY (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] == NULL))
|
||||
if (JERRY_UNLIKELY (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] == JMEM_CP_NULL))
|
||||
{
|
||||
ecma_instantiate_builtin (builtin_id);
|
||||
}
|
||||
|
||||
return JERRY_CONTEXT (ecma_builtin_objects)[builtin_id];
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_builtin_objects)[builtin_id]);
|
||||
} /* ecma_builtin_get */
|
||||
|
||||
/**
|
||||
@@ -311,9 +313,9 @@ ecma_builtin_get (ecma_builtin_id_t builtin_id) /**< id of built-in to check on
|
||||
inline ecma_object_t * JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_builtin_get_global (void)
|
||||
{
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_builtin_objects)[ECMA_BUILTIN_ID_GLOBAL] != NULL);
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_builtin_objects)[ECMA_BUILTIN_ID_GLOBAL] != JMEM_CP_NULL);
|
||||
|
||||
return JERRY_CONTEXT (ecma_builtin_objects)[ECMA_BUILTIN_ID_GLOBAL];
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_builtin_objects)[ECMA_BUILTIN_ID_GLOBAL]);
|
||||
} /* ecma_builtin_get_global */
|
||||
|
||||
/**
|
||||
@@ -339,7 +341,7 @@ static void
|
||||
ecma_instantiate_builtin (ecma_builtin_id_t obj_builtin_id) /**< built-in id */
|
||||
{
|
||||
JERRY_ASSERT (obj_builtin_id < ECMA_BUILTIN_ID__COUNT);
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_builtin_objects)[obj_builtin_id] == NULL);
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_builtin_objects)[obj_builtin_id] == JMEM_CP_NULL);
|
||||
|
||||
ecma_builtin_descriptor_t builtin_desc = ecma_builtin_descriptors[obj_builtin_id];
|
||||
ecma_builtin_id_t object_prototype_builtin_id = (ecma_builtin_id_t) (builtin_desc >> ECMA_BUILTIN_PROTOTYPE_ID_SHIFT);
|
||||
@@ -352,11 +354,12 @@ ecma_instantiate_builtin (ecma_builtin_id_t obj_builtin_id) /**< built-in id */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JERRY_CONTEXT (ecma_builtin_objects)[object_prototype_builtin_id] == NULL)
|
||||
if (JERRY_CONTEXT (ecma_builtin_objects)[object_prototype_builtin_id] == JMEM_CP_NULL)
|
||||
{
|
||||
ecma_instantiate_builtin (object_prototype_builtin_id);
|
||||
}
|
||||
prototype_obj_p = JERRY_CONTEXT (ecma_builtin_objects)[object_prototype_builtin_id];
|
||||
prototype_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t,
|
||||
JERRY_CONTEXT (ecma_builtin_objects)[object_prototype_builtin_id]);
|
||||
JERRY_ASSERT (prototype_obj_p != NULL);
|
||||
}
|
||||
|
||||
@@ -429,6 +432,8 @@ ecma_instantiate_builtin (ecma_builtin_id_t obj_builtin_id) /**< built-in id */
|
||||
|
||||
ext_object_p->u.array.length = 0;
|
||||
ext_object_p->u.array.length_prop = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
ext_object_p->u.array.is_fast_mode = false;
|
||||
ext_object_p->u.array.hole_count = 0;
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_ARRAY) */
|
||||
@@ -502,7 +507,7 @@ ecma_instantiate_builtin (ecma_builtin_id_t obj_builtin_id) /**< built-in id */
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_CONTEXT (ecma_builtin_objects)[obj_builtin_id] = obj_p;
|
||||
ECMA_SET_NON_NULL_POINTER (JERRY_CONTEXT (ecma_builtin_objects)[obj_builtin_id], obj_p);
|
||||
} /* ecma_instantiate_builtin */
|
||||
|
||||
/**
|
||||
@@ -515,10 +520,10 @@ ecma_finalize_builtins (void)
|
||||
id < ECMA_BUILTIN_ID__COUNT;
|
||||
id = (ecma_builtin_id_t) (id + 1))
|
||||
{
|
||||
if (JERRY_CONTEXT (ecma_builtin_objects)[id] != NULL)
|
||||
if (JERRY_CONTEXT (ecma_builtin_objects)[id] != JMEM_CP_NULL)
|
||||
{
|
||||
ecma_deref_object (JERRY_CONTEXT (ecma_builtin_objects)[id]);
|
||||
JERRY_CONTEXT (ecma_builtin_objects)[id] = NULL;
|
||||
ecma_deref_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_builtin_objects)[id]));
|
||||
JERRY_CONTEXT (ecma_builtin_objects)[id] = JMEM_CP_NULL;
|
||||
}
|
||||
}
|
||||
} /* ecma_finalize_builtins */
|
||||
@@ -656,9 +661,9 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|
||||
if (JERRY_UNLIKELY (ecma_prop_name_is_symbol (string_p)))
|
||||
{
|
||||
if (string_p->hash & ECMA_GLOBAL_SYMBOL_FLAG)
|
||||
if (string_p->u.hash & ECMA_GLOBAL_SYMBOL_FLAG)
|
||||
{
|
||||
magic_string_id = (string_p->hash >> ECMA_GLOBAL_SYMBOL_SHIFT);
|
||||
magic_string_id = (string_p->u.hash >> ECMA_GLOBAL_SYMBOL_SHIFT);
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
|
||||
@@ -738,6 +743,10 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
|
||||
{
|
||||
ECMA_NUMBER_MAX_VALUE,
|
||||
ECMA_NUMBER_MIN_VALUE,
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN)
|
||||
ECMA_NUMBER_EPSILON,
|
||||
ECMA_NUMBER_MAX_SAFE_INTEGER,
|
||||
#endif /* ENABLED (JERRY_BUILTIN_NUMBER) */
|
||||
ECMA_NUMBER_E,
|
||||
ECMA_NUMBER_PI,
|
||||
ECMA_NUMBER_LN10,
|
||||
@@ -745,7 +754,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
|
||||
ECMA_NUMBER_LOG2E,
|
||||
ECMA_NUMBER_LOG10E,
|
||||
ECMA_NUMBER_SQRT2,
|
||||
ECMA_NUMBER_SQRT_1_2
|
||||
ECMA_NUMBER_SQRT_1_2,
|
||||
};
|
||||
|
||||
num = builtin_number_list[curr_property_p->value - ECMA_BUILTIN_NUMBER_MAX];
|
||||
@@ -795,7 +804,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
|
||||
|
||||
ecma_string_t *symbol_p = ecma_new_symbol_from_descriptor_string (symbol_desc_value);
|
||||
lit_magic_string_id_t symbol_id = (lit_magic_string_id_t) curr_property_p->value;
|
||||
symbol_p->hash = (uint16_t) ((symbol_id << ECMA_GLOBAL_SYMBOL_SHIFT) | ECMA_GLOBAL_SYMBOL_FLAG);
|
||||
symbol_p->u.hash = (uint16_t) ((symbol_id << ECMA_GLOBAL_SYMBOL_SHIFT) | ECMA_GLOBAL_SYMBOL_FLAG);
|
||||
|
||||
value = ecma_make_symbol_value (symbol_p);
|
||||
break;
|
||||
@@ -889,24 +898,22 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
|
||||
* properties,
|
||||
* false - list all properties into main collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped 'non-enumerable'
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped 'non-enumerable'
|
||||
* collection */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_is_builtin (object_p));
|
||||
|
||||
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
|
||||
&& ecma_builtin_function_is_routine (object_p))
|
||||
{
|
||||
ecma_collection_header_t *for_enumerable_p = main_collection_p;
|
||||
ecma_collection_t *for_enumerable_p = main_collection_p;
|
||||
JERRY_UNUSED (for_enumerable_p);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
/* 'length' property is non-enumerable (ECMA-262 v5, 15) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -932,7 +939,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
|
||||
ecma_length_t index = 0;
|
||||
uint32_t *bitset_p = built_in_props_p->instantiated_bitset;
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p
|
||||
ecma_collection_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p
|
||||
: main_collection_p);
|
||||
|
||||
while (curr_property_p->magic_string_id != LIT_MAGIC_STRING__COUNT)
|
||||
@@ -960,11 +967,9 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
|
||||
{
|
||||
ecma_value_t name = ecma_make_magic_string_value ((lit_magic_string_id_t) curr_property_p->magic_string_id);
|
||||
|
||||
ecma_append_to_values_collection (for_non_enumerable_p, name, 0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, name);
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
|
||||
curr_property_p++;
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -92,8 +92,8 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, ecma_string_t
|
||||
void
|
||||
ecma_builtin_list_lazy_property_names (ecma_object_t *object_p,
|
||||
bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
bool
|
||||
ecma_builtin_is (ecma_object_t *obj_p, ecma_builtin_id_t builtin_id);
|
||||
ecma_object_t *
|
||||
|
||||
@@ -288,42 +288,31 @@ BUILTIN (ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
typedarray_prototype)
|
||||
|
||||
/* The %TypedArray% intrinsic object (ES2015 22.2.1) */
|
||||
/* The %TypedArray% intrinsic object (ES2015 22.2.1)
|
||||
Note: The routines must be in this order. */
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_TYPEDARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE,
|
||||
true,
|
||||
typedarray)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
int8array_prototype)
|
||||
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_INT8ARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY,
|
||||
true,
|
||||
int8array)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_UINT8ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
uint8array_prototype)
|
||||
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_UINT8ARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY,
|
||||
true,
|
||||
uint8array)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_INT16ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
int16array_prototype)
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY,
|
||||
true,
|
||||
uint8clampedarray)
|
||||
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_INT16ARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
@@ -331,48 +320,24 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_INT16ARRAY,
|
||||
true,
|
||||
int16array)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_UINT16ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
uint16array_prototype)
|
||||
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_UINT16ARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY,
|
||||
true,
|
||||
uint16array)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_INT32ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
int32array_prototype)
|
||||
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_INT32ARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY,
|
||||
true,
|
||||
int32array)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
uint32array_prototype)
|
||||
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_UINT32ARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY,
|
||||
true,
|
||||
uint32array)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_FLOAT32ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
float32array_prototype)
|
||||
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_FLOAT32ARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY,
|
||||
@@ -380,12 +345,6 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_FLOAT32ARRAY,
|
||||
float32array)
|
||||
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
BUILTIN (ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
float64array_prototype)
|
||||
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_FLOAT64ARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY,
|
||||
@@ -393,18 +352,62 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_FLOAT64ARRAY,
|
||||
float64array)
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
int8array_prototype)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_UINT8ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
uint8array_prototype)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
uint8clampedarray_prototype)
|
||||
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY,
|
||||
true,
|
||||
uint8clampedarray)
|
||||
BUILTIN (ECMA_BUILTIN_ID_INT16ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
int16array_prototype)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_UINT16ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
uint16array_prototype)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_INT32ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
int32array_prototype)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
uint32array_prototype)
|
||||
|
||||
BUILTIN (ECMA_BUILTIN_ID_FLOAT32ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
float32array_prototype)
|
||||
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
BUILTIN (ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE,
|
||||
true,
|
||||
float64array_prototype)
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
|
||||
|
||||
@@ -66,7 +66,7 @@ ecma_builtin_float32array_dispatch_construct (const ecma_value_t *arguments_list
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
|
||||
ECMA_BUILTIN_ID_FLOAT32ARRAY);
|
||||
ECMA_FLOAT32_ARRAY);
|
||||
} /* ecma_builtin_float32array_dispatch_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -67,7 +67,7 @@ ecma_builtin_float64array_dispatch_construct (const ecma_value_t *arguments_list
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
|
||||
ECMA_BUILTIN_ID_FLOAT64ARRAY);
|
||||
ECMA_FLOAT64_ARRAY);
|
||||
} /* ecma_builtin_float64array_dispatch_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,7 +66,7 @@ ecma_builtin_int16array_dispatch_construct (const ecma_value_t *arguments_list_p
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
|
||||
ECMA_BUILTIN_ID_INT16ARRAY);
|
||||
ECMA_INT16_ARRAY);
|
||||
} /* ecma_builtin_int16array_dispatch_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,7 +66,7 @@ ecma_builtin_int32array_dispatch_construct (const ecma_value_t *arguments_list_p
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
|
||||
ECMA_BUILTIN_ID_INT32ARRAY);
|
||||
ECMA_INT32_ARRAY);
|
||||
} /* ecma_builtin_int32array_dispatch_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,7 +66,7 @@ ecma_builtin_int8array_dispatch_construct (const ecma_value_t *arguments_list_p,
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
|
||||
ECMA_BUILTIN_ID_INT8ARRAY);
|
||||
ECMA_INT8_ARRAY);
|
||||
} /* ecma_builtin_int8array_dispatch_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,182 +25,6 @@
|
||||
#define ECMA_BUILTINS_INTERNAL
|
||||
#include "ecma-builtins-internal.h"
|
||||
|
||||
/**
|
||||
* Returns true if the builtin is a TypedArray type.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
bool
|
||||
ecma_typedarray_helper_is_typedarray (uint8_t builtin_id) /**< the builtin id of a type **/
|
||||
{
|
||||
switch (builtin_id)
|
||||
{
|
||||
case ECMA_BUILTIN_ID_INT8ARRAY:
|
||||
case ECMA_BUILTIN_ID_UINT8ARRAY:
|
||||
case ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY:
|
||||
case ECMA_BUILTIN_ID_INT16ARRAY:
|
||||
case ECMA_BUILTIN_ID_UINT16ARRAY:
|
||||
case ECMA_BUILTIN_ID_INT32ARRAY:
|
||||
case ECMA_BUILTIN_ID_UINT32ARRAY:
|
||||
case ECMA_BUILTIN_ID_FLOAT32ARRAY:
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
case ECMA_BUILTIN_ID_FLOAT64ARRAY:
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} /* ecma_typedarray_helper_is_typedarray */
|
||||
|
||||
/**
|
||||
* Get the element shift size of a TypedArray type.
|
||||
*
|
||||
* @return uint8_t
|
||||
*/
|
||||
uint8_t
|
||||
ecma_typedarray_helper_get_shift_size (uint8_t builtin_id) /**< the builtin id of the typedarray **/
|
||||
{
|
||||
switch (builtin_id)
|
||||
{
|
||||
case ECMA_BUILTIN_ID_INT8ARRAY:
|
||||
case ECMA_BUILTIN_ID_UINT8ARRAY:
|
||||
case ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
case ECMA_BUILTIN_ID_INT16ARRAY:
|
||||
case ECMA_BUILTIN_ID_UINT16ARRAY:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case ECMA_BUILTIN_ID_INT32ARRAY:
|
||||
case ECMA_BUILTIN_ID_UINT32ARRAY:
|
||||
case ECMA_BUILTIN_ID_FLOAT32ARRAY:
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
case ECMA_BUILTIN_ID_FLOAT64ARRAY:
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
} /* ecma_typedarray_helper_get_shift_size */
|
||||
|
||||
/**
|
||||
* Get the built-in TypedArray type from a magic string.
|
||||
*
|
||||
* @return uint8_t
|
||||
*/
|
||||
uint8_t
|
||||
ecma_typedarray_helper_get_builtin_id (ecma_object_t *obj_p) /**< typedarray object **/
|
||||
{
|
||||
#define TYPEDARRAY_ID_CASE(magic_id, builtin_id) \
|
||||
case magic_id: \
|
||||
{ \
|
||||
return builtin_id; \
|
||||
}
|
||||
|
||||
switch (ecma_object_get_class_name (obj_p))
|
||||
{
|
||||
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT8_ARRAY_UL, ECMA_BUILTIN_ID_INT8ARRAY)
|
||||
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT8_ARRAY_UL, ECMA_BUILTIN_ID_UINT8ARRAY)
|
||||
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL, ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY)
|
||||
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT16_ARRAY_UL, ECMA_BUILTIN_ID_INT16ARRAY)
|
||||
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT16_ARRAY_UL, ECMA_BUILTIN_ID_UINT16ARRAY)
|
||||
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT32_ARRAY_UL, ECMA_BUILTIN_ID_INT32ARRAY)
|
||||
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT32_ARRAY_UL, ECMA_BUILTIN_ID_UINT32ARRAY)
|
||||
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_FLOAT32_ARRAY_UL, ECMA_BUILTIN_ID_FLOAT32ARRAY)
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_FLOAT64_ARRAY_UL, ECMA_BUILTIN_ID_FLOAT64ARRAY)
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
#undef TYPEDARRAY_ID_CASE
|
||||
} /* ecma_typedarray_helper_get_builtin_id */
|
||||
|
||||
/**
|
||||
* Get the magic string of a TypedArray type.
|
||||
*
|
||||
* @return lit_magic_string_id_t
|
||||
*/
|
||||
lit_magic_string_id_t
|
||||
ecma_typedarray_helper_get_magic_string (uint8_t builtin_id) /**< the builtin id of the typedarray **/
|
||||
{
|
||||
#define TYPEDARRAY_ID_CASE(builtin_id, magic_id) \
|
||||
case builtin_id: \
|
||||
{ \
|
||||
return (lit_magic_string_id_t) magic_id; \
|
||||
}
|
||||
|
||||
switch (builtin_id)
|
||||
{
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT8ARRAY, LIT_MAGIC_STRING_INT8_ARRAY_UL)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8ARRAY, LIT_MAGIC_STRING_UINT8_ARRAY_UL)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY, LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT16ARRAY, LIT_MAGIC_STRING_INT16_ARRAY_UL)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT16ARRAY, LIT_MAGIC_STRING_UINT16_ARRAY_UL)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT32ARRAY, LIT_MAGIC_STRING_INT32_ARRAY_UL)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT32ARRAY, LIT_MAGIC_STRING_UINT32_ARRAY_UL)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT32ARRAY, LIT_MAGIC_STRING_FLOAT32_ARRAY_UL)
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT64ARRAY, LIT_MAGIC_STRING_FLOAT64_ARRAY_UL)
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
#undef TYPEDARRAY_ID_CASE
|
||||
} /* ecma_typedarray_helper_get_magic_string */
|
||||
|
||||
/**
|
||||
* Get the prototype ID of a TypedArray type.
|
||||
*
|
||||
* @return uint8_t
|
||||
*/
|
||||
uint8_t
|
||||
ecma_typedarray_helper_get_prototype_id (uint8_t builtin_id) /**< the builtin id of the typedarray **/
|
||||
{
|
||||
#define TYPEDARRAY_ID_CASE(builtin_id) \
|
||||
case builtin_id: \
|
||||
{ \
|
||||
return builtin_id ## _PROTOTYPE; \
|
||||
}
|
||||
|
||||
switch (builtin_id)
|
||||
{
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT8ARRAY)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8ARRAY)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT16ARRAY)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT16ARRAY)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT32ARRAY)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT32ARRAY)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT32ARRAY)
|
||||
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
|
||||
TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT64ARRAY)
|
||||
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
#undef TYPEDARRAY_ID_CASE
|
||||
} /* ecma_typedarray_helper_get_prototype_id */
|
||||
|
||||
/**
|
||||
* Common implementation of the [[Construct]] call of TypedArrays.
|
||||
*
|
||||
@@ -210,17 +34,16 @@ ecma_typedarray_helper_get_prototype_id (uint8_t builtin_id) /**< the builtin id
|
||||
ecma_value_t
|
||||
ecma_typedarray_helper_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_list_len, /**< number of arguments */
|
||||
uint8_t builtin_id) /**< the builtin id of the typedarray */
|
||||
ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */
|
||||
{
|
||||
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
|
||||
JERRY_ASSERT (ecma_typedarray_helper_is_typedarray (builtin_id));
|
||||
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (builtin_id));
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (typedarray_id));
|
||||
ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
|
||||
arguments_list_len,
|
||||
prototype_obj_p,
|
||||
ecma_typedarray_helper_get_shift_size (builtin_id),
|
||||
ecma_typedarray_helper_get_magic_string (builtin_id));
|
||||
ecma_typedarray_helper_get_shift_size (typedarray_id),
|
||||
typedarray_id);
|
||||
|
||||
return val;
|
||||
} /* ecma_typedarray_helper_dispatch_construct */
|
||||
|
||||
@@ -26,16 +26,10 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
bool ecma_typedarray_helper_is_typedarray (uint8_t builtin_id);
|
||||
uint8_t ecma_typedarray_helper_get_shift_size (uint8_t builtin_id);
|
||||
uint8_t ecma_typedarray_helper_get_builtin_id (ecma_object_t *obj_p);
|
||||
lit_magic_string_id_t ecma_typedarray_helper_get_magic_string (uint8_t builtin_id);
|
||||
uint8_t ecma_typedarray_helper_get_prototype_id (uint8_t builtin_id);
|
||||
|
||||
ecma_value_t
|
||||
ecma_typedarray_helper_dispatch_construct (const ecma_value_t *arguments_list_p,
|
||||
ecma_length_t arguments_list_len,
|
||||
uint8_t builtin_id);
|
||||
ecma_typedarray_type_t typedarray_id);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -70,6 +70,11 @@ ROUTINE (LIT_MAGIC_STRING_FILL, ecma_builtin_typedarray_prototype_fill, 3, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_SORT, ecma_builtin_typedarray_prototype_sort, 1, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_FIND, ecma_builtin_typedarray_prototype_find, 2, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_FIND_INDEX, ecma_builtin_typedarray_prototype_find_index, 2, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_INDEX_OF_UL, ecma_builtin_typedarray_prototype_index_of, NON_FIXED, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_LAST_INDEX_OF_UL, ecma_builtin_typedarray_prototype_last_index_of, NON_FIXED, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_COPY_WITHIN, ecma_builtin_typedarray_prototype_copy_within, NON_FIXED, 2)
|
||||
ROUTINE (LIT_MAGIC_STRING_SLICE, ecma_builtin_typedarray_prototype_slice, NON_FIXED, 2)
|
||||
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL, ecma_builtin_typedarray_prototype_to_locale_string, 0, 0)
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
|
||||
|
||||
|
||||
@@ -99,17 +99,17 @@ ecma_builtin_typedarray_from (ecma_value_t this_arg, /**< 'this' argument */
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a typedarray constructor"));
|
||||
}
|
||||
|
||||
ecma_object_t *proto_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (builtin_id));
|
||||
const uint8_t element_size_shift = ecma_typedarray_helper_get_shift_size (builtin_id);
|
||||
const lit_magic_string_id_t class_id = ecma_typedarray_helper_get_magic_string (builtin_id);
|
||||
ecma_typedarray_type_t typedarray_id = ecma_typedarray_helper_builtin_to_typedarray_id (builtin_id);
|
||||
|
||||
ecma_object_t *proto_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (typedarray_id));
|
||||
const uint8_t element_size_shift = ecma_typedarray_helper_get_shift_size (typedarray_id);
|
||||
|
||||
return ecma_op_typedarray_from (source,
|
||||
map_fn,
|
||||
this_in_fn,
|
||||
proto_p,
|
||||
element_size_shift,
|
||||
class_id);
|
||||
typedarray_id);
|
||||
|
||||
} /* ecma_builtin_typedarray_from */
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ ecma_builtin_uint16array_dispatch_construct (const ecma_value_t *arguments_list_
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
|
||||
ECMA_BUILTIN_ID_UINT16ARRAY);
|
||||
ECMA_UINT16_ARRAY);
|
||||
} /* ecma_builtin_uint16array_dispatch_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#define BUILTIN_UNDERSCORED_ID uint32array
|
||||
#include "ecma-builtin-internal-routines-template.inc.h"
|
||||
|
||||
#include "ecma-builtin-typedarray-helpers.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
@@ -65,14 +67,8 @@ ecma_builtin_uint32array_dispatch_construct (const ecma_value_t *arguments_list_
|
||||
{
|
||||
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
|
||||
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE);
|
||||
ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
|
||||
arguments_list_len,
|
||||
prototype_obj_p,
|
||||
2,
|
||||
LIT_MAGIC_STRING_UINT32_ARRAY_UL);
|
||||
|
||||
return val;
|
||||
return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
|
||||
ECMA_UINT32_ARRAY);
|
||||
} /* ecma_builtin_uint32array_dispatch_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,7 +66,7 @@ ecma_builtin_uint8array_dispatch_construct (const ecma_value_t *arguments_list_p
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
|
||||
ECMA_BUILTIN_ID_UINT8ARRAY);
|
||||
ECMA_UINT8_ARRAY);
|
||||
} /* ecma_builtin_uint8array_dispatch_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#define BUILTIN_UNDERSCORED_ID uint8clampedarray
|
||||
#include "ecma-builtin-internal-routines-template.inc.h"
|
||||
|
||||
#include "ecma-builtin-typedarray-helpers.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
@@ -65,15 +67,8 @@ ecma_builtin_uint8clampedarray_dispatch_construct (const ecma_value_t *arguments
|
||||
{
|
||||
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
|
||||
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY_PROTOTYPE);
|
||||
ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
|
||||
arguments_list_len,
|
||||
prototype_obj_p,
|
||||
0,
|
||||
LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL);
|
||||
|
||||
|
||||
return val;
|
||||
return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
|
||||
ECMA_UINT8_CLAMPED_ARRAY);
|
||||
} /* ecma_builtin_uint8clampedarray_dispatch_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-property-hashmap.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-number-arithmetic.h"
|
||||
#include "ecma-objects.h"
|
||||
@@ -33,6 +34,533 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate a new array object with the given length
|
||||
*
|
||||
* @return pointer to the constructed array object
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_new_array_object (ecma_length_t length) /**< length of the new array */
|
||||
{
|
||||
#if ENABLED (JERRY_BUILTIN_ARRAY)
|
||||
ecma_object_t *array_prototype_object_p = ecma_builtin_get (ECMA_BUILTIN_ID_ARRAY_PROTOTYPE);
|
||||
#else /* !ENABLED (JERRY_BUILTIN_ARRAY) */
|
||||
ecma_object_t *array_prototype_object_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
#endif /* (ENABLED (JERRY_BUILTIN_ARRAY)) */
|
||||
|
||||
ecma_object_t *object_p = ecma_create_object (array_prototype_object_p,
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_ARRAY type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
ext_obj_p->u.array.length = length;
|
||||
ext_obj_p->u.array.length_prop = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
ext_obj_p->u.array.is_fast_mode = false;
|
||||
ext_obj_p->u.array.hole_count = 0;
|
||||
|
||||
return object_p;
|
||||
} /* ecma_op_new_array_object */
|
||||
|
||||
/**
|
||||
* Allocate a new fast access mode array object with the given length
|
||||
*
|
||||
* @return NULL - if the allocation of the underlying buffer failed
|
||||
* pointer to the constructed fast access mode array object otherwise
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_new_fast_array_object (ecma_length_t length) /**< length of the new fast access mode array */
|
||||
{
|
||||
const uint32_t aligned_length = ECMA_FAST_ARRAY_ALIGN_LENGTH (length);
|
||||
ecma_value_t *values_p = NULL;
|
||||
|
||||
if (length != 0)
|
||||
{
|
||||
values_p = (ecma_value_t *) jmem_heap_alloc_block_null_on_error (aligned_length * sizeof (ecma_value_t));
|
||||
|
||||
if (JERRY_UNLIKELY (values_p == NULL))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_op_new_array_object (length);
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
ext_obj_p->u.array.is_fast_mode = true;
|
||||
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp == JMEM_CP_NULL);
|
||||
|
||||
for (uint32_t i = 0; i < aligned_length; i++)
|
||||
{
|
||||
values_p[i] = ECMA_VALUE_ARRAY_HOLE;
|
||||
}
|
||||
|
||||
ECMA_SET_POINTER (object_p->u1.property_list_cp, values_p);
|
||||
return object_p;
|
||||
} /* ecma_op_new_fast_array_object */
|
||||
|
||||
/**
|
||||
* Property name type flag for array indices.
|
||||
*/
|
||||
#define ECMA_FAST_ARRAY_UINT32_DIRECT_STRING_PROP_TYPE 0x80
|
||||
|
||||
/**
|
||||
* Converts a fast access mode array back to a normal property list based array
|
||||
*/
|
||||
void
|
||||
ecma_fast_array_convert_to_normal (ecma_object_t *object_p) /**< fast access mode array object */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
JERRY_ASSERT (ext_obj_p->u.array.is_fast_mode);
|
||||
|
||||
if (object_p->u1.property_list_cp == JMEM_CP_NULL)
|
||||
{
|
||||
ext_obj_p->u.array.is_fast_mode = false;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t length = ext_obj_p->u.array.length;
|
||||
const uint32_t aligned_length = ECMA_FAST_ARRAY_ALIGN_LENGTH (length);
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
|
||||
/* Check whether the buffer contains only array holes */
|
||||
if (JERRY_UNLIKELY (ext_obj_p->u.array.length == ext_obj_p->u.array.hole_count))
|
||||
{
|
||||
ext_obj_p->u.array.is_fast_mode = false;
|
||||
jmem_heap_free_block (values_p, aligned_length * sizeof (ecma_value_t));
|
||||
object_p->u1.property_list_cp = JMEM_CP_NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_ref_object (object_p);
|
||||
|
||||
ecma_property_pair_t *property_pair_p = NULL;
|
||||
jmem_cpointer_t next_property_pair_cp = JMEM_CP_NULL;
|
||||
|
||||
uint32_t prop_index = 1;
|
||||
int32_t index = (int32_t) (length - 1);
|
||||
|
||||
while (index >= 0)
|
||||
{
|
||||
if (ecma_is_value_array_hole (values_p[index]))
|
||||
{
|
||||
index--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prop_index == 1)
|
||||
{
|
||||
property_pair_p = ecma_alloc_property_pair ();
|
||||
property_pair_p->header.next_property_cp = next_property_pair_cp;
|
||||
property_pair_p->names_cp[0] = LIT_INTERNAL_MAGIC_STRING_DELETED;
|
||||
property_pair_p->header.types[0] = ECMA_PROPERTY_TYPE_DELETED;
|
||||
ECMA_SET_NON_NULL_POINTER (next_property_pair_cp, property_pair_p);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (index <= ECMA_DIRECT_STRING_MAX_IMM);
|
||||
|
||||
property_pair_p->names_cp[prop_index] = (jmem_cpointer_t) index;
|
||||
property_pair_p->header.types[prop_index] = (ecma_property_t) (ECMA_PROPERTY_TYPE_NAMEDDATA
|
||||
| ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE
|
||||
| ECMA_FAST_ARRAY_UINT32_DIRECT_STRING_PROP_TYPE);
|
||||
|
||||
property_pair_p->values[prop_index].value = values_p[index];
|
||||
|
||||
index--;
|
||||
prop_index = !prop_index;
|
||||
}
|
||||
|
||||
ext_obj_p->u.array.is_fast_mode = false;
|
||||
jmem_heap_free_block (values_p, aligned_length * sizeof (ecma_value_t));
|
||||
ECMA_SET_POINTER (object_p->u1.property_list_cp, property_pair_p);
|
||||
|
||||
ecma_deref_object (object_p);
|
||||
} /* ecma_fast_array_convert_to_normal */
|
||||
|
||||
#if ENABLED (JERRY_SYSTEM_ALLOCATOR)
|
||||
/**
|
||||
* Maximum length of the array length to allocate fast mode access for it
|
||||
* e.g. new Array(5000) is constructed as fast mode access array,
|
||||
* but new Array(50000000) is consturcted as normal property list based array
|
||||
*/
|
||||
#define ECMA_FAST_ARRAY_MAX_INITIAL_LENGTH (1 << 17)
|
||||
#else
|
||||
/**
|
||||
* Maximum length of the array length to allocate fast mode access for it
|
||||
* e.g. new Array(5000) is constructed as fast mode access array,
|
||||
* but new Array(50000000) is consturcted as normal property list based array
|
||||
*/
|
||||
#define ECMA_FAST_ARRAY_MAX_INITIAL_LENGTH (1 << 13)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* [[Put]] operation for a fast access mode array
|
||||
*
|
||||
* @return false - If the property name is not array index, or the requested index to be set
|
||||
* would result too much array hole in the underlying buffer. The these cases
|
||||
* the array is converted back to normal property list based array.
|
||||
* true - If the indexed property can be set with/without resizing the underlying buffer.
|
||||
*/
|
||||
bool
|
||||
ecma_fast_array_set_property (ecma_object_t *object_p, /**< fast access mode array object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
ecma_value_t value) /**< value to be set */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
uint32_t index = ecma_string_get_array_index (property_name_p);
|
||||
JERRY_ASSERT (ext_obj_p->u.array.is_fast_mode);
|
||||
|
||||
if (JERRY_UNLIKELY (index == ECMA_STRING_NOT_ARRAY_INDEX))
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (object_p);
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_value_t *values_p;
|
||||
|
||||
if (JERRY_LIKELY (index < ext_obj_p->u.array.length))
|
||||
{
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp != JMEM_CP_NULL);
|
||||
|
||||
values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
|
||||
if (ecma_is_value_array_hole (values_p[index]))
|
||||
{
|
||||
ext_obj_p->u.array.hole_count = (uint8_t) JERRY_MAX (ext_obj_p->u.array.hole_count - 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_free_value_if_not_object (values_p[index]);
|
||||
}
|
||||
|
||||
values_p[index] = ecma_copy_value_if_not_object (value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t new_holes = index - ext_obj_p->u.array.length;
|
||||
uint32_t old_length = ext_obj_p->u.array.length;
|
||||
uint32_t new_length = index + 1;
|
||||
|
||||
const uint32_t aligned_length = ECMA_FAST_ARRAY_ALIGN_LENGTH (old_length);
|
||||
|
||||
if (JERRY_LIKELY (index < aligned_length))
|
||||
{
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp != JMEM_CP_NULL);
|
||||
|
||||
values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
JERRY_ASSERT (ecma_is_value_array_hole (values_p[index]));
|
||||
ext_obj_p->u.array.length = new_length;
|
||||
ext_obj_p->u.array.hole_count = (uint8_t) JERRY_MIN (ext_obj_p->u.array.hole_count + new_holes,
|
||||
ECMA_FAST_ARRAY_MAX_HOLE_COUNT);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ext_obj_p->u.array.hole_count <= ECMA_FAST_ARRAY_MAX_HOLE_COUNT);
|
||||
|
||||
if (new_holes > (uint32_t) (ECMA_FAST_ARRAY_MAX_HOLE_COUNT - ext_obj_p->u.array.hole_count))
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (object_p);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
values_p = ecma_fast_array_extend (object_p, new_length);
|
||||
ext_obj_p->u.array.hole_count = (uint8_t) (ext_obj_p->u.array.hole_count + new_holes);
|
||||
}
|
||||
|
||||
values_p[index] = ecma_copy_value_if_not_object (value);
|
||||
|
||||
return true;
|
||||
} /* ecma_fast_array_set_property */
|
||||
|
||||
|
||||
/**
|
||||
* Extend the underlying buffer of a fast mode access array for the given new length
|
||||
*
|
||||
* @return pointer to the extended underlying buffer
|
||||
*/
|
||||
ecma_value_t *
|
||||
ecma_fast_array_extend (ecma_object_t *object_p, /**< fast access mode array object */
|
||||
uint32_t new_length) /**< new length of the fast access mode array */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
uint32_t old_length = ext_obj_p->u.array.length;
|
||||
|
||||
JERRY_ASSERT (ext_obj_p->u.array.is_fast_mode);
|
||||
JERRY_ASSERT (old_length < new_length);
|
||||
|
||||
ecma_ref_object (object_p);
|
||||
|
||||
ecma_value_t *new_values_p;
|
||||
const uint32_t old_length_aligned = ECMA_FAST_ARRAY_ALIGN_LENGTH (old_length);
|
||||
const uint32_t new_length_aligned = ECMA_FAST_ARRAY_ALIGN_LENGTH (new_length);
|
||||
|
||||
if (object_p->u1.property_list_cp == JMEM_CP_NULL)
|
||||
{
|
||||
new_values_p = jmem_heap_alloc_block (new_length_aligned * sizeof (ecma_value_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
new_values_p = (ecma_value_t *) jmem_heap_realloc_block (values_p,
|
||||
old_length_aligned * sizeof (ecma_value_t),
|
||||
new_length_aligned * sizeof (ecma_value_t));
|
||||
}
|
||||
|
||||
for (uint32_t i = old_length; i < new_length_aligned; i++)
|
||||
{
|
||||
new_values_p[i] = ECMA_VALUE_ARRAY_HOLE;
|
||||
}
|
||||
|
||||
ext_obj_p->u.array.length = new_length;
|
||||
|
||||
ECMA_SET_POINTER (object_p->u1.property_list_cp, new_values_p);
|
||||
|
||||
ecma_deref_object (object_p);
|
||||
return new_values_p;
|
||||
} /* ecma_fast_array_extend */
|
||||
|
||||
/**
|
||||
* Delete the array object's property referenced by its value pointer.
|
||||
*
|
||||
* Note: specified property must be owned by specified object.
|
||||
*/
|
||||
void
|
||||
ecma_array_object_delete_property (ecma_object_t *object_p, /**< object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
ecma_property_value_t *prop_value_p) /**< property value reference */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (!ext_obj_p->u.array.is_fast_mode)
|
||||
{
|
||||
ecma_delete_property (object_p, prop_value_p);
|
||||
return;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp != JMEM_CP_NULL);
|
||||
|
||||
uint32_t index = ecma_string_get_array_index (property_name_p);
|
||||
|
||||
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
|
||||
JERRY_ASSERT (index < ext_obj_p->u.array.length);
|
||||
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
|
||||
if (ecma_is_value_array_hole (values_p[index]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_free_value_if_not_object (values_p[index]);
|
||||
|
||||
if (JERRY_UNLIKELY (ext_obj_p->u.array.length == 1))
|
||||
{
|
||||
const uint32_t old_length_aligned = ECMA_FAST_ARRAY_ALIGN_LENGTH (ext_obj_p->u.array.length);
|
||||
jmem_heap_free_block (values_p, old_length_aligned * sizeof (ecma_value_t));
|
||||
ext_obj_p->u.array.hole_count = 0;
|
||||
ext_obj_p->u.array.length = 0;
|
||||
object_p->u1.property_list_cp = JMEM_CP_NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
values_p[index] = ECMA_VALUE_ARRAY_HOLE;
|
||||
|
||||
if (++ext_obj_p->u.array.hole_count > ECMA_FAST_ARRAY_MAX_HOLE_COUNT)
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (object_p);
|
||||
}
|
||||
} /* ecma_array_object_delete_property */
|
||||
|
||||
/**
|
||||
* Low level delete of fast access mode array items
|
||||
*
|
||||
* @return the updated value of new_length
|
||||
*/
|
||||
static uint32_t
|
||||
ecma_delete_fast_array_properties (ecma_object_t *object_p, /**< fast access mode array */
|
||||
uint32_t new_length) /**< new length of the fast access mode array */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
JERRY_ASSERT (ext_obj_p->u.array.is_fast_mode);
|
||||
|
||||
ecma_ref_object (object_p);
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
|
||||
uint32_t old_length = ext_obj_p->u.array.length;
|
||||
const uint32_t old_aligned_length = ECMA_FAST_ARRAY_ALIGN_LENGTH (old_length);
|
||||
JERRY_ASSERT (new_length < old_length);
|
||||
JERRY_ASSERT (ext_obj_p->u.array.is_fast_mode);
|
||||
|
||||
if (new_length == 0)
|
||||
{
|
||||
for (uint32_t i = 0; i < old_length; i++)
|
||||
{
|
||||
ecma_free_value_if_not_object (values_p[i]);
|
||||
}
|
||||
|
||||
jmem_heap_free_block (values_p, old_aligned_length * sizeof (ecma_value_t));
|
||||
object_p->u1.property_list_cp = JMEM_CP_NULL;
|
||||
ext_obj_p->u.array.length = new_length;
|
||||
ecma_deref_object (object_p);
|
||||
return new_length;
|
||||
}
|
||||
|
||||
for (uint32_t i = new_length; i < old_length; i++)
|
||||
{
|
||||
if (ecma_is_value_array_hole (values_p[i]))
|
||||
{
|
||||
ext_obj_p->u.array.hole_count = (uint8_t) JERRY_MAX (ext_obj_p->u.array.hole_count - 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_free_value_if_not_object (values_p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t new_aligned_length = ECMA_FAST_ARRAY_ALIGN_LENGTH (new_length);
|
||||
|
||||
ecma_value_t *new_values_p;
|
||||
new_values_p = (ecma_value_t *) jmem_heap_realloc_block (values_p,
|
||||
old_aligned_length * sizeof (ecma_value_t),
|
||||
new_aligned_length * sizeof (ecma_value_t));
|
||||
|
||||
for (uint32_t i = new_length; i < new_aligned_length; i++)
|
||||
{
|
||||
new_values_p[i] = ECMA_VALUE_ARRAY_HOLE;
|
||||
}
|
||||
|
||||
ext_obj_p->u.array.length = new_length;
|
||||
|
||||
ECMA_SET_POINTER (object_p->u1.property_list_cp, new_values_p);
|
||||
ecma_deref_object (object_p);
|
||||
|
||||
return new_length;
|
||||
} /* ecma_delete_fast_array_properties */
|
||||
|
||||
/**
|
||||
* Update the length of a fast access mode array to a new length
|
||||
*
|
||||
* Note: if the new length would result too much array hole in the underlying arraybuffer
|
||||
* the array is converted back to normal property list based array
|
||||
*/
|
||||
static void
|
||||
ecma_fast_array_set_length (ecma_object_t *object_p, /**< fast access mode array object */
|
||||
uint32_t new_length) /**< new length of the fast access mode array object*/
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
uint32_t old_length = ext_obj_p->u.array.length;
|
||||
|
||||
JERRY_ASSERT (ext_obj_p->u.array.is_fast_mode);
|
||||
JERRY_ASSERT (new_length >= old_length);
|
||||
|
||||
if (new_length == old_length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t new_holes = new_length - old_length - 1;
|
||||
|
||||
JERRY_ASSERT (ext_obj_p->u.array.hole_count <= ECMA_FAST_ARRAY_MAX_HOLE_COUNT);
|
||||
|
||||
if (new_holes > (uint32_t) (ECMA_FAST_ARRAY_MAX_HOLE_COUNT - ext_obj_p->u.array.hole_count))
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (object_p);
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_fast_array_extend (object_p, new_length);
|
||||
ext_obj_p->u.array.hole_count = (uint8_t) (ext_obj_p->u.array.hole_count + new_holes);
|
||||
|
||||
return;
|
||||
} /* ecma_fast_array_set_length */
|
||||
|
||||
/**
|
||||
* Get collection of property names of a fast access mode array object
|
||||
*
|
||||
* Note: Since the fast array object only contains indexed, enumerable, writable, configurable properties
|
||||
* we can return a collection of non-array hole array indices
|
||||
*
|
||||
* @return collection of strings - property names
|
||||
*/
|
||||
ecma_collection_t *
|
||||
ecma_fast_array_get_property_names (ecma_object_t *object_p, /**< fast access mode array object */
|
||||
uint32_t opts) /**< any combination of ecma_list_properties_options_t values */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
JERRY_ASSERT (ext_obj_p->u.array.is_fast_mode);
|
||||
|
||||
ecma_collection_t *ret_p = ecma_new_collection ();
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|
||||
if (opts & ECMA_LIST_SYMBOLS)
|
||||
{
|
||||
return ret_p;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
|
||||
|
||||
uint32_t length = ext_obj_p->u.array.length;
|
||||
|
||||
bool append_length = (!(opts & ECMA_LIST_ENUMERABLE) && !(opts & ECMA_LIST_ARRAY_INDICES));
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
if (append_length)
|
||||
{
|
||||
ecma_collection_push_back (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
}
|
||||
|
||||
return ret_p;
|
||||
}
|
||||
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
if (ecma_is_value_array_hole (values_p[i]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (i);
|
||||
|
||||
ecma_collection_push_back (ret_p, ecma_make_string_value (index_str_p));
|
||||
}
|
||||
|
||||
if (append_length)
|
||||
{
|
||||
ecma_collection_push_back (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
}
|
||||
|
||||
if (opts & ECMA_LIST_CONVERT_FAST_ARRAYS)
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (object_p);
|
||||
}
|
||||
|
||||
return ret_p;
|
||||
} /* ecma_fast_array_get_property_names */
|
||||
|
||||
/**
|
||||
* Array object creation operation.
|
||||
*
|
||||
@@ -77,6 +605,22 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of
|
||||
array_items_p = NULL;
|
||||
array_items_count = 0;
|
||||
}
|
||||
|
||||
if (length > ECMA_FAST_ARRAY_MAX_INITIAL_LENGTH)
|
||||
{
|
||||
return ecma_make_object_value (ecma_op_new_array_object (length));
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_op_new_fast_array_object (length);
|
||||
|
||||
if (object_p == NULL)
|
||||
{
|
||||
return ecma_make_object_value (ecma_op_new_array_object (length));
|
||||
}
|
||||
|
||||
JERRY_ASSERT (((ecma_extended_object_t *) object_p)->u.array.is_fast_mode);
|
||||
|
||||
return ecma_make_object_value (object_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -85,44 +629,29 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of
|
||||
array_items_count = arguments_list_len;
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_ARRAY)
|
||||
ecma_object_t *array_prototype_object_p = ecma_builtin_get (ECMA_BUILTIN_ID_ARRAY_PROTOTYPE);
|
||||
#else /* ENABLED (JERRY_BUILTIN_ARRAY) */
|
||||
ecma_object_t *array_prototype_object_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
#endif /* !(ENABLED (JERRY_BUILTIN_ARRAY)) */
|
||||
ecma_object_t *object_p = ecma_op_new_fast_array_object (length);
|
||||
|
||||
ecma_object_t *object_p = ecma_create_object (array_prototype_object_p,
|
||||
sizeof (ecma_extended_object_t),
|
||||
ECMA_OBJECT_TYPE_ARRAY);
|
||||
/* At this point we were not able to allocate a length * sizeof (ecma_value_t) amount of memory,
|
||||
so we can terminate the engine since converting it into normal property list based array
|
||||
would consume more memory. */
|
||||
if (object_p == NULL)
|
||||
{
|
||||
jerry_fatal (ERR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_ARRAY type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
if (length == 0)
|
||||
{
|
||||
return ecma_make_object_value (object_p);
|
||||
}
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
ext_obj_p->u.array.length = length;
|
||||
ext_obj_p->u.array.length_prop = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
|
||||
for (uint32_t index = 0;
|
||||
index < array_items_count;
|
||||
index++)
|
||||
{
|
||||
if (ecma_is_value_array_hole (array_items_p[index]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ecma_string_t *item_name_string_p = ecma_new_ecma_string_from_uint32 (index);
|
||||
|
||||
ecma_builtin_helper_def_prop (object_p,
|
||||
item_name_string_p,
|
||||
array_items_p[index],
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
|
||||
ecma_deref_ecma_string (item_name_string_p);
|
||||
JERRY_ASSERT (!ecma_is_value_array_hole (array_items_p[index]));
|
||||
values_p[index] = ecma_copy_value_if_not_object (array_items_p[index]);
|
||||
}
|
||||
|
||||
return ecma_make_object_value (object_p);
|
||||
@@ -161,6 +690,167 @@ ecma_op_create_array_object_by_constructor (const ecma_value_t *arguments_list_p
|
||||
} /* ecma_op_create_array_object_by_constructor */
|
||||
#endif /* ENABLED (JERRY_ES2015_CLASS) */
|
||||
|
||||
/**
|
||||
* Low level delete of array items from new_length to old_length
|
||||
*
|
||||
* Note: new_length must be less than old_length
|
||||
*
|
||||
* @return the updated value of new_length
|
||||
*/
|
||||
static uint32_t
|
||||
ecma_delete_array_properties (ecma_object_t *object_p, /**< object */
|
||||
uint32_t new_length, /**< new length */
|
||||
uint32_t old_length) /**< old length */
|
||||
{
|
||||
JERRY_ASSERT (new_length < old_length);
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (ext_obj_p->u.array.is_fast_mode)
|
||||
{
|
||||
return ecma_delete_fast_array_properties (object_p, new_length);
|
||||
}
|
||||
|
||||
/* First the minimum value of new_length is updated. */
|
||||
jmem_cpointer_t current_prop_cp = object_p->u1.property_list_cp;
|
||||
|
||||
if (current_prop_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return new_length;
|
||||
}
|
||||
|
||||
ecma_property_header_t *current_prop_p;
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
current_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, current_prop_cp);
|
||||
|
||||
if (current_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
current_prop_cp = current_prop_p->next_property_cp;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
while (current_prop_cp != JMEM_CP_NULL)
|
||||
{
|
||||
current_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, current_prop_cp);
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (current_prop_p));
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) current_prop_p;
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
{
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (current_prop_p->types[i])
|
||||
&& !ecma_is_property_configurable (current_prop_p->types[i]))
|
||||
{
|
||||
uint32_t index = ecma_string_get_property_index (current_prop_p->types[i],
|
||||
prop_pair_p->names_cp[i]);
|
||||
|
||||
if (index < old_length && index >= new_length)
|
||||
{
|
||||
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
|
||||
|
||||
new_length = index + 1;
|
||||
|
||||
if (new_length == old_length)
|
||||
{
|
||||
/* Early return. */
|
||||
return new_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current_prop_cp = current_prop_p->next_property_cp;
|
||||
}
|
||||
|
||||
/* Second all properties between new_length and old_length are deleted. */
|
||||
current_prop_cp = object_p->u1.property_list_cp;
|
||||
ecma_property_header_t *prev_prop_p = NULL;
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
JERRY_ASSERT (current_prop_cp != JMEM_CP_NULL);
|
||||
|
||||
ecma_property_hashmap_delete_status hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_NO_HASHMAP;
|
||||
current_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, current_prop_cp);
|
||||
|
||||
if (current_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
|
||||
{
|
||||
prev_prop_p = current_prop_p;
|
||||
current_prop_cp = current_prop_p->next_property_cp;
|
||||
hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
while (current_prop_cp != JMEM_CP_NULL)
|
||||
{
|
||||
current_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, current_prop_cp);
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (current_prop_p));
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) current_prop_p;
|
||||
|
||||
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
|
||||
{
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (current_prop_p->types[i])
|
||||
&& ecma_is_property_configurable (current_prop_p->types[i]))
|
||||
{
|
||||
uint32_t index = ecma_string_get_property_index (current_prop_p->types[i],
|
||||
prop_pair_p->names_cp[i]);
|
||||
|
||||
if (index < old_length && index >= new_length)
|
||||
{
|
||||
JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX);
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP)
|
||||
{
|
||||
hashmap_status = ecma_property_hashmap_delete (object_p,
|
||||
prop_pair_p->names_cp[i],
|
||||
current_prop_p->types + i);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
ecma_free_property (object_p, prop_pair_p->names_cp[i], current_prop_p->types + i);
|
||||
current_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED;
|
||||
prop_pair_p->names_cp[i] = LIT_INTERNAL_MAGIC_STRING_DELETED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (current_prop_p->types[0] == ECMA_PROPERTY_TYPE_DELETED
|
||||
&& current_prop_p->types[1] == ECMA_PROPERTY_TYPE_DELETED)
|
||||
{
|
||||
if (prev_prop_p == NULL)
|
||||
{
|
||||
object_p->u1.property_list_cp = current_prop_p->next_property_cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_prop_p->next_property_cp = current_prop_p->next_property_cp;
|
||||
}
|
||||
|
||||
jmem_cpointer_t next_prop_cp = current_prop_p->next_property_cp;
|
||||
ecma_dealloc_property_pair ((ecma_property_pair_t *) current_prop_p);
|
||||
current_prop_cp = next_prop_cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_prop_p = current_prop_p;
|
||||
current_prop_cp = current_prop_p->next_property_cp;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP)
|
||||
{
|
||||
ecma_property_hashmap_free (object_p);
|
||||
ecma_property_hashmap_create (object_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
|
||||
|
||||
return new_length;
|
||||
} /* ecma_delete_array_properties */
|
||||
|
||||
/**
|
||||
* Update the length of an array to a new length
|
||||
*
|
||||
@@ -245,6 +935,10 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object
|
||||
{
|
||||
current_len_uint32 = ecma_delete_array_properties (object_p, new_len_uint32, old_len_uint32);
|
||||
}
|
||||
else if (ext_object_p->u.array.is_fast_mode)
|
||||
{
|
||||
ecma_fast_array_set_length (object_p, new_len_uint32);
|
||||
}
|
||||
|
||||
ext_object_p->u.array.length = current_len_uint32;
|
||||
|
||||
@@ -262,6 +956,19 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object
|
||||
return ecma_reject (is_throw);
|
||||
} /* ecma_op_array_object_set_length */
|
||||
|
||||
/**
|
||||
* Property descriptor bitset for fast array data properties.
|
||||
* If the property desciptor fields contains all the flags below
|
||||
* attempt to stay fast access array during [[DefineOwnProperty]] operation.
|
||||
*/
|
||||
#define ECMA_FAST_ARRAY_DATA_PROP_FLAGS (ECMA_PROP_IS_VALUE_DEFINED \
|
||||
| ECMA_PROP_IS_ENUMERABLE_DEFINED \
|
||||
| ECMA_PROP_IS_ENUMERABLE \
|
||||
| ECMA_PROP_IS_CONFIGURABLE_DEFINED \
|
||||
| ECMA_PROP_IS_CONFIGURABLE \
|
||||
| ECMA_PROP_IS_WRITABLE_DEFINED \
|
||||
| ECMA_PROP_IS_WRITABLE)
|
||||
|
||||
/**
|
||||
* [[DefineOwnProperty]] ecma array object's operation
|
||||
*
|
||||
@@ -275,42 +982,44 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object
|
||||
ecma_value_t
|
||||
ecma_op_array_object_define_own_property (ecma_object_t *object_p, /**< the array object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
const ecma_property_descriptor_t *property_desc_p, /**< property descriptor */
|
||||
bool is_throw) /**< flag that controls failure handling */
|
||||
const ecma_property_descriptor_t *property_desc_p) /**< property descriptor */
|
||||
{
|
||||
if (ecma_string_is_length (property_name_p))
|
||||
{
|
||||
JERRY_ASSERT (property_desc_p->is_configurable_defined || !property_desc_p->is_configurable);
|
||||
JERRY_ASSERT (property_desc_p->is_enumerable_defined || !property_desc_p->is_enumerable);
|
||||
JERRY_ASSERT (property_desc_p->is_writable_defined || !property_desc_p->is_writable);
|
||||
JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE_DEFINED)
|
||||
|| !(property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE));
|
||||
JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED)
|
||||
|| !(property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE));
|
||||
JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)
|
||||
|| !(property_desc_p->flags & ECMA_PROP_IS_WRITABLE));
|
||||
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (is_throw)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_THROW)
|
||||
{
|
||||
flags |= ECMA_ARRAY_OBJECT_SET_LENGTH_FLAG_IS_THROW;
|
||||
}
|
||||
|
||||
/* Only the writable and data properties can be modified. */
|
||||
if (property_desc_p->is_configurable
|
||||
|| property_desc_p->is_enumerable
|
||||
|| property_desc_p->is_get_defined
|
||||
|| property_desc_p->is_set_defined)
|
||||
if (property_desc_p->flags & (ECMA_PROP_IS_CONFIGURABLE
|
||||
| ECMA_PROP_IS_ENUMERABLE
|
||||
| ECMA_PROP_IS_GET_DEFINED
|
||||
| ECMA_PROP_IS_SET_DEFINED))
|
||||
{
|
||||
flags |= ECMA_ARRAY_OBJECT_SET_LENGTH_FLAG_REJECT;
|
||||
}
|
||||
|
||||
if (property_desc_p->is_writable_defined)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)
|
||||
{
|
||||
flags |= ECMA_ARRAY_OBJECT_SET_LENGTH_FLAG_WRITABLE_DEFINED;
|
||||
}
|
||||
|
||||
if (property_desc_p->is_writable)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_WRITABLE)
|
||||
{
|
||||
flags |= ECMA_ARRAY_OBJECT_SET_LENGTH_FLAG_WRITABLE;
|
||||
}
|
||||
|
||||
if (property_desc_p->is_value_defined)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
|
||||
{
|
||||
return ecma_op_array_object_set_length (object_p, property_desc_p->value, flags);
|
||||
}
|
||||
@@ -324,31 +1033,53 @@ ecma_op_array_object_define_own_property (ecma_object_t *object_p, /**< the arra
|
||||
return result;
|
||||
}
|
||||
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
if (ext_object_p->u.array.is_fast_mode)
|
||||
{
|
||||
if ((property_desc_p->flags & ECMA_FAST_ARRAY_DATA_PROP_FLAGS) == ECMA_FAST_ARRAY_DATA_PROP_FLAGS)
|
||||
{
|
||||
if (ecma_fast_array_set_property (object_p, property_name_p, property_desc_p->value))
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (!ext_object_p->u.array.is_fast_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (object_p);
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_ASSERT (!ext_object_p->u.array.is_fast_mode);
|
||||
uint32_t index = ecma_string_get_array_index (property_name_p);
|
||||
|
||||
if (index == ECMA_STRING_NOT_ARRAY_INDEX)
|
||||
{
|
||||
return ecma_op_general_object_define_own_property (object_p, property_name_p, property_desc_p, is_throw);
|
||||
return ecma_op_general_object_define_own_property (object_p, property_name_p, property_desc_p);
|
||||
}
|
||||
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
bool update_length = (index >= ext_object_p->u.array.length);
|
||||
|
||||
if (update_length && !ecma_is_property_writable (ext_object_p->u.array.length_prop))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
|
||||
prop_desc = *property_desc_p;
|
||||
prop_desc.flags &= (uint16_t) ~ECMA_PROP_IS_THROW;
|
||||
|
||||
ecma_value_t completition = ecma_op_general_object_define_own_property (object_p,
|
||||
property_name_p,
|
||||
property_desc_p,
|
||||
false);
|
||||
&prop_desc);
|
||||
JERRY_ASSERT (ecma_is_value_boolean (completition));
|
||||
|
||||
if (ecma_is_value_false (completition))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
|
||||
if (update_length)
|
||||
@@ -373,19 +1104,16 @@ ecma_op_array_list_lazy_property_names (ecma_object_t *obj_p, /**< a String obje
|
||||
* false - list all properties into main
|
||||
* collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main'
|
||||
* collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
} /* ecma_op_array_list_lazy_property_names */
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,6 +25,13 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Maximum number of array holes in a fast mode access array.
|
||||
* If the number of holes exceeds this limit, the array is converted back
|
||||
* to normal property list based array.
|
||||
*/
|
||||
#define ECMA_FAST_ARRAY_MAX_HOLE_COUNT 32
|
||||
|
||||
/**
|
||||
* Flags for ecma_op_array_object_set_length
|
||||
*/
|
||||
@@ -39,6 +46,28 @@ typedef enum
|
||||
* in the property descriptor */
|
||||
} ecma_array_object_set_length_flags_t;
|
||||
|
||||
ecma_object_t *
|
||||
ecma_op_new_array_object (ecma_length_t length);
|
||||
|
||||
ecma_object_t *
|
||||
ecma_op_new_fast_array_object (ecma_length_t length);
|
||||
|
||||
ecma_value_t *
|
||||
ecma_fast_array_extend (ecma_object_t *object_p, uint32_t new_lengt);
|
||||
|
||||
bool
|
||||
ecma_fast_array_set_property (ecma_object_t *object_p, ecma_string_t *property_name_p, ecma_value_t value);
|
||||
|
||||
void
|
||||
ecma_array_object_delete_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
ecma_property_value_t *prop_value_p);
|
||||
|
||||
ecma_collection_t *
|
||||
ecma_fast_array_get_property_names (ecma_object_t *object_p, uint32_t opts);
|
||||
|
||||
void
|
||||
ecma_fast_array_convert_to_normal (ecma_object_t *object_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_op_create_array_object (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len,
|
||||
bool is_treat_single_arg_as_length);
|
||||
@@ -54,12 +83,12 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, ecma_value_t new_value
|
||||
|
||||
ecma_value_t
|
||||
ecma_op_array_object_define_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
const ecma_property_descriptor_t *property_desc_p, bool is_throw);
|
||||
const ecma_property_descriptor_t *property_desc_p);
|
||||
|
||||
void
|
||||
ecma_op_array_list_lazy_property_names (ecma_object_t *obj_p, bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-array-object.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-builtin-helpers.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-gc.h"
|
||||
@@ -244,6 +246,13 @@ ecma_op_container_to_key (ecma_value_t key_arg) /**< key argument */
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (key_arg);
|
||||
ecma_string_t *key_string_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_MAP_KEY);
|
||||
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY
|
||||
&& ((ecma_extended_object_t *) obj_p)->u.array.is_fast_mode)
|
||||
{
|
||||
ecma_fast_array_convert_to_normal (obj_p);
|
||||
}
|
||||
|
||||
ecma_property_t *property_p = ecma_find_named_property (obj_p, key_string_p);
|
||||
ecma_string_t *object_key_string;
|
||||
|
||||
@@ -259,7 +268,6 @@ ecma_op_container_to_key (ecma_value_t key_arg) /**< key argument */
|
||||
else
|
||||
{
|
||||
object_key_string = ecma_get_string_from_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
|
||||
|
||||
}
|
||||
|
||||
ecma_ref_ecma_string (object_key_string);
|
||||
@@ -381,7 +389,7 @@ ecma_value_t
|
||||
ecma_op_container_set (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_value_t key_arg, /**< key argument */
|
||||
ecma_value_t value_arg, /**< value argument */
|
||||
lit_magic_string_id_t lit_id) /**< internal class id */
|
||||
lit_magic_string_id_t lit_id) /**< internal class id */
|
||||
{
|
||||
ecma_map_object_t *map_object_p = ecma_op_container_get_object (this_arg, lit_id);
|
||||
|
||||
@@ -449,21 +457,22 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */
|
||||
|
||||
ecma_object_t *internal_obj_p = ecma_get_object_from_value (map_object_p->header.u.class_prop.u.value);
|
||||
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS);
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
ecma_value_t ret_value = ECMA_VALUE_UNDEFINED;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
ecma_ref_object (internal_obj_p);
|
||||
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (*ecma_value_p);
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (buffer_p[i]);
|
||||
ecma_property_t *property_p = ecma_find_named_property (internal_obj_p, prop_name_p);
|
||||
JERRY_ASSERT (property_p != NULL);
|
||||
|
||||
if (ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value))
|
||||
{
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -476,7 +485,7 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */
|
||||
}
|
||||
else if (ecma_prop_name_is_map_key (prop_name_p))
|
||||
{
|
||||
key_arg = prop_name_p->u.value;
|
||||
key_arg = ((ecma_extended_string_t *) prop_name_p)->u.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -487,7 +496,7 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */
|
||||
}
|
||||
else
|
||||
{
|
||||
key_arg = *ecma_value_p;
|
||||
key_arg = buffer_p[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,11 +513,10 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */
|
||||
}
|
||||
|
||||
ecma_free_value (call_value);
|
||||
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_deref_object (internal_obj_p);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_container_foreach */
|
||||
@@ -565,7 +573,7 @@ ecma_op_container_delete (ecma_value_t this_arg, /**< this argument */
|
||||
|
||||
ecma_deref_ecma_string (prop_name_p);
|
||||
|
||||
if (property_p == NULL)
|
||||
if (property_p == NULL || ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value))
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
@@ -653,7 +661,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */
|
||||
ecma_map_object_t *map_object_p = (ecma_map_object_t *) (ecma_get_object_from_value (iterated_value));
|
||||
|
||||
ecma_object_t *internal_obj_p = ecma_get_object_from_value (map_object_p->header.u.class_prop.u.value);
|
||||
ecma_collection_header_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS);
|
||||
ecma_collection_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS);
|
||||
|
||||
uint32_t length = props_p->item_count;
|
||||
uint32_t index = ext_obj_p->u.pseudo_array.u1.iterator_index;
|
||||
@@ -687,34 +695,31 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */
|
||||
if (index >= length)
|
||||
{
|
||||
ext_obj_p->u.pseudo_array.u2.iterated_value = ECMA_VALUE_EMPTY;
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
return ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE);
|
||||
}
|
||||
|
||||
uint8_t iterator_kind = ext_obj_p->u.pseudo_array.extra_info;
|
||||
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
|
||||
ecma_value_t *buffer_p = props_p->buffer_p;
|
||||
|
||||
ecma_value_t ret_value = ECMA_VALUE_UNDEFINED;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
{
|
||||
if (index > 0)
|
||||
{
|
||||
index--;
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
continue;
|
||||
}
|
||||
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (*ecma_value_p);
|
||||
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (buffer_p[i]);
|
||||
ecma_property_t *property_p = ecma_find_named_property (internal_obj_p, prop_name_p);
|
||||
JERRY_ASSERT (property_p != NULL);
|
||||
|
||||
if (ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value))
|
||||
{
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
|
||||
if (ecma_value_p == NULL)
|
||||
if (i == props_p->item_count - 1)
|
||||
{
|
||||
ret_value = ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE);
|
||||
}
|
||||
@@ -730,7 +735,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */
|
||||
}
|
||||
else if (ecma_prop_name_is_map_key (prop_name_p))
|
||||
{
|
||||
key_arg = prop_name_p->u.value;
|
||||
key_arg = ((ecma_extended_string_t *) prop_name_p)->u.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -741,7 +746,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */
|
||||
}
|
||||
else
|
||||
{
|
||||
key_arg = *ecma_value_p;
|
||||
key_arg = buffer_p[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -768,7 +773,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */
|
||||
break;
|
||||
}
|
||||
|
||||
ecma_free_values_collection (props_p, 0);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_container_iterator_next */
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
* Implementation of ECMA-defined conversion routines
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-boolean-object.h"
|
||||
#include "ecma-conversion.h"
|
||||
@@ -148,6 +150,12 @@ ecma_op_same_value (ecma_value_t x, /**< ecma value */
|
||||
{
|
||||
return (ecma_is_value_true (x) == ecma_is_value_true (y));
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
|
||||
else if (ecma_is_value_symbol (x))
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (is_x_object);
|
||||
@@ -613,48 +621,41 @@ ecma_op_from_property_descriptor (const ecma_property_descriptor_t *src_prop_des
|
||||
ecma_value_t completion;
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
{
|
||||
prop_desc.is_value_defined = true;
|
||||
|
||||
prop_desc.is_writable_defined = true;
|
||||
prop_desc.is_writable = true;
|
||||
|
||||
prop_desc.is_enumerable_defined = true;
|
||||
prop_desc.is_enumerable = true;
|
||||
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = true;
|
||||
prop_desc.flags = (ECMA_PROP_IS_VALUE_DEFINED
|
||||
| ECMA_PROP_IS_WRITABLE_DEFINED
|
||||
| ECMA_PROP_IS_WRITABLE
|
||||
| ECMA_PROP_IS_ENUMERABLE_DEFINED
|
||||
| ECMA_PROP_IS_ENUMERABLE
|
||||
| ECMA_PROP_IS_CONFIGURABLE_DEFINED
|
||||
| ECMA_PROP_IS_CONFIGURABLE);
|
||||
}
|
||||
|
||||
/* 3. */
|
||||
if (src_prop_desc_p->is_value_defined
|
||||
|| src_prop_desc_p->is_writable_defined)
|
||||
if (src_prop_desc_p->flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED))
|
||||
{
|
||||
JERRY_ASSERT (prop_desc.is_value_defined && prop_desc.is_writable_defined);
|
||||
JERRY_ASSERT ((prop_desc.flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED))
|
||||
== (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED));
|
||||
|
||||
/* a. */
|
||||
prop_desc.value = src_prop_desc_p->value;
|
||||
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_VALUE),
|
||||
&prop_desc,
|
||||
false);
|
||||
&prop_desc);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
/* b. */
|
||||
const bool is_writable = (src_prop_desc_p->is_writable);
|
||||
prop_desc.value = ecma_make_boolean_value (is_writable);
|
||||
prop_desc.value = ecma_make_boolean_value (src_prop_desc_p->flags & ECMA_PROP_IS_WRITABLE);
|
||||
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_WRITABLE),
|
||||
&prop_desc,
|
||||
false);
|
||||
&prop_desc);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 4. */
|
||||
JERRY_ASSERT (src_prop_desc_p->is_get_defined
|
||||
|| src_prop_desc_p->is_set_defined);
|
||||
JERRY_ASSERT (src_prop_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED));
|
||||
|
||||
/* a. */
|
||||
if (src_prop_desc_p->get_p == NULL)
|
||||
@@ -668,8 +669,7 @@ ecma_op_from_property_descriptor (const ecma_property_descriptor_t *src_prop_des
|
||||
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_GET),
|
||||
&prop_desc,
|
||||
false);
|
||||
&prop_desc);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
/* b. */
|
||||
@@ -684,27 +684,22 @@ ecma_op_from_property_descriptor (const ecma_property_descriptor_t *src_prop_des
|
||||
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_SET),
|
||||
&prop_desc,
|
||||
false);
|
||||
&prop_desc);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
}
|
||||
|
||||
const bool is_enumerable = src_prop_desc_p->is_enumerable;
|
||||
prop_desc.value = ecma_make_boolean_value (is_enumerable);
|
||||
prop_desc.value = ecma_make_boolean_value (src_prop_desc_p->flags & ECMA_PROP_IS_ENUMERABLE);
|
||||
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_ENUMERABLE),
|
||||
&prop_desc,
|
||||
false);
|
||||
&prop_desc);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
const bool is_configurable = src_prop_desc_p->is_configurable;
|
||||
prop_desc.value = ecma_make_boolean_value (is_configurable);
|
||||
prop_desc.value = ecma_make_boolean_value (src_prop_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE);
|
||||
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_CONFIGURABLE),
|
||||
&prop_desc,
|
||||
false);
|
||||
&prop_desc);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
return obj_p;
|
||||
@@ -746,8 +741,10 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
|
||||
|
||||
if (ecma_is_value_found (enumerable_prop_value))
|
||||
{
|
||||
prop_desc.is_enumerable_defined = true;
|
||||
prop_desc.is_enumerable = ECMA_BOOL_TO_BITFIELD (ecma_op_to_boolean (enumerable_prop_value));
|
||||
uint32_t is_enumerable = (ecma_op_to_boolean (enumerable_prop_value) ? ECMA_PROP_IS_ENUMERABLE
|
||||
: ECMA_PROP_NO_OPTS);
|
||||
|
||||
prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_ENUMERABLE_DEFINED | is_enumerable);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (enumerable_prop_value);
|
||||
@@ -763,8 +760,10 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
|
||||
|
||||
if (ecma_is_value_found (configurable_prop_value))
|
||||
{
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = ECMA_BOOL_TO_BITFIELD (ecma_op_to_boolean (configurable_prop_value));
|
||||
uint32_t is_configurable = (ecma_op_to_boolean (configurable_prop_value) ? ECMA_PROP_IS_CONFIGURABLE
|
||||
: ECMA_PROP_NO_OPTS);
|
||||
|
||||
prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_CONFIGURABLE_DEFINED | is_configurable);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (configurable_prop_value);
|
||||
@@ -781,7 +780,7 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
|
||||
|
||||
if (ecma_is_value_found (value_prop_value))
|
||||
{
|
||||
prop_desc.is_value_defined = true;
|
||||
prop_desc.flags |= ECMA_PROP_IS_VALUE_DEFINED;
|
||||
prop_desc.value = ecma_copy_value (value_prop_value);
|
||||
}
|
||||
|
||||
@@ -799,8 +798,10 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
|
||||
|
||||
if (ecma_is_value_found (writable_prop_value))
|
||||
{
|
||||
prop_desc.is_writable_defined = true;
|
||||
prop_desc.is_writable = ECMA_BOOL_TO_BITFIELD (ecma_op_to_boolean (writable_prop_value));
|
||||
uint32_t is_writable = (ecma_op_to_boolean (writable_prop_value) ? ECMA_PROP_IS_WRITABLE
|
||||
: ECMA_PROP_NO_OPTS);
|
||||
|
||||
prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_WRITABLE_DEFINED | is_writable);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (writable_prop_value);
|
||||
@@ -824,7 +825,7 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_desc.is_get_defined = true;
|
||||
prop_desc.flags |= ECMA_PROP_IS_GET_DEFINED;
|
||||
|
||||
if (ecma_is_value_undefined (get_prop_value))
|
||||
{
|
||||
@@ -863,7 +864,7 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_desc.is_set_defined = true;
|
||||
prop_desc.flags |= ECMA_PROP_IS_SET_DEFINED;
|
||||
|
||||
if (ecma_is_value_undefined (set_prop_value))
|
||||
{
|
||||
@@ -889,8 +890,8 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
|
||||
/* 9. */
|
||||
if ((prop_desc.is_get_defined || prop_desc.is_set_defined)
|
||||
&& (prop_desc.is_value_defined || prop_desc.is_writable_defined))
|
||||
if ((prop_desc.flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED))
|
||||
&& (prop_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Accessors cannot be writable."));
|
||||
}
|
||||
@@ -911,6 +912,119 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
|
||||
return ret_value;
|
||||
} /* ecma_op_to_property_descriptor */
|
||||
|
||||
/**
|
||||
* ToInteger operation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 9.4
|
||||
* ECMA-262 v6, 7.1.4
|
||||
*
|
||||
* @return ECMA_VALUE_EMPTY if successful
|
||||
* conversion error otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_to_integer (ecma_value_t value, /**< ecma value*/
|
||||
ecma_number_t *number_p) /**< [out] ecma number */
|
||||
{
|
||||
if (ECMA_IS_VALUE_ERROR (value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/* 1 */
|
||||
ecma_value_t to_number = ecma_get_number (value, number_p);
|
||||
|
||||
/* 2 */
|
||||
if (ECMA_IS_VALUE_ERROR (to_number))
|
||||
{
|
||||
return to_number;
|
||||
}
|
||||
|
||||
ecma_number_t number = *number_p;
|
||||
|
||||
/* 3 */
|
||||
if (ecma_number_is_nan (number))
|
||||
{
|
||||
*number_p = ECMA_NUMBER_ZERO;
|
||||
return ECMA_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
/* 4 */
|
||||
if (ecma_number_is_zero (number) || ecma_number_is_infinity (number))
|
||||
{
|
||||
return ECMA_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
ecma_number_t floor_fabs = floor (fabs (number));
|
||||
|
||||
/* 5 */
|
||||
*number_p = ecma_number_is_negative (number) ? -floor_fabs : floor_fabs;
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* ecma_op_to_integer */
|
||||
|
||||
/**
|
||||
* ToLength operation.
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v6, 7.1.15
|
||||
*
|
||||
* @return ECMA_VALUE_EMPTY if successful
|
||||
* conversion error otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_to_length (ecma_value_t value, /**< ecma value*/
|
||||
uint32_t *length) /**< [out] ecma number */
|
||||
{
|
||||
/* 1 */
|
||||
if (ECMA_IS_VALUE_ERROR (value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
/* 2 */
|
||||
ecma_number_t num;
|
||||
ecma_value_t length_num = ecma_op_to_integer (value, &num);
|
||||
|
||||
/* 3 */
|
||||
if (ECMA_IS_VALUE_ERROR (length_num))
|
||||
{
|
||||
return length_num;
|
||||
}
|
||||
|
||||
/* 4 */
|
||||
if (num <= 0.0f)
|
||||
{
|
||||
*length = 0;
|
||||
return ECMA_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
/* 5 */
|
||||
if (num >= (ecma_number_t) UINT32_MAX)
|
||||
{
|
||||
*length = UINT32_MAX;
|
||||
return ECMA_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
/* 6 */
|
||||
*length = (uint32_t) num;
|
||||
return ECMA_VALUE_EMPTY;
|
||||
#else /* !ENABLED (JERRY_ES2015) */
|
||||
/* In the case of ES5, ToLength(ES6) operation is the same as ToUint32(ES5) */
|
||||
ecma_number_t num;
|
||||
ecma_value_t to_number = ecma_get_number (value, &num);
|
||||
|
||||
/* 2 */
|
||||
if (ECMA_IS_VALUE_ERROR (to_number))
|
||||
{
|
||||
return to_number;
|
||||
}
|
||||
|
||||
*length = ecma_number_to_uint32 (num);
|
||||
return ECMA_VALUE_EMPTY;
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
} /* ecma_op_to_length */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@@ -49,6 +49,8 @@ ecma_value_t ecma_get_number (ecma_value_t value, ecma_number_t *number_p);
|
||||
ecma_value_t ecma_op_to_string (ecma_value_t value);
|
||||
ecma_string_t *ecma_op_to_prop_name (ecma_value_t value);
|
||||
ecma_value_t ecma_op_to_object (ecma_value_t value);
|
||||
ecma_value_t ecma_op_to_integer (ecma_value_t value, ecma_number_t *number_p);
|
||||
ecma_value_t ecma_op_to_length (ecma_value_t value, uint32_t *length);
|
||||
|
||||
ecma_object_t *ecma_op_from_property_descriptor (const ecma_property_descriptor_t *src_prop_desc_p);
|
||||
ecma_value_t ecma_op_to_property_descriptor (ecma_value_t obj_value, ecma_property_descriptor_t *out_prop_desc_p);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "ecma-arraybuffer-object.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-builtin-typedarray-helpers.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-helpers.h"
|
||||
@@ -118,6 +117,11 @@ ecma_op_dataview_create (const ecma_value_t *arguments_list_p, /**< arguments li
|
||||
}
|
||||
else if (ecma_number_is_infinity (byte_length))
|
||||
{
|
||||
if (ecma_number_is_negative (byte_length))
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid DataView length"));
|
||||
}
|
||||
|
||||
viewByteLength = UINT32_MAX;
|
||||
}
|
||||
else if (byte_length_int32 <= 0)
|
||||
@@ -130,7 +134,7 @@ ecma_op_dataview_create (const ecma_value_t *arguments_list_p, /**< arguments li
|
||||
}
|
||||
|
||||
/* 12.c */
|
||||
if ((ecma_length_t) offset + viewByteLength > buffer_byte_length)
|
||||
if ((ecma_number_t) offset + viewByteLength > buffer_byte_length)
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Start offset is outside the bounds of the buffer."));
|
||||
}
|
||||
@@ -245,7 +249,7 @@ ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'vi
|
||||
ecma_value_t is_little_endian_value, /**< the operation's
|
||||
* 'isLittleEndian' argument */
|
||||
ecma_value_t value_to_set, /**< the operation's 'value' argument */
|
||||
uint8_t type) /**< the operation's 'type' argument */
|
||||
ecma_typedarray_type_t id) /**< the operation's 'type' argument */
|
||||
{
|
||||
/* 1 - 2. */
|
||||
ecma_dataview_object_t *view_p = ecma_op_dataview_get_object (view);
|
||||
@@ -288,7 +292,7 @@ ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'vi
|
||||
uint32_t view_size = view_p->header.u.class_prop.u.length;
|
||||
|
||||
/* 12. */
|
||||
uint8_t element_size = (uint8_t) (1 << (ecma_typedarray_helper_get_shift_size (type)));
|
||||
uint8_t element_size = (uint8_t) (1 << (ecma_typedarray_helper_get_shift_size (id)));
|
||||
|
||||
/* 13. */
|
||||
if ((uint32_t) get_index + element_size > view_size)
|
||||
@@ -298,7 +302,6 @@ ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'vi
|
||||
|
||||
/* 14. */
|
||||
uint32_t buffer_index = (uint32_t) get_index + view_offset;
|
||||
lit_magic_string_id_t id = ecma_typedarray_helper_get_magic_string (type);
|
||||
lit_utf8_byte_t *block_p = ecma_arraybuffer_get_buffer (buffer_p) + buffer_index;
|
||||
|
||||
bool system_is_little_endian = ecma_dataview_check_little_endian ();
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
ecma_value_t ecma_op_dataview_create (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len);
|
||||
ecma_dataview_object_t *ecma_op_dataview_get_object (ecma_value_t this_arg);
|
||||
ecma_value_t ecma_op_dataview_get_set_view_value (ecma_value_t view, ecma_value_t request_index,
|
||||
ecma_value_t little_endian, ecma_value_t value_to_set, uint8_t type);
|
||||
ecma_value_t little_endian, ecma_value_t value_to_set,
|
||||
ecma_typedarray_type_t id);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -170,17 +170,20 @@ ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error typ
|
||||
ecma_standard_error_t
|
||||
ecma_get_error_type (ecma_object_t *error_object) /**< possible error object */
|
||||
{
|
||||
ecma_object_t *prototype_p = ecma_get_object_prototype (error_object);
|
||||
if (prototype_p != NULL)
|
||||
if (error_object->u2.prototype_cp == JMEM_CP_NULL)
|
||||
{
|
||||
uint8_t builtin_id = ecma_get_object_builtin_id (prototype_p);
|
||||
return ECMA_ERROR_NONE;
|
||||
}
|
||||
|
||||
for (uint8_t idx = 0; idx < sizeof (ecma_error_mappings) / sizeof (ecma_error_mappings[0]); idx++)
|
||||
ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, error_object->u2.prototype_cp);
|
||||
|
||||
uint8_t builtin_id = ecma_get_object_builtin_id (prototype_p);
|
||||
|
||||
for (uint8_t idx = 0; idx < sizeof (ecma_error_mappings) / sizeof (ecma_error_mappings[0]); idx++)
|
||||
{
|
||||
if (ecma_error_mappings[idx].error_prototype_id == builtin_id)
|
||||
{
|
||||
if (ecma_error_mappings[idx].error_prototype_id == builtin_id)
|
||||
{
|
||||
return ecma_error_mappings[idx].error_type;
|
||||
}
|
||||
return ecma_error_mappings[idx].error_type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -361,13 +361,15 @@ ecma_op_implicit_class_constructor_has_instance (ecma_object_t *func_obj_p, /**<
|
||||
|
||||
while (true)
|
||||
{
|
||||
v_obj_p = ecma_get_object_prototype (v_obj_p);
|
||||
jmem_cpointer_t v_obj_cp = v_obj_p->u2.prototype_cp;
|
||||
|
||||
if (v_obj_p == NULL)
|
||||
if (v_obj_cp == JMEM_CP_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, v_obj_cp);
|
||||
|
||||
if (v_obj_p == prototype_obj_p)
|
||||
{
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
@@ -451,13 +453,15 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
|
||||
|
||||
while (true)
|
||||
{
|
||||
v_obj_p = ecma_get_object_prototype (v_obj_p);
|
||||
jmem_cpointer_t v_obj_cp = v_obj_p->u2.prototype_cp;
|
||||
|
||||
if (v_obj_p == NULL)
|
||||
if (v_obj_cp == JMEM_CP_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, v_obj_cp);
|
||||
|
||||
if (v_obj_p == prototype_obj_p)
|
||||
{
|
||||
result = ECMA_VALUE_TRUE;
|
||||
@@ -535,24 +539,30 @@ ecma_op_function_has_construct_flag (const ecma_value_t *arguments_list_p) /**<
|
||||
static ecma_object_t *
|
||||
ecma_op_find_super_declerative_lex_env (ecma_object_t *lex_env_p) /**< starting lexical enviroment */
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p);
|
||||
JERRY_ASSERT (lex_env_p != NULL);
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) != ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND);
|
||||
|
||||
while (lex_env_p != NULL)
|
||||
while (true)
|
||||
{
|
||||
ecma_object_t *lex_env_outer_p = ecma_get_lex_env_outer_reference (lex_env_p);
|
||||
jmem_cpointer_t lex_env_outer_cp = lex_env_p->u2.outer_reference_cp;
|
||||
|
||||
if (lex_env_outer_p != NULL &&
|
||||
ecma_get_lex_env_type (lex_env_outer_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND)
|
||||
if (lex_env_outer_cp != JMEM_CP_NULL)
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
|
||||
return lex_env_p;
|
||||
ecma_object_t *lex_env_outer_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_outer_cp);
|
||||
|
||||
if (ecma_get_lex_env_type (lex_env_outer_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND)
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
|
||||
return lex_env_p;
|
||||
}
|
||||
|
||||
lex_env_p = lex_env_outer_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lex_env_p = lex_env_outer_p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
} /* ecma_op_find_super_declerative_lex_env */
|
||||
|
||||
/**
|
||||
@@ -673,10 +683,11 @@ ecma_op_set_class_prototype (ecma_value_t completion_value, /**< completion_valu
|
||||
JERRY_ASSERT (ecma_is_value_object (this_arg));
|
||||
|
||||
ecma_object_t *completion_obj_p = ecma_get_object_from_value (completion_value);
|
||||
ecma_object_t *prototype_obj_p = ecma_get_object_prototype (ecma_get_object_from_value (this_arg));
|
||||
jmem_cpointer_t prototype_obj_cp = ecma_get_object_from_value (this_arg)->u2.prototype_cp;
|
||||
|
||||
JERRY_ASSERT (prototype_obj_p);
|
||||
ECMA_SET_POINTER (completion_obj_p->prototype_or_outer_reference_cp, prototype_obj_p);
|
||||
JERRY_ASSERT (prototype_obj_cp != JMEM_CP_NULL);
|
||||
|
||||
completion_obj_p->u2.prototype_cp = prototype_obj_cp;
|
||||
} /* ecma_op_set_class_prototype */
|
||||
#endif /* ENABLED (JERRY_ES2015_CLASS) */
|
||||
|
||||
@@ -1143,7 +1154,9 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
|
||||
/* Catch the special case when a the class extends value in null
|
||||
and the class has no explicit constructor to raise TypeError.*/
|
||||
JERRY_ASSERT (!ecma_op_function_has_construct_flag (arguments_list_p));
|
||||
JERRY_ASSERT (ecma_get_object_prototype (func_obj_p) == ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE));
|
||||
JERRY_ASSERT (func_obj_p->u2.prototype_cp != JMEM_CP_NULL);
|
||||
JERRY_ASSERT ((ECMA_GET_NON_NULL_POINTER (ecma_object_t, func_obj_p->u2.prototype_cp) \
|
||||
== ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE)));
|
||||
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Super constructor null is not a constructor."));
|
||||
break;
|
||||
@@ -1403,24 +1416,20 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio
|
||||
* false - list all properties into main
|
||||
* collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
{
|
||||
JERRY_UNUSED (main_collection_p);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
/* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
|
||||
/* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE));
|
||||
|
||||
const ecma_compiled_code_t *bytecode_data_p;
|
||||
|
||||
@@ -1440,14 +1449,10 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
|
||||
{
|
||||
/* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER));
|
||||
|
||||
/* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS));
|
||||
}
|
||||
} /* ecma_op_function_list_lazy_property_names */
|
||||
|
||||
@@ -1467,19 +1472,16 @@ ecma_op_external_function_list_lazy_property_names (bool separate_enumerable, /*
|
||||
* false - list all properties into
|
||||
* main collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main'
|
||||
* collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped
|
||||
* collection */
|
||||
{
|
||||
JERRY_UNUSED (main_collection_p);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
/* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE));
|
||||
} /* ecma_op_external_function_list_lazy_property_names */
|
||||
|
||||
/**
|
||||
@@ -1498,30 +1500,23 @@ ecma_op_bound_function_list_lazy_property_names (bool separate_enumerable, /**<
|
||||
* false - list all properties into
|
||||
* main collection.
|
||||
*/
|
||||
ecma_collection_header_t *main_collection_p, /**< 'main'
|
||||
* collection */
|
||||
ecma_collection_header_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
ecma_collection_t *main_collection_p, /**< 'main' collection */
|
||||
ecma_collection_t *non_enum_collection_p) /**< skipped
|
||||
* 'non-enumerable'
|
||||
* collection */
|
||||
{
|
||||
JERRY_UNUSED (main_collection_p);
|
||||
|
||||
ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p;
|
||||
|
||||
/* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
|
||||
|
||||
/* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER));
|
||||
|
||||
/* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */
|
||||
ecma_append_to_values_collection (for_non_enumerable_p,
|
||||
ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS),
|
||||
0);
|
||||
ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS));
|
||||
} /* ecma_op_bound_function_list_lazy_property_names */
|
||||
|
||||
/**
|
||||
|
||||
@@ -97,18 +97,18 @@ ecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p
|
||||
void
|
||||
ecma_op_function_list_lazy_property_names (ecma_object_t *object_p,
|
||||
bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
|
||||
void
|
||||
ecma_op_external_function_list_lazy_property_names (bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
|
||||
void
|
||||
ecma_op_bound_function_list_lazy_property_names (bool separate_enumerable,
|
||||
ecma_collection_header_t *main_collection_p,
|
||||
ecma_collection_header_t *non_enum_collection_p);
|
||||
ecma_collection_t *main_collection_p,
|
||||
ecma_collection_t *non_enum_collection_p);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -50,7 +50,7 @@ ecma_op_get_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
|
||||
JERRY_ASSERT (lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (lex_env_p));
|
||||
|
||||
while (lex_env_p != NULL)
|
||||
while (true)
|
||||
{
|
||||
switch (ecma_get_lex_env_type (lex_env_p))
|
||||
{
|
||||
@@ -89,7 +89,12 @@ ecma_op_get_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
|
||||
}
|
||||
}
|
||||
|
||||
lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
|
||||
if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
|
||||
}
|
||||
|
||||
*ref_base_lex_env_p = NULL;
|
||||
@@ -147,10 +152,7 @@ ecma_op_get_value_object_base (ecma_value_t base_value, /**< base value */
|
||||
|
||||
ecma_value_t ret_value = ECMA_VALUE_UNDEFINED;
|
||||
|
||||
/* Circular reference is possible in JavaScript and testing it is complicated. */
|
||||
int max_depth = ECMA_PROPERTY_SEARCH_DEPTH_LIMIT;
|
||||
|
||||
do
|
||||
while (true)
|
||||
{
|
||||
ecma_value_t value = ecma_op_object_find_own (base_value, object_p, property_name_p);
|
||||
|
||||
@@ -160,14 +162,13 @@ ecma_op_get_value_object_base (ecma_value_t base_value, /**< base value */
|
||||
break;
|
||||
}
|
||||
|
||||
if (--max_depth == 0)
|
||||
if (object_p->u2.prototype_cp == JMEM_CP_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
object_p = ecma_get_object_prototype (object_p);
|
||||
object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp);
|
||||
}
|
||||
while (object_p != NULL);
|
||||
|
||||
ecma_free_value (object_base);
|
||||
|
||||
@@ -191,7 +192,7 @@ ecma_op_put_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
|
||||
JERRY_ASSERT (lex_env_p != NULL
|
||||
&& ecma_is_lexical_environment (lex_env_p));
|
||||
|
||||
while (lex_env_p != NULL)
|
||||
while (true)
|
||||
{
|
||||
switch (ecma_get_lex_env_type (lex_env_p))
|
||||
{
|
||||
@@ -245,7 +246,12 @@ ecma_op_put_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
|
||||
}
|
||||
}
|
||||
|
||||
lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
|
||||
if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
|
||||
}
|
||||
|
||||
if (is_strict)
|
||||
|
||||
@@ -64,8 +64,7 @@ ecma_create_array_from_iter_element (ecma_value_t value, /**< value */
|
||||
ecma_value_t completion = ecma_builtin_helper_def_prop (new_array_p,
|
||||
index_string_p,
|
||||
(index == 0) ? index_value : value,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
false); /* Failure handling */
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
|
||||
/* 4.b */
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
@@ -41,9 +41,10 @@ ecma_init_global_lex_env (void)
|
||||
{
|
||||
ecma_object_t *glob_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL);
|
||||
|
||||
JERRY_CONTEXT (ecma_global_lex_env_p) = ecma_create_object_lex_env (NULL,
|
||||
glob_obj_p,
|
||||
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
ecma_object_t *global_lex_env_p = ecma_create_object_lex_env (NULL,
|
||||
glob_obj_p,
|
||||
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
ECMA_SET_NON_NULL_POINTER (JERRY_CONTEXT (ecma_global_lex_env_cp), global_lex_env_p);
|
||||
} /* ecma_init_global_lex_env */
|
||||
|
||||
/**
|
||||
@@ -52,8 +53,8 @@ ecma_init_global_lex_env (void)
|
||||
void
|
||||
ecma_finalize_global_lex_env (void)
|
||||
{
|
||||
ecma_deref_object (JERRY_CONTEXT (ecma_global_lex_env_p));
|
||||
JERRY_CONTEXT (ecma_global_lex_env_p) = NULL;
|
||||
ecma_deref_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_global_lex_env_cp)));
|
||||
JERRY_CONTEXT (ecma_global_lex_env_cp) = JMEM_CP_NULL;
|
||||
} /* ecma_finalize_global_lex_env */
|
||||
|
||||
/**
|
||||
@@ -65,7 +66,8 @@ ecma_finalize_global_lex_env (void)
|
||||
ecma_object_t *
|
||||
ecma_get_global_environment (void)
|
||||
{
|
||||
return JERRY_CONTEXT (ecma_global_lex_env_p);
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_global_lex_env_cp) != JMEM_CP_NULL);
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_global_lex_env_cp));
|
||||
} /* ecma_get_global_environment */
|
||||
|
||||
/**
|
||||
@@ -141,18 +143,18 @@ ecma_op_create_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environme
|
||||
|
||||
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
|
||||
|
||||
ecma_value_t completion;
|
||||
if (!ecma_get_object_extensible (binding_obj_p))
|
||||
{
|
||||
return ECMA_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
completion = ecma_builtin_helper_def_prop (binding_obj_p,
|
||||
name_p,
|
||||
ECMA_VALUE_UNDEFINED,
|
||||
is_deletable ? ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE
|
||||
: ECMA_PROPERTY_ENUMERABLE_WRITABLE,
|
||||
true); /* Failure handling */
|
||||
const uint32_t flags = ECMA_PROPERTY_ENUMERABLE_WRITABLE | ECMA_IS_THROW;
|
||||
|
||||
ecma_value_t completion = ecma_builtin_helper_def_prop (binding_obj_p,
|
||||
name_p,
|
||||
ECMA_VALUE_UNDEFINED,
|
||||
is_deletable ? flags | ECMA_PROPERTY_FLAG_CONFIGURABLE
|
||||
: flags);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (completion))
|
||||
{
|
||||
|
||||
@@ -155,30 +155,23 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
/* 14. */
|
||||
prop_desc = ecma_make_empty_property_descriptor ();
|
||||
{
|
||||
prop_desc.is_get_defined = true;
|
||||
prop_desc.get_p = thrower_p;
|
||||
|
||||
prop_desc.is_set_defined = true;
|
||||
prop_desc.set_p = thrower_p;
|
||||
|
||||
prop_desc.is_enumerable_defined = true;
|
||||
prop_desc.is_enumerable = false;
|
||||
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = false;
|
||||
prop_desc.flags = (ECMA_PROP_IS_GET_DEFINED
|
||||
| ECMA_PROP_IS_SET_DEFINED
|
||||
| ECMA_PROP_IS_ENUMERABLE_DEFINED
|
||||
| ECMA_PROP_IS_CONFIGURABLE_DEFINED);
|
||||
}
|
||||
prop_desc.set_p = thrower_p;
|
||||
prop_desc.get_p = thrower_p;
|
||||
|
||||
ecma_value_t completion = ecma_op_object_define_own_property (obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_CALLEE),
|
||||
&prop_desc,
|
||||
false);
|
||||
&prop_desc);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
completion = ecma_op_object_define_own_property (obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_CALLER),
|
||||
&prop_desc,
|
||||
false);
|
||||
&prop_desc);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
}
|
||||
|
||||
@@ -221,15 +214,13 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
ecma_value_t
|
||||
ecma_op_arguments_object_define_own_property (ecma_object_t *object_p, /**< the object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
const ecma_property_descriptor_t *property_desc_p, /**< property
|
||||
const ecma_property_descriptor_t *property_desc_p) /**< property
|
||||
* descriptor */
|
||||
bool is_throw) /**< flag that controls failure handling */
|
||||
{
|
||||
/* 3. */
|
||||
ecma_value_t ret_value = ecma_op_general_object_define_own_property (object_p,
|
||||
property_name_p,
|
||||
property_desc_p,
|
||||
is_throw);
|
||||
property_desc_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
@@ -259,15 +250,14 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *object_p, /**< the
|
||||
|
||||
ecma_string_t *name_p = ecma_get_string_from_value (arg_Literal_p[index]);
|
||||
|
||||
if (property_desc_p->is_get_defined
|
||||
|| property_desc_p->is_set_defined)
|
||||
if (property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))
|
||||
{
|
||||
ecma_deref_ecma_string (name_p);
|
||||
arg_Literal_p[index] = ECMA_VALUE_EMPTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (property_desc_p->is_value_defined)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
|
||||
{
|
||||
/* emulating execution of function described by MakeArgSetter */
|
||||
ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
@@ -281,8 +271,8 @@ ecma_op_arguments_object_define_own_property (ecma_object_t *object_p, /**< the
|
||||
JERRY_ASSERT (ecma_is_value_empty (completion));
|
||||
}
|
||||
|
||||
if (property_desc_p->is_writable_defined
|
||||
&& !property_desc_p->is_writable)
|
||||
if ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)
|
||||
&& !(property_desc_p->flags & ECMA_PROP_IS_WRITABLE))
|
||||
{
|
||||
ecma_deref_ecma_string (name_p);
|
||||
arg_Literal_p[index] = ECMA_VALUE_EMPTY;
|
||||
|
||||
@@ -28,6 +28,6 @@ ecma_value_t
|
||||
ecma_op_arguments_object_delete (ecma_object_t *object_p, ecma_string_t *property_name_p, bool is_throw);
|
||||
ecma_value_t
|
||||
ecma_op_arguments_object_define_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
const ecma_property_descriptor_t *property_desc_p, bool is_throw);
|
||||
const ecma_property_descriptor_t *property_desc_p);
|
||||
|
||||
#endif /* !ECMA_OBJECTS_ARGUMENTS_H */
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecma-array-object.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-function-object.h"
|
||||
@@ -159,8 +160,15 @@ ecma_op_general_object_delete (ecma_object_t *obj_p, /**< the object */
|
||||
/* 3. */
|
||||
if (ecma_is_property_configurable (property))
|
||||
{
|
||||
/* a. */
|
||||
ecma_delete_property (obj_p, property_ref.value_p);
|
||||
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY)
|
||||
{
|
||||
ecma_array_object_delete_property (obj_p, property_name_p, property_ref.value_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* a. */
|
||||
ecma_delete_property (obj_p, property_ref.value_p);
|
||||
}
|
||||
|
||||
/* b. */
|
||||
return ECMA_VALUE_TRUE;
|
||||
@@ -271,35 +279,38 @@ ecma_op_general_object_default_value (ecma_object_t *obj_p, /**< the object */
|
||||
ecma_value_t
|
||||
ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the object */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
const ecma_property_descriptor_t *property_desc_p, /**< property
|
||||
const ecma_property_descriptor_t *property_desc_p) /**< property
|
||||
* descriptor */
|
||||
bool is_throw) /**< flag that controls failure handling */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL
|
||||
&& !ecma_is_lexical_environment (object_p));
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) != ECMA_OBJECT_TYPE_ARRAY
|
||||
|| !((ecma_extended_object_t *) object_p)->u.array.is_fast_mode);
|
||||
JERRY_ASSERT (property_name_p != NULL);
|
||||
|
||||
ecma_property_types_t property_desc_type = ECMA_PROPERTY_TYPE_GENERIC;
|
||||
|
||||
if (property_desc_p->is_value_defined
|
||||
|| property_desc_p->is_writable_defined)
|
||||
if (property_desc_p->flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED))
|
||||
{
|
||||
/* A property descriptor cannot be both named data and named accessor. */
|
||||
JERRY_ASSERT (!property_desc_p->is_get_defined
|
||||
&& !property_desc_p->is_set_defined);
|
||||
JERRY_ASSERT ((property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))
|
||||
!= (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED));
|
||||
property_desc_type = ECMA_PROPERTY_TYPE_NAMEDDATA;
|
||||
}
|
||||
else if (property_desc_p->is_get_defined
|
||||
|| property_desc_p->is_set_defined)
|
||||
else if (property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))
|
||||
{
|
||||
JERRY_ASSERT (!(property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED));
|
||||
property_desc_type = ECMA_PROPERTY_TYPE_NAMEDACCESSOR;
|
||||
}
|
||||
|
||||
/* These three asserts ensures that a new property is created with the appropriate default flags.
|
||||
* E.g. if is_configurable_defined is false, the newly created property must be non-configurable. */
|
||||
JERRY_ASSERT (property_desc_p->is_configurable_defined || !property_desc_p->is_configurable);
|
||||
JERRY_ASSERT (property_desc_p->is_enumerable_defined || !property_desc_p->is_enumerable);
|
||||
JERRY_ASSERT (property_desc_p->is_writable_defined || !property_desc_p->is_writable);
|
||||
* E.g. if ECMA_PROP_IS_CONFIGURABLE_DEFINED is false, the newly created property must be non-configurable. */
|
||||
JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE_DEFINED)
|
||||
|| !(property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE));
|
||||
JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED)
|
||||
|| !(property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE));
|
||||
JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)
|
||||
|| !(property_desc_p->flags & ECMA_PROP_IS_WRITABLE));
|
||||
|
||||
/* 1. */
|
||||
ecma_extended_property_ref_t ext_property_ref = { .property_ref.value_p = NULL, .property_p = NULL };
|
||||
@@ -316,39 +327,25 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
if (!ecma_get_object_extensible (object_p))
|
||||
{
|
||||
/* 2. */
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
|
||||
/* 4. */
|
||||
uint8_t prop_attributes = (uint8_t) (property_desc_p->flags & ECMA_PROPERTY_FLAGS_MASK);
|
||||
|
||||
if (property_desc_type != ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
|
||||
{
|
||||
/* a. */
|
||||
|
||||
JERRY_ASSERT (property_desc_type == ECMA_PROPERTY_TYPE_GENERIC
|
||||
|| property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA);
|
||||
|
||||
uint8_t prop_attributes = 0;
|
||||
|
||||
if (property_desc_p->is_configurable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_CONFIGURABLE);
|
||||
}
|
||||
if (property_desc_p->is_enumerable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_ENUMERABLE);
|
||||
}
|
||||
if (property_desc_p->is_writable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_WRITABLE);
|
||||
}
|
||||
|
||||
ecma_property_value_t *new_prop_value_p = ecma_create_named_data_property (object_p,
|
||||
property_name_p,
|
||||
prop_attributes,
|
||||
NULL);
|
||||
|
||||
JERRY_ASSERT (property_desc_p->is_value_defined
|
||||
JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
|
||||
|| ecma_is_value_undefined (property_desc_p->value));
|
||||
|
||||
new_prop_value_p->value = ecma_copy_value_if_not_object (property_desc_p->value);
|
||||
@@ -357,17 +354,6 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
{
|
||||
/* b. */
|
||||
|
||||
uint8_t prop_attributes = 0;
|
||||
|
||||
if (property_desc_p->is_configurable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_CONFIGURABLE);
|
||||
}
|
||||
if (property_desc_p->is_enumerable)
|
||||
{
|
||||
prop_attributes = (uint8_t) (prop_attributes | ECMA_PROPERTY_FLAG_ENUMERABLE);
|
||||
}
|
||||
|
||||
ecma_create_named_accessor_property (object_p,
|
||||
property_name_p,
|
||||
property_desc_p->get_p,
|
||||
@@ -388,16 +374,17 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
|| current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL);
|
||||
|
||||
/* 7. a., b. */
|
||||
bool is_enumerable = (property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE) != 0;
|
||||
if (!is_current_configurable
|
||||
&& (property_desc_p->is_configurable
|
||||
|| (property_desc_p->is_enumerable_defined
|
||||
&& (property_desc_p->is_enumerable != ecma_is_property_enumerable (current_prop)))))
|
||||
&& ((property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE)
|
||||
|| ((property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED)
|
||||
&& (is_enumerable != ecma_is_property_enumerable (current_prop)))))
|
||||
{
|
||||
if (current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL)
|
||||
{
|
||||
ecma_free_value (ext_property_ref.property_ref.virtual_value);
|
||||
}
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
|
||||
if (current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL)
|
||||
@@ -407,12 +394,12 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
ecma_value_t result = ECMA_VALUE_TRUE;
|
||||
|
||||
if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
|
||||
|| property_desc_p->is_writable
|
||||
|| (property_desc_p->is_value_defined
|
||||
|| (property_desc_p->flags & ECMA_PROP_IS_WRITABLE)
|
||||
|| ((property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
|
||||
&& !ecma_op_same_value (property_desc_p->value,
|
||||
ext_property_ref.property_ref.virtual_value)))
|
||||
{
|
||||
result = ecma_reject (is_throw);
|
||||
result = ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
|
||||
ecma_free_value (ext_property_ref.property_ref.virtual_value);
|
||||
@@ -433,12 +420,12 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
{
|
||||
/* 10. a. i. & ii. */
|
||||
if (!ecma_is_property_writable (current_prop)
|
||||
&& (property_desc_p->is_writable
|
||||
|| (property_desc_p->is_value_defined
|
||||
&& ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE)
|
||||
|| ((property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
|
||||
&& !ecma_op_same_value (property_desc_p->value,
|
||||
ext_property_ref.property_ref.value_p->value))))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -448,13 +435,18 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
/* a. */
|
||||
ecma_property_value_t *value_p = ext_property_ref.property_ref.value_p;
|
||||
|
||||
if ((property_desc_p->is_get_defined
|
||||
&& property_desc_p->get_p != ecma_get_named_accessor_property_getter (value_p))
|
||||
|| (property_desc_p->is_set_defined
|
||||
&& property_desc_p->set_p != ecma_get_named_accessor_property_setter (value_p)))
|
||||
ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (value_p);
|
||||
jmem_cpointer_t prop_desc_getter_cp, prop_desc_setter_cp;
|
||||
ECMA_SET_POINTER (prop_desc_getter_cp, property_desc_p->get_p);
|
||||
ECMA_SET_POINTER (prop_desc_setter_cp, property_desc_p->set_p);
|
||||
|
||||
if (((property_desc_p->flags & ECMA_PROP_IS_GET_DEFINED)
|
||||
&& prop_desc_getter_cp != get_set_pair_p->getter_cp)
|
||||
|| ((property_desc_p->flags & ECMA_PROP_IS_SET_DEFINED)
|
||||
&& prop_desc_setter_cp != get_set_pair_p->setter_cp))
|
||||
{
|
||||
/* i., ii. */
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -465,7 +457,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
if (!is_current_configurable)
|
||||
{
|
||||
/* a. */
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
|
||||
ecma_property_value_t *value_p = ext_property_ref.property_ref.value_p;
|
||||
@@ -478,12 +470,12 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
#if ENABLED (JERRY_CPOINTER_32_BIT)
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
getter_setter_pair_p = jmem_pools_alloc (sizeof (ecma_getter_setter_pointers_t));
|
||||
getter_setter_pair_p->getter_p = JMEM_CP_NULL;
|
||||
getter_setter_pair_p->setter_p = JMEM_CP_NULL;
|
||||
ECMA_SET_POINTER (value_p->getter_setter_pair_cp, getter_setter_pair_p);
|
||||
getter_setter_pair_p->getter_cp = JMEM_CP_NULL;
|
||||
getter_setter_pair_p->setter_cp = JMEM_CP_NULL;
|
||||
ECMA_SET_NON_NULL_POINTER (value_p->getter_setter_pair_cp, getter_setter_pair_p);
|
||||
#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
value_p->getter_setter_pair.getter_p = JMEM_CP_NULL;
|
||||
value_p->getter_setter_pair.setter_p = JMEM_CP_NULL;
|
||||
value_p->getter_setter_pair.getter_cp = JMEM_CP_NULL;
|
||||
value_p->getter_setter_pair.setter_cp = JMEM_CP_NULL;
|
||||
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
}
|
||||
else
|
||||
@@ -491,8 +483,8 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
|
||||
#if ENABLED (JERRY_CPOINTER_32_BIT)
|
||||
ecma_getter_setter_pointers_t *getter_setter_pair_p;
|
||||
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
|
||||
value_p->getter_setter_pair_cp);
|
||||
getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t,
|
||||
value_p->getter_setter_pair_cp);
|
||||
jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
|
||||
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
||||
value_p->value = ECMA_VALUE_UNDEFINED;
|
||||
@@ -510,30 +502,30 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*ext_property_ref.property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
|
||||
|
||||
if (property_desc_p->is_value_defined)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
|
||||
{
|
||||
ecma_named_data_property_assign_value (object_p,
|
||||
ext_property_ref.property_ref.value_p,
|
||||
property_desc_p->value);
|
||||
}
|
||||
|
||||
if (property_desc_p->is_writable_defined)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)
|
||||
{
|
||||
ecma_set_property_writable_attr (ext_property_ref.property_p, property_desc_p->is_writable);
|
||||
ecma_set_property_writable_attr (ext_property_ref.property_p, (property_desc_p->flags & ECMA_PROP_IS_WRITABLE));
|
||||
}
|
||||
}
|
||||
else if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*ext_property_ref.property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
|
||||
|
||||
if (property_desc_p->is_get_defined)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_GET_DEFINED)
|
||||
{
|
||||
ecma_set_named_accessor_property_getter (object_p,
|
||||
ext_property_ref.property_ref.value_p,
|
||||
property_desc_p->get_p);
|
||||
}
|
||||
|
||||
if (property_desc_p->is_set_defined)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_SET_DEFINED)
|
||||
{
|
||||
ecma_set_named_accessor_property_setter (object_p,
|
||||
ext_property_ref.property_ref.value_p,
|
||||
@@ -541,14 +533,16 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
}
|
||||
}
|
||||
|
||||
if (property_desc_p->is_enumerable_defined)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED)
|
||||
{
|
||||
ecma_set_property_enumerable_attr (ext_property_ref.property_p, property_desc_p->is_enumerable);
|
||||
ecma_set_property_enumerable_attr (ext_property_ref.property_p,
|
||||
(property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE));
|
||||
}
|
||||
|
||||
if (property_desc_p->is_configurable_defined)
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE_DEFINED)
|
||||
{
|
||||
ecma_set_property_configurable_attr (ext_property_ref.property_p, property_desc_p->is_configurable);
|
||||
ecma_set_property_configurable_attr (ext_property_ref.property_p,
|
||||
(property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE));
|
||||
}
|
||||
|
||||
return ECMA_VALUE_TRUE;
|
||||
|
||||
@@ -34,8 +34,7 @@ ecma_object_t *ecma_op_create_object_object_noarg_and_set_prototype (ecma_object
|
||||
ecma_value_t ecma_op_general_object_delete (ecma_object_t *obj_p, ecma_string_t *property_name_p, bool is_throw);
|
||||
ecma_value_t ecma_op_general_object_default_value (ecma_object_t *obj_p, ecma_preferred_type_hint_t hint);
|
||||
ecma_value_t ecma_op_general_object_define_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
const ecma_property_descriptor_t *property_desc_p,
|
||||
bool is_throw);
|
||||
const ecma_property_descriptor_t *property_desc_p);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,8 @@ bool ecma_op_object_has_own_property (ecma_object_t *object_p, ecma_string_t *pr
|
||||
bool ecma_op_object_has_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
ecma_value_t ecma_op_object_find_own (ecma_value_t base_value, ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
ecma_value_t ecma_op_object_find (ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
ecma_value_t ecma_op_object_find_by_uint32_index (ecma_object_t *object_p, uint32_t index);
|
||||
ecma_value_t ecma_op_object_find_by_number_index (ecma_object_t *object_p, ecma_number_t index);
|
||||
ecma_value_t ecma_op_object_get_own_data_prop (ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
ecma_value_t ecma_op_object_get (ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
ecma_value_t ecma_op_object_get_by_magic_id (ecma_object_t *object_p, lit_magic_string_id_t property_id);
|
||||
@@ -41,15 +43,21 @@ ecma_value_t ecma_op_get_method_by_symbol_id (ecma_value_t value, lit_magic_stri
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
|
||||
ecma_value_t ecma_op_object_put (ecma_object_t *object_p, ecma_string_t *property_name_p, ecma_value_t value,
|
||||
bool is_throw);
|
||||
ecma_value_t ecma_op_object_put_by_uint32_index (ecma_object_t *object_p, uint32_t index,
|
||||
ecma_value_t value, bool is_throw);
|
||||
ecma_value_t ecma_op_object_put_by_number_index (ecma_object_t *object_p, ecma_number_t index,
|
||||
ecma_value_t value, bool is_throw);
|
||||
ecma_value_t ecma_op_object_delete (ecma_object_t *obj_p, ecma_string_t *property_name_p, bool is_throw);
|
||||
ecma_value_t ecma_op_object_delete_by_uint32_index (ecma_object_t *obj_p, uint32_t index, bool is_throw);
|
||||
ecma_value_t ecma_op_object_delete_by_number_index (ecma_object_t *obj_p, ecma_number_t index, bool is_throw);
|
||||
ecma_value_t ecma_op_object_default_value (ecma_object_t *obj_p, ecma_preferred_type_hint_t hint);
|
||||
ecma_value_t ecma_op_object_define_own_property (ecma_object_t *obj_p, ecma_string_t *property_name_p,
|
||||
const ecma_property_descriptor_t *property_desc_p, bool is_throw);
|
||||
const ecma_property_descriptor_t *property_desc_p);
|
||||
bool ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
ecma_property_descriptor_t *prop_desc_p);
|
||||
ecma_value_t ecma_op_object_has_instance (ecma_object_t *obj_p, ecma_value_t value);
|
||||
bool ecma_op_object_is_prototype_of (ecma_object_t *base_p, ecma_object_t *target_p);
|
||||
ecma_collection_header_t * ecma_op_object_get_property_names (ecma_object_t *obj_p, uint32_t opts);
|
||||
ecma_collection_t * ecma_op_object_get_property_names (ecma_object_t *obj_p, uint32_t opts);
|
||||
|
||||
lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *obj_p);
|
||||
bool ecma_object_class_is (ecma_object_t *object_p, uint32_t class_id);
|
||||
|
||||
@@ -145,15 +145,14 @@ ecma_set_already_resolved_value (ecma_value_t already_resolved, /**< the already
|
||||
* See also: ES2015 25.4.1.8
|
||||
*/
|
||||
static void
|
||||
ecma_promise_trigger_reactions (ecma_collection_header_t *reactions, /**< lists of reactions */
|
||||
ecma_promise_trigger_reactions (ecma_collection_t *reactions, /**< lists of reactions */
|
||||
ecma_value_t value) /**< value for resolve or reject */
|
||||
{
|
||||
ecma_value_t *ecma_value_p = ecma_collection_iterator_init (reactions);
|
||||
ecma_value_t *buffer_p = reactions->buffer_p;
|
||||
|
||||
while (ecma_value_p != NULL)
|
||||
for (uint32_t i = 0; i < reactions->item_count; i++)
|
||||
{
|
||||
ecma_enqueue_promise_reaction_job (*ecma_value_p, value);
|
||||
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
|
||||
ecma_enqueue_promise_reaction_job (buffer_p[i], value);
|
||||
}
|
||||
} /* ecma_promise_trigger_reactions */
|
||||
|
||||
@@ -174,19 +173,19 @@ ecma_reject_promise (ecma_value_t promise, /**< promise */
|
||||
ecma_promise_set_result (obj_p, ecma_copy_value_if_not_object (reason));
|
||||
ecma_promise_object_t *promise_p = (ecma_promise_object_t *) obj_p;
|
||||
|
||||
/* GC can be triggered by ecma_new_values_collection so freeing the collection
|
||||
/* GC can be triggered by ecma_new_collection so freeing the collection
|
||||
first and creating a new one might cause a heap after use event. */
|
||||
ecma_collection_header_t *reject_reactions = promise_p->reject_reactions;
|
||||
ecma_collection_header_t *fulfill_reactions = promise_p->fulfill_reactions;
|
||||
ecma_collection_t *reject_reactions = promise_p->reject_reactions;
|
||||
ecma_collection_t *fulfill_reactions = promise_p->fulfill_reactions;
|
||||
|
||||
/* Fulfill reactions will never be triggered. */
|
||||
ecma_promise_trigger_reactions (reject_reactions, reason);
|
||||
|
||||
promise_p->reject_reactions = ecma_new_values_collection ();
|
||||
promise_p->fulfill_reactions = ecma_new_values_collection ();
|
||||
promise_p->reject_reactions = ecma_new_collection ();
|
||||
promise_p->fulfill_reactions = ecma_new_collection ();
|
||||
|
||||
ecma_free_values_collection (reject_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_free_values_collection (fulfill_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_collection_free_if_not_object (reject_reactions);
|
||||
ecma_collection_free_if_not_object (fulfill_reactions);
|
||||
} /* ecma_reject_promise */
|
||||
|
||||
/**
|
||||
@@ -206,19 +205,19 @@ ecma_fulfill_promise (ecma_value_t promise, /**< promise */
|
||||
ecma_promise_set_result (obj_p, ecma_copy_value_if_not_object (value));
|
||||
ecma_promise_object_t *promise_p = (ecma_promise_object_t *) obj_p;
|
||||
|
||||
/* GC can be triggered by ecma_new_values_collection so freeing the collection
|
||||
/* GC can be triggered by ecma_new_collection so freeing the collection
|
||||
first and creating a new one might cause a heap after use event. */
|
||||
ecma_collection_header_t *reject_reactions = promise_p->reject_reactions;
|
||||
ecma_collection_header_t *fulfill_reactions = promise_p->fulfill_reactions;
|
||||
ecma_collection_t *reject_reactions = promise_p->reject_reactions;
|
||||
ecma_collection_t *fulfill_reactions = promise_p->fulfill_reactions;
|
||||
|
||||
/* Reject reactions will never be triggered. */
|
||||
ecma_promise_trigger_reactions (fulfill_reactions, value);
|
||||
|
||||
promise_p->reject_reactions = ecma_new_values_collection ();
|
||||
promise_p->fulfill_reactions = ecma_new_values_collection ();
|
||||
promise_p->reject_reactions = ecma_new_collection ();
|
||||
promise_p->fulfill_reactions = ecma_new_collection ();
|
||||
|
||||
ecma_free_values_collection (reject_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_free_values_collection (fulfill_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_collection_free_if_not_object (reject_reactions);
|
||||
ecma_collection_free_if_not_object (fulfill_reactions);
|
||||
} /* ecma_fulfill_promise */
|
||||
|
||||
/**
|
||||
@@ -502,8 +501,8 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
|
||||
/* 5 */
|
||||
ecma_promise_set_state (object_p, ECMA_PROMISE_STATE_PENDING);
|
||||
/* 6-7. */
|
||||
promise_object_p->fulfill_reactions = ecma_new_values_collection ();
|
||||
promise_object_p->reject_reactions = ecma_new_values_collection ();
|
||||
promise_object_p->fulfill_reactions = ecma_new_collection ();
|
||||
promise_object_p->reject_reactions = ecma_new_collection ();
|
||||
/* 8. */
|
||||
ecma_promise_resolving_functions_t *funcs = ecma_promise_create_resolving_functions (object_p);
|
||||
|
||||
@@ -706,13 +705,8 @@ ecma_promise_do_then (ecma_value_t promise, /**< the promise which call 'then' *
|
||||
if (ecma_promise_get_state (obj_p) == ECMA_PROMISE_STATE_PENDING)
|
||||
{
|
||||
/* 7. */
|
||||
ecma_append_to_values_collection (promise_p->fulfill_reactions,
|
||||
ecma_make_object_value (fulfill_reaction_p),
|
||||
ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
|
||||
ecma_append_to_values_collection (promise_p->reject_reactions,
|
||||
ecma_make_object_value (reject_reaction_p),
|
||||
ECMA_COLLECTION_NO_REF_OBJECTS);
|
||||
ecma_collection_push_back (promise_p->fulfill_reactions, ecma_make_object_value (fulfill_reaction_p));
|
||||
ecma_collection_push_back (promise_p->reject_reactions, ecma_make_object_value (reject_reaction_p));
|
||||
}
|
||||
else if (ecma_promise_get_state (obj_p) == ECMA_PROMISE_STATE_FULFILLED)
|
||||
{
|
||||
|
||||
@@ -64,8 +64,8 @@ typedef struct
|
||||
{
|
||||
ecma_extended_object_t ecma_extended_object_t; /**< extended object part */
|
||||
uint8_t state; /**< promise state, see ecma_promise_state_t */
|
||||
ecma_collection_header_t *fulfill_reactions; /**< list of PromiseFullfillReactions */
|
||||
ecma_collection_header_t *reject_reactions; /**< list of PromiseRejectReactions */
|
||||
ecma_collection_t *fulfill_reactions; /**< list of PromiseFullfillReactions */
|
||||
ecma_collection_t *reject_reactions; /**< list of PromiseRejectReactions */
|
||||
} ecma_promise_object_t;
|
||||
|
||||
bool ecma_is_promise (ecma_object_t *obj_p);
|
||||
|
||||
@@ -44,27 +44,28 @@ ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, /**< starting lexical
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL);
|
||||
|
||||
ecma_object_t *lex_env_iter_p = lex_env_p;
|
||||
|
||||
while (lex_env_iter_p != NULL)
|
||||
while (true)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015_CLASS)
|
||||
if (ecma_get_lex_env_type (lex_env_iter_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND)
|
||||
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND)
|
||||
{
|
||||
lex_env_iter_p = ecma_get_lex_env_outer_reference (lex_env_iter_p);
|
||||
JERRY_ASSERT (lex_env_iter_p != NULL);
|
||||
JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL);
|
||||
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_CLASS) */
|
||||
|
||||
if (ecma_op_has_binding (lex_env_iter_p, name_p))
|
||||
if (ecma_op_has_binding (lex_env_p, name_p))
|
||||
{
|
||||
return lex_env_iter_p;
|
||||
return lex_env_p;
|
||||
}
|
||||
|
||||
lex_env_iter_p = ecma_get_lex_env_outer_reference (lex_env_iter_p);
|
||||
}
|
||||
if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
|
||||
}
|
||||
} /* ecma_op_resolve_reference_base */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_CLASS)
|
||||
@@ -85,7 +86,9 @@ ecma_op_resolve_super_reference_value (ecma_object_t *lex_env_p) /**< starting l
|
||||
return ecma_get_lex_env_binding_object (lex_env_p);
|
||||
}
|
||||
|
||||
lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
|
||||
JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL);
|
||||
|
||||
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
|
||||
}
|
||||
} /* ecma_op_resolve_super_reference_value */
|
||||
#endif /* ENABLED (JERRY_ES2015_CLASS) */
|
||||
@@ -101,7 +104,7 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
|
||||
{
|
||||
JERRY_ASSERT (lex_env_p != NULL);
|
||||
|
||||
while (lex_env_p != NULL)
|
||||
while (true)
|
||||
{
|
||||
ecma_lexical_environment_type_t lex_env_type = ecma_get_lex_env_type (lex_env_p);
|
||||
|
||||
@@ -132,13 +135,15 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
|
||||
|
||||
ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (prop_value_p);
|
||||
ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (prop_value_p);
|
||||
|
||||
if (getter_p == NULL)
|
||||
if (get_set_pair_p->getter_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return ECMA_VALUE_UNDEFINED;
|
||||
}
|
||||
|
||||
ecma_object_t *getter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp);
|
||||
|
||||
ecma_value_t base_value = ecma_make_object_value (binding_obj_p);
|
||||
return ecma_op_function_call (getter_p, base_value, NULL, 0);
|
||||
}
|
||||
@@ -160,7 +165,12 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
|
||||
#endif /* ENABLED (JERRY_ES2015_CLASS) */
|
||||
}
|
||||
|
||||
lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
|
||||
if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ERROR_MESSAGES)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user