upgrade jerry from v2.1 to v2.3 <wanggang203@huawei.com>

Signed-off-by: Gavin1012 <wanggang203@huawei.com>
This commit is contained in:
Gavin1012 2021-08-11 11:23:51 +08:00
parent 9f796f548a
commit 0c184d985a
810 changed files with 67456 additions and 19128 deletions

View File

@ -1,8 +1,8 @@
language: c
# Default environment: Ubuntu Trusty 14.04.
# Default environment: Ubuntu Bionic 18.04.
os: linux
dist: trusty
dist: bionic
# Default job task: run tests as defined in the $OPT environment variable.
# Jobs can redefine the 'script' stage in the matrix below.
@ -12,13 +12,12 @@ script: tools/run-tests.py $OPTS
matrix:
include:
- name: "Checks"
install: pip install --user pylint==1.6.5
script:
- tools/run-tests.py --check-signed-off=travis --check-doxygen --check-vera --check-license --check-magic-strings --check-pylint
- travis_wait 40 tools/run-tests.py --check-cppcheck
addons:
apt:
packages: [doxygen, cppcheck, vera++]
packages: [doxygen, cppcheck, vera++, pylint]
- name: "Linux/x86-64 Build, Correctness & Debugger Tests"
env:
@ -40,10 +39,17 @@ matrix:
apt:
packages: [gcc-arm-linux-gnueabihf, libc6-dev-armhf-cross, qemu-user-static]
- name: "Linux/AArch64 Native Build & Correctness Tests"
arch: arm64
env:
- OPTS="--quiet --jerry-tests --jerry-test-suite --buildoptions=--linker-flag=-static"
- TIMEOUT=300
- name: "OSX/x86-64 Build, Correctness & Unit Tests"
env:
- OPTS="--quiet --jerry-tests --jerry-test-suite --unittests"
os: osx
osx_image: xcode11.4
addons:
homebrew:
packages: [cmake, cppcheck, vera++]
@ -55,10 +61,14 @@ matrix:
apt:
packages: [gcc-multilib]
- name: "Conformance Tests"
- name: "Conformance Tests - ES5.1"
env:
- OPTS="--test262"
- name: "Conformance Tests - ES2015"
env:
- OPTS="--test262-es2015"
- name: "Unit Tests"
env:
- OPTS="--unittests"
@ -67,25 +77,23 @@ matrix:
env:
# Skipping maximum stack usage related tests due to 'detect_stack_use_after_return=1' ASAN option.
# For more detailed description: https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn#compatibility
- OPTS="--quiet --jerry-tests --jerry-test-suite --skip-list=parser-oom.js,parser-oom2.js,stack-limit.js,regression-test-issue-2190.js,regression-test-issue-2258-2963.js,regression-test-issue-2448.js,regression-test-issue-2905.js --buildoptions=--stack-limit=0,--compile-flag=-fsanitize=address,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--compile-flag=-O2,--debug,--system-allocator=on,--linker-flag=-fuse-ld=gold"
- OPTS="--quiet --jerry-tests --jerry-test-suite --skip-list=parser-oom.js,parser-oom2.js,stack-limit.js,regression-test-issue-2190.js,regression-test-issue-2258-2963.js,regression-test-issue-2448.js,regression-test-issue-2905.js,regression-test-issue-3785.js --buildoptions=--stack-limit=0,--compile-flag=-fsanitize=address,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--compile-flag=-O2,--debug,--system-allocator=on,--linker-flag=-fuse-ld=gold"
- ASAN_OPTIONS=detect_stack_use_after_return=1:check_initialization_order=true:strict_init_order=true
- TIMEOUT=600
compiler: gcc-5
addons:
apt:
sources: ubuntu-toolchain-r-test
packages: [gcc-5, gcc-5-multilib]
packages: [gcc-multilib]
- name: "UBSAN Tests"
env:
- OPTS="--quiet --jerry-tests --jerry-test-suite --skip-list=parser-oom.js,parser-oom2.js --buildoptions=--compile-flag=-fsanitize=undefined,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--debug,--system-allocator=on,--linker-flag=-fuse-ld=gold"
- UBSAN_OPTIONS=print_stacktrace=1
- TIMEOUT=600
compiler: gcc-5
addons:
apt:
sources: ubuntu-toolchain-r-test
packages: [gcc-5, gcc-5-multilib]
packages: [gcc-multilib]
- name: "Coverity Scan & SonarQube"
env:
@ -120,11 +128,13 @@ matrix:
script: make -f ./targets/mbedos5/Makefile.travis script
- name: "Zephyr/Arduino 101 Build Test"
language: python # NOTE: only way to ensure python>=2.7.10 on Trusty image
python: 3.6
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: [gperf, dfu-util, device-tree-compiler]
- name: "NuttX/STM32F4 Build Test"
install: make -f targets/nuttx-stm32f4/Makefile.travis install-noapt

View File

@ -92,6 +92,7 @@ if (defined(ohos_lite)) { # is on lite Os for ipcamera
"jerry-core/ecma/base/ecma-module.c",
"jerry-core/ecma/base/ecma-property-hashmap.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype-unscopables.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-array.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c",
@ -108,12 +109,16 @@ if (defined(ohos_lite)) { # is on lite Os for ipcamera
"jerry-core/ecma/builtin-objects/ecma-builtin-evalerror.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-function.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-generator-function.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-generator-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-generator.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-global.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-helpers-error.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-helpers-json.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-helpers-sort.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-intrinsic.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-iterator-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-json.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-map-iterator-prototype.c",
@ -126,10 +131,12 @@ if (defined(ohos_lite)) { # is on lite Os for ipcamera
"jerry-core/ecma/builtin-objects/ecma-builtin-object.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-promise-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-promise.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-proxy.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-rangeerror-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-rangeerror.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-referenceerror-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-referenceerror.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-regexp.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-set-iterator-prototype.c",
@ -147,6 +154,10 @@ if (defined(ohos_lite)) { # is on lite Os for ipcamera
"jerry-core/ecma/builtin-objects/ecma-builtin-typeerror.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-urierror-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-urierror.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-weakmap-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-weakmap.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-weakset-prototype.c",
"jerry-core/ecma/builtin-objects/ecma-builtin-weakset.c",
"jerry-core/ecma/builtin-objects/ecma-builtins.c",
"jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float32array-prototype.c",
"jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float32array.c",
@ -189,6 +200,7 @@ if (defined(ohos_lite)) { # is on lite Os for ipcamera
"jerry-core/ecma/operations/ecma-objects-general.c",
"jerry-core/ecma/operations/ecma-objects.c",
"jerry-core/ecma/operations/ecma-promise-object.c",
"jerry-core/ecma/operations/ecma-proxy-object.c",
"jerry-core/ecma/operations/ecma-reference.c",
"jerry-core/ecma/operations/ecma-regexp-object.c",
"jerry-core/ecma/operations/ecma-string-object.c",
@ -212,8 +224,10 @@ if (defined(ohos_lite)) { # is on lite Os for ipcamera
"jerry-core/parser/js/js-parser-mem.c",
"jerry-core/parser/js/js-parser-module.c",
"jerry-core/parser/js/js-parser-statm.c",
"jerry-core/parser/js/js-parser-tagged-template-literal.c",
"jerry-core/parser/js/js-parser-util.c",
"jerry-core/parser/js/js-parser.c",
"jerry-core/parser/js/js-scanner-ops.c",
"jerry-core/parser/js/js-scanner-util.c",
"jerry-core/parser/js/js-scanner.c",
"jerry-core/parser/regexp/re-bytecode.c",
@ -264,6 +278,7 @@ if (defined(ohos_lite)) { # is on lite Os for ipcamera
"jerry-ext/handler/handler-gc.c",
"jerry-ext/handler/handler-print.c",
"jerry-ext/handler/handler-register.c",
"jerry-ext/handler/handler-resource-name.c",
"jerry-ext/module/module.c",
]
jerry_ext_include_dirs = [
@ -290,22 +305,33 @@ if (defined(ohos_lite)) { # is on lite Os for ipcamera
jerry_libm_sources = [
"jerry-libm/acos.c",
"jerry-libm/acosh.c",
"jerry-libm/asin.c",
"jerry-libm/asinh.c",
"jerry-libm/atan.c",
"jerry-libm/atan2.c",
"jerry-libm/atanh.c",
"jerry-libm/cbrt.c",
"jerry-libm/ceil.c",
"jerry-libm/copysign.c",
"jerry-libm/cosh.c",
"jerry-libm/exp.c",
"jerry-libm/expm1.c",
"jerry-libm/fabs.c",
"jerry-libm/finite.c",
"jerry-libm/floor.c",
"jerry-libm/fmod.c",
"jerry-libm/isnan.c",
"jerry-libm/log.c",
"jerry-libm/log10.c",
"jerry-libm/log1p.c",
"jerry-libm/log2.c",
"jerry-libm/nextafter.c",
"jerry-libm/pow.c",
"jerry-libm/scalbn.c",
"jerry-libm/sinh.c",
"jerry-libm/sqrt.c",
"jerry-libm/tanh.c",
"jerry-libm/trig.c",
]
jerry_libm_include_dirs = [ "jerry-libm/include" ]

View File

@ -798,7 +798,6 @@ RECURSIVE = YES
# who are familiar with the undocumented parts.
EXCLUDE = \
jerry-core/ecma/base/ecma-globals.h \
jerry-core/ecma/base/ecma-helpers.h \
jerry-core/ecma/operations/ecma-exceptions.h \
jerry-core/include/jerryscript-debugger-transport.h \
jerry-core/jcontext/jcontext.h \

View File

@ -3,7 +3,7 @@
"Name": "jerryscript",
"License": "Apache-2.0",
"License File": "LICENSE",
"Version Number": "v2.1.0",
"Version Number": "v2.3.0",
"Owner": "pengbiao1@huawei.com",
"Upstream URL": "https://github.com/jerryscript-project/jerryscript.git",
"Description": "JerryScript is the lightweight JavaScript engine intended to run on a very constrained devices such as microcontrollers."

View File

@ -22,11 +22,10 @@ Additional information can be found on our [project page](http://jerryscript.net
Memory usage and Binary footprint are measured at [here](https://jerryscript-project.github.io/jerryscript-test-results) with real target daily.
The following table shows the latest results on the devices:
The latest results on **Raspberry Pi 2**:
| STM32F4-Discovery | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/jsremote-testrunner.appspot.com/o/status%2Fjerryscript%2Fstm32f4dis.svg?alt=media&token=1)](https://jerryscript-project.github.io/jerryscript-test-results/?view=stm32f4dis) |
| :---: | :---: |
| **Raspberry Pi 2** | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/jsremote-testrunner.appspot.com/o/status%2Fjerryscript%2Frpi2.svg?alt=media&token=1)](https://jerryscript-project.github.io/jerryscript-test-results/?view=rpi2) |
[![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/jsremote-testrunner.appspot.com/o/status%2Fjerryscript%2Frpi2.svg?alt=media&token=1)](https://jerryscript-project.github.io/jerryscript-test-results/?view=rpi2)
IRC channel: #jerryscript on [freenode](https://freenode.net)
Mailing list: jerryscript-dev@groups.io, you can subscribe [here](https://groups.io/g/jerryscript-dev) and access the mailing list archive [here](https://groups.io/g/jerryscript-dev/topics).

View File

@ -17,20 +17,16 @@ platform:
environment:
matrix:
- FEATURE_DEBUGGER: ON
- FEATURE_DEBUGGER: OFF
- JERRY_DEBUGGER: ON
- JERRY_DEBUGGER: OFF
# Steps of a job.
init:
- cmake -version
before_build:
- if "%PLATFORM%"=="Win32" cmake -G"Visual Studio 15 2017" -Bbuild -H. -DFEATURE_DEBUGGER=%FEATURE_DEBUGGER%
- if "%PLATFORM%"=="x64" cmake -G"Visual Studio 15 2017 Win64" -Bbuild -H. -DFEATURE_DEBUGGER=%FEATURE_DEBUGGER%
- if "%PLATFORM%"=="Win32" cmake -G"Visual Studio 15 2017" -Bbuild -H. -DJERRY_DEBUGGER=%JERRY_DEBUGGER%
- if "%PLATFORM%"=="x64" cmake -G"Visual Studio 15 2017 Win64" -Bbuild -H. -DJERRY_DEBUGGER=%JERRY_DEBUGGER%
build:
project: build\Jerry.sln
parallel: true
verbosity: minimal
artifacts:
- path: build\bin\$(configuration)\
name: JerryScriptBinary

View File

@ -0,0 +1,18 @@
# 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 Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)

View File

@ -1,6 +1,6 @@
## Setting up prerequisites
Currently, only Ubuntu 14.04+ is officially supported as primary development environment.
Currently, only Ubuntu 18.04+ is officially supported as primary development environment.
There are several dependencies, that should be installed manually. The following list is the absolute minimum for building:

View File

@ -211,6 +211,17 @@ A value of 0 will use the default value.
| CMake: | `-DJERRY_GC_LIMIT=(int)` |
| Python: | `--gc-limit=(int)` |
### GC mark recursion limit
This option can be used to adjust the maximum recursion depth during the GC mark phase. The provided value should be an integer, which represents the allowed number of recursive calls. Increasing the depth of the recursion reduces the time of GC cycles, however increases stack usage.
A value of 0 will prevent any recursive GC calls.
| Options | |
|---------|---------------------------------------------------|
| C: | `-DJERRY_GC_MARK_LIMIT=(int)` |
| CMake: | `-DJERRY_GC_MARK_LIMIT=(int)` |
| Python: | `--gc-mark-limit=(int)` |
### Stack limit
This option can be used to cap the stack usage of the engine, and prevent stack overflows due to recursion. The provided value should be an integer, which represents the allowed stack usage in kilobytes.
@ -296,9 +307,27 @@ These files can be directly compiled with an application using the JerryScript A
For example with the following command:
```sh
$ gcc -Wall -o demo_app demo_app.c gen_src/jerryscript.c gen_src/jerryscript-port-default.c jerryscript-libm.c -Igen_src/
$ gcc -Wall -o demo_app demo_app.c gen_src/jerryscript.c gen_src/jerryscript-port-default.c jerryscript-libm.c -Igen_src/
```
Please note that the headers must be available on the include path.
In addition there is a `-DENABLE_ALL_IN_ONE_SOURCE=ON` CMake option to use this kind of sources during the build.
# Target specific information
## x86 with GCC
When building for Intel 32 bit architecture it is possible that GCC uses conservative options, thus assuming the most
basic floating-point support (that is it does not generate SSE or others instructions).
However this could lead to loss off precision and/or different results than what is required by the JavaScript standard
in regards of floating-point values and arithmetic.
To resolve this precision problem it is advised to use at least SSE2.
To do this with GCC please provide the `-mfpmath=sse -msse2` options during build.
These options can also be specified via the `build.py` script:
```sh
$ ./tools/build.py --compile-flag=-mfpmath=sse --compile-flag=-msse2 --compile-flag=-m32
```

File diff suppressed because it is too large Load Diff

View File

@ -1084,7 +1084,8 @@ int
main (void)
{
/* Initialize srand value */
srand ((unsigned) jerry_port_get_current_time ());
union { double d; unsigned u; } now = { .d = jerry_port_get_current_time () };
srand (now.u);
/* Generate a random number, and print it */
const jerry_char_t script[] = "var a = Math.random (); print(a)";

View File

@ -1,24 +1,24 @@
# Copyright (c) 2020 Huawei Device Co., Ltd.
# 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.
engine_path = "//third_party/jerryscript"
core_path = "${engine_path}/jerry-core"
debugger_path = "${engine_path}/jerry-debugger"
ext_path = "${engine_path}/jerry-ext"
libm_path = "${engine_path}/jerry-libm"
port_path = "${engine_path}/jerry-port"
# Copyright (c) 2020 Huawei Device Co., Ltd.
# 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.
engine_path = "//third_party/jerryscript"
core_path = "${engine_path}/jerry-core"
debugger_path = "${engine_path}/jerry-debugger"
ext_path = "${engine_path}/jerry-ext"
libm_path = "${engine_path}/jerry-libm"
port_path = "${engine_path}/jerry-port"

View File

@ -43,6 +43,7 @@ lite_library("jerry-core_shared") {
"ecma/base/ecma-module.c",
"ecma/base/ecma-property-hashmap.c",
"ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c",
"ecma/builtin-objects/ecma-builtin-array-prototype-unscopables.c",
"ecma/builtin-objects/ecma-builtin-array-prototype.c",
"ecma/builtin-objects/ecma-builtin-array.c",
"ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c",
@ -59,12 +60,16 @@ lite_library("jerry-core_shared") {
"ecma/builtin-objects/ecma-builtin-evalerror.c",
"ecma/builtin-objects/ecma-builtin-function-prototype.c",
"ecma/builtin-objects/ecma-builtin-function.c",
"ecma/builtin-objects/ecma-builtin-generator-function.c",
"ecma/builtin-objects/ecma-builtin-generator-prototype.c",
"ecma/builtin-objects/ecma-builtin-generator.c",
"ecma/builtin-objects/ecma-builtin-global.c",
"ecma/builtin-objects/ecma-builtin-helpers-date.c",
"ecma/builtin-objects/ecma-builtin-helpers-error.c",
"ecma/builtin-objects/ecma-builtin-helpers-json.c",
"ecma/builtin-objects/ecma-builtin-helpers-sort.c",
"ecma/builtin-objects/ecma-builtin-helpers.c",
"ecma/builtin-objects/ecma-builtin-intrinsic.c",
"ecma/builtin-objects/ecma-builtin-iterator-prototype.c",
"ecma/builtin-objects/ecma-builtin-json.c",
"ecma/builtin-objects/ecma-builtin-map-iterator-prototype.c",
@ -77,10 +82,12 @@ lite_library("jerry-core_shared") {
"ecma/builtin-objects/ecma-builtin-object.c",
"ecma/builtin-objects/ecma-builtin-promise-prototype.c",
"ecma/builtin-objects/ecma-builtin-promise.c",
"ecma/builtin-objects/ecma-builtin-proxy.c",
"ecma/builtin-objects/ecma-builtin-rangeerror-prototype.c",
"ecma/builtin-objects/ecma-builtin-rangeerror.c",
"ecma/builtin-objects/ecma-builtin-referenceerror-prototype.c",
"ecma/builtin-objects/ecma-builtin-referenceerror.c",
"ecma/builtin-objects/ecma-builtin-reflect.c",
"ecma/builtin-objects/ecma-builtin-regexp-prototype.c",
"ecma/builtin-objects/ecma-builtin-regexp.c",
"ecma/builtin-objects/ecma-builtin-set-iterator-prototype.c",
@ -98,6 +105,10 @@ lite_library("jerry-core_shared") {
"ecma/builtin-objects/ecma-builtin-typeerror.c",
"ecma/builtin-objects/ecma-builtin-urierror-prototype.c",
"ecma/builtin-objects/ecma-builtin-urierror.c",
"ecma/builtin-objects/ecma-builtin-weakmap-prototype.c",
"ecma/builtin-objects/ecma-builtin-weakmap.c",
"ecma/builtin-objects/ecma-builtin-weakset-prototype.c",
"ecma/builtin-objects/ecma-builtin-weakset.c",
"ecma/builtin-objects/ecma-builtins.c",
"ecma/builtin-objects/typedarray/ecma-builtin-float32array-prototype.c",
"ecma/builtin-objects/typedarray/ecma-builtin-float32array.c",
@ -140,6 +151,7 @@ lite_library("jerry-core_shared") {
"ecma/operations/ecma-objects-general.c",
"ecma/operations/ecma-objects.c",
"ecma/operations/ecma-promise-object.c",
"ecma/operations/ecma-proxy-object.c",
"ecma/operations/ecma-reference.c",
"ecma/operations/ecma-regexp-object.c",
"ecma/operations/ecma-string-object.c",
@ -163,8 +175,10 @@ lite_library("jerry-core_shared") {
"parser/js/js-parser-mem.c",
"parser/js/js-parser-module.c",
"parser/js/js-parser-statm.c",
"parser/js/js-parser-tagged-template-literal.c",
"parser/js/js-parser-util.c",
"parser/js/js-parser.c",
"parser/js/js-scanner-ops.c",
"parser/js/js-scanner-util.c",
"parser/js/js-scanner.c",
"parser/regexp/re-bytecode.c",

View File

@ -41,6 +41,7 @@ set(JERRY_VM_EXEC_STOP OFF CACHE BOOL "Enable VM execution st
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")
set(JERRY_GC_MARK_LIMIT "(8)" CACHE STRING "Maximum depth of recursion during GC mark phase")
# Option overrides
if(USING_MSVC)
@ -104,6 +105,7 @@ 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})
message(STATUS "JERRY_GC_MARK_LIMIT " ${JERRY_GC_MARK_LIMIT})
# Include directories
set(INCLUDE_CORE_PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
@ -315,6 +317,9 @@ jerry_add_define01(JERRY_VM_EXEC_STOP)
# Maximum size of stack memory usage
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_STACK_LIMIT=${JERRY_STACK_LIMIT})
# Maximum depth of recursion during GC mark phase
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_GC_MARK_LIMIT=${JERRY_GC_MARK_LIMIT})
## This function is to read "config.h" for default values
function(read_set_defines FILE PREFIX OUTPUTVAR)
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}" INPUT_FILE_CONTENTS)
@ -405,6 +410,11 @@ target_include_directories(${JERRY_CORE_NAME} PRIVATE ${INCLUDE_CORE_PRIVATE})
set(JERRY_CORE_PKGCONFIG_REQUIRES)
set(JERRY_CORE_PKGCONFIG_LIBS)
set(JERRY_CORE_PKGCONFIG_CFLAGS)
if(ENABLE_LTO)
set(JERRY_CORE_PKGCONFIG_CFLAGS "${JERRY_CORE_PKGCONFIG_CFLAGS} -flto")
endif()
if(JERRY_LIBM)
target_link_libraries(${JERRY_CORE_NAME} jerry-libm)

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +1,51 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
* Description: Definition of header file for generating bytecode.
* Create: 2020/09/07
*/
#ifndef GENERATE_BYTECODE_H
#define GENERATE_BYTECODE_H
#ifdef JERRY_FOR_IAR_CONFIG
#include "jerryscript.h"
typedef enum {
EXCE_ACE_JERRY_EXEC_OK = 0, // program function OK
EXCE_ACE_JERRY_NULL_PATH, // null path for generateing snapshot
EXCE_ACE_JERRY_MALLOC_ERROR, // error when malloc
EXCE_ACE_JERRY_INPUT_PATH_ERROR, // passed input path is NULL OR open failed
EXCE_ACE_JERRY_INPUT_PATH_NOT_DIR, // passed input path is not a directory
EXCE_ACE_JERRY_OPEN_DIR_FAILED, // open directory failed
EXCE_ACE_JERRY_GENERATE_SNAPSHOT_FAILED, // jerry_generate_snapshot failed
EXCE_ACE_JERRY_OPEN_FILE_FAILED, // open file failed
EXCE_ACE_JERRY_WRITE_SNAPSHOT_FILE_FAILED, // write into snapshot file failed
EXCE_ACE_JERRY_READ_JSFILE_FAILED, // read .js file process failed
EXCE_ACE_JERRY_JSFILE_TOO_LARGE, // bytes of js file out of psRAM
EXCE_ACE_JERRY_SPLICE_PATH_ERROR, // error when splice path
EXCE_ACE_JERRY_SPLICE_OUTPUT_PATH_ERROR, // error when splice output file abs name
EXCE_ACE_JERRY_SPRINTFS_VERSION_ERROR, // error when sprintf_s for jerry_version
EXCE_ACE_JERRY_GET_FILE_STAT_ERROR, // error when getting file stat
EXCE_ACE_JERRY_LINKLIST_ERROR, // error when malloc for list node
EXCE_ACE_JERRY_UNLINKFILE_ERROR, // error when unlink bytecode file
} EXECRES;
typedef struct
{
jerry_context_t *context_p;
} ContextRecord;
char* get_jerry_version_no();
EXECRES walk_directory(char* filefolder);
EXECRES walk_del_bytecode(char* filefolder);
void bms_task_context_init (void);
void js_task_context_init (void);
void jerry_port_default_remove_current_context_record ();
void jerry_external_context_init(uint32_t heap_size, jerry_context_alloc_t alloc, void *cb_data_p);
#endif // JERRY_FOR_IAR_CONFIG
#endif // GENERATE_BYTECODE_H
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
* Description: Definition of header file for generating bytecode.
* Create: 2020/09/07
*/
#ifndef GENERATE_BYTECODE_H
#define GENERATE_BYTECODE_H
#ifdef JERRY_FOR_IAR_CONFIG
#include "jerryscript.h"
typedef enum {
EXCE_ACE_JERRY_EXEC_OK = 0, // program function OK
EXCE_ACE_JERRY_NULL_PATH, // null path for generateing snapshot
EXCE_ACE_JERRY_MALLOC_ERROR, // error when malloc
EXCE_ACE_JERRY_INPUT_PATH_ERROR, // passed input path is NULL OR open failed
EXCE_ACE_JERRY_INPUT_PATH_NOT_DIR, // passed input path is not a directory
EXCE_ACE_JERRY_OPEN_DIR_FAILED, // open directory failed
EXCE_ACE_JERRY_GENERATE_SNAPSHOT_FAILED, // jerry_generate_snapshot failed
EXCE_ACE_JERRY_OPEN_FILE_FAILED, // open file failed
EXCE_ACE_JERRY_WRITE_SNAPSHOT_FILE_FAILED, // write into snapshot file failed
EXCE_ACE_JERRY_READ_JSFILE_FAILED, // read .js file process failed
EXCE_ACE_JERRY_JSFILE_TOO_LARGE, // bytes of js file out of psRAM
EXCE_ACE_JERRY_SPLICE_PATH_ERROR, // error when splice path
EXCE_ACE_JERRY_SPLICE_OUTPUT_PATH_ERROR, // error when splice output file abs name
EXCE_ACE_JERRY_SPRINTFS_VERSION_ERROR, // error when sprintf_s for jerry_version
EXCE_ACE_JERRY_GET_FILE_STAT_ERROR, // error when getting file stat
EXCE_ACE_JERRY_LINKLIST_ERROR, // error when malloc for list node
EXCE_ACE_JERRY_UNLINKFILE_ERROR, // error when unlink bytecode file
} EXECRES;
typedef struct
{
jerry_context_t *context_p;
} ContextRecord;
char* get_jerry_version_no();
EXECRES walk_directory(char* filefolder);
EXECRES walk_del_bytecode(char* filefolder);
void bms_task_context_init (void);
void js_task_context_init (void);
void jerry_port_default_remove_current_context_record ();
void jerry_external_context_init(uint32_t heap_size, jerry_context_alloc_t alloc, void *cb_data_p);
#endif // JERRY_FOR_IAR_CONFIG
#endif // GENERATE_BYTECODE_H

View File

@ -45,9 +45,9 @@ snapshot_get_global_flags (bool has_regex, /**< regex literal is present */
#if ENABLED (JERRY_BUILTIN_REGEXP)
flags |= (has_regex ? JERRY_SNAPSHOT_HAS_REGEX_LITERAL : 0);
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
#if ENABLED (JERRY_ES2015_CLASS)
#if ENABLED (JERRY_ES2015)
flags |= (has_class ? JERRY_SNAPSHOT_HAS_CLASS_LITERAL : 0);
#endif /* ENABLED (JERRY_ES2015_CLASS) */
#endif /* ENABLED (JERRY_ES2015) */
return flags;
} /* snapshot_get_global_flags */
@ -63,9 +63,9 @@ snapshot_check_global_flags (uint32_t global_flags) /**< global flags */
#if ENABLED (JERRY_BUILTIN_REGEXP)
global_flags &= (uint32_t) ~JERRY_SNAPSHOT_HAS_REGEX_LITERAL;
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
#if ENABLED (JERRY_ES2015_CLASS)
#if ENABLED (JERRY_ES2015)
global_flags &= (uint32_t) ~JERRY_SNAPSHOT_HAS_CLASS_LITERAL;
#endif /* ENABLED (JERRY_ES2015_CLASS) */
#endif /* ENABLED (JERRY_ES2015) */
return global_flags == snapshot_get_global_flags (false, false);
} /* snapshot_check_global_flags */
@ -160,12 +160,19 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
uint8_t *copied_code_start_p = snapshot_buffer_p + globals_p->snapshot_buffer_write_offset;
ecma_compiled_code_t *copied_code_p = (ecma_compiled_code_t *) copied_code_start_p;
#if ENABLED (JERRY_ES2015_CLASS)
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_CONSTRUCTOR)
#if ENABLED (JERRY_ES2015)
if (compiled_code_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
{
const char * const error_message_p = "Unsupported feature: tagged template literals.";
globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
return 0;
}
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR)
{
globals_p->class_found = true;
}
#endif /* ENABLED (JERRY_ES2015_CLASS) */
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_BUILTIN_REGEXP)
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
@ -288,19 +295,20 @@ static void
static_snapshot_error_unsupported_literal (snapshot_globals_t *globals_p, /**< snapshot globals */
ecma_value_t literal) /**< literal form the literal pool */
{
const lit_utf8_byte_t error_prefix[] = "Unsupported static snapshot literal: ";
lit_utf8_byte_t *str_p = (lit_utf8_byte_t *) "Unsupported static snapshot literal: ";
ecma_stringbuilder_t builder = ecma_stringbuilder_create_raw (str_p, 37);
ecma_string_t *error_message_p = ecma_new_ecma_string_from_utf8 (error_prefix, sizeof (error_prefix) - 1);
literal = ecma_op_to_string (literal);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (literal));
ecma_string_t *literal_string_p = ecma_get_string_from_value (literal);
error_message_p = ecma_concat_ecma_strings (error_message_p, literal_string_p);
ecma_string_t *literal_string_p = ecma_op_to_string (literal);
JERRY_ASSERT (literal_string_p != NULL);
ecma_stringbuilder_append (&builder, literal_string_p);
ecma_deref_ecma_string (literal_string_p);
ecma_object_t *error_object_p = ecma_new_standard_error_with_message (ECMA_ERROR_RANGE, error_message_p);
ecma_deref_ecma_string (error_message_p);
ecma_object_t *error_object_p = ecma_new_standard_error_with_message (ECMA_ERROR_RANGE,
ecma_stringbuilder_finalize (&builder));
globals_p->snapshot_error = ecma_create_error_object_reference (error_object_p);
} /* static_snapshot_error_unsupported_literal */
@ -416,7 +424,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
}
}
if (CBC_NON_STRICT_ARGUMENTS_NEEDED (compiled_code_p))
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
{
buffer_p += ((size_t) compiled_code_p->size) << JMEM_ALIGNMENT_LOG;
literal_start_p = ((ecma_value_t *) buffer_p) - argument_end;
@ -488,7 +496,7 @@ jerry_snapshot_set_offsets (uint32_t *buffer_p, /**< buffer */
}
}
if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_p))
if (bytecode_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
{
uint8_t *byte_p = (uint8_t *) bytecode_p;
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
@ -551,7 +559,6 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
#if ENABLED (JERRY_BUILTIN_REGEXP)
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
{
const re_compiled_code_t *re_bytecode_p = NULL;
const uint8_t *regex_start_p = ((const uint8_t *) bytecode_p) + sizeof (ecma_compiled_code_t);
@ -559,10 +566,8 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
ecma_string_t *pattern_str_p = ecma_new_ecma_string_from_utf8 (regex_start_p,
bytecode_p->refs);
re_compile_bytecode (&re_bytecode_p,
pattern_str_p,
bytecode_p->status_flags);
const re_compiled_code_t *re_bytecode_p = re_compile_bytecode (pattern_str_p,
bytecode_p->status_flags);
ecma_deref_ecma_string (pattern_str_p);
return (ecma_compiled_code_t *) re_bytecode_p;
@ -581,7 +586,7 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
uint8_t *byte_p = (uint8_t *) bytecode_p;
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) byte_p;
if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_p))
if (bytecode_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
{
argument_end = args_p->argument_end;
}
@ -595,7 +600,7 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
uint8_t *byte_p = (uint8_t *) bytecode_p;
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) byte_p;
if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_p))
if (bytecode_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
{
argument_end = args_p->argument_end;
}
@ -738,9 +743,9 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr
JERRY_UNUSED (resource_name_p);
JERRY_UNUSED (resource_name_length);
#if ENABLED (JERRY_LINE_INFO)
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
JERRY_CONTEXT (resource_name) = ECMA_VALUE_UNDEFINED;
#endif /* ENABLED (JERRY_LINE_INFO) */
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
snapshot_globals_t globals;
ecma_value_t parse_status;
@ -762,7 +767,7 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr
if (ECMA_IS_VALUE_ERROR (parse_status))
{
return ecma_create_error_reference (JERRY_CONTEXT (error_value), true);
return ecma_create_error_reference_from_context ();
}
JERRY_ASSERT (bytecode_data_p != NULL);
@ -981,9 +986,15 @@ jerry_snapshot_result (const uint32_t *snapshot_p, /**< snapshot */
if (as_function)
{
ecma_object_t *lex_env_p = ecma_get_global_environment ();
ecma_object_t *func_obj_p = ecma_op_create_function_object (lex_env_p,
bytecode_p);
#if ENABLED (JERRY_ES2015)
if (bytecode_p->status_flags & CBC_CODE_FLAGS_LEXICAL_BLOCK_NEEDED)
{
ecma_create_global_lexical_block ();
}
#endif /* ENABLED (JERRY_ES2015) */
ecma_object_t *lex_env_p = ecma_get_global_scope ();
ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_p);
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
{
@ -1091,7 +1102,7 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
}
}
if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_p))
if (bytecode_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
{
uint8_t *byte_p = (uint8_t *) bytecode_p;
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
@ -1169,7 +1180,7 @@ update_literal_offsets (uint8_t *buffer_p, /**< [in,out] snapshot buffer start *
}
}
if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_p))
if (bytecode_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
{
uint8_t *byte_p = (uint8_t *) bytecode_p;
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
@ -1543,42 +1554,6 @@ jerry_append_number_to_buffer (uint8_t *buffer_p, /**< buffer */
utf8_str_size);
} /* jerry_append_number_to_buffer */
/**
* Check whether the passed ecma-string is a valid identifier.
*
* @return true - if the ecma-string is a valid identifier,
* false - otherwise
*/
static bool
ecma_string_is_valid_identifier (const ecma_string_t *string_p)
{
bool result = false;
ECMA_STRING_TO_UTF8_STRING (string_p, str_buffer_p, str_buffer_size);
if (lit_char_is_identifier_start (str_buffer_p))
{
const uint8_t *str_start_p = str_buffer_p;
const uint8_t *str_end_p = str_buffer_p + str_buffer_size;
result = true;
while (str_start_p < str_end_p)
{
if (!lit_char_is_identifier_part (str_start_p))
{
result = false;
break;
}
lit_utf8_incr (&str_start_p);
}
}
ECMA_FINALIZE_UTF8_STRING (str_buffer_p, str_buffer_size);
return result;
} /* ecma_string_is_valid_identifier */
#endif /* ENABLED (JERRY_SNAPSHOT_SAVE) */
/**
@ -1631,14 +1606,7 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
{
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
* identifier or it's a magic string.
* TODO:
* Save all of the literals in C format as well.
*/
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
&& (!is_c_format || ecma_string_is_valid_identifier (literal_p)))
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT)
{
literal_count++;
}
@ -1666,14 +1634,7 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
{
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
* identifier or it's a magic string.
* TODO:
* Save all of the literals in C format as well.
*/
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
&& (!is_c_format || ecma_string_is_valid_identifier (literal_p)))
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT)
{
literal_array[literal_idx++] = literal_p;
}
@ -1707,7 +1668,29 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
for (lit_utf8_size_t i = 0; i < literal_count; i++)
{
lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, " \"", 0);
lit_buf_p = jerry_append_ecma_string_to_buffer (lit_buf_p, buffer_end_p, literal_array[i]);
ECMA_STRING_TO_UTF8_STRING (literal_array[i], str_buffer_p, str_buffer_size);
for (lit_utf8_size_t j = 0; j < str_buffer_size; j++)
{
uint8_t byte = str_buffer_p[j];
if (byte < 32 || byte > 127)
{
lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "\\x", 0);
ecma_char_t hex_digit = (ecma_char_t) (byte >> 4);
*lit_buf_p++ = (lit_utf8_byte_t) ((hex_digit > 9) ? (hex_digit + ('A' - 10)) : (hex_digit + '0'));
hex_digit = (lit_utf8_byte_t) (byte & 0xf);
*lit_buf_p++ = (lit_utf8_byte_t) ((hex_digit > 9) ? (hex_digit + ('A' - 10)) : (hex_digit + '0'));
}
else
{
if (byte == '\\' || byte == '"')
{
*lit_buf_p++ = '\\';
}
*lit_buf_p++ = byte;
}
}
ECMA_FINALIZE_UTF8_STRING (str_buffer_p, str_buffer_size);
lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "\"", 0);
if (i < literal_count - 1)
@ -1779,7 +1762,6 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho
#endif /* ENABLED (JERRY_SNAPSHOT_SAVE) */
} /* jerry_get_literals_from_snapshot */
/**
* Generate snapshot function from specified source and arguments
*

File diff suppressed because it is too large Load Diff

View File

@ -1,41 +1,41 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* 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.
*/
#ifdef JERRY_IAR_JUPITER
#include "jerryscript.h"
#include "jmem.h"
#include "config-jupiter.h"
uint8_t* input_buffer;
uint8_t* snapshot_buffer;
uint8_t* bms_context_and_heap;
uint8_t* js_context_and_heap;
void JerryPsRamMemInit()
{
// memory for js task
js_context_and_heap = OhosMalloc(MEM_TYPE_JERRY_LSRAM, JS_TASK_CONTEXT_AND_HEAP_SIZE_BYTE);
}
void JerryBmsPsRamMemInit()
{
// memory for input_js file, snapshot file and bms task
input_buffer = OhosMalloc(MEM_TYPE_JERRY_LSRAM, INPUTJS_BUFFER_SIZE);
snapshot_buffer = OhosMalloc(MEM_TYPE_JERRY_LSRAM, SNAPSHOT_BUFFER_SIZE);
bms_context_and_heap = OhosMalloc(MEM_TYPE_JERRY_LSRAM, BMS_TASK_CONTEXT_AND_HEAP_SIZE * CONVERTION_RATIO);
}
#endif // JERRY_IAR_JUPITER
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* 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.
*/
#ifdef JERRY_IAR_JUPITER
#include "jerryscript.h"
#include "jmem.h"
#include "config-jupiter.h"
uint8_t* input_buffer;
uint8_t* snapshot_buffer;
uint8_t* bms_context_and_heap;
uint8_t* js_context_and_heap;
void JerryPsRamMemInit()
{
// memory for js task
js_context_and_heap = OhosMalloc(MEM_TYPE_JERRY_LSRAM, JS_TASK_CONTEXT_AND_HEAP_SIZE_BYTE);
}
void JerryBmsPsRamMemInit()
{
// memory for input_js file, snapshot file and bms task
input_buffer = OhosMalloc(MEM_TYPE_JERRY_LSRAM, INPUTJS_BUFFER_SIZE);
snapshot_buffer = OhosMalloc(MEM_TYPE_JERRY_LSRAM, SNAPSHOT_BUFFER_SIZE);
bms_context_and_heap = OhosMalloc(MEM_TYPE_JERRY_LSRAM, BMS_TASK_CONTEXT_AND_HEAP_SIZE * CONVERTION_RATIO);
}
#endif // JERRY_IAR_JUPITER

View File

@ -33,7 +33,7 @@
#ifndef JERRY_FOR_IAR_CONFIG
# define JERRY_MEM_STATS 1
# define JERRY_LOGGING 1
#endif
#endif /* JERRY_FOR_IAR_CONFIG */
#ifndef JERRY_GLOBAL_HEAP_SIZE
//Maximum size of heap in kilobytes
@ -44,7 +44,14 @@
// disable builtin eval() function
# define JERRY_BUILTIN_EVAL_DISABLED 1
#endif
#endif /* JERRY_FOR_IAR_CONFIG */
#if defined (__linux__)
#ifndef JERRY_SNAPSHOT_SAVE
# define JERRY_SNAPSHOT_SAVE 1
#endif
#endif /* binary tool compiling in linux platform */
#endif /* !defined(_WIN32) && !defined(_WIN64) */
/*
* Here define the special config for Win simulator build.
@ -64,9 +71,9 @@
# define JERRY_MEM_STATS 1
# define JERRY_SNAPSHOT_EXEC 1
# define JERRY_SNAPSHOT_SAVE 1
# ifndef JERRY_LOGGING
# define JERRY_LOGGING 1
# endif
#ifndef JERRY_LOGGING
# define JERRY_LOGGING 1
#endif
// following config controls temp changes in jerry for debugger function with IDE
# define ACE_DEBUGGER_CUSTOM
@ -144,18 +151,10 @@
# define JERRY_ES2015 1
#endif /* !defined (JERRY_ES2015) */
#ifndef JERRY_ES2015_BUILTIN
# define JERRY_ES2015_BUILTIN JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN) */
#ifndef JERRY_ES2015_BUILTIN_DATAVIEW
# define JERRY_ES2015_BUILTIN_DATAVIEW JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_DATAVIEW) */
#ifndef JERRY_ES2015_BUILTIN_ITERATOR
# define JERRY_ES2015_BUILTIN_ITERATOR JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_ITERATOR) */
#ifndef JERRY_ES2015_BUILTIN_MAP
# define JERRY_ES2015_BUILTIN_MAP JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_MAP) */
@ -164,50 +163,34 @@
# define JERRY_ES2015_BUILTIN_SET JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_SET) */
#ifndef JERRY_ES2015_BUILTIN_WEAKMAP
# define JERRY_ES2015_BUILTIN_WEAKMAP JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_WEAKMAP) */
#ifndef JERRY_ES2015_BUILTIN_WEAKSET
# define JERRY_ES2015_BUILTIN_WEAKSET JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_WEAKSET) */
#ifndef JERRY_ES2015_BUILTIN_PROMISE
# define JERRY_ES2015_BUILTIN_PROMISE JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_PROMISE) */
#ifndef JERRY_ES2015_BUILTIN_SYMBOL
# define JERRY_ES2015_BUILTIN_SYMBOL JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_SYMBOL) */
#ifndef JERRY_ES2015_BUILTIN_PROXY
# define JERRY_ES2015_BUILTIN_PROXY JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_PROXY) */
#ifndef JERRY_ES2015_BUILTIN_REFLECT
# define JERRY_ES2015_BUILTIN_REFLECT JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_REFLECT) */
#ifndef JERRY_ES2015_BUILTIN_TYPEDARRAY
# define JERRY_ES2015_BUILTIN_TYPEDARRAY JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
#ifndef JERRY_ES2015_ARROW_FUNCTION
# define JERRY_ES2015_ARROW_FUNCTION JERRY_ES2015
#endif /* !defined (JERRY_ES2015_ARROW_FUNCTION) */
#ifndef JERRY_ES2015_CLASS
# define JERRY_ES2015_CLASS JERRY_ES2015
#endif /* !defined (JERRY_ES2015_CLASS) */
#ifndef JERRY_ES2015_FOR_OF
# define JERRY_ES2015_FOR_OF JERRY_ES2015
#endif /* !defined (JERRY_ES2015_FOR_OF) */
#ifndef JERRY_ES2015_FUNCTION_PARAMETER_INITIALIZER
# define JERRY_ES2015_FUNCTION_PARAMETER_INITIALIZER JERRY_ES2015
#endif /* !defined (JERRY_ES2015_FUNCTION_PARAMETER_INITIALIZER) */
#ifndef JERRY_ES2015_FUNCTION_REST_PARAMETER
# define JERRY_ES2015_FUNCTION_REST_PARAMETER JERRY_ES2015
#endif /* !defined (JERRY_ES2015_FUNCTION_REST_PARAMETER) */
#ifndef JERRY_ES2015_OBJECT_INITIALIZER
# define JERRY_ES2015_OBJECT_INITIALIZER JERRY_ES2015
#endif /* !defined (JERRY_ES2015_OBJECT_INITIALIZER) */
#ifndef JERRY_ES2015_MODULE_SYSTEM
# define JERRY_ES2015_MODULE_SYSTEM JERRY_ES2015
#endif /* !defined (JERRY_ES2015_MODULE_SYSTEM) */
#ifndef JERRY_ES2015_TEMPLATE_STRINGS
# define JERRY_ES2015_TEMPLATE_STRINGS JERRY_ES2015
#endif /* !defined (JERRY_ES2015_TEMPLATE_STRINGS) */
/**
* Engine internal and misc configurations.
*/
@ -294,6 +277,15 @@
# define JERRY_STACK_LIMIT (0)
#endif /* !defined (JERRY_STACK_LIMIT) */
/**
* Maximum depth of recursion during GC mark phase
*
* Default value: 8
*/
#ifndef JERRY_GC_MARK_LIMIT
# define JERRY_GC_MARK_LIMIT (8)
#endif /* !defined (JERRY_GC_MARK_LIMIT) */
/**
* Enable/Disable property lookup cache.
*
@ -539,7 +531,6 @@
# define JERRY_ATTR_GLOBAL_HEAP
#endif /* !defined (JERRY_ATTR_GLOBAL_HEAP) */
/**
* Sanity check for macros to see if the values are 0 or 1
*
@ -600,18 +591,6 @@
|| ((JERRY_ES2015 != 0) && (JERRY_ES2015 != 1))
# error "Invalid value for JERRY_ES2015 macro."
#endif
#if !defined (JERRY_ES2015_ARROW_FUNCTION) \
|| ((JERRY_ES2015_ARROW_FUNCTION != 0) && (JERRY_ES2015_ARROW_FUNCTION != 1))
# error "Invalid value for JERRY_ES2015_ARROW_FUNCTION macro."
#endif
#if !defined (JERRY_ES2015_BUILTIN) \
|| ((JERRY_ES2015_BUILTIN != 0) && (JERRY_ES2015_BUILTIN != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN macro."
#endif
#if !defined (JERRY_ES2015_BUILTIN_ITERATOR) \
|| ((JERRY_ES2015_BUILTIN_ITERATOR != 0) && (JERRY_ES2015_BUILTIN_ITERATOR != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_ITERATOR macro."
#endif
#if !defined (JERRY_ES2015_BUILTIN_DATAVIEW) \
|| ((JERRY_ES2015_BUILTIN_DATAVIEW != 0) && (JERRY_ES2015_BUILTIN_DATAVIEW != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_DATAVIEW macro."
@ -620,50 +599,38 @@
|| ((JERRY_ES2015_BUILTIN_MAP != 0) && (JERRY_ES2015_BUILTIN_MAP != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_MAP macro."
#endif
#if !defined (JERRY_ES2015_BUILTIN_REFLECT) \
|| ((JERRY_ES2015_BUILTIN_REFLECT != 0) && (JERRY_ES2015_BUILTIN_REFLECT != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_REFLECT macro."
#endif
#if !defined (JERRY_ES2015_BUILTIN_SET) \
|| ((JERRY_ES2015_BUILTIN_SET != 0) && (JERRY_ES2015_BUILTIN_SET != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_SET macro."
#endif
#if !defined (JERRY_ES2015_BUILTIN_WEAKMAP) \
|| ((JERRY_ES2015_BUILTIN_WEAKMAP != 0) && (JERRY_ES2015_BUILTIN_WEAKMAP != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_WEAKMAP macro."
#endif
#if !defined (JERRY_ES2015_BUILTIN_WEAKSET) \
|| ((JERRY_ES2015_BUILTIN_WEAKSET != 0) && (JERRY_ES2015_BUILTIN_WEAKSET != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_WEAKSET macro."
#endif
#if !defined (JERRY_ES2015_BUILTIN_PROMISE) \
|| ((JERRY_ES2015_BUILTIN_PROMISE != 0) && (JERRY_ES2015_BUILTIN_PROMISE != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_PROMISE macro."
#endif
#if !defined (JERRY_ES2015_BUILTIN_SYMBOL) \
|| ((JERRY_ES2015_BUILTIN_SYMBOL != 0) && (JERRY_ES2015_BUILTIN_SYMBOL != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_SYMBOL macro."
#if !defined (JERRY_ES2015_BUILTIN_PROXY) \
|| ((JERRY_ES2015_BUILTIN_PROXY != 0) && (JERRY_ES2015_BUILTIN_PROXY != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_PROXY macro."
#endif
#if !defined (JERRY_ES2015_BUILTIN_TYPEDARRAY) \
|| ((JERRY_ES2015_BUILTIN_TYPEDARRAY != 0) && (JERRY_ES2015_BUILTIN_TYPEDARRAY != 1))
# error "Invalid value for JERRY_ES2015_BUILTIN_TYPEDARRAY macro."
#endif
#if !defined (JERRY_ES2015_CLASS) \
|| ((JERRY_ES2015_CLASS != 0) && (JERRY_ES2015_CLASS != 1))
# error "Invalid value for JERRY_ES2015_CLASS macro."
#endif
#if !defined (JERRY_ES2015_FOR_OF) \
|| ((JERRY_ES2015_FOR_OF != 0) && (JERRY_ES2015_FOR_OF != 1))
# error "Invalid value for JERRY_ES2015_FOR_OF macro."
#endif
#if !defined (JERRY_ES2015_FUNCTION_PARAMETER_INITIALIZER) \
|| ((JERRY_ES2015_FUNCTION_PARAMETER_INITIALIZER != 0) && (JERRY_ES2015_FUNCTION_PARAMETER_INITIALIZER != 1))
# error "Invalid value for JERRY_ES2015_FUNCTION_PARAMETER_INITIALIZER macro."
#endif
#if !defined (JERRY_ES2015_FUNCTION_REST_PARAMETER) \
|| ((JERRY_ES2015_FUNCTION_REST_PARAMETER != 0) && (JERRY_ES2015_FUNCTION_REST_PARAMETER != 1))
# error "Invalid value for JERRY_ES2015_FUNCTION_REST_PARAMETER macro."
#endif
#if !defined (JERRY_ES2015_OBJECT_INITIALIZER) \
|| ((JERRY_ES2015_OBJECT_INITIALIZER != 0) && (JERRY_ES2015_OBJECT_INITIALIZER != 1))
# error "Invalid value for JERRY_ES2015_OBJECT_INITIALIZER macro."
#endif
#if !defined (JERRY_ES2015_MODULE_SYSTEM) \
|| ((JERRY_ES2015_MODULE_SYSTEM != 0) && (JERRY_ES2015_MODULE_SYSTEM != 1))
# error "Invalid value for JERRY_ES2015_MODULE_SYSTEM macro."
#endif
#if !defined (JERRY_ES2015_TEMPLATE_STRINGS) \
|| ((JERRY_ES2015_TEMPLATE_STRINGS != 0) && (JERRY_ES2015_TEMPLATE_STRINGS != 1))
# error "Invalid value for JERRY_ES2015_TEMPLATE_STRINGS macro."
#endif
/**
* Internal options.
@ -693,6 +660,9 @@
#if !defined (JERRY_STACK_LIMIT) || (JERRY_STACK_LIMIT < 0)
# error "Invalid value for 'JERRY_STACK_LIMIT' macro."
#endif
#if !defined (JERRY_GC_MARK_LIMIT) || (JERRY_GC_MARK_LIMIT < 0)
# error "Invalid value for 'JERRY_GC_MARK_LIMIT' macro."
#endif
#if !defined (JERRY_LCACHE) \
|| ((JERRY_LCACHE != 0) && (JERRY_LCACHE != 1))
# error "Invalid value for 'JERRY_LCACHE' macro."
@ -762,7 +732,6 @@
# error "Invalid value for 'JERRY_VM_EXEC_STOP' macro."
#endif
#define ENABLED(FEATURE) ((FEATURE) == 1)
#define DISABLED(FEATURE) ((FEATURE) != 1)
@ -777,4 +746,14 @@
# error "Date does not support float32"
#endif
/**
* Wrap container types into a single guard
*/
#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) \
|| ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) || ENABLED (JERRY_ES2015_BUILTIN_WEAKSET)
# define JERRY_ES2015_BUILTIN_CONTAINER 1
#else
# define JERRY_ES2015_BUILTIN_CONTAINER 0
#endif
#endif /* !JERRYSCRIPT_CONFIG_H */

View File

@ -244,7 +244,7 @@ jerry_debugger_send_scope_chain (void)
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
{
if ((lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_NON_CLOSURE) != 0)
if ((lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK) != 0)
{
message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_NON_CLOSURE;
}
@ -313,7 +313,7 @@ jerry_debugger_get_variable_type (ecma_value_t value) /**< input ecma value */
{
JERRY_ASSERT (ecma_is_value_object (value));
if (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_ARRAY_UL)
if (ecma_get_object_type (ecma_get_object_from_value (value)) == ECMA_OBJECT_TYPE_ARRAY)
{
ret_value = JERRY_DEBUGGER_VALUE_ARRAY;
}
@ -467,14 +467,9 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer
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);
if (JERRY_UNLIKELY (ecma_get_object_type (binding_obj_p) == ECMA_OBJECT_TYPE_ARRAY))
if (JERRY_UNLIKELY (ecma_op_object_is_fast_array (binding_obj_p)))
{
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);
}
ecma_fast_array_convert_to_normal (binding_obj_p);
}
prop_iter_cp = binding_obj_p->u1.property_list_cp;
@ -517,22 +512,22 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer
ecma_deref_ecma_string (prop_name);
ecma_property_value_t prop_value_p = prop_pair_p->values[i];
ecma_value_t property_value;
uint8_t variable_type = jerry_debugger_get_variable_type (prop_value_p.value);
property_value = ecma_op_to_string (prop_value_p.value);
ecma_string_t *str_p = ecma_op_to_string (prop_value_p.value);
JERRY_ASSERT (str_p != NULL);
if (!jerry_debugger_copy_variables_to_string_message (variable_type,
ecma_get_string_from_value (property_value),
str_p,
message_string_p,
&buffer_pos))
{
ecma_free_value (property_value);
ecma_deref_ecma_string (str_p);
return;
}
ecma_free_value (property_value);
ecma_deref_ecma_string (str_p);
}
}
@ -568,21 +563,15 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
{
if (eval_string_p[4] != JERRY_DEBUGGER_EVAL_EVAL)
{
JERRY_ASSERT (eval_string_p[4] == JERRY_DEBUGGER_EVAL_THROW || eval_string_p[4] == JERRY_DEBUGGER_EVAL_ABORT);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
JERRY_CONTEXT (error_value) = result;
/* Stop where the error is caught. */
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
if (eval_string_p[4] == JERRY_DEBUGGER_EVAL_THROW)
{
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
}
else
{
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
}
jcontext_raise_exception (result);
jcontext_set_abort_flag (eval_string_p[4] == JERRY_DEBUGGER_EVAL_ABORT);
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
return true;
@ -590,7 +579,8 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
if (!ecma_is_value_string (result))
{
ecma_value_t to_string_value = ecma_op_to_string (result);
ecma_string_t *str_p = ecma_op_to_string (result);
ecma_value_t to_string_value = ecma_make_string_value (str_p);
ecma_free_value (result);
result = to_string_value;
}
@ -628,8 +618,10 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
else
{
/* Primitive type. */
message = ecma_op_to_string (result);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (message));
ecma_string_t *str_p = ecma_op_to_string (result);
JERRY_ASSERT (str_p != NULL);
message = ecma_make_string_value (str_p);
}
ecma_free_value (result);
@ -1212,7 +1204,6 @@ jerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p) /**< [out]
}
} /* jerry_debugger_receive */
#undef JERRY_DEBUGGER_CHECK_PACKET_SIZE
/**
@ -1276,7 +1267,6 @@ jerry_debugger_send_type (jerry_debugger_header_type_t type) /**< message type *
jerry_debugger_send (sizeof (jerry_debugger_send_type_t));
} /* jerry_debugger_send_type */
/**
* Send the type signal to the client.
*
@ -1538,11 +1528,9 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /**
}
}
lit_utf8_size_t size = lit_get_magic_string_size (string_id);
JERRY_ASSERT (size <= 14);
ecma_stringbuilder_t builder = ecma_stringbuilder_create ();
lit_utf8_byte_t data[16];
memcpy (data, lit_get_magic_string_utf8 (string_id), size);
ecma_stringbuilder_append_magic (&builder, string_id);
ecma_property_t *property_p;
property_p = ecma_find_named_property (ecma_get_object_from_value (exception_obj_value),
@ -1551,21 +1539,21 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /**
if (property_p == NULL
|| ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA)
{
return ecma_new_ecma_string_from_utf8 (data, size);
return ecma_stringbuilder_finalize (&builder);
}
ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
if (!ecma_is_value_string (prop_value_p->value))
{
return ecma_new_ecma_string_from_utf8 (data, size);
return ecma_stringbuilder_finalize (&builder);
}
data[size] = LIT_CHAR_COLON;
data[size + 1] = LIT_CHAR_SP;
ecma_stringbuilder_append_byte (&builder, LIT_CHAR_COLON);
ecma_stringbuilder_append_byte (&builder, LIT_CHAR_SP);
ecma_stringbuilder_append (&builder, ecma_get_string_from_value (prop_value_p->value));
return ecma_concat_ecma_strings (ecma_new_ecma_string_from_utf8 (data, size + 2),
ecma_get_string_from_value (prop_value_p->value));
return ecma_stringbuilder_finalize (&builder);
} /* jerry_debugger_exception_object_to_string */
/**
@ -1575,12 +1563,11 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /**
* false - otherwise
*/
bool
jerry_debugger_send_exception_string (void)
jerry_debugger_send_exception_string (ecma_value_t exception_value)
{
JERRY_ASSERT (jcontext_has_pending_exception ());
ecma_string_t *string_p = NULL;
ecma_value_t exception_value = JERRY_CONTEXT (error_value);
if (ecma_is_value_object (exception_value))
{
string_p = jerry_debugger_exception_object_to_string (exception_value);
@ -1597,8 +1584,7 @@ jerry_debugger_send_exception_string (void)
}
else
{
exception_value = ecma_op_to_string (exception_value);
string_p = ecma_get_string_from_value (exception_value);
string_p = ecma_op_to_string (exception_value);
}
ECMA_STRING_TO_UTF8_STRING (string_p, string_data_p, string_size);

View File

@ -487,7 +487,7 @@ bool jerry_debugger_send_string (uint8_t message_type, uint8_t sub_type, const u
bool jerry_debugger_send_function_cp (jerry_debugger_header_type_t type, ecma_compiled_code_t *compiled_code_p);
bool jerry_debugger_send_parse_function (uint32_t line, uint32_t column);
void jerry_debugger_send_memstats (void);
bool jerry_debugger_send_exception_string (void);
bool jerry_debugger_send_exception_string (ecma_value_t exception_value);
#endif /* ENABLED (JERRY_DEBUGGER) */

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
void ecma_init_gc_info (ecma_object_t *object_p);
void ecma_ref_object (ecma_object_t *object_p);
void ecma_deref_object (ecma_object_t *object_p);
void ecma_gc_free_properties (ecma_object_t *object_p);
void ecma_gc_run (void);
void ecma_free_unused_memory (jmem_pressure_t pressure);

View File

@ -36,6 +36,15 @@
*/
#define ECMA_NULL_POINTER JMEM_CP_NULL
#if defined (JMEM_CAN_STORE_POINTER_VALUE_DIRECTLY)
/**
* JMEM_ALIGNMENT_LOG aligned pointers can be stored directly in ecma_value_t
*/
#define ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
#endif /* JMEM_CAN_STORE_POINTER_VALUE_DIRECTLY */
/**
* @}
*/
@ -62,6 +71,7 @@ typedef enum
ECMA_STATUS_HIGH_PRESSURE_GC = (1u << 2), /**< last gc was under high pressure */
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
ECMA_STATUS_EXCEPTION = (1u << 3), /**< last exception is a normal exception */
ECMA_STATUS_ABORT = (1u << 4), /**< last exception is an abort */
} ecma_status_flag_t;
/**
@ -88,23 +98,37 @@ typedef enum
#endif /* ENABLED (JERRY_DEBUGGER) */
/**
* Option flags for script parsing.
* Option flags for parser_parse_script and internal flags for global_status_flags in parser context.
* Note:
* The enum members must be kept in sync with parser_general_flags_t
* The last 16 bits are reserved for scope chain index
* the last 16 bits is reserved for internal parser flags, because the debugger uses these
* 16 bits to encode the scope chain skip index as well (see ECMA_PARSE_CHAIN_INDEX_SHIFT)
*/
typedef enum
{
ECMA_PARSE_NO_OPTS = 0, /**< no options passed */
ECMA_PARSE_STRICT_MODE = (1u << 0), /**< enable strict mode */
ECMA_PARSE_DIRECT_EVAL = (1u << 1), /**< eval is called directly (ECMA-262 v5, 15.1.2.1.1) */
/* These four status flags must be in this order. See PARSER_CLASS_PARSE_OPTS_OFFSET. */
ECMA_PARSE_CLASS_CONSTRUCTOR = (1u << 2), /**< a class constructor is being parsed (this value must be kept in
* in sync with PARSER_CLASS_CONSTRUCTOR) */
ECMA_PARSE_HAS_SUPER = (1u << 3), /**< the current context has super reference */
ECMA_PARSE_HAS_IMPL_SUPER = (1u << 4), /**< the current context has implicit parent class */
ECMA_PARSE_HAS_STATIC_SUPER = (1u << 5), /**< the current context is a static class method */
ECMA_PARSE_EVAL = (1u << 6), /**< eval is called */
ECMA_PARSE_STRICT_MODE = (1u << 0), /**< enable strict mode, must be same as PARSER_IS_STRICT */
ECMA_PARSE_MODULE = (1u << 1), /**< module is parsed */
ECMA_PARSE_EVAL = (1u << 2), /**< eval is called */
ECMA_PARSE_DIRECT_EVAL = (1u << 3), /**< eval is called directly (ECMA-262 v5, 15.1.2.1.1) */
ECMA_PARSE_CLASS_CONSTRUCTOR = (1u << 4), /**< a class constructor is being parsed */
/* These four status flags must be in this order. The first three are also parser status flags.
* See PARSER_SAVE_STATUS_FLAGS / PARSER_RESTORE_STATUS_FLAGS. */
ECMA_PARSE_ALLOW_SUPER = (1u << 5), /**< allow super property access */
ECMA_PARSE_ALLOW_SUPER_CALL = (1u << 6), /**< allow super constructor call */
ECMA_PARSE_ALLOW_NEW_TARGET = (1u << 7), /**< allow new.target access */
ECMA_PARSE_FUNCTION_CONTEXT = (1u << 8), /**< function context is present (ECMA_PARSE_DIRECT_EVAL must be set) */
ECMA_PARSE_GENERATOR_FUNCTION = (1u << 9), /**< generator function is parsed */
/* These flags are internally used by the parser. */
#ifndef JERRY_NDEBUG
/**
* This flag represents an error in for in/of statements, which cannot be set
* if the parsing is completed successfully.
*/
ECMA_PARSE_INTERNAL_FOR_IN_OFF_CONTEXT_ERROR = (1u << 30),
#endif /* !JERRY_NDEBUG */
} ecma_parse_opts_t;
/**
@ -119,15 +143,6 @@ typedef uint32_t ecma_value_t;
*/
typedef int32_t ecma_integer_value_t;
#if UINTPTR_MAX <= UINT32_MAX
/**
* JMEM_ALIGNMENT_LOG aligned pointers can be stored directly in ecma_value_t
*/
#define ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
#endif /* UINTPTR_MAX <= UINT32_MAX */
/**
* Mask for ecma types in ecma_value_t
*/
@ -187,7 +202,11 @@ enum
* ecma_op_object_find */
ECMA_VALUE_REGISTER_REF = ECMA_MAKE_VALUE (8), /**< register reference,
* a special "base" value for vm */
ECMA_VALUE_IMPLICIT_CONSTRUCTOR = ECMA_MAKE_VALUE (9), /**< special value for bound class constructors */
ECMA_VALUE_RELEASE_LEX_ENV = ECMA_MAKE_VALUE (9), /**< if this error remains on the stack when an exception occours
the top lexical environment of the VM frame should be popped */
ECMA_VALUE_UNINITIALIZED = ECMA_MAKE_VALUE (10), /**< a special value for uninitialized let/const declarations */
ECMA_VALUE_SPREAD_ELEMENT = ECMA_MAKE_VALUE (11), /**< a special value for spread elements in array initialization
* or function call argument list */
};
#if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
@ -327,10 +346,11 @@ typedef enum
* that are not indices */
ECMA_LIST_ENUMERABLE = (1 << 1), /**< exclude non-enumerable properties */
ECMA_LIST_PROTOTYPE = (1 << 2), /**< list properties from prototype chain */
#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
#if ENABLED (JERRY_ES2015)
ECMA_LIST_SYMBOLS = (1 << 3), /**< list symbol properties */
ECMA_LIST_SYMBOLS_ONLY = (1 << 4), /**< list symbol properties only */
#endif /* ENABLED (JERRY_ES2015) */
ECMA_LIST_CONVERT_FAST_ARRAYS = (1 << 5), /**< after listing the properties convert
* the fast access mode array back to normal array */
} ecma_list_properties_options_t;
@ -390,6 +410,15 @@ typedef enum
*/
#define ECMA_PROPERTY_FIXED 0
/**
* Default flag of length property.
*/
#if ENABLED (JERRY_ES2015)
#define ECMA_PROPERTY_FLAG_DEFAULT_LENGTH ECMA_PROPERTY_FLAG_CONFIGURABLE
#else /* !ENABLED (JERRY_ES2015) */
#define ECMA_PROPERTY_FLAG_DEFAULT_LENGTH ECMA_PROPERTY_FIXED
#endif /* ENABLED (JERRY_ES2015) */
/**
* Shift for property name part.
*/
@ -593,6 +622,7 @@ typedef enum
ECMA_PROPERTY_GET_NO_OPTIONS = 0, /**< no option flags for ecma_op_object_get_property */
ECMA_PROPERTY_GET_VALUE = 1u << 0, /**< fill virtual_value field for virtual properties */
ECMA_PROPERTY_GET_EXT_REFERENCE = 1u << 1, /**< get extended reference to the property */
ECMA_PROPERTY_GET_HAS_OWN_PROP = 1u << 2, /**< internal [[HasOwnProperty]] method */
} ecma_property_get_option_bits_t;
/**
@ -602,15 +632,13 @@ typedef enum
{
ECMA_OBJECT_TYPE_GENERAL = 0, /**< all objects that are not belongs to the sub-types below. */
ECMA_OBJECT_TYPE_CLASS = 1, /**< Objects with class property */
ECMA_OBJECT_TYPE_FUNCTION = 2, /**< Function objects (15.3), created through 13.2 routine */
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 3, /**< External (host) function object */
ECMA_OBJECT_TYPE_ARRAY = 4, /**< Array object (15.4) */
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 5, /**< Function objects (15.3), created through 15.3.4.5 routine */
ECMA_OBJECT_TYPE_PSEUDO_ARRAY = 6, /**< Array-like object, such as Arguments object (10.6) */
#if ENABLED (JERRY_ES2015_ARROW_FUNCTION)
ECMA_OBJECT_TYPE_ARROW_FUNCTION = 7, /**< arrow function objects */
#endif /* ENABLED (JERRY_ES2015_ARROW_FUNCTION) */
ECMA_OBJECT_TYPE_ARRAY = 2, /**< Array object (15.4) */
ECMA_OBJECT_TYPE_PSEUDO_ARRAY = 3, /**< Array-like object, such as Arguments object (10.6) */
ECMA_OBJECT_TYPE_PROXY = 4, /**< Proxy object ECMAScript v6 26.2 */
/* Note: these 4 types must be in this order. See IsCallable operation. */
ECMA_OBJECT_TYPE_FUNCTION = 5, /**< Function objects (15.3), created through 13.2 routine */
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 6, /**< Function objects (15.3), created through 15.3.4.5 routine */
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 7, /**< External (host) function object */
/* Types between 13-15 cannot have a built-in flag. See ecma_lexical_environment_type_t. */
ECMA_OBJECT_TYPE__MAX /**< maximum value */
@ -641,15 +669,16 @@ typedef enum
ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE = 13, /**< declarative lexical environment */
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND = 14, /**< object-bound lexical environment
* with provideThis flag */
ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND = 15, /**< object-bound lexical environment
* with provided super reference */
ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND = 15, /**< object-bound lexical environment
* with provided home object reference */
ECMA_LEXICAL_ENVIRONMENT_TYPE_START = ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE, /**< first lexical
* environment type */
ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND /**< maximum value */
ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND /**< maximum value */
} ecma_lexical_environment_type_t;
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#if ENABLED (JERRY_ES2015)
/**
* Types of array iterators.
*/
@ -658,35 +687,37 @@ typedef enum
ECMA_ITERATOR_KEYS, /**< List only key indices */
ECMA_ITERATOR_VALUES, /**< List only key values */
ECMA_ITERATOR_KEYS_VALUES, /**< List key indices and values */
} ecma_iterator_type_t;
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
} ecma_array_iterator_type_t;
#endif /* ENABLED (JERRY_ES2015) */
/**
* Offset for JERRY_CONTEXT (status_flags) top 8 bits.
*/
#define ECMA_SUPER_EVAL_OPTS_OFFSET (32 - 8)
#define ECMA_LOCAL_PARSE_OPTS_OFFSET ((sizeof (uint32_t) - sizeof (uint8_t)) * JERRY_BITSINBYTE)
/**
* Set JERRY_CONTEXT (status_flags) top 8 bits to the specified 'opts'.
*/
#define ECMA_SET_SUPER_EVAL_PARSER_OPTS(opts) \
#define ECMA_SET_LOCAL_PARSE_OPTS(opts) \
do \
{ \
JERRY_CONTEXT (status_flags) |= ((uint32_t) opts << ECMA_SUPER_EVAL_OPTS_OFFSET) | ECMA_STATUS_DIRECT_EVAL; \
JERRY_CONTEXT (status_flags) |= ((uint32_t) opts << ECMA_LOCAL_PARSE_OPTS_OFFSET) | ECMA_STATUS_DIRECT_EVAL; \
} while (0)
/**
* Get JERRY_CONTEXT (status_flags) top 8 bits.
*/
#define ECMA_GET_SUPER_EVAL_PARSER_OPTS() (JERRY_CONTEXT (status_flags) >> ECMA_SUPER_EVAL_OPTS_OFFSET)
#define ECMA_GET_LOCAL_PARSE_OPTS() \
(JERRY_CONTEXT (status_flags) >> (ECMA_LOCAL_PARSE_OPTS_OFFSET - JERRY_LOG2 (ECMA_PARSE_ALLOW_SUPER)))
/**
* Clear JERRY_CONTEXT (status_flags) top 8 bits.
*/
#define ECMA_CLEAR_SUPER_EVAL_PARSER_OPTS() \
#define ECMA_CLEAR_LOCAL_PARSE_OPTS() \
do \
{ \
JERRY_CONTEXT (status_flags) &= ((1 << ECMA_SUPER_EVAL_OPTS_OFFSET) - 1); \
JERRY_CONTEXT (status_flags) &= ((1 << ECMA_LOCAL_PARSE_OPTS_OFFSET) - 1); \
} while (0)
/**
@ -709,19 +740,32 @@ typedef enum
/**
* Non closure flag for debugger.
*/
#if ENABLED (JERRY_DEBUGGER)
#define ECMA_OBJECT_FLAG_NON_CLOSURE 0x20
#endif /* ENABLED (JERRY_DEBUGGER) */
#define ECMA_OBJECT_FLAG_BLOCK ECMA_OBJECT_FLAG_EXTENSIBLE
/**
* Bitshift index for an ecma-object reference count field
*/
#define ECMA_OBJECT_REF_SHIFT 6
/**
* Bitmask for an ecma-object reference count field
*/
#define ECMA_OBJECT_REF_MASK (((1u << 10) - 1) << ECMA_OBJECT_REF_SHIFT)
/**
* Value for increasing or decreasing the object reference counter.
*/
#define ECMA_OBJECT_REF_ONE (1u << 6)
#define ECMA_OBJECT_REF_ONE (1u << ECMA_OBJECT_REF_SHIFT)
/**
* Maximum value of the object reference counter (1023).
* Represents non-visited white object
*/
#define ECMA_OBJECT_MAX_REF (0x3ffu << 6)
#define ECMA_OBJECT_NON_VISITED (0x3ffu << ECMA_OBJECT_REF_SHIFT)
/**
* Maximum value of the object reference counter (1022).
*/
#define ECMA_OBJECT_MAX_REF (ECMA_OBJECT_NON_VISITED - ECMA_OBJECT_REF_ONE)
/**
* Description of ECMA-object or lexical environment
@ -732,8 +776,8 @@ typedef struct
/** type : 4 bit : ecma_object_type_t or ecma_lexical_environment_type_t
depending on ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV
flags : 2 bit : ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV,
ECMA_OBJECT_FLAG_EXTENSIBLE or ECMA_OBJECT_FLAG_NON_CLOSURE
refs : 10 bit (max 1023) */
ECMA_OBJECT_FLAG_EXTENSIBLE or ECMA_OBJECT_FLAG_BLOCK
refs : 10 bit (max 1022) */
uint16_t type_flags_refs;
/** next in the object chain maintained by the garbage collector */
@ -743,8 +787,9 @@ typedef struct
union
{
jmem_cpointer_t property_list_cp; /**< compressed pointer to object's
* or declerative lexical environments's property list */
* or declerative lexical environments's property list */
jmem_cpointer_t bound_object_cp; /**< compressed pointer to lexical environments's the bound object */
jmem_cpointer_t home_object_cp; /**< compressed pointer to lexical environments's the home object */
} u1;
/** object prototype or outer reference */
@ -764,7 +809,15 @@ typedef struct
uint8_t length_and_bitset_size; /**< length for built-in functions and
* bit set size for all built-ins */
uint16_t routine_id; /**< routine id for built-in functions */
uint32_t instantiated_bitset[1]; /**< bit set for instantiated properties */
union
{
uint32_t instantiated_bitset[1]; /**< bit set for instantiated properties */
struct
{
uint16_t name; /**< name of the built-in functions */
uint16_t bitset; /**< bit set for instantiated properties of builtin functions */
} builtin_routine;
} u;
} ecma_built_in_props_t;
/**
@ -804,6 +857,7 @@ typedef struct
{
ecma_value_t value; /**< value of the object (e.g. boolean, number, string, etc.) */
uint32_t length; /**< length related property (e.g. length of ArrayBuffer) */
ecma_value_t target; /**< [[ProxyTarget]] internal property */
} u;
} class_prop;
@ -812,7 +866,7 @@ typedef struct
*/
struct
{
ecma_value_t scope_cp; /**< function scope */
jmem_cpointer_tag_t scope_cp; /**< function scope */
ecma_value_t bytecode_cp; /**< function byte code */
} function;
@ -822,10 +876,13 @@ typedef struct
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 */
union
{
ecma_property_t length_prop; /**< length property */
uint32_t hole_count; /**< number of array holes in a fast access mode array
* multiplied ECMA_FAST_ACCESS_HOLE_ONE */
} u;
} array;
/**
@ -848,6 +905,7 @@ typedef struct
ecma_value_t lex_env_cp; /**< for arguments: lexical environment */
ecma_value_t arraybuffer; /**< for typedarray: internal arraybuffer */
ecma_value_t iterated_value; /**< for %Iterator%: [[IteratedObject]] property */
ecma_value_t spread_value; /**< for spread object: spreaded element */
} u2;
} pseudo_array;
@ -856,7 +914,7 @@ typedef struct
*/
struct
{
ecma_value_t target_function; /**< target function */
jmem_cpointer_tag_t target_function; /**< target function */
ecma_value_t args_len_or_this; /**< length of arguments or this value */
} bound_function;
@ -885,7 +943,6 @@ typedef struct
#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.
*/
@ -900,6 +957,17 @@ typedef struct
* If regexp, the other flags must be RE_FLAG... */
} ecma_compiled_code_t;
/**
* Description of bound function objects.
*/
typedef struct
{
ecma_extended_object_t header; /**< extended object header */
#if ENABLED (JERRY_ES2015)
ecma_integer_value_t target_length; /**< length of target function */
#endif /* ENABLED (JERRY_ES2015) */
} ecma_bound_function_t;
#if ENABLED (JERRY_SNAPSHOT_EXEC)
/**
@ -913,17 +981,16 @@ typedef struct
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
#if ENABLED (JERRY_ES2015_ARROW_FUNCTION)
#if ENABLED (JERRY_ES2015)
/**
* Description of arrow function objects.
*/
typedef struct
{
ecma_object_t object; /**< object header */
ecma_extended_object_t header; /**< extended object header */
ecma_value_t this_binding; /**< value of 'this' binding */
jmem_cpointer_t scope_cp; /**< function scope */
jmem_cpointer_t bytecode_cp; /**< function byte code */
ecma_value_t new_target; /**< value of new.target */
} ecma_arrow_function_t;
#if ENABLED (JERRY_SNAPSHOT_EXEC)
@ -939,18 +1006,62 @@ typedef struct
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
#endif /* ENABLED (JERRY_ES2015_ARROW_FUNCTION) */
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET)
#if ENABLED (JERRY_ES2015_BUILTIN_CONTAINER)
/**
* Description of Map/Set objects.
* Flags for container objects
*/
typedef enum
{
ECMA_CONTAINER_FLAGS_EMPTY = (0), /** empty flags */
ECMA_CONTAINER_FLAGS_WEAK = (1 << 0) /** container object is weak */
} ecma_container_flags_t;
/**
* Description of map collection.
*/
typedef struct
{
ecma_extended_object_t header; /**< header part */
uint32_t size; /**< size of the map object */
} ecma_map_object_t;
#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */
ecma_value_t key; /**< key value */
ecma_value_t value; /**< value of the key */
} ecma_container_pair_t;
/**
* Size of a single element (in ecma_value_t unit).
*/
#define ECMA_CONTAINER_VALUE_SIZE 1
/**
* Size of a key - value pair (in ecma_value_t unit).
*/
#define ECMA_CONTAINER_PAIR_SIZE 2
/**
* Size of the internal buffer.
*/
#define ECMA_CONTAINER_GET_SIZE(container_p) \
(container_p->buffer_p[0])
/**
* Remove the size field of the internal buffer.
*/
#define ECMA_CONTAINER_SET_SIZE(container_p, size) \
(container_p->buffer_p[0] = (ecma_value_t) (size))
/**
* Number of entries of the internal buffer.
*/
#define ECMA_CONTAINER_ENTRY_COUNT(collection_p) \
(collection_p->item_count - 1)
/**
* Pointer to the first entry of the internal buffer.
*/
#define ECMA_CONTAINER_START(collection_p) \
(collection_p->buffer_p + 1)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_CONTAINER) */
typedef enum
{
@ -1148,6 +1259,26 @@ typedef union
* See also: ECMA_262 v5, 15.7.3.2
*/
# define ECMA_NUMBER_MAX_VALUE (FLT_MAX)
/**
* Number.EPSILON
*
* See also: ECMA_262 v6, 20.1.2.1
*/
# define ECMA_NUMBER_EPSILON ((ecma_number_t) 1.1920928955078125e-7)
/**
* Number.MAX_SAFE_INTEGER
*
* See also: ECMA_262 v6, 20.1.2.6
*/
# define ECMA_NUMBER_MAX_SAFE_INTEGER ((ecma_number_t) 0xFFFFFF)
/**
* Number.MIN_SAFE_INTEGER
*
* See also: ECMA_262 v6, 20.1.2.8
*/
# define ECMA_NUMBER_MIN_SAFE_INTEGER ((ecma_number_t) -0xFFFFFF)
#elif ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
/**
* Number.MAX_VALUE (i.e., the maximum value of ecma-number)
@ -1155,29 +1286,36 @@ typedef union
* See also: ECMA_262 v5, 15.7.3.2
*/
# define ECMA_NUMBER_MAX_VALUE ((ecma_number_t) 1.7976931348623157e+308)
/**
* Number.MIN_VALUE (i.e., the smallest positive value of ecma-number)
*
* See also: ECMA_262 v5, 15.7.3.3
*/
# 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
* See also: ECMA_262 v6, 20.1.2.6
*/
# define ECMA_NUMBER_MAX_SAFE_INTEGER ((ecma_number_t) 0x1FFFFFFFFFFFFF)
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
/**
* Number.MIN_SAFE_INTEGER
*
* See also: ECMA_262 v6, 20.1.2.8
*/
# define ECMA_NUMBER_MIN_SAFE_INTEGER ((ecma_number_t) -0x1FFFFFFFFFFFFF)
#endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
/**
* Euler number
*/
@ -1363,9 +1501,7 @@ typedef enum
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_CONTAINER__MAX = ECMA_STRING_CONTAINER_MAP_KEY /**< maximum value */
ECMA_STRING_CONTAINER__MAX = ECMA_STRING_CONTAINER_SYMBOL /**< maximum value */
} ecma_string_container_t;
/**
@ -1622,12 +1758,12 @@ typedef struct
/**
* Function callback descriptor of a %TypedArray% object getter
*/
typedef ecma_number_t (*ecma_typedarray_getter_fn_t)(lit_utf8_byte_t *src);
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);
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
@ -1703,6 +1839,27 @@ typedef struct
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
#if ENABLED (JERRY_ES2015)
/**
* Executable (e.g. generator, async) object flags.
*/
typedef enum
{
ECMA_EXECUTABLE_OBJECT_COMPLETED = (1u << 0), /**< executable object is completed and cannot be resumed */
ECMA_EXECUTABLE_OBJECT_RUNNING = (1u << 1), /**< executable object is currently running */
/* Generator specific flags. */
ECMA_GENERATOR_ITERATE_AND_YIELD = (1u << 2), /**< the generator performs a yield* operation */
} ecma_executable_object_flags_t;
/**
* Checks whether the executable object is waiting for resuming.
*/
#define ECMA_EXECUTABLE_OBJECT_IS_SUSPENDED(extra_info) \
(!((extra_info) & (ECMA_EXECUTABLE_OBJECT_COMPLETED | ECMA_EXECUTABLE_OBJECT_RUNNING)))
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/**
* Description of DataView objects.
@ -1771,6 +1928,32 @@ do \
#define CHECK_JERRY_STACK_USAGE(context_p)
#endif /* (JERRY_STACK_LIMIT != 0) */
/**
* Invalid object pointer which represents abrupt completion
*/
#define ECMA_OBJECT_POINTER_ERROR ((ecma_object_t *) 0x01)
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
/**
* Description of Proxy objects.
*/
typedef struct
{
ecma_object_t header; /**< header part */
ecma_value_t target; /**< [[ProxyTarget]] internal slot */
ecma_value_t handler; /**< [[ProxyHandler]] internal slot */
} ecma_proxy_object_t;
/**
* Description of Proxy objects.
*/
typedef struct
{
ecma_extended_object_t header; /**< header part */
ecma_value_t proxy; /**< [[RevocableProxy]] internal slot */
} ecma_revocable_proxy_object_t;
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
/**
* @}
* @}

View File

@ -144,6 +144,49 @@ ecma_collection_push_back (ecma_collection_t *collection_p, /**< value collectio
collection_p->buffer_p = buffer_p;
} /* ecma_collection_push_back */
/**
* Reserve space for the given amount of ecma_values in the collection
*/
void
ecma_collection_reserve (ecma_collection_t *collection_p, /**< value collection */
uint32_t count) /**< number of ecma values to reserve */
{
JERRY_ASSERT (collection_p != NULL);
JERRY_ASSERT (UINT32_MAX - count > collection_p->capacity);
const uint32_t new_capacity = collection_p->capacity + count;
const uint32_t old_size = ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity);
const uint32_t new_size = ECMA_COLLECTION_ALLOCATED_SIZE (new_capacity);
ecma_value_t *buffer_p = collection_p->buffer_p;
buffer_p = jmem_heap_realloc_block (buffer_p, old_size, new_size);
collection_p->capacity = new_capacity;
collection_p->buffer_p = buffer_p;
} /* ecma_collection_reserve */
/**
* Append a list of values to the end of the collection
*/
void
ecma_collection_append (ecma_collection_t *collection_p, /**< value collection */
const ecma_value_t *buffer_p, /**< values to append */
uint32_t count) /**< number of ecma values to append */
{
JERRY_ASSERT (collection_p != NULL);
JERRY_ASSERT (collection_p->capacity >= collection_p->item_count);
uint32_t free_count = collection_p->capacity - collection_p->item_count;
if (free_count < count)
{
ecma_collection_reserve (collection_p, count - free_count);
}
memcpy (collection_p->buffer_p + collection_p->item_count, buffer_p, count * sizeof (ecma_value_t));
collection_p->item_count += count;
} /* ecma_collection_append */
/**
* @}
* @}

View File

@ -280,13 +280,87 @@ static const uint8_t ecma_uint4_clz[] = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0,
*/
#define EPSILON 0.0000001
/**
* ECMA-defined conversion from string to number for different radixes (2, 8, 16).
*
* See also:
* ECMA-262 v5 9.3.1
* ECMA-262 v6 7.1.3.1
*
* @return NaN - if the conversion fails
* converted number - otherwise
*/
static ecma_number_t
ecma_utf8_string_to_number_by_radix (const lit_utf8_byte_t *str_p, /**< utf-8 string */
const lit_utf8_byte_t *end_p, /**< end of utf-8 string */
uint32_t radix) /**< radix */
{
JERRY_ASSERT (radix == 2 || radix == 8 || radix == 16);
ecma_number_t num = ECMA_NUMBER_ZERO;
#if ENABLED (JERRY_ES2015)
if (radix <= 8)
{
lit_code_point_t upper_limit = LIT_CHAR_0 + radix;
for (const lit_utf8_byte_t * iter_p = str_p; iter_p <= end_p; iter_p++)
{
int32_t digit_value;
if (*iter_p >= LIT_CHAR_0 && *iter_p < upper_limit)
{
digit_value = (*iter_p - LIT_CHAR_0);
}
else
{
return ecma_number_make_nan ();
}
num = num * radix + (ecma_number_t) digit_value;
}
return num;
}
#endif /* ENABLED (JERRY_ES2015) */
for (const lit_utf8_byte_t * iter_p = str_p; iter_p <= end_p; iter_p++)
{
int32_t digit_value;
if (*iter_p >= LIT_CHAR_0
&& *iter_p <= LIT_CHAR_9)
{
digit_value = (*iter_p - LIT_CHAR_0);
}
else if (*iter_p >= LIT_CHAR_LOWERCASE_A
&& *iter_p <= LIT_CHAR_LOWERCASE_F)
{
digit_value = 10 + (*iter_p - LIT_CHAR_LOWERCASE_A);
}
else if (*iter_p >= LIT_CHAR_UPPERCASE_A
&& *iter_p <= LIT_CHAR_UPPERCASE_F)
{
digit_value = 10 + (*iter_p - LIT_CHAR_UPPERCASE_A);
}
else
{
return ecma_number_make_nan ();
}
num = num * radix + (ecma_number_t) digit_value;
}
return num;
} /* ecma_utf8_string_to_number_by_radix */
/**
* ECMA-defined conversion of string to Number.
*
* See also:
* ECMA-262 v5, 9.3.1
*
* @return ecma-number
* @return NaN - if the conversion fails
* converted number - otherwise
*/
ecma_number_t
ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
@ -307,46 +381,28 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
return ECMA_NUMBER_ZERO;
}
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))
if (end_p >= str_p + 2
&& str_p[0] == LIT_CHAR_0)
{
/* Hex literal handling */
str_p += 2;
ecma_number_t num = ECMA_NUMBER_ZERO;
for (const lit_utf8_byte_t * iter_p = str_p;
iter_p <= end_p;
iter_p++)
switch (LEXER_TO_ASCII_LOWERCASE (str_p[1]))
{
int32_t digit_value;
if (*iter_p >= LIT_CHAR_0
&& *iter_p <= LIT_CHAR_9)
case LIT_CHAR_LOWERCASE_X :
{
digit_value = (*iter_p - LIT_CHAR_0);
return ecma_utf8_string_to_number_by_radix (str_p + 2, end_p, 16);
}
else if (*iter_p >= LIT_CHAR_LOWERCASE_A
&& *iter_p <= LIT_CHAR_LOWERCASE_F)
case LIT_CHAR_LOWERCASE_O :
{
digit_value = 10 + (*iter_p - LIT_CHAR_LOWERCASE_A);
return ecma_utf8_string_to_number_by_radix (str_p + 2, end_p, 8);
}
else if (*iter_p >= LIT_CHAR_UPPERCASE_A
&& *iter_p <= LIT_CHAR_UPPERCASE_F)
case LIT_CHAR_LOWERCASE_B :
{
digit_value = 10 + (*iter_p - LIT_CHAR_UPPERCASE_A);
return ecma_utf8_string_to_number_by_radix (str_p + 2, end_p, 2);
}
else
default:
{
return ecma_number_make_nan ();
break;
}
num = num * 16 + (ecma_number_t) digit_value;
}
return num;
}
bool sign = false; /* positive */
@ -703,9 +759,7 @@ ecma_uint32_to_utf8_string (uint32_t value, /**< value to convert */
uint32_t
ecma_number_to_uint32 (ecma_number_t num) /**< ecma-number */
{
if (ecma_number_is_nan (num)
|| ecma_number_is_zero (num)
|| ecma_number_is_infinity (num))
if (JERRY_UNLIKELY (ecma_number_is_zero (num) || !ecma_number_is_finite (num)))
{
return 0;
}

View File

@ -17,6 +17,7 @@
#include "ecma-array-object.h"
#include "ecma-globals.h"
#include "ecma-objects.h"
#include "ecma-objects-general.h"
#include "ecma-helpers.h"
/** \addtogroup ecma ECMA
@ -39,8 +40,7 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create
{
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)
if (ecma_op_object_is_fast_array (obj_p))
{
ecma_fast_array_convert_to_normal (obj_p);
}
@ -115,8 +115,7 @@ 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)
if (ecma_op_object_is_fast_array (obj_p))
{
/* Fast access mode array can not have native pointer properties */
return NULL;
@ -164,8 +163,7 @@ 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)
if (ecma_op_object_is_fast_array (obj_p))
{
/* Fast access mode array can not have native pointer properties */
return false;
@ -196,7 +194,8 @@ ecma_delete_native_pointer_property (ecma_object_t *obj_p, /**< object to delete
if (native_pointer_p->next_p == NULL)
{
/* Only one native pointer property exists, so the property can be deleted as well. */
ecma_op_object_delete (obj_p, name_p, false);
ecma_op_general_object_delete (obj_p, name_p, false);
jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
return true;
}

View File

@ -13,8 +13,10 @@
* limitations under the License.
*/
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include <math.h>
#include "ecma-conversion.h"
#include "lit-char-helpers.h"
/** \addtogroup ecma ECMA
* @{
@ -298,8 +300,6 @@ ecma_number_is_negative (ecma_number_t num) /**< ecma-number */
bool
ecma_number_is_zero (ecma_number_t num) /**< ecma-number */
{
JERRY_ASSERT (!ecma_number_is_nan (num));
bool is_zero = (num == ECMA_NUMBER_ZERO);
#ifndef JERRY_NDEBUG
@ -323,8 +323,6 @@ ecma_number_is_zero (ecma_number_t num) /**< ecma-number */
bool
ecma_number_is_infinity (ecma_number_t num) /**< ecma-number */
{
JERRY_ASSERT (!ecma_number_is_nan (num));
uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
uint64_t fraction = ecma_number_get_fraction_field (num);
@ -333,6 +331,24 @@ ecma_number_is_infinity (ecma_number_t num) /**< ecma-number */
&& (fraction == 0));
} /* ecma_number_is_infinity */
/**
* Check if number is finite
*
* @return true - if number is finite
* false - if number is NaN or infinity
*/
extern inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_number_is_finite (ecma_number_t num) /**< ecma-number */
{
#if defined (__GNUC__) || defined (__clang__)
return __builtin_isfinite (num);
#elif defined (WIN32)
return isfinite (num);
#else
return !ecma_number_is_nan (num) && !ecma_number_is_infinity (num);
#endif /* defined (__GNUC__) || defined (__clang__) */
} /* ecma_number_is_finite */
/**
* Get fraction and exponent of the number
*
@ -642,6 +658,31 @@ ecma_number_calc_remainder (ecma_number_t left_num, /**< left operand */
return r;
} /* ecma_number_calc_remainder */
/**
* Compute power operation according to the ES standard.
*
* @return x ** y
*/
ecma_number_t
ecma_number_pow (ecma_number_t x, /**< left operand */
ecma_number_t y) /**< right operand */
{
if (ecma_number_is_nan (y) ||
(ecma_number_is_infinity (y) && (x == 1.0 || x == -1.0)))
{
/* Handle differences between ES5.1 and ISO C standards for pow. */
return ecma_number_make_nan ();
}
if (ecma_number_is_zero (y))
{
/* Handle differences between ES5.1 and ISO C standards for pow. */
return (ecma_number_t) 1.0;
}
return DOUBLE_TO_ECMA_NUMBER_T (pow (x, y));
} /* ecma_number_pow */
/**
* ECMA-integer number multiplication.
*
@ -667,6 +708,371 @@ ecma_integer_multiply (ecma_integer_value_t left_integer, /**< left operand */
return ecma_make_integer_value (left_integer * right_integer);
} /* ecma_integer_multiply */
/**
* The Number object's 'parseInt' routine
*
* See also:
* ECMA-262 v5, 15.1.2.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_number_parse_int (const lit_utf8_byte_t *string_buff, /**< routine's first argument's
* string buffer */
lit_utf8_size_t string_buff_size, /**< routine's first argument's
* string buffer's size */
ecma_value_t radix) /**< routine's second argument */
{
if (string_buff_size == 0)
{
return ecma_make_nan_value ();
}
const lit_utf8_byte_t *string_curr_p = string_buff;
/* 2. Remove leading whitespace. */
ecma_string_trim_helper (&string_curr_p, &string_buff_size);
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)
{
return ecma_make_nan_value ();
}
/* 3. */
int sign = 1;
/* 4. */
ecma_char_t current = lit_cesu8_read_next (&string_curr_p);
if (current == LIT_CHAR_MINUS)
{
sign = -1;
}
/* 5. */
if (current == LIT_CHAR_MINUS || current == LIT_CHAR_PLUS)
{
start_p = string_curr_p;
if (string_curr_p < string_end_p)
{
current = lit_cesu8_read_next (&string_curr_p);
}
}
/* 6. */
ecma_number_t radix_num;
radix = ecma_get_number (radix, &radix_num);
if (!ecma_is_value_empty (radix))
{
return radix;
}
int32_t rad = ecma_number_to_int32 (radix_num);
/* 7.*/
bool strip_prefix = true;
/* 8. */
if (rad != 0)
{
/* 8.a */
if (rad < 2 || rad > 36)
{
return ecma_make_nan_value ();
}
/* 8.b */
else if (rad != 16)
{
strip_prefix = false;
}
}
/* 9. */
else
{
rad = 10;
}
/* 10. */
if (strip_prefix
&& ((end_p - start_p) >= 2)
&& (current == LIT_CHAR_0))
{
ecma_char_t next = *string_curr_p;
if (next == LIT_CHAR_LOWERCASE_X || next == LIT_CHAR_UPPERCASE_X)
{
/* Skip the 'x' or 'X' characters. */
start_p = ++string_curr_p;
rad = 16;
}
}
/* 11. Check if characters are in [0, Radix - 1]. We also convert them to number values in the process. */
string_curr_p = start_p;
while (string_curr_p < string_end_p)
{
ecma_char_t current_char = *string_curr_p++;
int32_t current_number;
if ((current_char >= LIT_CHAR_LOWERCASE_A && current_char <= LIT_CHAR_LOWERCASE_Z))
{
current_number = current_char - LIT_CHAR_LOWERCASE_A + 10;
}
else if ((current_char >= LIT_CHAR_UPPERCASE_A && current_char <= LIT_CHAR_UPPERCASE_Z))
{
current_number = current_char - LIT_CHAR_UPPERCASE_A + 10;
}
else if (lit_char_is_decimal_digit (current_char))
{
current_number = current_char - LIT_CHAR_0;
}
else
{
/* Not a valid number char, set value to radix so it fails to pass as a valid character. */
current_number = rad;
}
if (!(current_number < rad))
{
end_p = --string_curr_p;
break;
}
}
/* 12. */
if (end_p == start_p)
{
return ecma_make_nan_value ();
}
ecma_number_t value = ECMA_NUMBER_ZERO;
ecma_number_t multiplier = 1.0f;
/* 13. and 14. */
string_curr_p = end_p;
while (string_curr_p > start_p)
{
ecma_char_t current_char = *(--string_curr_p);
ecma_number_t current_number = ECMA_NUMBER_MINUS_ONE;
if ((current_char >= LIT_CHAR_LOWERCASE_A && current_char <= LIT_CHAR_LOWERCASE_Z))
{
current_number = (ecma_number_t) current_char - LIT_CHAR_LOWERCASE_A + 10;
}
else if ((current_char >= LIT_CHAR_UPPERCASE_A && current_char <= LIT_CHAR_UPPERCASE_Z))
{
current_number = (ecma_number_t) current_char - LIT_CHAR_UPPERCASE_A + 10;
}
else
{
JERRY_ASSERT (lit_char_is_decimal_digit (current_char));
current_number = (ecma_number_t) current_char - LIT_CHAR_0;
}
value += current_number * multiplier;
multiplier *= (ecma_number_t) rad;
}
/* 15. */
if (sign < 0)
{
value *= (ecma_number_t) sign;
}
return ecma_make_number_value (value);
} /* ecma_number_parse_int */
/**
* The Number object's 'parseFloat' routine
*
* See also:
* ECMA-262 v5, 15.1.2.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_number_parse_float (const lit_utf8_byte_t *string_buff, /**< routine's first argument's
* string buffer */
lit_utf8_size_t string_buff_size) /**< routine's first argument's
* string buffer's size */
{
if (string_buff_size == 0)
{
return ecma_make_nan_value ();
}
const lit_utf8_byte_t *str_curr_p = string_buff;
/* 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;
bool sign = false;
ecma_char_t current;
if (str_curr_p < str_end_p)
{
/* Check if sign is present. */
current = *str_curr_p;
if (current == LIT_CHAR_MINUS)
{
sign = true;
}
if (current == LIT_CHAR_MINUS || current == LIT_CHAR_PLUS)
{
/* Set starting position to be after the sign character. */
start_p = ++str_curr_p;
}
}
/* Check if string is equal to "Infinity". */
const lit_utf8_byte_t *infinity_str_p = lit_get_magic_string_utf8 (LIT_MAGIC_STRING_INFINITY_UL);
const lit_utf8_size_t infinity_length = lit_get_magic_string_size (LIT_MAGIC_STRING_INFINITY_UL);
/* The input string should be at least the length of "Infinity" to be correctly processed as
* the infinity value.
*/
if ((str_end_p - str_curr_p) >= (int) infinity_length
&& memcmp (infinity_str_p, str_curr_p, infinity_length) == 0)
{
/* String matched Infinity. */
return ecma_make_number_value (ecma_number_make_infinity (sign));
}
/* Reset to starting position. */
str_curr_p = start_p;
/* String ended after sign character, or was empty after removing leading whitespace. */
if (str_curr_p >= str_end_p)
{
return ecma_make_nan_value ();
}
/* Reset to starting position. */
str_curr_p = start_p;
current = *str_curr_p;
bool has_whole_part = false;
bool has_fraction_part = false;
/* Check digits of whole part. */
if (lit_char_is_decimal_digit (current))
{
has_whole_part = true;
str_curr_p++;
while (str_curr_p < str_end_p)
{
current = *str_curr_p++;
if (!lit_char_is_decimal_digit (current))
{
str_curr_p--;
break;
}
}
}
/* Set end position to the end of whole part. */
end_p = str_curr_p;
if (str_curr_p < str_end_p)
{
current = *str_curr_p;
/* Check decimal point. */
if (current == LIT_CHAR_DOT)
{
str_curr_p++;
if (str_curr_p < str_end_p)
{
current = *str_curr_p;
if (lit_char_is_decimal_digit (current))
{
has_fraction_part = true;
/* Check digits of fractional part. */
while (str_curr_p < str_end_p)
{
current = *str_curr_p++;
if (!lit_char_is_decimal_digit (current))
{
str_curr_p--;
break;
}
}
/* Set end position to end of fraction part. */
end_p = str_curr_p;
}
}
}
}
if (str_curr_p < str_end_p)
{
current = *str_curr_p++;
}
/* Check exponent. */
if ((current == LIT_CHAR_LOWERCASE_E || current == LIT_CHAR_UPPERCASE_E)
&& (has_whole_part || has_fraction_part)
&& str_curr_p < str_end_p)
{
current = *str_curr_p++;
/* Check sign of exponent. */
if ((current == LIT_CHAR_PLUS || current == LIT_CHAR_MINUS)
&& str_curr_p < str_end_p)
{
current = *str_curr_p++;
}
if (lit_char_is_decimal_digit (current))
{
/* Check digits of exponent part. */
while (str_curr_p < str_end_p)
{
current = *str_curr_p++;
if (!lit_char_is_decimal_digit (current))
{
str_curr_p--;
break;
}
}
/* Set end position to end of exponent part. */
end_p = str_curr_p;
}
}
/* String did not contain a valid number. */
if (start_p == end_p)
{
return ecma_make_nan_value ();
}
/* 5. */
ecma_number_t ret_num = ecma_utf8_string_to_number (start_p, (lit_utf8_size_t) (end_p - start_p));
if (sign)
{
ret_num *= ECMA_NUMBER_MINUS_ONE;
}
return ecma_make_number_value (ret_num);
} /* ecma_number_parse_float */
/**
* @}
* @}

View File

@ -204,7 +204,7 @@ ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t id) /**<
return string_desc_p;
} /* ecma_new_ecma_string_from_magic_string_ex_id */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/**
* Allocate new ecma-string and fill it with reference to the symbol descriptor
*
@ -238,42 +238,7 @@ ecma_prop_name_is_symbol (ecma_string_t *string_p) /**< ecma-string */
return (!ECMA_IS_DIRECT_STRING (string_p)
&& ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_SYMBOL);
} /* ecma_prop_name_is_symbol */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET)
/**
* Allocate new ecma-string and fill it with reference to the map key descriptor
*
* @return pointer to ecma-string descriptor
*/
ecma_string_t *
ecma_new_map_key_string (ecma_value_t value) /**< non prop-name ecma-value */
{
JERRY_ASSERT (!ecma_is_value_prop_name (value));
ecma_extended_string_t *string_p = ecma_alloc_extended_string ();
string_p->header.refs_and_container = ECMA_STRING_REF_ONE | ECMA_STRING_CONTAINER_MAP_KEY;
string_p->u.value = ecma_copy_value_if_not_object (value);
string_p->header.u.hash = (lit_string_hash_t) (ecma_is_value_simple (value) ? value : 0);
return (ecma_string_t *) string_p;
} /* ecma_new_map_key_string */
/**
* Check whether an ecma-string contains a map key string
*
* @return true - if the ecma-string contains a map key string
* false - otherwise
*/
bool
ecma_prop_name_is_map_key (ecma_string_t *string_p) /**< ecma-string */
{
JERRY_ASSERT (string_p != NULL);
return (!ECMA_IS_DIRECT_STRING (string_p)
&& ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAP_KEY);
} /* ecma_prop_name_is_map_key */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* Allocate new UTF8 ecma-string and fill it with characters from the given utf8 buffer
@ -461,16 +426,9 @@ ecma_new_ecma_string_from_utf8_converted_to_cesu8 (const lit_utf8_byte_t *string
if ((string_p[pos] & LIT_UTF8_4_BYTE_MASK) == LIT_UTF8_4_BYTE_MARKER)
{
/* Processing 4 byte unicode sequence. Always converted to two 3 byte long sequence. */
uint32_t character = ((((uint32_t) string_p[pos++]) & 0x7) << 18);
character |= ((((uint32_t) string_p[pos++]) & LIT_UTF8_LAST_6_BITS_MASK) << 12);
character |= ((((uint32_t) string_p[pos++]) & LIT_UTF8_LAST_6_BITS_MASK) << 6);
character |= (((uint32_t) string_p[pos++]) & LIT_UTF8_LAST_6_BITS_MASK);
JERRY_ASSERT (character >= 0x10000);
character -= 0x10000;
data_p += lit_char_to_utf8_bytes (data_p, (ecma_char_t) (0xd800 | (character >> 10)));
data_p += lit_char_to_utf8_bytes (data_p, (ecma_char_t) (0xdc00 | (character & LIT_UTF16_LAST_10_BITS_MASK)));
lit_four_byte_utf8_char_to_cesu8 (data_p, string_p + pos);
data_p += 3 * 2;
pos += 4;
}
else
{
@ -499,7 +457,8 @@ ecma_new_ecma_string_from_code_unit (ecma_char_t code_unit) /**< code unit */
return ecma_new_ecma_string_from_utf8 (lit_utf8_bytes, bytes_size);
} /* ecma_new_ecma_string_from_code_unit */
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#if ENABLED (JERRY_ES2015)
/**
* Allocate new ecma-string and fill it with cesu-8 character which represents specified code units
*
@ -515,7 +474,8 @@ ecma_new_ecma_string_from_code_units (ecma_char_t first_code_unit, /**< code uni
return ecma_new_ecma_string_from_utf8 (lit_utf8_bytes, bytes_size);
} /* ecma_new_ecma_string_from_code_units */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* Allocate new ecma-string and fill it with ecma-number
@ -681,7 +641,6 @@ ecma_append_chars_to_string (ecma_string_t *string1_p, /**< base ecma-string */
cesu8_string2_p,
cesu8_string2_size);
if (magic_string_id != LIT_MAGIC_STRING__COUNT)
{
ecma_deref_ecma_string (string1_p);
@ -790,30 +749,6 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
return result_p;
} /* ecma_concat_ecma_strings */
/**
* Append a magic string after an ecma-string
*
* Note:
* The string1_p argument is freed. If it needs to be preserved,
* call ecma_ref_ecma_string with string1_p before the call.
*
* @return concatenation of an ecma-string and a magic string
*/
ecma_string_t *
ecma_append_magic_string_to_string (ecma_string_t *string1_p, /**< string descriptor */
lit_magic_string_id_t string2_id) /**< magic string ID */
{
if (JERRY_UNLIKELY (ecma_string_is_empty (string1_p)))
{
return ecma_get_magic_string (string2_id);
}
const lit_utf8_byte_t *cesu8_string2_p = lit_get_magic_string_utf8 (string2_id);
lit_utf8_size_t cesu8_string2_size = lit_get_magic_string_size (string2_id);
return ecma_append_chars_to_string (string1_p, cesu8_string2_p, cesu8_string2_size, cesu8_string2_size);
} /* ecma_append_magic_string_to_string */
/**
* Increase reference counter of ecma-string.
*/
@ -910,7 +845,7 @@ ecma_destroy_ecma_string (ecma_string_t *string_p) /**< ecma-string */
((ecma_ascii_string_t *) string_p)->size + sizeof (ecma_ascii_string_t));
return;
}
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
case ECMA_STRING_CONTAINER_SYMBOL:
{
ecma_extended_string_t * symbol_p = (ecma_extended_string_t *) string_p;
@ -918,16 +853,7 @@ ecma_destroy_ecma_string (ecma_string_t *string_p) /**< ecma-string */
ecma_dealloc_extended_string (symbol_p);
return;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET)
case ECMA_STRING_CONTAINER_MAP_KEY:
{
ecma_extended_string_t *key_p = (ecma_extended_string_t *) string_p;
ecma_free_value_if_not_object (key_p->u.value);
ecma_dealloc_extended_string (key_p);
return;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */
#endif /* ENABLED (JERRY_ES2015) */
default:
{
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_UINT32_IN_DESC
@ -1809,20 +1735,12 @@ ecma_compare_ecma_strings (const ecma_string_t *string1_p, /**< ecma-string */
return true;
}
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
if (string1_container == ECMA_STRING_CONTAINER_SYMBOL)
{
return false;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#if ENABLED (JERRY_ES2015_BUILTIN_MAP)
if (string1_container == ECMA_STRING_CONTAINER_MAP_KEY)
{
return ecma_op_same_value_zero (((ecma_extended_string_t *) string1_p)->u.value,
((ecma_extended_string_t *) string2_p)->u.value);
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */
#endif /* ENABLED (JERRY_ES2015) */
return ecma_compare_ecma_strings_longpath (string1_p, string2_p);
} /* ecma_compare_ecma_strings */
@ -1863,20 +1781,12 @@ ecma_compare_ecma_non_direct_strings (const ecma_string_t *string1_p, /**< ecma-
return true;
}
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
if (string1_container == ECMA_STRING_CONTAINER_SYMBOL)
{
return false;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#if ENABLED (JERRY_ES2015_BUILTIN_MAP)
if (string1_container == ECMA_STRING_CONTAINER_MAP_KEY)
{
return ecma_op_same_value_zero (((ecma_extended_string_t *) string1_p)->u.value,
((ecma_extended_string_t *) string2_p)->u.value);
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */
#endif /* ENABLED (JERRY_ES2015) */
return ecma_compare_ecma_strings_longpath (string1_p, string2_p);
} /* ecma_compare_ecma_non_direct_strings */
@ -2452,8 +2362,7 @@ ecma_string_trim_helper (const lit_utf8_byte_t **utf8_str_p, /**< [in, out] curr
{
read_size = lit_read_code_unit_from_utf8 (current_p, &ch);
if (!lit_char_is_white_space (ch)
&& !lit_char_is_line_terminator (ch))
if (!lit_char_is_white_space (ch))
{
nonws_start_p = current_p;
break;
@ -2468,8 +2377,7 @@ ecma_string_trim_helper (const lit_utf8_byte_t **utf8_str_p, /**< [in, out] curr
{
read_size = lit_read_prev_code_unit_from_utf8 (current_p, &ch);
if (!lit_char_is_white_space (ch)
&& !lit_char_is_line_terminator (ch))
if (!lit_char_is_white_space (ch))
{
break;
}
@ -2558,6 +2466,29 @@ ecma_stringbuilder_create_from (ecma_string_t *string_p) /**< ecma string */
return ret;
} /* ecma_stringbuilder_create_from */
/**
* Create a string builder from a raw string
*
* @return new string builder
*/
ecma_stringbuilder_t
ecma_stringbuilder_create_raw (const lit_utf8_byte_t *data_p, /**< pointer to data */
const lit_utf8_size_t data_size) /**< size of the data */
{
const lit_utf8_size_t initial_size = data_size + (lit_utf8_size_t) sizeof (ecma_ascii_string_t);
ecma_stringbuilder_header_t *header_p = (ecma_stringbuilder_header_t *) jmem_heap_alloc_block (initial_size);
header_p->current_size = initial_size;
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_allocate_string_bytes (initial_size);
#endif /* ENABLED (JERRY_MEM_STATS) */
memcpy (ECMA_STRINGBUILDER_STRING_PTR (header_p), data_p, data_size);
ecma_stringbuilder_t ret = {.header_p = header_p};
return ret;
} /* ecma_stringbuilder_create_raw */
/**
* Grow the underlying buffer of a string builder
*
@ -2681,10 +2612,10 @@ void
ecma_stringbuilder_append_char (ecma_stringbuilder_t *builder_p, /**< string builder */
const ecma_char_t c) /**< ecma char */
{
const lit_utf8_size_t size = (lit_utf8_size_t) lit_char_get_utf8_length (c);
const lit_utf8_size_t size = (lit_utf8_size_t) lit_code_point_get_cesu8_length (c);
lit_utf8_byte_t *dest_p = ecma_stringbuilder_grow (builder_p, size);
lit_char_to_utf8_bytes (dest_p, c);
lit_code_point_to_cesu8_bytes (dest_p, c);
} /* ecma_stringbuilder_append_char */
/**
@ -2799,6 +2730,58 @@ ecma_stringbuilder_destroy (ecma_stringbuilder_t *builder_p) /**< string builder
#endif /* ENABLED (JERRY_MEM_STATS) */
} /* ecma_stringbuilder_destroy */
#if ENABLED (JERRY_ES2015)
/**
* AdvanceStringIndex operation
*
* See also:
* ECMA-262 v6.0, 21.2.5.2.3
*
* @return uint32_t - the proper character index based on the operation
*/
uint32_t
ecma_op_advance_string_index (ecma_string_t *str_p, /**< input string */
uint32_t index, /**< given character index */
bool is_unicode) /**< true - if regexp object's "unicode" flag is set
false - otherwise */
{
if (index >= UINT32_MAX - 1)
{
return UINT32_MAX;
}
uint32_t next_index = index + 1;
if (!is_unicode)
{
return next_index;
}
ecma_length_t str_len = ecma_string_get_length (str_p);
if (next_index >= str_len)
{
return next_index;
}
ecma_char_t first = ecma_string_get_char_at_pos (str_p, index);
if (first < LIT_UTF16_HIGH_SURROGATE_MIN || first > LIT_UTF16_HIGH_SURROGATE_MAX)
{
return next_index;
}
ecma_char_t second = ecma_string_get_char_at_pos (str_p, next_index);
if (second < LIT_UTF16_LOW_SURROGATE_MIN || second > LIT_UTF16_LOW_SURROGATE_MAX)
{
return next_index;
}
return next_index + 1;
} /* ecma_op_advance_string_index */
#endif /* ENABLED (JERRY_ES2015) */
/**
* @}
* @}

View File

@ -14,6 +14,7 @@
*/
#include "ecma-alloc.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
@ -35,8 +36,12 @@ JERRY_STATIC_ASSERT (ECMA_VALUE_SHIFT <= JMEM_ALIGNMENT_LOG,
JERRY_STATIC_ASSERT (sizeof (jmem_cpointer_t) <= sizeof (ecma_value_t),
size_of_jmem_cpointer_t_must_be_less_or_equal_to_the_size_of_ecma_value_t);
JERRY_STATIC_ASSERT (sizeof (jmem_cpointer_t) <= sizeof (jmem_cpointer_tag_t),
size_of_jmem_cpointer_t_must_be_less_or_equal_to_the_size_of_jmem_cpointer_tag_t);
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
/* cppcheck-suppress zerodiv */
JERRY_STATIC_ASSERT (sizeof (uintptr_t) <= sizeof (ecma_value_t),
uintptr_t_must_fit_in_ecma_value_t);
@ -63,7 +68,7 @@ JERRY_STATIC_ASSERT ((ECMA_VALUE_FALSE | (1 << ECMA_DIRECT_SHIFT)) == ECMA_VALUE
*
* @return type field
*/
static inline ecma_type_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
extern inline ecma_type_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_get_value_type_field (ecma_value_t value) /**< ecma value */
{
return value & ECMA_VALUE_TYPE_MASK;
@ -311,7 +316,7 @@ ecma_is_value_string (ecma_value_t value) /**< ecma value */
return ((value & (ECMA_VALUE_TYPE_MASK - 0x4)) == ECMA_TYPE_STRING);
} /* ecma_is_value_string */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/**
* Check if the value is symbol.
*
@ -323,7 +328,7 @@ ecma_is_value_symbol (ecma_value_t value) /**< ecma value */
{
return (ecma_get_value_type_field (value) == ECMA_TYPE_SYMBOL);
} /* ecma_is_value_symbol */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* Check if the value can be property name.
@ -334,11 +339,11 @@ ecma_is_value_symbol (ecma_value_t value) /**< ecma value */
inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
ecma_is_value_prop_name (ecma_value_t value) /**< ecma value */
{
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
return ecma_is_value_string (value) || ecma_is_value_symbol (value);
#else /* !ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#else /* !ENABLED (JERRY_ES2015) */
return ecma_is_value_string (value);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
} /* ecma_is_value_prop_name */
/**
@ -405,6 +410,45 @@ ecma_check_value_type_is_spec_defined (ecma_value_t value) /**< ecma value */
|| ecma_is_value_object (value));
} /* ecma_check_value_type_is_spec_defined */
/**
* Checks if the given argument is an array or not.
*
* @return ECMA_VALUE_ERROR- if the operation fails
* ECMA_VALUE_{TRUE/FALSE} - depends on whether 'arg' is an array object
*/
ecma_value_t
ecma_is_value_array (ecma_value_t arg) /**< argument */
{
if (!ecma_is_value_object (arg))
{
return ECMA_VALUE_FALSE;
}
ecma_object_t *arg_obj_p = ecma_get_object_from_value (arg);
if (ecma_get_object_type (arg_obj_p) == ECMA_OBJECT_TYPE_ARRAY)
{
return ECMA_VALUE_TRUE;
}
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (ECMA_OBJECT_IS_PROXY (arg_obj_p))
{
ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) arg_obj_p;
if (proxy_obj_p->handler == ECMA_VALUE_NULL)
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot perform 'IsArray' on the given proxy "
"because handler is null"));
}
return ecma_is_value_array (proxy_obj_p->target);
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
return ECMA_VALUE_FALSE;
} /* ecma_is_value_array */
/**
* Creates an ecma value from the given raw boolean.
*
@ -547,9 +591,9 @@ inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_make_string_value (const ecma_string_t *ecma_string_p) /**< string to reference in value */
{
JERRY_ASSERT (ecma_string_p != NULL);
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
JERRY_ASSERT (!ecma_prop_name_is_symbol ((ecma_string_t *) ecma_string_p));
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
if ((((uintptr_t) ecma_string_p) & ECMA_VALUE_TYPE_MASK) != 0)
{
@ -559,7 +603,7 @@ ecma_make_string_value (const ecma_string_t *ecma_string_p) /**< string to refer
return ecma_pointer_to_ecma_value (ecma_string_p) | ECMA_TYPE_STRING;
} /* ecma_make_string_value */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/**
* Symbol value constructor
*
@ -573,7 +617,7 @@ ecma_make_symbol_value (const ecma_string_t *ecma_symbol_p) /**< symbol to refer
return ecma_pointer_to_ecma_value (ecma_symbol_p) | ECMA_TYPE_SYMBOL;
} /* ecma_make_symbol_value */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* Property-name value constructor
@ -585,12 +629,12 @@ ecma_make_prop_name_value (const ecma_string_t *ecma_prop_name_p) /**< property
{
JERRY_ASSERT (ecma_prop_name_p != NULL);
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
if (ecma_prop_name_is_symbol ((ecma_string_t *) ecma_prop_name_p))
{
return ecma_make_symbol_value (ecma_prop_name_p);
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
return ecma_make_string_value (ecma_prop_name_p);
} /* ecma_make_prop_name_value */
@ -705,7 +749,7 @@ ecma_get_string_from_value (ecma_value_t value) /**< ecma value */
return (ecma_string_t *) ecma_get_pointer_from_ecma_value (value);
} /* ecma_get_string_from_value */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/**
* Get pointer to ecma-string from ecma value
*
@ -718,7 +762,7 @@ ecma_get_symbol_from_value (ecma_value_t value) /**< ecma value */
return (ecma_string_t *) ecma_get_pointer_from_ecma_value (value);
} /* ecma_get_symbol_from_value */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* Get pointer to a property name from ecma value
@ -798,13 +842,13 @@ ecma_copy_value (ecma_value_t value) /**< value description */
ecma_ref_ecma_string (ecma_get_string_from_value (value));
return value;
}
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
case ECMA_TYPE_SYMBOL:
{
ecma_ref_ecma_string (ecma_get_symbol_from_value (value));
return value;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
case ECMA_TYPE_OBJECT:
{
ecma_ref_object (ecma_get_object_from_value (value));
@ -842,10 +886,10 @@ ecma_fast_copy_value (ecma_value_t value) /**< value description */
*
* @return copy of the given value
*/
ecma_value_t
inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
ecma_copy_value_if_not_object (ecma_value_t value) /**< value description */
{
if (ecma_get_value_type_field (value) != ECMA_TYPE_OBJECT)
if (!ecma_is_value_object (value))
{
return ecma_copy_value (value);
}
@ -853,6 +897,30 @@ ecma_copy_value_if_not_object (ecma_value_t value) /**< value description */
return value;
} /* ecma_copy_value_if_not_object */
/**
* Increase reference counter of a value if it is an object.
*/
inline void JERRY_ATTR_ALWAYS_INLINE
ecma_ref_if_object (ecma_value_t value) /**< value description */
{
if (ecma_is_value_object (value))
{
ecma_ref_object (ecma_get_object_from_value (value));
}
} /* ecma_ref_if_object */
/**
* Decrease reference counter of a value if it is an object.
*/
inline void JERRY_ATTR_ALWAYS_INLINE
ecma_deref_if_object (ecma_value_t value) /**< value description */
{
if (ecma_is_value_object (value))
{
ecma_deref_object (ecma_get_object_from_value (value));
}
} /* ecma_deref_if_object */
/**
* Assign a new value to an ecma-value
*
@ -995,13 +1063,13 @@ ecma_free_value (ecma_value_t value) /**< value description */
ecma_deref_ecma_string (string_p);
break;
}
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
case ECMA_TYPE_SYMBOL:
{
ecma_deref_ecma_string (ecma_get_symbol_from_value (value));
break;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
case ECMA_TYPE_OBJECT:
{
ecma_deref_object (ecma_get_object_from_value (value));
@ -1101,12 +1169,12 @@ ecma_get_typeof_lit_id (ecma_value_t value) /**< input ecma value */
{
ret_value = LIT_MAGIC_STRING_STRING;
}
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
else if (ecma_is_value_symbol (value))
{
ret_value = LIT_MAGIC_STRING_SYMBOL;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
else
{
JERRY_ASSERT (ecma_is_value_object (value));

View File

@ -14,6 +14,7 @@
*/
#include "ecma-alloc.h"
#include "ecma-array-object.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
@ -54,8 +55,8 @@ JERRY_STATIC_ASSERT (ECMA_OBJECT_FLAG_EXTENSIBLE == (ECMA_OBJECT_FLAG_BUILT_IN_O
JERRY_STATIC_ASSERT (ECMA_OBJECT_REF_ONE == (ECMA_OBJECT_FLAG_EXTENSIBLE << 1),
ecma_object_ref_one_must_follow_the_extensible_flag);
JERRY_STATIC_ASSERT ((ECMA_OBJECT_MAX_REF | (ECMA_OBJECT_REF_ONE - 1)) == UINT16_MAX,
ecma_object_max_ref_does_not_fill_the_remaining_bits);
JERRY_STATIC_ASSERT (((ECMA_OBJECT_MAX_REF + ECMA_OBJECT_REF_ONE) | (ECMA_OBJECT_REF_ONE - 1)) == UINT16_MAX,
ecma_object_max_ref_does_not_fill_the_remaining_bits);
JERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_DELETED == (ECMA_DIRECT_STRING_MAGIC << ECMA_PROPERTY_NAME_TYPE_SHIFT),
ecma_property_type_deleted_must_have_magic_string_name_type);
@ -138,12 +139,12 @@ ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< out
ecma_object_t *binding_obj_p, /**< binding object */
ecma_lexical_environment_type_t type) /**< type of the new lexical environment */
{
#if ENABLED (JERRY_ES2015_CLASS)
#if ENABLED (JERRY_ES2015)
JERRY_ASSERT (type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND
|| type == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND);
#else /* !ENABLED (JERRY_ES2015_CLASS) */
|| type == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
#else /* !ENABLED (JERRY_ES2015) */
JERRY_ASSERT (type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
#endif /* ENABLED (JERRY_ES2015_CLASS) */
#endif /* ENABLED (JERRY_ES2015) */
JERRY_ASSERT (binding_obj_p != NULL
&& !ecma_is_lexical_environment (binding_obj_p));
@ -178,40 +179,17 @@ ecma_is_lexical_environment (const ecma_object_t *object_p) /**< object or lexic
return full_type >= (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | ECMA_LEXICAL_ENVIRONMENT_TYPE_START);
} /* ecma_is_lexical_environment */
/**
* Get value of [[Extensible]] object's internal property.
*
* @return true - if object is extensible
* false - otherwise
*/
inline bool JERRY_ATTR_PURE
ecma_get_object_extensible (const ecma_object_t *object_p) /**< object */
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (!ecma_is_lexical_environment (object_p));
return (object_p->type_flags_refs & ECMA_OBJECT_FLAG_EXTENSIBLE) != 0;
} /* ecma_get_object_extensible */
/**
* Set value of [[Extensible]] object's internal property.
*/
inline void
ecma_set_object_extensible (ecma_object_t *object_p, /**< object */
bool is_extensible) /**< value of [[Extensible]] */
ecma_op_ordinary_object_set_extensible (ecma_object_t *object_p) /**< object */
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (!ecma_is_lexical_environment (object_p));
if (is_extensible)
{
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_FLAG_EXTENSIBLE);
}
else
{
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & ~ECMA_OBJECT_FLAG_EXTENSIBLE);
}
} /* ecma_set_object_extensible */
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_FLAG_EXTENSIBLE);
} /* ecma_op_ordinary_object_set_extensible */
/**
* Get object's internal implementation-defined type.
@ -308,16 +286,86 @@ ecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-boun
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (ecma_is_lexical_environment (object_p));
#if ENABLED (JERRY_ES2015_CLASS)
#if ENABLED (JERRY_ES2015)
JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND
|| ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND);
#else /* !ENABLED (JERRY_ES2015_CLASS) */
|| ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
#else /* !ENABLED (JERRY_ES2015) */
JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
#endif /* ENABLED (JERRY_ES2015_CLASS) */
#endif /* ENABLED (JERRY_ES2015) */
return ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u1.bound_object_cp);
} /* ecma_get_lex_env_binding_object */
/**
* Create a new lexical environment with the same property list as the passed lexical environment
*
* @return pointer to the newly created lexical environment
*/
ecma_object_t *
ecma_clone_decl_lexical_environment (ecma_object_t *lex_env_p, /**< declarative lexical environment */
bool copy_values) /**< copy property values as well */
{
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL);
ecma_object_t *outer_lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
ecma_object_t *new_lex_env_p = ecma_create_decl_lex_env (outer_lex_env_p);
jmem_cpointer_t prop_iter_cp = lex_env_p->u1.property_list_cp;
JERRY_ASSERT (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)
{
prop_iter_cp = prop_iter_p->next_property_cp;
}
JERRY_ASSERT (prop_iter_cp != JMEM_CP_NULL);
do
{
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;
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED)
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[i]) == ECMA_PROPERTY_TYPE_NAMEDDATA);
uint8_t prop_attributes = (uint8_t) (prop_iter_p->types[i] & ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_string_t *name_p = ecma_string_from_property_name (prop_iter_p->types[i], prop_pair_p->names_cp[i]);
ecma_property_value_t *property_value_p;
property_value_p = ecma_create_named_data_property (new_lex_env_p, name_p, prop_attributes, NULL);
ecma_deref_ecma_string (name_p);
JERRY_ASSERT (property_value_p->value == ECMA_VALUE_UNDEFINED);
if (copy_values)
{
property_value_p->value = ecma_copy_value_if_not_object (prop_pair_p->values[i].value);
}
else
{
property_value_p->value = ECMA_VALUE_UNINITIALIZED;
}
}
}
prop_iter_cp = prop_iter_p->next_property_cp;
}
while (prop_iter_cp != JMEM_CP_NULL);
ecma_deref_object (lex_env_p);
return new_lex_env_p;
} /* ecma_clone_decl_lexical_environment */
/**
* Create a property in an object and link it into
* the object's properties' linked-list (at start of the list).
@ -473,8 +521,7 @@ ecma_create_named_data_property (ecma_object_t *object_p, /**< object */
{
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);
|| !ecma_op_object_is_fast_array (object_p));
JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL);
JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE) == 0);
@ -502,8 +549,7 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */
{
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);
|| !ecma_op_object_is_fast_array (object_p));
JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL);
JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE) == 0);
@ -537,8 +583,7 @@ 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_op_object_is_fast_array (obj_p));
ecma_property_t *property_p = NULL;
@ -696,8 +741,7 @@ 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_op_object_is_fast_array (obj_p));
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
@ -1202,8 +1246,13 @@ ecma_create_error_reference (ecma_value_t value, /**< referenced value */
ecma_value_t
ecma_create_error_reference_from_context (void)
{
return ecma_create_error_reference (JERRY_CONTEXT (error_value),
(JERRY_CONTEXT (status_flags) & ECMA_STATUS_EXCEPTION) != 0);
bool is_abort = jcontext_has_pending_abort ();
if (is_abort)
{
jcontext_set_abort_flag (false);
}
return ecma_create_error_reference (jcontext_take_exception (), !is_abort);
} /* ecma_create_error_reference_from_context */
/**
@ -1254,40 +1303,35 @@ ecma_deref_error_reference (ecma_error_reference_t *error_ref_p) /**< error refe
} /* ecma_deref_error_reference */
/**
* Clears error reference, and returns with the value.
* Raise error from the given error reference.
*
* @return value referenced by the error
* Note: the error reference's ref count is also decreased
*/
ecma_value_t
ecma_clear_error_reference (ecma_value_t value, /**< error reference */
bool set_abort_flag) /**< set abort flag */
void
ecma_raise_error_from_error_reference (ecma_value_t value) /**< error reference */
{
JERRY_ASSERT (!jcontext_has_pending_exception () && !jcontext_has_pending_abort ());
ecma_error_reference_t *error_ref_p = ecma_get_error_reference_from_value (value);
if (set_abort_flag)
{
if (error_ref_p->refs_and_flags & ECMA_ERROR_REF_ABORT)
{
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
}
else
{
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
}
}
JERRY_ASSERT (error_ref_p->refs_and_flags >= ECMA_ERROR_REF_ONE);
ecma_value_t referenced_value = error_ref_p->value;
jcontext_set_exception_flag (true);
jcontext_set_abort_flag (error_ref_p->refs_and_flags & ECMA_ERROR_REF_ABORT);
if (error_ref_p->refs_and_flags >= 2 * ECMA_ERROR_REF_ONE)
{
error_ref_p->refs_and_flags -= ECMA_ERROR_REF_ONE;
return ecma_copy_value (error_ref_p->value);
referenced_value = ecma_copy_value (referenced_value);
}
else
{
jmem_pools_free (error_ref_p, sizeof (ecma_error_reference_t));
}
ecma_value_t referenced_value = error_ref_p->value;
jmem_pools_free (error_ref_p, sizeof (ecma_error_reference_t));
return referenced_value;
} /* ecma_clear_error_reference */
JERRY_CONTEXT (error_value) = referenced_value;
} /* ecma_raise_error_from_error_reference */
/**
* Increase reference counter of Compact
@ -1394,6 +1438,18 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
}
#endif /* ENABLED (JERRY_DEBUGGER) */
#if ENABLED (JERRY_ES2015)
if (bytecode_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
{
ecma_collection_t *collection_p = ecma_compiled_code_get_tagged_template_collection (bytecode_p);
/* Since the objects in the tagged template collection are not strong referenced anymore by the compiled code
we can treat them as 'new' objects. */
JERRY_CONTEXT (ecma_gc_new_objects) += collection_p->item_count;
ecma_collection_free (collection_p);
}
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_free_byte_code_bytes (((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG);
#endif /* ENABLED (JERRY_MEM_STATS) */
@ -1411,6 +1467,51 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG);
} /* ecma_bytecode_deref */
#if ENABLED (JERRY_ES2015)
/**
* Get the tagged template collection of the compiled code
*
* @return pointer to the tagged template collection
*/
ecma_collection_t *
ecma_compiled_code_get_tagged_template_collection (const ecma_compiled_code_t *bytecode_header_p) /**< compiled code */
{
JERRY_ASSERT (bytecode_header_p != NULL);
JERRY_ASSERT (bytecode_header_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS);
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
ecma_value_t *tagged_base_p = (ecma_value_t *) byte_p;
tagged_base_p -= ecma_compiled_code_get_formal_params (bytecode_header_p);
return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, tagged_base_p[-1]);
} /* ecma_compiled_code_get_tagged_template_collection */
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015)
/**
* Get the number of formal parameters of the compiled code
*
* @return number of formal parameters
*/
ecma_length_t
ecma_compiled_code_get_formal_params (const ecma_compiled_code_t *bytecode_header_p) /**< compiled code */
{
if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED))
{
return 0;
}
if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
return ((cbc_uint16_arguments_t *) bytecode_header_p)->argument_end;
}
return ((cbc_uint8_arguments_t *) bytecode_header_p)->argument_end;
} /* ecma_compiled_code_get_formal_params */
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015) */
#if (JERRY_STACK_LIMIT != 0)
/**
* Check the current stack usage by calculating the difference from the initial stack base.
@ -1421,7 +1522,7 @@ uintptr_t JERRY_ATTR_NOINLINE
ecma_get_current_stack_usage (void)
{
volatile int __sp;
return (uintptr_t) (JERRY_CONTEXT (stack_base) - (uintptr_t)&__sp);
return (uintptr_t) (JERRY_CONTEXT (stack_base) - (uintptr_t) &__sp);
} /* ecma_get_current_stack_usage */
#endif /* (JERRY_STACK_LIMIT != 0) */

View File

@ -32,6 +32,12 @@
*/
#define ECMA_GET_NON_NULL_POINTER(type, field) JMEM_CP_GET_NON_NULL_POINTER (type, field)
/**
* Extract value of pointer from specified pointer-tag value
*/
#define ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG(type, field) \
JMEM_CP_GET_NON_NULL_POINTER_FROM_POINTER_TAG (type, field)
/**
* Get value of pointer from specified compressed pointer.
*/
@ -44,12 +50,39 @@
#define ECMA_SET_NON_NULL_POINTER(field, non_compressed_pointer) JMEM_CP_SET_NON_NULL_POINTER (field, \
non_compressed_pointer)
/**
* Set value of pointer-tag value so that it will correspond
* to specified non_compressed_pointer along with tag
*/
#define ECMA_SET_NON_NULL_POINTER_TAG(field, non_compressed_pointer, tag) \
JMEM_CP_SET_NON_NULL_POINTER_TAG (field, non_compressed_pointer, tag)
/**
* Set value of compressed pointer so that it will correspond
* to specified non_compressed_pointer.
*/
#define ECMA_SET_POINTER(field, non_compressed_pointer) JMEM_CP_SET_POINTER (field, non_compressed_pointer)
/**
* Get value of each tag bit from specified pointer-tag value
*/
#define ECMA_GET_FIRST_BIT_FROM_POINTER_TAG(field) \
JMEM_CP_GET_FIRST_BIT_FROM_POINTER_TAG (field) /**< get first tag bit from jmem_cpointer_tag_t **/
#define ECMA_GET_SECOND_BIT_FROM_POINTER_TAG(field) \
JMEM_CP_GET_SECOND_BIT_FROM_POINTER_TAG (field) /**< get second tag bit from jmem_cpointer_tag_t **/
#define ECMA_GET_THIRD_BIT_FROM_POINTER_TAG(field) \
JMEM_CP_GET_THIRD_BIT_FROM_POINTER_TAG (field) /**< get third tag bit from jmem_cpointer_tag_t **/
/**
* Set value of each tag bit to specified pointer-tag value
*/
#define ECMA_SET_FIRST_BIT_TO_POINTER_TAG(field) \
JMEM_CP_SET_FIRST_BIT_TO_POINTER_TAG (field) /**< set first tag bit to jmem_cpointer_tag_t **/
#define ECMA_SET_SECOND_BIT_TO_POINTER_TAG(field) \
JMEM_CP_SET_SECOND_BIT_TO_POINTER_TAG (field) /**< set second tag bit to jmem_cpointer_tag_t **/
#define ECMA_SET_THIRD_BIT_TO_POINTER_TAG(field) \
JMEM_CP_SET_THIRD_BIT_TO_POINTER_TAG (field) /**< set third tag bit to jmem_cpointer_tag_t **/
/**
* Status flags for ecma_string_get_chars function
*/
@ -147,19 +180,38 @@ typedef enum
*/
#define ECMA_BOOL_TO_BITFIELD(x) ((x) ? 1 : 0)
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/**
* JERRY_ASSERT compatible macro for checking whether the given ecma-value is symbol
*/
#define ECMA_ASSERT_VALUE_IS_SYMBOL(value) (ecma_is_value_symbol ((value)))
#else /* !ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#else /* !ENABLED (JERRY_ES2015) */
/**
* JERRY_ASSERT compatible macro for checking whether the given ecma-value is symbol
*/
#define ECMA_ASSERT_VALUE_IS_SYMBOL(value) (false)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* Check whether the given type is ECMA_OBJECT_TYPE_PROXY
*
* @param type object type
*/
#define ECMA_OBJECT_TYPE_IS_PROXY(type) (JERRY_UNLIKELY ((type) == ECMA_OBJECT_TYPE_PROXY))
/**
* Check whether the given object has [[ProxyHandler]] and [[ProxyTarger]] internal slots
*
* @param obj_p ecma-object
*/
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
#define ECMA_OBJECT_IS_PROXY(obj_p) (ECMA_OBJECT_TYPE_IS_PROXY (ecma_get_object_type ((obj_p))))
#else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
#define ECMA_OBJECT_IS_PROXY(obj_p) (false)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
/* ecma-helpers-value.c */
ecma_type_t JERRY_ATTR_CONST ecma_get_value_type_field (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_direct (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_simple (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_empty (ecma_value_t value);
@ -176,14 +228,15 @@ bool JERRY_ATTR_CONST ecma_are_values_integer_numbers (ecma_value_t first_value,
bool JERRY_ATTR_CONST ecma_is_value_float_number (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_number (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_string (ecma_value_t value);
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
bool JERRY_ATTR_CONST ecma_is_value_symbol (ecma_value_t value);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
bool JERRY_ATTR_CONST ecma_is_value_prop_name (ecma_value_t value);
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);
ecma_value_t ecma_is_value_array (ecma_value_t arg);
void ecma_check_value_type_is_spec_defined (ecma_value_t value);
@ -195,9 +248,9 @@ 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);
ecma_value_t JERRY_ATTR_PURE ecma_make_string_value (const ecma_string_t *ecma_string_p);
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
ecma_value_t JERRY_ATTR_PURE ecma_make_symbol_value (const ecma_string_t *ecma_symbol_p);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
ecma_value_t JERRY_ATTR_PURE ecma_make_prop_name_value (const ecma_string_t *ecma_prop_name_p);
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);
@ -207,9 +260,9 @@ 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)
#if ENABLED (JERRY_ES2015)
ecma_string_t JERRY_ATTR_PURE *ecma_get_symbol_from_value (ecma_value_t value);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
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);
@ -217,6 +270,8 @@ 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);
ecma_value_t ecma_copy_value_if_not_object (ecma_value_t value);
void ecma_ref_if_object (ecma_value_t value);
void ecma_deref_if_object (ecma_value_t value);
ecma_value_t ecma_update_float_number (ecma_value_t float_value, ecma_number_t new_number);
void ecma_value_assign_value (ecma_value_t *value_p, ecma_value_t ecma_value);
void ecma_value_assign_number (ecma_value_t *value_p, ecma_number_t ecma_number);
@ -227,10 +282,11 @@ void ecma_free_number (ecma_value_t value);
lit_magic_string_id_t ecma_get_typeof_lit_id (ecma_value_t value);
/* ecma-helpers-string.c */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
ecma_string_t *ecma_new_symbol_from_descriptor_string (ecma_value_t string_desc);
bool ecma_prop_name_is_symbol (ecma_string_t *string_p);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
uint32_t ecma_op_advance_string_index (ecma_string_t *str_p, uint32_t index, bool is_unicode);
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET)
ecma_string_t *ecma_new_map_key_string (ecma_value_t value);
bool ecma_prop_name_is_map_key (ecma_string_t *string_p);
@ -239,9 +295,9 @@ ecma_string_t *ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p,
ecma_string_t *ecma_new_ecma_string_from_utf8_converted_to_cesu8 (const lit_utf8_byte_t *string_p,
lit_utf8_size_t string_size);
ecma_string_t *ecma_new_ecma_string_from_code_unit (ecma_char_t code_unit);
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#if ENABLED (JERRY_ES2015)
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) */
#endif /* ENABLED (JERRY_ES2015) */
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);
@ -252,7 +308,6 @@ ecma_string_t *ecma_append_chars_to_string (ecma_string_t *string1_p,
lit_utf8_size_t cesu8_string2_size,
lit_utf8_size_t cesu8_string2_length);
ecma_string_t *ecma_concat_ecma_strings (ecma_string_t *string1_p, ecma_string_t *string2_p);
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);
@ -316,6 +371,8 @@ 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);
ecma_stringbuilder_t ecma_stringbuilder_create_raw (const lit_utf8_byte_t *data_p,
const lit_utf8_size_t data_size);
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);
@ -336,12 +393,19 @@ bool ecma_number_is_nan (ecma_number_t num);
bool ecma_number_is_negative (ecma_number_t num);
bool ecma_number_is_zero (ecma_number_t num);
bool ecma_number_is_infinity (ecma_number_t num);
bool ecma_number_is_finite (ecma_number_t num);
ecma_number_t
ecma_number_make_from_sign_mantissa_and_exponent (bool sign, uint64_t mantissa, int32_t exponent);
ecma_number_t ecma_number_get_prev (ecma_number_t num);
ecma_number_t ecma_number_get_next (ecma_number_t num);
ecma_number_t ecma_number_trunc (ecma_number_t num);
ecma_number_t ecma_number_calc_remainder (ecma_number_t left_num, ecma_number_t right_num);
ecma_number_t ecma_number_pow (ecma_number_t x, ecma_number_t y);
ecma_value_t ecma_number_parse_int (const lit_utf8_byte_t *string_buff,
lit_utf8_size_t string_buff_size,
ecma_value_t radix);
ecma_value_t ecma_number_parse_float (const lit_utf8_byte_t *string_buff,
lit_utf8_size_t string_buff_size);
ecma_value_t ecma_integer_multiply (ecma_integer_value_t left_integer, ecma_integer_value_t right_integer);
lit_utf8_size_t ecma_number_to_decimal (ecma_number_t num, lit_utf8_byte_t *out_digits_p, int32_t *out_decimal_exp_p);
lit_utf8_size_t ecma_number_to_binary_floating_point_number (ecma_number_t num,
@ -351,6 +415,8 @@ lit_utf8_size_t ecma_number_to_binary_floating_point_number (ecma_number_t num,
/* 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_reserve (ecma_collection_t *collection_p, uint32_t count);
void ecma_collection_append (ecma_collection_t *collection_p, const ecma_value_t *buffer_p, uint32_t count);
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);
@ -362,15 +428,14 @@ ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environmen
ecma_object_t *ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, ecma_object_t *binding_obj_p,
ecma_lexical_environment_type_t type);
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);
void ecma_op_ordinary_object_set_extensible (ecma_object_t *object_p);
ecma_object_type_t JERRY_ATTR_PURE ecma_get_object_type (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_object_t JERRY_ATTR_PURE *ecma_get_lex_env_binding_object (const ecma_object_t *object_p);
ecma_object_t *ecma_clone_decl_lexical_environment (ecma_object_t *lex_env_p, bool copy_values);
ecma_property_value_t *
ecma_create_named_data_property (ecma_object_t *object_p, ecma_string_t *name_p, uint8_t prop_attributes,
@ -416,10 +481,16 @@ ecma_value_t ecma_create_error_reference_from_context (void);
ecma_value_t ecma_create_error_object_reference (ecma_object_t *object_p);
void ecma_ref_error_reference (ecma_error_reference_t *error_ref_p);
void ecma_deref_error_reference (ecma_error_reference_t *error_ref_p);
ecma_value_t ecma_clear_error_reference (ecma_value_t value, bool set_abort_flag);
void ecma_raise_error_from_error_reference (ecma_value_t value);
void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p);
void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p);
#if ENABLED (JERRY_ES2015)
ecma_collection_t *ecma_compiled_code_get_tagged_template_collection (const ecma_compiled_code_t *bytecode_header_p);
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015)
ecma_length_t ecma_compiled_code_get_formal_params (const ecma_compiled_code_t *bytecode_p);
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015) */
#if (JERRY_STACK_LIMIT != 0)
uintptr_t ecma_get_current_stack_usage (void);
#endif /* (JERRY_STACK_LIMIT != 0) */

View File

@ -29,13 +29,22 @@
* @{
*/
/**
* Maximum number of GC loops on cleanup.
*/
#define JERRY_GC_LOOP_LIMIT 100
/**
* Initialize ECMA components
*/
void
ecma_init (void)
{
ecma_init_global_lex_env ();
#if (JERRY_GC_MARK_LIMIT != 0)
JERRY_CONTEXT (ecma_gc_mark_recursion_limit) = JERRY_GC_MARK_LIMIT;
#endif /* (JERRY_GC_MARK_LIMIT != 0) */
ecma_init_global_environment ();
#if ENABLED (JERRY_PROPRETY_HASHMAP)
JERRY_CONTEXT (ecma_prop_hashmap_alloc_state) = ECMA_PROP_HASHMAP_ALLOC_ON;
@ -44,12 +53,17 @@ ecma_init (void)
#if (JERRY_STACK_LIMIT != 0)
volatile int sp;
JERRY_CONTEXT (stack_base) = (uintptr_t)&sp;
JERRY_CONTEXT (stack_base) = (uintptr_t) &sp;
#endif /* (JERRY_STACK_LIMIT != 0) */
#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
ecma_job_queue_init ();
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
#if ENABLED (JERRY_ES2015)
JERRY_CONTEXT (current_new_target) = NULL;
JERRY_CONTEXT (current_function_obj_p) = NULL;
#endif /* ENABLED (JERRY_ES2015) */
} /* ecma_init */
/**
@ -58,9 +72,23 @@ ecma_init (void)
void
ecma_finalize (void)
{
ecma_finalize_global_lex_env ();
ecma_finalize_builtins ();
ecma_gc_run ();
#if ENABLED (JERRY_ES2015)
JERRY_ASSERT (JERRY_CONTEXT (current_new_target) == NULL);
JERRY_ASSERT (JERRY_CONTEXT (current_function_obj_p) == NULL);
#endif /* ENABLED (JERRY_ES2015) */
ecma_finalize_global_environment ();
uint8_t runs = 0;
do
{
ecma_finalize_builtins ();
ecma_gc_run ();
if (++runs >= JERRY_GC_LOOP_LIMIT)
{
jerry_fatal (ERR_UNTERMINATED_GC_LOOPS);
}
}
while (JERRY_CONTEXT (ecma_gc_new_objects) != 0);
ecma_finalize_lit_storage ();
} /* ecma_finalize */

View File

@ -25,7 +25,7 @@
* @{
*/
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/**
* Free symbol list
*/
@ -53,7 +53,7 @@ ecma_free_symbol_list (jmem_cpointer_t symbol_list_cp) /**< symbol list */
symbol_list_cp = next_item_cp;
}
} /* ecma_free_symbol_list */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* Free string list
@ -115,9 +115,9 @@ ecma_free_number_list (jmem_cpointer_t number_list_cp) /**< string list */
void
ecma_finalize_lit_storage (void)
{
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
ecma_free_symbol_list (JERRY_CONTEXT (symbol_list_first_cp));
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
ecma_free_string_list (JERRY_CONTEXT (string_list_first_cp));
ecma_free_number_list (JERRY_CONTEXT (number_list_first_cp));
} /* ecma_finalize_lit_storage */
@ -346,7 +346,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
const_literal_end = args_p->const_literal_end - register_end;
literal_end = args_p->literal_end - register_end;
if (CBC_NON_STRICT_ARGUMENTS_NEEDED (compiled_code_p))
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
{
argument_end = args_p->argument_end;
}
@ -361,7 +361,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
const_literal_end = args_p->const_literal_end - register_end;
literal_end = args_p->literal_end - register_end;
if (CBC_NON_STRICT_ARGUMENTS_NEEDED (compiled_code_p))
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
{
argument_end = args_p->argument_end;
}

View File

@ -79,7 +79,6 @@ ecma_module_create_normalized_path (const uint8_t *char_p, /**< module specifier
ECMA_MODULE_MAX_PATH,
(char *) module_path_p);
if (normalized_size > 0)
{
/* Convert the normalized path to cesu8. */
@ -661,7 +660,7 @@ ecma_module_evaluate (ecma_module_t *module_p) /**< module */
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
ecma_value_t
static ecma_value_t
ecma_module_connect_imports (void)
{
ecma_module_context_t *current_context_p = JERRY_CONTEXT (module_top_context_p);
@ -670,6 +669,53 @@ ecma_module_connect_imports (void)
JERRY_ASSERT (ecma_is_lexical_environment (local_env_p));
ecma_module_node_t *import_node_p = current_context_p->imports_p;
/* Check that the imported bindings don't exist yet. */
while (import_node_p != NULL)
{
ecma_module_names_t *import_names_p = import_node_p->module_names_p;
while (import_names_p != NULL)
{
ecma_object_t *lex_env_p = local_env_p;
ecma_property_t *binding_p = NULL;
if (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_BLOCK)
{
binding_p = ecma_find_named_property (lex_env_p, import_names_p->local_name_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);
}
if (binding_p != NULL)
{
return ecma_raise_syntax_error (ECMA_ERR_MSG ("Imported binding shadows local variable."));
}
ecma_value_t status = ecma_op_has_binding (lex_env_p, import_names_p->local_name_p);
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (ECMA_IS_VALUE_ERROR (status))
{
return status;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
if (ecma_is_value_true (status))
{
return ecma_raise_syntax_error (ECMA_ERR_MSG ("Imported binding shadows local variable."));
}
import_names_p = import_names_p->next_p;
}
import_node_p = import_node_p->next_p;
}
import_node_p = current_context_p->imports_p;
/* Resolve imports and create local bindings. */
while (import_node_p != NULL)
{
ecma_value_t result = ecma_module_evaluate (import_node_p->module_request_p);
@ -762,6 +808,26 @@ ecma_module_connect_imports (void)
return ECMA_VALUE_EMPTY;
} /* ecma_module_connect_imports */
/**
* Initialize the current module by creating the local binding for the imported variables
* and verifying indirect exports.
*
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
ecma_value_t
ecma_module_initialize_current (void)
{
ecma_value_t ret_value = ecma_module_connect_imports ();
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_module_check_indirect_exports ();
}
return ret_value;
} /* ecma_module_initialize_current */
/**
* Parses an EcmaScript module.
*
@ -818,7 +884,7 @@ ecma_module_parse (ecma_module_t *module_p) /**< module */
0,
(jerry_char_t *) source_p,
source_size,
JERRY_PARSE_STRICT_MODE,
ECMA_PARSE_STRICT_MODE | ECMA_PARSE_MODULE,
&bytecode_data_p);
JERRY_CONTEXT (module_top_context_p) = module_p->context_p->parent_p;
@ -976,7 +1042,8 @@ ecma_module_release_module (ecma_module_t *module_p) /**< module */
ecma_module_release_module_context (module_p->context_p);
}
if (module_p->state >= ECMA_MODULE_STATE_EVALUATING)
if (module_p->state >= ECMA_MODULE_STATE_EVALUATING
&& module_p->scope_p != NULL)
{
ecma_deref_object (module_p->scope_p);
}
@ -997,11 +1064,6 @@ finished:
void
ecma_module_cleanup (void)
{
if (JERRY_CONTEXT (module_top_context_p)->parent_p != NULL)
{
return;
}
ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
while (current_p != NULL)
{
@ -1010,6 +1072,7 @@ ecma_module_cleanup (void)
current_p = next_p;
}
JERRY_CONTEXT (ecma_modules_p) = NULL;
JERRY_CONTEXT (module_top_context_p) = NULL;
} /* ecma_module_cleanup */

View File

@ -133,7 +133,7 @@ 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_initialize_current (void);
ecma_value_t ecma_module_parse_modules (void);
ecma_value_t ecma_module_check_indirect_exports (void);

View File

@ -245,7 +245,6 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
uint32_t mask = hashmap_p->max_property_count - 1;
entry_index &= mask;
#ifndef JERRY_NDEBUG
/* See the comment for this variable in ecma_property_hashmap_create. */
uint32_t start_entry_index = entry_index;

View File

@ -72,7 +72,6 @@ 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);
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) */

View File

@ -18,11 +18,7 @@
#include "ecma-iterator-object.h"
#include "ecma-typedarray-object.h"
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#if !ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#error "Iterator builtin requires ES2015 symbol builtin"
#endif /* !ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#if ENABLED (JERRY_ES2015)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
@ -82,40 +78,14 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t
ecma_object_t *array_object_p = ecma_get_object_from_value (iterated_value);
uint32_t length;
/* 8 - 9. */
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
if (ecma_is_typedarray (ecma_make_object_value (array_object_p)))
uint32_t length;
ecma_value_t len_value = ecma_op_object_get_length (array_object_p, &length);
if (ECMA_IS_VALUE_ERROR (len_value))
{
length = ecma_typedarray_get_length (array_object_p);
return len_value;
}
else
{
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
ecma_value_t len_value = ecma_op_object_get (array_object_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH));
if (ECMA_IS_VALUE_ERROR (len_value))
{
return len_value;
}
ecma_number_t length_number;
ecma_value_t length_value = ecma_get_number (len_value, &length_number);
if (ECMA_IS_VALUE_ERROR (length_value))
{
ecma_free_value (len_value);
return length_value;
}
length = ecma_number_to_uint32 (length_number);
ecma_free_value (len_value);
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
uint32_t index = ext_obj_p->u.pseudo_array.u1.iterator_index;
@ -161,12 +131,8 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t
return ecma_create_iter_result_object (ecma_make_uint32_value (index), ECMA_VALUE_FALSE);
}
/* 13. */
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
/* 14. */
ecma_value_t get_value = ecma_op_object_get (array_object_p, index_string_p);
ecma_deref_ecma_string (index_string_p);
ecma_value_t get_value = ecma_op_object_get_by_uint32_index (array_object_p, index);
/* 15. */
if (ECMA_IS_VALUE_ERROR (get_value))
@ -206,4 +172,4 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
#endif /* ENABLED (JERRY_ES2015) */

View File

@ -19,7 +19,7 @@
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#if ENABLED (JERRY_ES2015)
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_ARRAY_ITERATOR_UL,
@ -29,6 +29,6 @@ STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_NEXT, ecma_builtin_array_iterator_prototype_object_next, 0, 0)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
#endif /* ENABLED (JERRY_ES2015) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -0,0 +1,28 @@
/* 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-builtin-helpers.h"
#include "ecma-builtins.h"
#if ENABLED (JERRY_ES2015)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-array-prototype-unscopables.inc.h"
#define BUILTIN_UNDERSCORED_ID array_prototype_unscopables
#include "ecma-builtin-internal-routines-template.inc.h"
#endif /* ENABLED (JERRY_ES2015) */

View File

@ -0,0 +1,54 @@
/* 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.
*/
/*
* Array.prototype[@@unscopables] built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015)
SIMPLE_VALUE (LIT_MAGIC_STRING_COPY_WITHIN,
ECMA_VALUE_TRUE,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE)
SIMPLE_VALUE (LIT_MAGIC_STRING_ENTRIES,
ECMA_VALUE_TRUE,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE)
SIMPLE_VALUE (LIT_MAGIC_STRING_FILL,
ECMA_VALUE_TRUE,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE)
SIMPLE_VALUE (LIT_MAGIC_STRING_FIND,
ECMA_VALUE_TRUE,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE)
SIMPLE_VALUE (LIT_MAGIC_STRING_FIND_INDEX,
ECMA_VALUE_TRUE,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE)
SIMPLE_VALUE (LIT_MAGIC_STRING_KEYS,
ECMA_VALUE_TRUE,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE)
SIMPLE_VALUE (LIT_MAGIC_STRING_VALUES,
ECMA_VALUE_TRUE,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,13 @@ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_ARRAY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 22.1.3.31 */
OBJECT_VALUE (LIT_GLOBAL_SYMBOL_UNSCOPABLES,
ECMA_BUILTIN_ID_ARRAY_PROTOTYPE_UNSCOPABLES,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015) */
/* Number properties:
* (property name, object pointer getter) */
@ -60,18 +67,20 @@ ROUTINE (LIT_MAGIC_STRING_FOR_EACH_UL, ECMA_ARRAY_PROTOTYPE_FOR_EACH, 2, 1)
ROUTINE (LIT_MAGIC_STRING_MAP, ECMA_ARRAY_PROTOTYPE_MAP, 2, 1)
ROUTINE (LIT_MAGIC_STRING_FILTER, ECMA_ARRAY_PROTOTYPE_FILTER, 2, 1)
/* Note these 2 routines must be in this order */
ROUTINE (LIT_MAGIC_STRING_REDUCE, ECMA_ARRAY_PROTOTYPE_REDUCE, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ECMA_ARRAY_PROTOTYPE_REDUCE_RIGHT, NON_FIXED, 1)
#if ENABLED (JERRY_ES2015_BUILTIN)
ROUTINE (LIT_MAGIC_STRING_REDUCE, ECMA_ARRAY_PROTOTYPE_REDUCE, 2, 1)
ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ECMA_ARRAY_PROTOTYPE_REDUCE_RIGHT, 2, 1)
#if ENABLED (JERRY_ES2015)
ROUTINE (LIT_MAGIC_STRING_FIND, ECMA_ARRAY_PROTOTYPE_FIND, 2, 1)
ROUTINE (LIT_MAGIC_STRING_FIND_INDEX, ECMA_ARRAY_PROTOTYPE_FIND_INDEX, 2, 1)
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
ROUTINE (LIT_MAGIC_STRING_FILL, ECMA_ARRAY_PROTOTYPE_FILL, 3, 1)
ROUTINE (LIT_MAGIC_STRING_COPY_WITHIN, ECMA_ARRAY_PROTOTYPE_COPY_WITHIN, NON_FIXED, 2)
ROUTINE (LIT_MAGIC_STRING_ENTRIES, ECMA_ARRAY_PROTOTYPE_ENTRIES, 0, 0)
ROUTINE (LIT_MAGIC_STRING_VALUES, ECMA_ARRAY_PROTOTYPE_VALUES, 0, 0)
ROUTINE (LIT_MAGIC_STRING_KEYS, ECMA_ARRAY_PROTOTYPE_KEYS, 0, 0)
ROUTINE (LIT_GLOBAL_SYMBOL_ITERATOR, ECMA_ARRAY_PROTOTYPE_SYMBOL_ITERATOR, 0, 0)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
INTRINSIC_PROPERTY (LIT_MAGIC_STRING_VALUES, LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
INTRINSIC_PROPERTY (LIT_GLOBAL_SYMBOL_ITERATOR, LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015) */
#endif /* ENABLED (JERRY_BUILTIN_ARRAY) */

View File

@ -15,14 +15,17 @@
#include "ecma-alloc.h"
#include "ecma-builtins.h"
#include "ecma-builtin-helpers.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-iterator-object.h"
#include "ecma-objects.h"
#include "ecma-array-object.h"
#include "ecma-try-catch-macro.h"
#include "jcontext.h"
#include "jrt.h"
#if ENABLED (JERRY_BUILTIN_ARRAY)
@ -58,20 +61,419 @@ ecma_builtin_array_object_is_array (ecma_value_t this_arg, /**< 'this' argument
ecma_value_t arg) /**< first argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t is_array = ECMA_VALUE_FALSE;
if (ecma_is_value_object (arg))
return ecma_is_value_array (arg);
} /* ecma_builtin_array_object_is_array */
#if ENABLED (JERRY_ES2015)
/**
* The Array object's 'from' routine
*
* See also:
* ECMA-262 v6, 22.1.2.1
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_array_object_from (ecma_value_t this_arg, /**< 'this' argument */
const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
/* 1. */
ecma_value_t constructor = this_arg;
ecma_value_t call_this_arg = ECMA_VALUE_UNDEFINED;
ecma_value_t items = arguments_list_p[0];
ecma_value_t mapfn = (arguments_list_len > 1) ? arguments_list_p[1] : ECMA_VALUE_UNDEFINED;
/* 2. */
ecma_object_t *mapfn_obj_p = NULL;
/* 3. */
if (!ecma_is_value_undefined (mapfn))
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_ARRAY_UL)
/* 3.a */
if (!ecma_op_is_callable (mapfn))
{
is_array = ECMA_VALUE_TRUE;
return ecma_raise_type_error (ECMA_ERR_MSG ("Callback function is not callable."));
}
/* 3.b */
if (arguments_list_len > 2)
{
call_this_arg = arguments_list_p[2];
}
/* 3.c */
mapfn_obj_p = ecma_get_object_from_value (mapfn);
}
return is_array;
} /* ecma_builtin_array_object_is_array */
/* 4. */
ecma_value_t using_iterator = ecma_op_get_method_by_symbol_id (items, LIT_GLOBAL_SYMBOL_ITERATOR);
/* 5. */
if (ECMA_IS_VALUE_ERROR (using_iterator))
{
return using_iterator;
}
ecma_value_t ret_value = ECMA_VALUE_ERROR;
/* 6. */
if (!ecma_is_value_undefined (using_iterator))
{
ecma_value_t array;
/* 6.a */
if (ecma_is_constructor (constructor))
{
ecma_object_t *constructor_obj_p = ecma_get_object_from_value (constructor);
array = ecma_op_function_construct (constructor_obj_p, constructor_obj_p, NULL, 0);
if (ecma_is_value_undefined (array) || ecma_is_value_null (array))
{
ecma_free_value (using_iterator);
return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot convert undefined or null to object"));
}
}
else
{
/* 6.b */
array = ecma_op_create_array_object (NULL, 0, false);
}
/* 6.c */
if (ECMA_IS_VALUE_ERROR (array))
{
ecma_free_value (using_iterator);
return array;
}
ecma_object_t *array_obj_p = ecma_get_object_from_value (array);
/* 6.d */
ecma_value_t iterator = ecma_op_get_iterator (items, using_iterator);
ecma_free_value (using_iterator);
/* 6.e */
if (ECMA_IS_VALUE_ERROR (iterator))
{
ecma_free_value (array);
return iterator;
}
/* 6.f */
uint32_t k = 0;
/* 6.g */
while (true)
{
/* 6.g.ii */
ecma_value_t next = ecma_op_iterator_step (iterator);
/* 6.g.iii */
if (ECMA_IS_VALUE_ERROR (next))
{
goto iterator_cleanup;
}
/* 6.g.iii */
if (ecma_is_value_false (next))
{
/* 6.g.iv.1 */
ecma_value_t len_value = ecma_make_uint32_value (k);
ecma_value_t set_status = ecma_op_object_put (array_obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH),
len_value,
true);
ecma_free_value (len_value);
/* 6.g.iv.2 */
if (ECMA_IS_VALUE_ERROR (set_status))
{
goto iterator_cleanup;
}
ecma_free_value (iterator);
/* 6.g.iv.3 */
return array;
}
/* 6.g.v */
ecma_value_t next_value = ecma_op_iterator_value (next);
ecma_free_value (next);
/* 6.g.vi */
if (ECMA_IS_VALUE_ERROR (next_value))
{
goto iterator_cleanup;
}
ecma_value_t mapped_value;
/* 6.g.vii */
if (mapfn_obj_p != NULL)
{
/* 6.g.vii.1 */
ecma_value_t args_p[2] = { next_value, ecma_make_uint32_value (k) };
/* 6.g.vii.3 */
mapped_value = ecma_op_function_call (mapfn_obj_p, call_this_arg, args_p, 2);
ecma_free_value (args_p[1]);
ecma_free_value (next_value);
/* 6.g.vii.2 */
if (ECMA_IS_VALUE_ERROR (mapped_value))
{
ecma_op_iterator_close (iterator);
goto iterator_cleanup;
}
}
else
{
/* 6.g.viii */
mapped_value = next_value;
}
/* 6.g.ix */
const uint32_t flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW;
ecma_value_t set_status = ecma_builtin_helper_def_prop_by_index (array_obj_p, k, mapped_value, flags);
ecma_free_value (mapped_value);
/* 6.g.x */
if (ECMA_IS_VALUE_ERROR (set_status))
{
ecma_op_iterator_close (iterator);
goto iterator_cleanup;
}
/* 6.g.xi */
k++;
}
iterator_cleanup:
ecma_free_value (iterator);
ecma_free_value (array);
return ret_value;
}
/* 8. */
ecma_value_t array_like = ecma_op_to_object (items);
/* 9. */
if (ECMA_IS_VALUE_ERROR (array_like))
{
return array_like;
}
ecma_object_t *array_like_obj_p = ecma_get_object_from_value (array_like);
/* 10. */
uint32_t len;
ecma_value_t len_value = ecma_op_object_get_length (array_like_obj_p, &len);
/* 11. */
if (ECMA_IS_VALUE_ERROR (len_value))
{
goto cleanup;
}
len_value = ecma_make_uint32_value (len);
/* 12. */
ecma_value_t array;
/* 12.a */
if (ecma_is_constructor (constructor))
{
ecma_object_t *constructor_obj_p = ecma_get_object_from_value (constructor);
array = ecma_op_function_construct (constructor_obj_p, constructor_obj_p, &len_value, 1);
if (ecma_is_value_undefined (array) || ecma_is_value_null (array))
{
ecma_free_value (len_value);
ecma_raise_type_error (ECMA_ERR_MSG ("Cannot convert undefined or null to object"));
goto cleanup;
}
}
else
{
/* 13.a */
array = ecma_op_create_array_object (&len_value, 1, true);
}
ecma_free_value (len_value);
/* 14. */
if (ECMA_IS_VALUE_ERROR (array))
{
goto cleanup;
}
ecma_object_t *array_obj_p = ecma_get_object_from_value (array);
/* 15. */
uint32_t k = 0;
/* 16. */
while (k < len)
{
/* 16.b */
ecma_value_t k_value = ecma_op_object_get_by_uint32_index (array_like_obj_p, k);
/* 16.c */
if (ECMA_IS_VALUE_ERROR (k_value))
{
goto construct_cleanup;
}
ecma_value_t mapped_value;
/* 16.d */
if (mapfn_obj_p != NULL)
{
/* 16.d.i */
ecma_value_t args_p[2] = { k_value, ecma_make_uint32_value (k) };
mapped_value = ecma_op_function_call (mapfn_obj_p, call_this_arg, args_p, 2);
ecma_free_value (args_p[1]);
ecma_free_value (k_value);
/* 16.d.ii */
if (ECMA_IS_VALUE_ERROR (mapped_value))
{
goto construct_cleanup;
}
}
else
{
/* 16.e */
mapped_value = k_value;
}
/* 16.f */
const uint32_t flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW;
ecma_value_t set_status = ecma_builtin_helper_def_prop_by_index (array_obj_p, k, mapped_value, flags);
ecma_free_value (mapped_value);
/* 16.g */
if (ECMA_IS_VALUE_ERROR (set_status))
{
goto construct_cleanup;
}
/* 16.h */
k++;
}
/* 17. */
len_value = ecma_make_uint32_value (k);
ecma_value_t set_status = ecma_op_object_put (array_obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH),
len_value,
true);
ecma_free_value (len_value);
/* 18. */
if (ECMA_IS_VALUE_ERROR (set_status))
{
goto construct_cleanup;
}
/* 19. */
ecma_deref_object (array_like_obj_p);
return ecma_make_object_value (array_obj_p);
construct_cleanup:
ecma_deref_object (array_obj_p);
cleanup:
ecma_deref_object (array_like_obj_p);
return ret_value;
} /* ecma_builtin_array_object_from */
/**
* The Array object's 'of' routine
*
* See also:
* ECMA-262 v6, 22.1.2.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_array_object_of (ecma_value_t this_arg, /**< 'this' argument */
const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
if (!ecma_is_constructor (this_arg))
{
return ecma_op_create_array_object (arguments_list_p, arguments_list_len, false);
}
ecma_value_t len = ecma_make_uint32_value (arguments_list_len);
ecma_value_t ret_val = ecma_op_function_construct (ecma_get_object_from_value (this_arg),
ecma_get_object_from_value (this_arg),
&len,
1);
if (ECMA_IS_VALUE_ERROR (ret_val))
{
ecma_free_value (len);
return ret_val;
}
uint32_t k = 0;
ecma_object_t *obj_p = ecma_get_object_from_value (ret_val);
const uint32_t prop_status_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW;
while (k < arguments_list_len)
{
ecma_value_t define_status = ecma_builtin_helper_def_prop_by_index (obj_p,
k,
arguments_list_p[k],
prop_status_flags);
if (ECMA_IS_VALUE_ERROR (define_status))
{
ecma_free_value (len);
ecma_deref_object (obj_p);
return define_status;
}
k++;
}
ret_val = ecma_op_object_put (obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH),
len,
true);
ecma_free_value (len);
if (ECMA_IS_VALUE_ERROR (ret_val))
{
ecma_deref_object (obj_p);
return ret_val;
}
return ecma_make_object_value (obj_p);
} /* ecma_builtin_array_object_of */
/**
* 22.1.2.5 get Array [ @@species ] accessor
*
* @return ecma_value
* returned value must be freed with ecma_free_value
*/
ecma_value_t
ecma_builtin_array_species_get (ecma_value_t this_value) /**< This Value */
{
return ecma_copy_value (this_value);
} /* ecma_builtin_array_species_get */
#endif /* ENABLED (JERRY_ES2015) */
/**
* Handle calling [[Call]] of built-in Array object
@ -84,7 +486,7 @@ ecma_builtin_array_dispatch_call (const ecma_value_t *arguments_list_p, /**< arg
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_builtin_array_dispatch_construct (arguments_list_p, arguments_list_len);
return ecma_op_create_array_object (arguments_list_p, arguments_list_len, true);
} /* ecma_builtin_array_dispatch_call */
/**
@ -98,7 +500,30 @@ ecma_builtin_array_dispatch_construct (const ecma_value_t *arguments_list_p, /**
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
#if !ENABLED (JERRY_ES2015)
return ecma_op_create_array_object (arguments_list_p, arguments_list_len, true);
#else /* ENABLED (JERRY_ES2015) */
ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_new_target),
ECMA_BUILTIN_ID_ARRAY_PROTOTYPE);
if (proto_p == NULL)
{
return ECMA_VALUE_ERROR;
}
ecma_value_t result = ecma_op_create_array_object (arguments_list_p, arguments_list_len, true);
if (ECMA_IS_VALUE_ERROR (result))
{
ecma_deref_object (proto_p);
return ECMA_VALUE_ERROR;
}
ecma_object_t *object_p = ecma_get_object_from_value (result);
ECMA_SET_NON_NULL_POINTER (object_p->u2.prototype_cp, proto_p);
ecma_deref_object (proto_p);
return result;
#endif /* ENABLED (JERRY_ES2015) */
} /* ecma_builtin_array_dispatch_construct */
/**

View File

@ -32,14 +32,22 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
/* Number properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.4.3 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_DEFAULT_LENGTH)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_IS_ARRAY_UL, ecma_builtin_array_object_is_array, 1, 1)
#if ENABLED (JERRY_ES2015)
ROUTINE (LIT_MAGIC_STRING_FROM, ecma_builtin_array_object_from, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_OF, ecma_builtin_array_object_of, NON_FIXED, 0)
/* ECMA-262 v6, 22.1.2.5 */
ACCESSOR_READ_ONLY (LIT_GLOBAL_SYMBOL_SPECIES,
ecma_builtin_array_species_get,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015) */
#endif /* !(ENABLED (JERRY_BUILTIN_ARRAY)) */

View File

@ -61,6 +61,10 @@ ecma_builtin_arraybuffer_prototype_bytelength_getter (ecma_value_t this_arg) /**
if (ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL))
{
if (ecma_arraybuffer_is_detached (object_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached."));
}
ecma_length_t len = ecma_arraybuffer_get_length (object_p);
return ecma_make_uint32_value (len);
@ -96,31 +100,34 @@ ecma_builtin_arraybuffer_prototype_object_slice (ecma_value_t this_arg, /**< thi
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an ArrayBuffer object."));
}
if (ecma_arraybuffer_is_detached (object_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached."));
}
ecma_length_t len = ecma_arraybuffer_get_length (object_p);
ecma_length_t start = 0, end = len;
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ECMA_OP_TO_NUMBER_TRY_CATCH (start_num,
arg1,
ret_value);
start = ecma_builtin_helper_array_index_normalize (start_num, len, false);
if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg1,
len,
&start)))
{
return ECMA_VALUE_ERROR;
}
if (!ecma_is_value_undefined (arg2))
{
ECMA_OP_TO_NUMBER_TRY_CATCH (end_num,
arg2,
ret_value);
end = ecma_builtin_helper_array_index_normalize (end_num, len, false);
ECMA_OP_TO_NUMBER_FINALIZE (end_num);
if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg2,
len,
&end)))
{
return ECMA_VALUE_ERROR;
}
}
ECMA_OP_TO_NUMBER_FINALIZE (start_num);
if (ret_value != ECMA_VALUE_EMPTY)
{
return ret_value;

View File

@ -31,14 +31,14 @@ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
/* Readonly accessor properties */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BYTE_LENGTH_UL,
ecma_builtin_arraybuffer_prototype_bytelength_getter,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 24.1.4.4 */
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_ARRAY_BUFFER_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */

View File

@ -19,7 +19,9 @@
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-arraybuffer-object.h"
#include "ecma-dataview-object.h"
#include "ecma-try-catch-macro.h"
#include "ecma-typedarray-object.h"
#include "jrt.h"
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
@ -55,11 +57,12 @@ ecma_builtin_arraybuffer_object_is_view (ecma_value_t this_arg, /**< 'this' argu
ecma_value_t arg) /**< argument 1 */
{
JERRY_UNUSED (this_arg);
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
return ecma_make_boolean_value (ecma_is_typedarray (arg) || ecma_is_dataview (arg));
#else
JERRY_UNUSED (arg);
/* TODO: if arg has [[ViewArrayBuffer]], return true */
return ECMA_VALUE_FALSE;
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
} /* ecma_builtin_arraybuffer_object_is_view */
/**
@ -94,6 +97,18 @@ ecma_builtin_arraybuffer_dispatch_construct (const ecma_value_t *arguments_list_
return ecma_op_create_arraybuffer_object (arguments_list_p, arguments_list_len);
} /* ecma_builtin_arraybuffer_dispatch_construct */
/**
* 24.1.3.3 get ArrayBuffer [ @@species ] accessor
*
* @return ecma_value
* returned value must be freed with ecma_free_value
*/
ecma_value_t
ecma_builtin_arraybuffer_species_get (ecma_value_t this_value) /**< This Value */
{
return ecma_copy_value (this_value);
} /* ecma_builtin_arraybuffer_species_get */
/**
* @}
* @}

View File

@ -26,7 +26,7 @@
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* Object properties:
* (property name, object pointer getter) */
@ -41,6 +41,11 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
/* ES2015 24.1.3.1 */
ROUTINE (LIT_MAGIC_STRING_IS_VIEW_UL, ecma_builtin_arraybuffer_object_is_view, 1, 1)
/* ES2015 24.1.3.3 */
ACCESSOR_READ_ONLY (LIT_GLOBAL_SYMBOL_SPECIES,
ecma_builtin_arraybuffer_species_get,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -32,10 +32,9 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
/* Number properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.6.3 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_DEFAULT_LENGTH)
#endif /* ENABLED (JERRY_BUILTIN_BOOLEAN) */

View File

@ -13,6 +13,8 @@
* limitations under the License.
*/
#include "ecma-arraybuffer-object.h"
#include "ecma-exceptions.h"
#include "ecma-dataview-object.h"
#include "ecma-gc.h"
@ -110,11 +112,20 @@ ecma_builtin_dataview_prototype_object_getters (ecma_value_t this_arg, /**< this
}
case ECMA_DATAVIEW_PROTOTYPE_BYTE_LENGTH_GETTER:
{
if (ecma_arraybuffer_is_detached (obj_p->buffer_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached."));
}
return ecma_make_uint32_value (obj_p->header.u.class_prop.u.length);
}
default:
{
JERRY_ASSERT (builtin_routine_id == ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER);
if (ecma_arraybuffer_is_detached (obj_p->buffer_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached."));
}
return ecma_make_uint32_value (obj_p->byte_offset);
}
}

View File

@ -29,12 +29,12 @@ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_DATAVIEW,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 23.2.4.21 */
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_DATAVIEW_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
@ -62,17 +62,17 @@ ROUTINE (LIT_MAGIC_STRING_SET_UINT32_UL, ECMA_DATAVIEW_PROTOTYPE_SET_UINT32, 2,
/* ECMA-262 v6, 24.2.4.1 */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BUFFER,
ECMA_DATAVIEW_PROTOTYPE_BUFFER_GETTER,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v6, 24.2.4.2 */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BYTE_LENGTH_UL,
ECMA_DATAVIEW_PROTOTYPE_BYTE_LENGTH_GETTER,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v6, 24.2.4.3 */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BYTE_OFFSET_UL,
ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */

View File

@ -27,7 +27,7 @@
/* ECMA-262 v6, 23.1.2 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
3,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v6, 23.1 */
STRING_VALUE (LIT_MAGIC_STRING_NAME,

View File

@ -22,6 +22,7 @@
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-objects-general.h"
#include "ecma-try-catch-macro.h"
#if ENABLED (JERRY_BUILTIN_DATE)
@ -98,6 +99,10 @@ enum
ECMA_DATE_PROTOTYPE_GET_TIME, /* ECMA-262 v5, 15.9.5.9 */
ECMA_DATE_PROTOTYPE_SET_TIME, /* ECMA-262 v5, 15.9.5.27 */
ECMA_DATE_PROTOTYPE_TO_JSON, /* ECMA-262 v5, 15.9.5.44 */
#if ENABLED (JERRY_ES2015)
ECMA_DATE_PROTOTYPE_TO_PRIMITIVE, /* ECMA-262 v6 20.3.4.45 */
#endif /* ENABLED (JERRY_ES2015) */
};
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-date-prototype.inc.h"
@ -179,6 +184,46 @@ ecma_builtin_date_prototype_to_json (ecma_value_t this_arg) /**< this argument *
return ret_value;
} /* ecma_builtin_date_prototype_to_json */
#if ENABLED (JERRY_ES2015)
/**
* The Date.prototype object's toPrimitive routine
*
* See also:
* ECMA-262 v6, 20.3.4.45
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_date_prototype_to_primitive (ecma_value_t this_arg, /**< this argument */
ecma_value_t hint_arg) /**< {"default", "number", "string"} */
{
if (ecma_is_value_object (this_arg) && ecma_is_value_string (hint_arg))
{
ecma_string_t *hint_str_p = ecma_get_string_from_value (hint_arg);
ecma_preferred_type_hint_t hint = ECMA_PREFERRED_TYPE_NUMBER;
if (hint_str_p == ecma_get_magic_string (LIT_MAGIC_STRING_STRING)
|| hint_str_p == ecma_get_magic_string (LIT_MAGIC_STRING_DEFAULT))
{
hint = ECMA_PREFERRED_TYPE_STRING;
}
else if (hint_str_p == ecma_get_magic_string (LIT_MAGIC_STRING_NUMBER))
{
hint = ECMA_PREFERRED_TYPE_NUMBER;
}
if (hint != ECMA_PREFERRED_TYPE_NO)
{
return ecma_op_general_object_ordinary_value (ecma_get_object_from_value (this_arg), hint);
}
}
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type in toPrimitive."));
} /* ecma_builtin_date_prototype_to_primitive */
#endif /* ENABLED (JERRY_ES2015) */
/**
* Dispatch get date functions
*
@ -192,7 +237,7 @@ ecma_builtin_date_prototype_dispatch_get (uint16_t builtin_routine_id, /**< buil
{
if (ecma_number_is_nan (date_num))
{
return ecma_make_magic_string_value (LIT_MAGIC_STRING_NAN);
return ecma_make_nan_value ();
}
switch (builtin_routine_id)
@ -560,15 +605,21 @@ ecma_builtin_date_prototype_dispatch_routine (uint16_t builtin_routine_id, /**<
return ecma_builtin_date_prototype_to_json (this_arg);
}
#if ENABLED (JERRY_ES2015)
if (JERRY_UNLIKELY (builtin_routine_id == ECMA_DATE_PROTOTYPE_TO_PRIMITIVE))
{
ecma_value_t argument = arguments_number > 0 ? arguments_list[0] : ECMA_VALUE_UNDEFINED;
return ecma_builtin_date_prototype_to_primitive (this_arg, argument);
}
#endif /* ENABLED (JERRY_ES2015) */
if (!ecma_is_value_object (this_arg)
|| !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_DATE_UL))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Date object expected"));
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a Date object"));
}
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) ecma_get_object_from_value (this_arg);
ecma_number_t *prim_value_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t,
ext_object_p->u.class_prop.u.value);

View File

@ -68,6 +68,9 @@ ROUTINE (LIT_MAGIC_STRING_SET_UTC_FULL_YEAR_UL, ECMA_DATE_PROTOTYPE_SET_UTC_FULL
ROUTINE (LIT_MAGIC_STRING_TO_UTC_STRING_UL, ECMA_DATE_PROTOTYPE_TO_UTC_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_ISO_STRING_UL, ECMA_DATE_PROTOTYPE_TO_ISO_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_JSON_UL, ECMA_DATE_PROTOTYPE_TO_JSON, 1, 1)
#if ENABLED (JERRY_ES2015)
ROUTINE_CONFIGURABLE_ONLY (LIT_GLOBAL_SYMBOL_TO_PRIMITIVE, ECMA_DATE_PROTOTYPE_TO_PRIMITIVE, 1, 1)
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_BUILTIN_ANNEXB)

View File

@ -15,6 +15,8 @@
#include <math.h>
#include "jcontext.h"
#include "ecma-function-object.h"
#include "ecma-alloc.h"
#include "ecma-builtin-helpers.h"
#include "ecma-conversion.h"
@ -52,22 +54,137 @@
static ecma_number_t
ecma_date_parse_date_chars (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */
const lit_utf8_byte_t *str_end_p, /**< pointer to the end of the string */
uint32_t num_of_chars) /**< number of characters to read and convert */
uint32_t num_of_chars, /**< number of characters to read and convert */
uint32_t min, /**< minimum valid value */
uint32_t max) /**< maximum valid value */
{
JERRY_ASSERT (num_of_chars > 0);
const lit_utf8_byte_t *str_start_p = *str_p;
while (num_of_chars--)
{
if (*str_p >= str_end_p || !lit_char_is_decimal_digit (lit_utf8_read_next (str_p)))
if (*str_p >= str_end_p || !lit_char_is_decimal_digit (lit_cesu8_read_next (str_p)))
{
return ecma_number_make_nan ();
}
}
return ecma_utf8_string_to_number (str_start_p, (lit_utf8_size_t) (*str_p - str_start_p));
ecma_number_t parsed_number = ecma_utf8_string_to_number (str_start_p, (lit_utf8_size_t) (*str_p - str_start_p));
if (parsed_number < min || parsed_number > max)
{
return ecma_number_make_nan ();
}
return parsed_number;
} /* ecma_date_parse_date_chars */
/**
* Helper function to try to parse a special chracter (+,-,T,Z,:,.) in a date string
*
* @return true if the first character is same as the expected, false otherwise
*/
static bool
ecma_date_parse_special_char (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */
const lit_utf8_byte_t *str_end_p, /**< pointer to the end of the string */
const lit_utf8_byte_t expected_char) /**< expected character */
{
if ((*str_p < str_end_p) && (**str_p == expected_char))
{
(*str_p)++;
return true;
}
return false;
} /* ecma_date_parse_special_char */
/**
* Helper function to try to parse a 4-5-6 digit year with optional negative sign in a date string
*
* Date.prototype.toString() and Date.prototype.toUTCString() emits year
* in this format and Date.parse() should parse this format too.
*
* @return the parsed year or NaN.
*/
static ecma_number_t
ecma_date_parse_year (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */
const lit_utf8_byte_t *str_end_p) /**< pointer to the end of the string */
{
bool is_year_sign_negative = ecma_date_parse_special_char (str_p, str_end_p, '-');
const lit_utf8_byte_t *str_start_p = *str_p;
int32_t parsed_year = 0;
while ((str_start_p - *str_p < 6) && (str_start_p < str_end_p) && lit_char_is_decimal_digit (*str_start_p))
{
parsed_year = 10 * parsed_year + *str_start_p - LIT_CHAR_0;
str_start_p++;
}
if (str_start_p - *str_p >=4)
{
*str_p = str_start_p;
if (is_year_sign_negative)
{
return -parsed_year;
}
return parsed_year;
}
return ecma_number_make_nan ();
} /* ecma_date_parse_year */
/**
* Helper function to try to parse a day name in a date string
* Valid day names: Sun, Mon, Tue, Wed, Thu, Fri, Sat
* See also:
* ECMA-262 v9, 20.3.4.41.2 Table 46
*
* @return true if the string starts with a valid day name, false otherwise
*/
static bool
ecma_date_parse_day_name (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */
const lit_utf8_byte_t *str_end_p) /**< pointer to the end of the string */
{
if (*str_p + 3 < str_end_p)
{
for (uint32_t i = 0; i < 7; i++)
{
if (!memcmp (day_names_p[i], *str_p, 3))
{
(*str_p) += 3;
return true;
}
}
}
return false;
} /* ecma_date_parse_day_name */
/**
* Helper function to try to parse a month name in a date string
* Valid month names: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
* See also:
* ECMA-262 v9, 20.3.4.41.2 Table 47
*
* @return number of the month if the string starts with a valid month name, 0 otherwise
*/
static uint32_t
ecma_date_parse_month_name (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */
const lit_utf8_byte_t *str_end_p) /**< pointer to the end of the string */
{
if (*str_p + 3 < str_end_p)
{
for (uint32_t i = 0; i < 12; i++)
{
if (!memcmp (month_names_p[i], *str_p, 3))
{
(*str_p) += 3;
return (i+1);
}
}
}
return 0;
} /* ecma_date_parse_month_name */
/**
* Calculate MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)) for Date constructor and UTC
*
@ -169,52 +286,31 @@ ecma_date_construct_helper (const ecma_value_t *args, /**< arguments passed to t
} /* ecma_date_construct_helper */
/**
* The Date object's 'parse' routine
* Helper function used by ecma_builtin_date_parse
*
* See also:
* ECMA-262 v5, 15.9.4.2
* ECMA-262 v5, 15.9.1.15
* ECMA-262 v5, 15.9.4.2 Date.parse (string)
* ECMA-262 v5, 15.9.1.15 Date Time String Format
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
* @return the parsed date as ecma_number_t or NaN otherwise
*/
static ecma_value_t
ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< string */
static ecma_number_t
ecma_builtin_date_parse_ISO_string_format (const lit_utf8_byte_t *date_str_curr_p,
const lit_utf8_byte_t *date_str_end_p)
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_number_t date_num = ecma_number_make_nan ();
/* Date Time String fromat (ECMA-262 v5, 15.9.1.15) */
ECMA_TRY_CATCH (date_str_value,
ecma_op_to_string (arg),
ret_value);
ecma_string_t *date_str_p = ecma_get_string_from_value (date_str_value);
ECMA_STRING_TO_UTF8_STRING (date_str_p, date_start_p, date_start_size);
const lit_utf8_byte_t *date_str_curr_p = date_start_p;
const lit_utf8_byte_t *date_str_end_p = date_start_p + date_start_size;
/* 1. read year */
uint32_t year_digits = 4;
bool year_sign = false; /* false: positive, true: negative */
if (*date_str_curr_p == '-' || *date_str_curr_p == '+')
bool is_year_sign_negative = ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '-');
if (is_year_sign_negative || ecma_date_parse_special_char (&date_str_curr_p, date_str_end_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)
ecma_number_t year = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, year_digits,
0, (year_digits == 4) ? 9999 : 999999);
if (is_year_sign_negative)
{
year = -year;
}
@ -226,40 +322,20 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
ecma_number_t time = ECMA_NUMBER_ZERO;
/* 2. read month if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == '-')
if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '-'))
{
/* eat up '-' */
date_str_curr_p++;
month = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (month > 12 || month < 1)
{
month = ecma_number_make_nan ();
}
month = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 1, 12);
}
/* 3. read day if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == '-')
if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '-'))
{
/* eat up '-' */
date_str_curr_p++;
day = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (day < 1 || day > 31)
{
day = ecma_number_make_nan ();
}
day = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 1, 31);
}
/* 4. read time if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == 'T')
if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, 'T'))
{
/* eat up 'T' */
date_str_curr_p++;
ecma_number_t hours = ECMA_NUMBER_ZERO;
ecma_number_t minutes = ECMA_NUMBER_ZERO;
ecma_number_t seconds = ECMA_NUMBER_ZERO;
@ -271,54 +347,28 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
if (remaining_length >= 5)
{
/* 4.1 read hours and minutes */
hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 24);
if (hours < 0 || hours > 24)
if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ':'))
{
hours = ecma_number_make_nan ();
}
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == ':')
{
/* eat up ':' */
date_str_curr_p++;
minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (minutes < 0 || minutes > 59)
{
minutes = ecma_number_make_nan ();
}
minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59);
/* 4.2 read seconds if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == ':')
if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ':'))
{
/* eat up ':' */
date_str_curr_p++;
seconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (seconds < 0 || seconds > 59)
{
seconds = ecma_number_make_nan ();
}
seconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59);
/* 4.3 read milliseconds if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == '.')
if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '.'))
{
/* eat up '.' */
date_str_curr_p++;
milliseconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 3);
if (milliseconds < 0)
{
milliseconds = ecma_number_make_nan ();
}
milliseconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 3, 0, 999);
}
}
}
else
{
minutes = ecma_number_make_nan ();
}
if (hours == 24 && (minutes != 0 || seconds != 0 || milliseconds != 0))
{
@ -333,62 +383,29 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
}
/* 4.4 read timezone if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == 'Z'
&& !ecma_number_is_nan (time))
if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, 'Z') && !ecma_number_is_nan (time))
{
date_str_curr_p++;
time = ecma_date_make_time (hours, minutes, seconds, milliseconds);
}
else if (date_str_curr_p < date_str_end_p
&& (*date_str_curr_p == '+' || *date_str_curr_p == '-'))
else
{
ecma_length_t remaining_date_length;
remaining_date_length = lit_utf8_string_length (date_str_curr_p,
(lit_utf8_size_t) (date_str_end_p - date_str_curr_p)) - 1;
if (remaining_date_length == 5)
bool is_timezone_sign_negative;
if ((lit_utf8_string_length (date_str_curr_p, (lit_utf8_size_t) (date_str_end_p - date_str_curr_p)) == 6)
&& ((is_timezone_sign_negative = ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '-'))
|| ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '+')))
{
bool is_negative = false;
if (*date_str_curr_p == '-')
{
is_negative = true;
}
/* eat up '+/-' */
date_str_curr_p++;
/* read hours and minutes */
hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 24);
if (hours < 0 || hours > 24)
{
hours = ecma_number_make_nan ();
}
else if (hours == 24)
if (hours == 24)
{
hours = ECMA_NUMBER_ZERO;
}
/* eat up ':' */
date_str_curr_p++;
minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (minutes < 0 || minutes > 59)
{
minutes = ecma_number_make_nan ();
}
if (is_negative)
{
time += ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO);
}
else
{
time -= ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO);
}
ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ':');
minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59);
ecma_number_t timezone_offset = ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO);
time += is_timezone_sign_negative ? timezone_offset : -timezone_offset;
}
}
}
@ -396,16 +413,232 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
if (date_str_curr_p >= date_str_end_p)
{
ecma_number_t date = ecma_date_make_day (year, month - 1, day);
date_num = ecma_date_make_date (date, time);
return ecma_date_make_date (date, time);
}
}
return ecma_number_make_nan ();
} /* ecma_builtin_date_parse_ISO_string_format */
/**
* Helper function used by ecma_builtin_date_parse
*
* See also:
* ECMA-262 v5, 15.9.4.2 Date.parse (string)
* ECMA-262 v9, 20.3.4.41 Date.prototype.toString ()
* ECMA-262 v9, 20.3.4.43 Date.prototype.toUTCString ()
*
* Used by: ecma_builtin_date_parse
*
* @return the parsed date as ecma_number_t or NaN otherwise
*/
static ecma_number_t
ecma_builtin_date_parse_toString_formats (const lit_utf8_byte_t *date_str_curr_p,
const lit_utf8_byte_t *date_str_end_p)
{
const ecma_number_t nan = ecma_number_make_nan ();
if (!ecma_date_parse_day_name (&date_str_curr_p, date_str_end_p))
{
return nan;
}
const bool is_toUTCString_format = ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ',');
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' '))
{
return nan;
}
ecma_number_t month = 0;
ecma_number_t day = 0;
if (is_toUTCString_format)
{
day = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 31);
if (ecma_number_is_nan (day))
{
return nan;
}
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' '))
{
return nan;
}
month = ecma_date_parse_month_name (&date_str_curr_p, date_str_end_p);
if (!(int) month)
{
return nan;
}
}
else
{
month = ecma_date_parse_month_name (&date_str_curr_p, date_str_end_p);
if (!(int) month)
{
return nan;
}
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' '))
{
return nan;
}
day = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 31);
if (ecma_number_is_nan (day))
{
return nan;
}
}
ret_value = ecma_make_number_value (date_num);
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' '))
{
return nan;
}
ecma_number_t year = ecma_date_parse_year (&date_str_curr_p, date_str_end_p);
if (ecma_number_is_nan (year))
{
return nan;
}
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' '))
{
return nan;
}
ecma_number_t hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 24);
if (ecma_number_is_nan (hours))
{
return nan;
}
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ':'))
{
return nan;
}
ecma_number_t minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59);
if (ecma_number_is_nan (minutes))
{
return nan;
}
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ':'))
{
return nan;
}
ecma_number_t seconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59);
if (ecma_number_is_nan (seconds))
{
return nan;
}
if (hours == 24 && (minutes != 0 || seconds != 0))
{
return nan;
}
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' '))
{
return nan;
}
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, 'G'))
{
return nan;
}
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, 'M'))
{
return nan;
}
if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, 'T'))
{
return nan;
}
ecma_number_t time = ecma_date_make_time (hours, minutes, seconds, 0);
if (!is_toUTCString_format)
{
bool is_timezone_sign_negative = ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '-');
if (!is_timezone_sign_negative && !ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '+'))
{
return nan;
}
hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 24);
if (ecma_number_is_nan (hours))
{
return nan;
}
if (hours == 24)
{
hours = ECMA_NUMBER_ZERO;
}
minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59);
if (ecma_number_is_nan (minutes))
{
return nan;
}
ecma_number_t timezone_offset = ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO);
time += is_timezone_sign_negative ? timezone_offset : -timezone_offset;
}
if (date_str_curr_p >= date_str_end_p)
{
ecma_number_t date = ecma_date_make_day (year, month - 1, day);
return ecma_date_make_date (date, time);
}
return nan;
} /* ecma_builtin_date_parse_toString_formats */
/**
* The Date object's 'parse' routine
*
* See also:
* ECMA-262 v5, 15.9.4.2 Date.parse (string)
* ECMA-262 v5, 15.9.1.15 Date Time String Format
* ECMA-262 v9, 20.3.4.41 Date.prototype.toString ()
* ECMA-262 v9, 20.3.4.43 Date.prototype.toUTCString ()
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< string */
{
JERRY_UNUSED (this_arg);
/* Date Time String fromat (ECMA-262 v5, 15.9.1.15) */
ecma_string_t *date_str_p = ecma_op_to_string (arg);
if (JERRY_UNLIKELY (date_str_p == NULL))
{
return ECMA_VALUE_ERROR;
}
ECMA_STRING_TO_UTF8_STRING (date_str_p, date_start_p, date_start_size);
const lit_utf8_byte_t *date_str_curr_p = date_start_p;
const lit_utf8_byte_t *date_str_end_p = date_start_p + date_start_size;
// try to parse date string as ISO string - ECMA-262 v5, 15.9.1.15
ecma_number_t ret_value = ecma_builtin_date_parse_ISO_string_format (date_str_curr_p, date_str_end_p);
if (ecma_number_is_nan (ret_value))
{
// try to parse date string in Date.prototype.toString() or toUTCString() format
ret_value = ecma_builtin_date_parse_toString_formats (date_str_curr_p, date_str_end_p);
}
ECMA_FINALIZE_UTF8_STRING (date_start_p, date_start_size);
ECMA_FINALIZE (date_str_value);
return ret_value;
ecma_deref_ecma_string (date_str_p);
return ecma_make_number_value (ret_value);
} /* ecma_builtin_date_parse */
/**
@ -503,6 +736,17 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
ecma_number_t prim_value_num = ECMA_NUMBER_ZERO;
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_DATE_PROTOTYPE);
#if ENABLED (JERRY_ES2015)
if (JERRY_CONTEXT (current_new_target))
{
prototype_obj_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_new_target),
ECMA_BUILTIN_ID_DATE_PROTOTYPE);
if (JERRY_UNLIKELY (prototype_obj_p == NULL))
{
return ECMA_VALUE_ERROR;
}
}
#endif /* !(ENABLED (JERRY_ES2015) */
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
sizeof (ecma_extended_object_t),
ECMA_OBJECT_TYPE_CLASS);
@ -579,7 +823,12 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
JERRY_ASSERT (ECMA_IS_VALUE_ERROR (ret_value));
ecma_deref_object (obj_p);
}
#if ENABLED (JERRY_ES2015)
if (JERRY_CONTEXT (current_new_target))
{
ecma_deref_object (prototype_obj_p);
}
#endif /* !(ENABLED (JERRY_ES2015) */
return ret_value;
} /* ecma_builtin_date_dispatch_construct */
@ -589,4 +838,7 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
* @}
*/
#undef BREAK_IF_FALSE
#undef BREAK_IF_NAN
#endif /* ENABLED (JERRY_BUILTIN_DATE) */

View File

@ -28,7 +28,7 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
7,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_DEFAULT_LENGTH)
ROUTINE (LIT_MAGIC_STRING_PARSE, ecma_builtin_date_parse, 1, 1)
ROUTINE (LIT_MAGIC_STRING_UTC_U, ecma_builtin_date_utc, NON_FIXED, 7)

View File

@ -20,6 +20,7 @@
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "lit-char-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
@ -43,6 +44,34 @@
* @{
*/
/**
* Helper method to get a property value from an error object
*
* @return ecma_string_t
*/
static ecma_string_t *
ecma_builtin_error_prototype_object_to_string_helper (ecma_object_t *obj_p, /**< error object */
lit_magic_string_id_t property_id, /**< property id */
lit_magic_string_id_t default_value) /**< default prop value */
{
ecma_value_t prop_value = ecma_op_object_get_by_magic_id (obj_p, property_id);
if (ECMA_IS_VALUE_ERROR (prop_value))
{
return NULL;
}
if (ecma_is_value_undefined (prop_value))
{
return ecma_get_magic_string (default_value);
}
ecma_string_t *ret_str_p = ecma_op_to_string (prop_value);
ecma_free_value (prop_value);
return ret_str_p;
} /* ecma_builtin_error_prototype_object_to_string_helper */
/**
* The Error.prototype object's 'toString' routine
*
@ -55,125 +84,52 @@
static ecma_value_t
ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 2. */
if (!ecma_is_value_object (this_arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an object."));
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an object."));
}
else
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
ecma_string_t *name_string_p = ecma_builtin_error_prototype_object_to_string_helper (obj_p,
LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_ERROR_UL);
if (JERRY_UNLIKELY (name_string_p == NULL))
{
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
ECMA_TRY_CATCH (name_get_ret_value,
ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_NAME),
ret_value);
ecma_value_t name_to_str_completion;
if (ecma_is_value_undefined (name_get_ret_value))
{
name_to_str_completion = ecma_make_magic_string_value (LIT_MAGIC_STRING_ERROR_UL);
}
else
{
name_to_str_completion = ecma_op_to_string (name_get_ret_value);
}
if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (name_to_str_completion)))
{
ret_value = ecma_copy_value (name_to_str_completion);
}
else
{
ECMA_TRY_CATCH (msg_get_ret_value,
ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_MESSAGE),
ret_value);
ecma_value_t msg_to_str_completion;
if (ecma_is_value_undefined (msg_get_ret_value))
{
msg_to_str_completion = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
}
else
{
msg_to_str_completion = ecma_op_to_string (msg_get_ret_value);
}
if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (msg_to_str_completion)))
{
ret_value = ecma_copy_value (msg_to_str_completion);
}
else
{
ecma_string_t *name_string_p = ecma_get_string_from_value (name_to_str_completion);
ecma_string_t *msg_string_p = ecma_get_string_from_value (msg_to_str_completion);
ecma_string_t *ret_str_p;
if (ecma_string_is_empty (name_string_p))
{
ret_str_p = msg_string_p;
ecma_ref_ecma_string (ret_str_p);
}
else if (ecma_string_is_empty (msg_string_p))
{
ret_str_p = name_string_p;
ecma_ref_ecma_string (ret_str_p);
}
else
{
const lit_utf8_size_t name_size = ecma_string_get_size (name_string_p);
const lit_utf8_size_t msg_size = ecma_string_get_size (msg_string_p);
const lit_utf8_size_t colon_size = lit_get_magic_string_size (LIT_MAGIC_STRING_COLON_CHAR);
const lit_utf8_size_t space_size = lit_get_magic_string_size (LIT_MAGIC_STRING_SPACE_CHAR);
const lit_utf8_size_t size = name_size + msg_size + colon_size + space_size;
JMEM_DEFINE_LOCAL_ARRAY (ret_str_buffer, size, lit_utf8_byte_t);
lit_utf8_byte_t *ret_str_buffer_p = ret_str_buffer;
lit_utf8_size_t bytes = ecma_string_copy_to_cesu8_buffer (name_string_p, ret_str_buffer_p, name_size);
JERRY_ASSERT (bytes == name_size);
ret_str_buffer_p = ret_str_buffer_p + bytes;
JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);
ret_str_buffer_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_COLON_CHAR,
ret_str_buffer_p,
colon_size);
JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);
ret_str_buffer_p = lit_copy_magic_string_to_buffer (LIT_MAGIC_STRING_SPACE_CHAR,
ret_str_buffer_p,
space_size);
JERRY_ASSERT (ret_str_buffer_p <= ret_str_buffer + size);
bytes = ecma_string_copy_to_cesu8_buffer (msg_string_p, ret_str_buffer_p, msg_size);
JERRY_ASSERT (bytes == msg_size);
ret_str_buffer_p = ret_str_buffer_p + bytes;
JERRY_ASSERT (ret_str_buffer_p == ret_str_buffer + size);
ret_str_p = ecma_new_ecma_string_from_utf8 (ret_str_buffer,
size);
JMEM_FINALIZE_LOCAL_ARRAY (ret_str_buffer);
}
ret_value = ecma_make_string_value (ret_str_p);
}
ecma_free_value (msg_to_str_completion);
ECMA_FINALIZE (msg_get_ret_value);
}
ecma_free_value (name_to_str_completion);
ECMA_FINALIZE (name_get_ret_value);
return ECMA_VALUE_ERROR;
}
return ret_value;
ecma_string_t *msg_string_p = ecma_builtin_error_prototype_object_to_string_helper (obj_p,
LIT_MAGIC_STRING_MESSAGE,
LIT_MAGIC_STRING__EMPTY);
if (JERRY_UNLIKELY (msg_string_p == NULL))
{
ecma_deref_ecma_string (name_string_p);
return ECMA_VALUE_ERROR;
}
if (ecma_string_is_empty (name_string_p))
{
return ecma_make_string_value (msg_string_p);
}
if (ecma_string_is_empty (msg_string_p))
{
return ecma_make_string_value (name_string_p);
}
ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (name_string_p);
ecma_stringbuilder_append_raw (&builder, (const lit_utf8_byte_t *)": ", 2);
ecma_stringbuilder_append (&builder, msg_string_p);
ecma_deref_ecma_string (name_string_p);
ecma_deref_ecma_string (msg_string_p);
return ecma_make_string_value (ecma_stringbuilder_finalize (&builder));
} /* ecma_builtin_error_prototype_object_to_string */
/**

View File

@ -22,10 +22,9 @@
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
/* ECMA-262 v5, 15.11.3 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_DEFAULT_LENGTH)
/* Object properties:
* (property name, object pointer getter) */

View File

@ -24,10 +24,9 @@
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
/* ECMA-262 v5, 15.11.3 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_DEFAULT_LENGTH)
/* Object properties:
* (property name, object pointer getter) */

View File

@ -23,8 +23,10 @@
#include "ecma-helpers.h"
#include "ecma-function-object.h"
#include "ecma-objects.h"
#include "ecma-proxy-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#include "ecma-builtin-function-prototype.h"
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
@ -44,6 +46,9 @@ enum
ECMA_FUNCTION_PROTOTYPE_CALL,
ECMA_FUNCTION_PROTOTYPE_APPLY,
ECMA_FUNCTION_PROTOTYPE_BIND,
#if ENABLED (JERRY_ES2015)
ECMA_FUNCTION_PROTOTYPE_SYMBOL_HAS_INSTANCE,
#endif /* ENABLED (JERRY_ES2015) */
};
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-function-prototype.inc.h"
@ -89,7 +94,7 @@ ecma_builtin_function_prototype_object_to_string (void)
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_value_t
ecma_builtin_function_prototype_object_apply (ecma_object_t *func_obj_p, /**< this argument object */
ecma_value_t arg1, /**< first argument */
ecma_value_t arg2) /**< second argument */
@ -108,27 +113,15 @@ ecma_builtin_function_prototype_object_apply (ecma_object_t *func_obj_p, /**< th
ecma_object_t *obj_p = ecma_get_object_from_value (arg2);
/* 4. */
ecma_value_t length_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LENGTH);
if (ECMA_IS_VALUE_ERROR (length_value))
/* 4-5. */
uint32_t length;
ecma_value_t len_value = ecma_op_object_get_length (obj_p, &length);
if (ECMA_IS_VALUE_ERROR (len_value))
{
return length_value;
return len_value;
}
ecma_number_t length_number;
ecma_value_t get_result = ecma_get_number (length_value, &length_number);
ecma_free_value (length_value);
if (ECMA_IS_VALUE_ERROR (get_result))
{
return get_result;
}
JERRY_ASSERT (ecma_is_value_empty (get_result));
/* 5. */
const uint32_t length = ecma_number_to_uint32 (length_number);
if (length >= ECMA_FUNCTION_APPLY_ARGUMENT_COUNT_LIMIT)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Too many arguments declared for Function.apply()."));
@ -142,9 +135,7 @@ ecma_builtin_function_prototype_object_apply (ecma_object_t *func_obj_p, /**< th
/* 7. */
for (index = 0; index < length; index++)
{
ecma_string_t *curr_idx_str_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t get_value = ecma_op_object_get (obj_p, curr_idx_str_p);
ecma_deref_ecma_string (curr_idx_str_p);
ecma_value_t get_value = ecma_op_object_get_by_uint32_index (obj_p, index);
if (ECMA_IS_VALUE_ERROR (get_value))
{
@ -218,49 +209,83 @@ ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /**
ecma_length_t arguments_number) /**< number of arguments */
{
/* 4. 11. 18. */
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
ecma_object_t *prototype_obj_p;
#if !ENABLED (JERRY_ES2015)
prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
#else /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (ECMA_OBJECT_IS_PROXY (this_arg_obj_p))
{
ecma_value_t proto = ecma_proxy_object_get_prototype_of (this_arg_obj_p);
if (ECMA_IS_VALUE_ERROR (proto))
{
return proto;
}
prototype_obj_p = ecma_is_value_null (proto) ? NULL : ecma_get_object_from_value (proto);
}
else
{
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (this_arg_obj_p);
if (proto_cp != JMEM_CP_NULL)
{
prototype_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp);
ecma_ref_object (prototype_obj_p);
}
else
{
prototype_obj_p = NULL;
}
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
#endif /* !ENABLED (JERRY_ES2015) */
ecma_object_t *function_p;
ecma_extended_object_t *ext_function_p;
ecma_bound_function_t *bound_func_p;
if (arguments_number == 0
|| (arguments_number == 1 && !ecma_is_value_integer_number (arguments_list_p[0])))
{
function_p = ecma_create_object (prototype_obj_p,
sizeof (ecma_extended_object_t),
sizeof (ecma_bound_function_t),
ECMA_OBJECT_TYPE_BOUND_FUNCTION);
/* 8. */
ext_function_p = (ecma_extended_object_t *) function_p;
ECMA_SET_INTERNAL_VALUE_POINTER (ext_function_p->u.bound_function.target_function,
this_arg_obj_p);
bound_func_p = (ecma_bound_function_t *) function_p;
ECMA_SET_NON_NULL_POINTER_TAG (bound_func_p->header.u.bound_function.target_function,
this_arg_obj_p,
0);
ext_function_p->u.bound_function.args_len_or_this = ECMA_VALUE_UNDEFINED;
bound_func_p->header.u.bound_function.args_len_or_this = ECMA_VALUE_UNDEFINED;
if (arguments_number != 0)
{
ext_function_p->u.bound_function.args_len_or_this = ecma_copy_value_if_not_object (arguments_list_p[0]);
bound_func_p->header.u.bound_function.args_len_or_this = ecma_copy_value_if_not_object (arguments_list_p[0]);
}
}
else
{
JERRY_ASSERT (arguments_number > 0);
size_t obj_size = sizeof (ecma_extended_object_t) + (arguments_number * sizeof (ecma_value_t));
size_t obj_size = sizeof (ecma_bound_function_t) + (arguments_number * sizeof (ecma_value_t));
function_p = ecma_create_object (prototype_obj_p,
obj_size,
ECMA_OBJECT_TYPE_BOUND_FUNCTION);
/* 8. */
ext_function_p = (ecma_extended_object_t *) function_p;
ECMA_SET_INTERNAL_VALUE_POINTER (ext_function_p->u.bound_function.target_function,
this_arg_obj_p);
bound_func_p = (ecma_bound_function_t *) function_p;
ECMA_SET_NON_NULL_POINTER_TAG (bound_func_p->header.u.bound_function.target_function,
this_arg_obj_p,
0);
/* NOTE: This solution provides temporary false data about the object's size
but prevents GC from freeing it until it's not fully initialized. */
ext_function_p->u.bound_function.args_len_or_this = ECMA_VALUE_UNDEFINED;
ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
bound_func_p->header.u.bound_function.args_len_or_this = ECMA_VALUE_UNDEFINED;
ecma_value_t *args_p = (ecma_value_t *) (bound_func_p + 1);
for (ecma_length_t i = 0; i < arguments_number; i++)
{
@ -268,8 +293,9 @@ ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /**
}
ecma_value_t args_len_or_this = ecma_make_integer_value ((ecma_integer_value_t) arguments_number);
ext_function_p->u.bound_function.args_len_or_this = args_len_or_this;
bound_func_p->header.u.bound_function.args_len_or_this = args_len_or_this;
}
#if defined(JERRY_FUNCTION_NAME) && !defined(__APPLE__)
ecma_object_type_t obj_type = ecma_get_object_type(this_arg_obj_p);
if (obj_type == ECMA_OBJECT_TYPE_BOUND_FUNCTION || obj_type == ECMA_OBJECT_TYPE_FUNCTION) {
@ -285,6 +311,48 @@ ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /**
}
#endif
#if ENABLED (JERRY_ES2015)
ecma_integer_value_t len = 0;
ecma_string_t *len_string = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);
ecma_property_descriptor_t prop_desc;
ecma_value_t status = ecma_op_object_get_own_property_descriptor (this_arg_obj_p,
len_string,
&prop_desc);
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (ECMA_IS_VALUE_ERROR (status))
{
return status;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
if (ecma_is_value_true (status))
{
ecma_free_property_descriptor (&prop_desc);
ecma_value_t len_value = ecma_op_object_get (this_arg_obj_p,
len_string);
if (ECMA_IS_VALUE_ERROR (len_value))
{
return len_value;
}
if (ecma_is_value_number (len_value))
{
ecma_number_t len_num;
ecma_op_to_integer (len_value, &len_num);
len = (ecma_integer_value_t) len_num;
}
}
bound_func_p->target_length = len;
if (prototype_obj_p != NULL)
{
ecma_deref_object (prototype_obj_p);
}
#endif /* ENABLED (JERRY_ES2015) */
/*
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
*
@ -339,6 +407,13 @@ ecma_builtin_function_prototype_dispatch_routine (uint16_t builtin_routine_id, /
{
if (!ecma_op_is_callable (this_arg))
{
#if ENABLED (JERRY_ES2015)
if (JERRY_UNLIKELY (builtin_routine_id == ECMA_FUNCTION_PROTOTYPE_SYMBOL_HAS_INSTANCE))
{
return ECMA_VALUE_FALSE;
}
#endif /* ENABLED (JERRY_ES2015) */
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a function."));
}
@ -364,6 +439,12 @@ ecma_builtin_function_prototype_dispatch_routine (uint16_t builtin_routine_id, /
{
return ecma_builtin_function_prototype_object_bind (func_obj_p, arguments_list_p, arguments_number);
}
#if ENABLED (JERRY_ES2015)
case ECMA_FUNCTION_PROTOTYPE_SYMBOL_HAS_INSTANCE:
{
return ecma_op_object_has_instance (func_obj_p, arguments_list_p[0]);
}
#endif /* ENABLED (JERRY_ES2015) */
default:
{
JERRY_UNREACHABLE ();

View File

@ -0,0 +1,23 @@
/* 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.
*/
#ifndef ECMA_BUILTIN_FUNCTION_PROTOTYPE_H
#define ECMA_BUILTIN_FUNCTION_PROTOTYPE_H
ecma_value_t ecma_builtin_function_prototype_object_apply (ecma_object_t *func_obj_p,
ecma_value_t arg1,
ecma_value_t arg2);
#endif /* !ECMA_BUILTIN_FUNCTION_PROTOTYPE_H */

View File

@ -30,10 +30,9 @@ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
/* Number properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.3.4 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
0,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_DEFAULT_LENGTH)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
@ -42,4 +41,20 @@ ROUTINE (LIT_MAGIC_STRING_APPLY, ECMA_FUNCTION_PROTOTYPE_APPLY, 2, 2)
ROUTINE (LIT_MAGIC_STRING_CALL, ECMA_FUNCTION_PROTOTYPE_CALL, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_BIND, ECMA_FUNCTION_PROTOTYPE_BIND, NON_FIXED, 1)
#if ENABLED (JERRY_ES2015)
/**
* ECMA-262 v6.0 19.2.3.6 @@hasInstance
* the property attributes are: { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
*/
ROUTINE_WITH_FLAGS (LIT_GLOBAL_SYMBOL_HAS_INSTANCE, ECMA_FUNCTION_PROTOTYPE_SYMBOL_HAS_INSTANCE, 1, 1, 0 /* flags */)
ACCESSOR_BUILTIN_FUNCTION (LIT_MAGIC_STRING_ARGUMENTS,
ECMA_BUILTIN_ID_TYPE_ERROR_THROWER,
ECMA_BUILTIN_ID_TYPE_ERROR_THROWER,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
ACCESSOR_BUILTIN_FUNCTION (LIT_MAGIC_STRING_CALLER,
ECMA_BUILTIN_ID_TYPE_ERROR_THROWER,
ECMA_BUILTIN_ID_TYPE_ERROR_THROWER,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -59,60 +59,6 @@ ecma_builtin_function_dispatch_call (const ecma_value_t *arguments_list_p, /**<
return ecma_builtin_function_dispatch_construct (arguments_list_p, arguments_list_len);
} /* ecma_builtin_function_dispatch_call */
/**
* Helper method to count and convert the arguments for the Function constructor call.
*
* Performs the operation described in ECMA 262 v5.1 15.3.2.1 steps 5.a-d
*
*
* @return ecma value - concatenated arguments as a string.
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_function_helper_get_function_arguments (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
if (arguments_list_len <= 1)
{
return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
}
ecma_value_t final_str = ecma_op_to_string (arguments_list_p[0]);
if (arguments_list_len == 2 || ECMA_IS_VALUE_ERROR (final_str))
{
return final_str;
}
for (ecma_length_t idx = 1; idx < arguments_list_len - 1; idx++)
{
ecma_value_t new_str = ecma_op_to_string (arguments_list_p[idx]);
if (ECMA_IS_VALUE_ERROR (new_str))
{
ecma_free_value (final_str);
/* Return with the error. */
final_str = new_str;
break;
}
ecma_string_t *final_str_p = ecma_get_string_from_value (final_str);
final_str_p = ecma_append_magic_string_to_string (final_str_p,
LIT_MAGIC_STRING_COMMA_CHAR);
ecma_string_t *new_str_p = ecma_get_string_from_value (new_str);
final_str_p = ecma_concat_ecma_strings (final_str_p, new_str_p);
ecma_deref_ecma_string (new_str_p);
final_str = ecma_make_string_value (final_str_p);
}
return final_str;
} /* ecma_builtin_function_helper_get_function_arguments */
/**
* Handle calling [[Construct]] of built-in Function object
*
@ -125,71 +71,7 @@ ecma_value_t
ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
ecma_value_t arguments_value = ecma_builtin_function_helper_get_function_arguments (arguments_list_p,
arguments_list_len);
if (ECMA_IS_VALUE_ERROR (arguments_value))
{
return arguments_value;
}
ecma_value_t function_body_value;
if (arguments_list_len > 0)
{
function_body_value = ecma_op_to_string (arguments_list_p[arguments_list_len - 1]);
if (ECMA_IS_VALUE_ERROR (function_body_value))
{
ecma_free_value (arguments_value);
return function_body_value;
}
}
else
{
/* Very unlikely code path, not optimized. */
function_body_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
}
ecma_string_t *arguments_str_p = ecma_get_string_from_value (arguments_value);
ecma_string_t *function_body_str_p = ecma_get_string_from_value (function_body_value);
ECMA_STRING_TO_UTF8_STRING (arguments_str_p, arguments_buffer_p, arguments_buffer_size);
ECMA_STRING_TO_UTF8_STRING (function_body_str_p, function_body_buffer_p, function_body_buffer_size);
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
ecma_compiled_code_t *bytecode_data_p = NULL;
ecma_value_t ret_value = parser_parse_script (arguments_buffer_p,
arguments_buffer_size,
function_body_buffer_p,
function_body_buffer_size,
ECMA_PARSE_NO_OPTS,
&bytecode_data_p);
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
JERRY_ASSERT (ecma_is_value_true (ret_value));
ecma_object_t *func_obj_p = ecma_op_create_function_object (ecma_get_global_environment (),
bytecode_data_p);
ecma_bytecode_deref (bytecode_data_p);
ret_value = ecma_make_object_value (func_obj_p);
}
ECMA_FINALIZE_UTF8_STRING (function_body_buffer_p, function_body_buffer_size);
ECMA_FINALIZE_UTF8_STRING (arguments_buffer_p, arguments_buffer_size);
ecma_deref_ecma_string (arguments_str_p);
ecma_deref_ecma_string (function_body_str_p);
return ret_value;
return ecma_op_create_dynamic_function (arguments_list_p, arguments_list_len, ECMA_PARSE_NO_OPTS);
} /* ecma_builtin_function_dispatch_construct */
/**

View File

@ -30,9 +30,8 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
/* Number properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.3.3.2 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_DEFAULT_LENGTH)
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -0,0 +1,72 @@
/* 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-globals.h"
#if ENABLED (JERRY_ES2015)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#include "ecma-function-object.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-generator-function.inc.h"
#define BUILTIN_UNDERSCORED_ID generator_function
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup generator ECMA GeneratorFunction object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in GeneratorFunction object
*
* @return constructed generator function object - if success
* raised error otherwise
*/
ecma_value_t
ecma_builtin_generator_function_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_op_create_dynamic_function (arguments_list_p, arguments_list_len, ECMA_PARSE_GENERATOR_FUNCTION);
} /* ecma_builtin_generator_function_dispatch_call */
/**
* Handle calling [[Construct]] of built-in GeneratorFunction object
*
* @return constructed generator function object - if success
* raised error otherwise
*/
ecma_value_t
ecma_builtin_generator_function_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_generator_function_dispatch_call (arguments_list_p, arguments_list_len);
} /* ecma_builtin_generator_function_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015) */

View File

@ -0,0 +1,41 @@
/* 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.
*/
/*
* %GeneratorFunction% built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 25.2.2 */
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_GENERATOR_FUNCTION_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v6, 25.2.2.1 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v6, 25.2.2.2 */
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_GENERATOR,
ECMA_PROPERTY_FIXED)
#endif /* ENABLED (JERRY_ES2015) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -0,0 +1,250 @@
/* 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-builtins.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-iterator-object.h"
#include "jcontext.h"
#include "opcodes.h"
#include "vm-defines.h"
#if ENABLED (JERRY_ES2015)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-generator-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID generator_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup generator ECMA Generator.prototype object built-in
* @{
*/
/**
* Byte code sequence which returns from the generator.
*/
static const uint8_t ecma_builtin_generator_prototype_return[2] =
{
CBC_EXT_OPCODE, CBC_EXT_RETURN
};
/**
* Byte code sequence which throws an exception.
*/
static const uint8_t ecma_builtin_generator_prototype_throw[1] =
{
CBC_THROW
};
/**
* Helper function for next / return / throw
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_generator_prototype_object_do (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg, /**< argument */
ecma_iterator_command_type_t resume_mode) /**< resume mode */
{
vm_executable_object_t *executable_object_p = NULL;
if (ecma_is_value_object (this_arg))
{
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_GENERATOR_UL)
{
executable_object_p = (vm_executable_object_t *) ext_object_p;
}
}
}
if (executable_object_p == NULL)
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a generator object."));
}
if (executable_object_p->extended_object.u.class_prop.extra_info & ECMA_EXECUTABLE_OBJECT_RUNNING)
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Generator is currently under execution."));
}
if (executable_object_p->extended_object.u.class_prop.extra_info & ECMA_EXECUTABLE_OBJECT_COMPLETED)
{
return ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE);
}
arg = ecma_copy_value (arg);
while (true)
{
if (executable_object_p->extended_object.u.class_prop.extra_info & ECMA_GENERATOR_ITERATE_AND_YIELD)
{
ecma_value_t iterator = executable_object_p->extended_object.u.class_prop.u.value;
bool done = false;
ecma_value_t result = ecma_op_iterator_do (resume_mode, iterator, arg, &done);
ecma_free_value (arg);
if (ECMA_IS_VALUE_ERROR (result))
{
arg = result;
}
else if (done)
{
arg = ecma_op_iterator_value (result);
ecma_free_value (result);
if (resume_mode == ECMA_ITERATOR_THROW)
{
/* This part is changed in the newest ECMAScript standard.
* It was ECMA_ITERATOR_RETURN in ES2015, but I think it was a typo. */
resume_mode = ECMA_ITERATOR_NEXT;
}
}
else
{
return result;
}
executable_object_p->extended_object.u.class_prop.extra_info &= (uint16_t) ~ECMA_GENERATOR_ITERATE_AND_YIELD;
if (ECMA_IS_VALUE_ERROR (arg))
{
arg = jcontext_take_exception ();
resume_mode = ECMA_ITERATOR_THROW;
}
}
if (resume_mode == ECMA_ITERATOR_RETURN)
{
executable_object_p->frame_ctx.byte_code_p = ecma_builtin_generator_prototype_return;
}
else if (resume_mode == ECMA_ITERATOR_THROW)
{
executable_object_p->frame_ctx.byte_code_p = ecma_builtin_generator_prototype_throw;
}
ecma_value_t value = opfunc_resume_executable_object (executable_object_p, arg);
if (ECMA_IS_VALUE_ERROR (value))
{
return value;
}
bool done = (executable_object_p->extended_object.u.class_prop.extra_info & ECMA_EXECUTABLE_OBJECT_COMPLETED);
if (!done)
{
const uint8_t *byte_code_p = executable_object_p->frame_ctx.byte_code_p;
JERRY_ASSERT (byte_code_p[-2] == CBC_EXT_OPCODE
&& (byte_code_p[-1] == CBC_EXT_YIELD || byte_code_p[-1] == CBC_EXT_YIELD_ITERATOR));
if (byte_code_p[-1] == CBC_EXT_YIELD_ITERATOR)
{
ecma_value_t iterator = ecma_op_get_iterator (value, ECMA_VALUE_EMPTY);
ecma_free_value (value);
if (ECMA_IS_VALUE_ERROR (iterator))
{
resume_mode = ECMA_ITERATOR_THROW;
arg = jcontext_take_exception ();
continue;
}
ecma_deref_object (ecma_get_object_from_value (iterator));
executable_object_p->extended_object.u.class_prop.extra_info |= ECMA_GENERATOR_ITERATE_AND_YIELD;
executable_object_p->extended_object.u.class_prop.u.value = iterator;
arg = ECMA_VALUE_UNDEFINED;
continue;
}
}
ecma_value_t result = ecma_create_iter_result_object (value, ecma_make_boolean_value (done));
ecma_fast_free_value (value);
return result;
}
} /* ecma_builtin_generator_prototype_object_do */
/**
* The Generator.prototype object's 'next' routine
*
* See also:
* ECMA-262 v6, 25.3.1.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_generator_prototype_object_next (ecma_value_t this_arg, /**< this argument */
ecma_value_t next_arg) /**< next argument */
{
return ecma_builtin_generator_prototype_object_do (this_arg, next_arg, ECMA_ITERATOR_NEXT);
} /* ecma_builtin_generator_prototype_object_next */
/**
* The Generator.prototype object's 'return' routine
*
* See also:
* ECMA-262 v6, 25.3.1.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_generator_prototype_object_return (ecma_value_t this_arg, /**< this argument */
ecma_value_t return_arg) /**< return argument */
{
return ecma_builtin_generator_prototype_object_do (this_arg, return_arg, ECMA_ITERATOR_RETURN);
} /* ecma_builtin_generator_prototype_object_return */
/**
* The Generator.prototype object's 'throw' routine
*
* See also:
* ECMA-262 v6, 25.3.1.4
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_generator_prototype_object_throw (ecma_value_t this_arg, /**< this argument */
ecma_value_t throw_arg) /**< throw argument */
{
return ecma_builtin_generator_prototype_object_do (this_arg, throw_arg, ECMA_ITERATOR_THROW);
} /* ecma_builtin_generator_prototype_object_throw */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015) */

View File

@ -0,0 +1,45 @@
/* 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.
*/
/*
* Generator.prototype built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v6, 25.3.1.5 */
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_GENERATOR_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v6, 25.2.3.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_GENERATOR,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_NEXT, ecma_builtin_generator_prototype_object_next, 1, 1)
ROUTINE (LIT_MAGIC_STRING_RETURN, ecma_builtin_generator_prototype_object_return, 1, 1)
ROUTINE (LIT_MAGIC_STRING_THROW, ecma_builtin_generator_prototype_object_throw, 1, 1)
#endif /* ENABLED (JERRY_ES2015) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -0,0 +1,43 @@
/* 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-globals.h"
#if ENABLED (JERRY_ES2015)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-generator.inc.h"
#define BUILTIN_UNDERSCORED_ID generator
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup generator ECMA Generator object built-in
* @{
*/
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015) */

View File

@ -0,0 +1,41 @@
/* 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.
*/
/*
* %Generator% built-in description (GeneratorFunction.prototype)
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 25.3.2.3.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_GENERATOR_FUNCTION,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v6, 25.3.2.3.2 */
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v6, 25.3.2.3.3 */
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_GENERATOR_FUNCTION_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -100,386 +100,17 @@ ecma_builtin_global_object_eval (ecma_value_t x) /**< routine's first argument *
parse_opts |= ECMA_PARSE_STRICT_MODE;
}
#if ENABLED (JERRY_ES2015_CLASS)
#if ENABLED (JERRY_ES2015)
if (vm_is_direct_eval_form_call ())
{
parse_opts |= ECMA_GET_SUPER_EVAL_PARSER_OPTS ();
parse_opts |= ECMA_GET_LOCAL_PARSE_OPTS ();
}
#endif /* ENABLED (JERRY_ES2015_CLASS) */
#endif /* ENABLED (JERRY_ES2015) */
/* steps 2 to 8 */
return ecma_op_eval (ecma_get_string_from_value (x), parse_opts);
} /* ecma_builtin_global_object_eval */
/**
* The Global object's 'parseInt' routine
*
* See also:
* ECMA-262 v5, 15.1.2.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_global_object_parse_int (const lit_utf8_byte_t *string_buff, /**< routine's first argument's
* string buffer */
lit_utf8_size_t string_buff_size, /**< routine's first argument's
* string buffer's size */
ecma_value_t radix) /**< routine's second argument */
{
if (string_buff_size <= 0)
{
return ecma_make_nan_value ();
}
const lit_utf8_byte_t *string_curr_p = string_buff;
/* 2. Remove leading whitespace. */
ecma_string_trim_helper (&string_curr_p, &string_buff_size);
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)
{
return ecma_make_nan_value ();
}
/* 3. */
int sign = 1;
/* 4. */
ecma_char_t current = lit_utf8_read_next (&string_curr_p);
if (current == LIT_CHAR_MINUS)
{
sign = -1;
}
/* 5. */
if (current == LIT_CHAR_MINUS || current == LIT_CHAR_PLUS)
{
start_p = string_curr_p;
if (string_curr_p < string_end_p)
{
current = lit_utf8_read_next (&string_curr_p);
}
}
/* 6. */
ecma_number_t radix_num;
radix = ecma_get_number (radix, &radix_num);
if (!ecma_is_value_empty (radix))
{
return radix;
}
int32_t rad = ecma_number_to_int32 (radix_num);
/* 7.*/
bool strip_prefix = true;
/* 8. */
if (rad != 0)
{
/* 8.a */
if (rad < 2 || rad > 36)
{
return ecma_make_nan_value ();
}
/* 8.b */
else if (rad != 16)
{
strip_prefix = false;
}
}
/* 9. */
else
{
rad = 10;
}
/* 10. */
if (strip_prefix
&& ((end_p - start_p) >= 2)
&& (current == LIT_CHAR_0))
{
ecma_char_t next = *string_curr_p;
if (next == LIT_CHAR_LOWERCASE_X || next == LIT_CHAR_UPPERCASE_X)
{
/* Skip the 'x' or 'X' characters. */
start_p = ++string_curr_p;
rad = 16;
}
}
/* 11. Check if characters are in [0, Radix - 1]. We also convert them to number values in the process. */
string_curr_p = start_p;
while (string_curr_p < string_end_p)
{
ecma_char_t current_char = *string_curr_p++;
int32_t current_number;
if ((current_char >= LIT_CHAR_LOWERCASE_A && current_char <= LIT_CHAR_LOWERCASE_Z))
{
current_number = current_char - LIT_CHAR_LOWERCASE_A + 10;
}
else if ((current_char >= LIT_CHAR_UPPERCASE_A && current_char <= LIT_CHAR_UPPERCASE_Z))
{
current_number = current_char - LIT_CHAR_UPPERCASE_A + 10;
}
else if (lit_char_is_decimal_digit (current_char))
{
current_number = current_char - LIT_CHAR_0;
}
else
{
/* Not a valid number char, set value to radix so it fails to pass as a valid character. */
current_number = rad;
}
if (!(current_number < rad))
{
end_p = --string_curr_p;
break;
}
}
/* 12. */
if (end_p == start_p)
{
return ecma_make_nan_value ();
}
ecma_number_t value = ECMA_NUMBER_ZERO;
ecma_number_t multiplier = 1.0f;
/* 13. and 14. */
string_curr_p = end_p;
while (string_curr_p > start_p)
{
ecma_char_t current_char = *(--string_curr_p);
ecma_number_t current_number = ECMA_NUMBER_MINUS_ONE;
if ((current_char >= LIT_CHAR_LOWERCASE_A && current_char <= LIT_CHAR_LOWERCASE_Z))
{
current_number = (ecma_number_t) current_char - LIT_CHAR_LOWERCASE_A + 10;
}
else if ((current_char >= LIT_CHAR_UPPERCASE_A && current_char <= LIT_CHAR_UPPERCASE_Z))
{
current_number = (ecma_number_t) current_char - LIT_CHAR_UPPERCASE_A + 10;
}
else
{
JERRY_ASSERT (lit_char_is_decimal_digit (current_char));
current_number = (ecma_number_t) current_char - LIT_CHAR_0;
}
value += current_number * multiplier;
multiplier *= (ecma_number_t) rad;
}
/* 15. */
if (sign < 0)
{
value *= (ecma_number_t) sign;
}
return ecma_make_number_value (value);
} /* ecma_builtin_global_object_parse_int */
/**
* The Global object's 'parseFloat' routine
*
* See also:
* ECMA-262 v5, 15.1.2.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_global_object_parse_float (const lit_utf8_byte_t *string_buff, /**< routine's first argument's
* string buffer */
lit_utf8_size_t string_buff_size) /**< routine's first argument's
* string buffer's size */
{
if (string_buff_size <= 0)
{
return ecma_make_nan_value ();
}
const lit_utf8_byte_t *str_curr_p = string_buff;
/* 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;
bool sign = false;
ecma_char_t current;
if (str_curr_p < str_end_p)
{
/* Check if sign is present. */
current = *str_curr_p;
if (current == LIT_CHAR_MINUS)
{
sign = true;
}
if (current == LIT_CHAR_MINUS || current == LIT_CHAR_PLUS)
{
/* Set starting position to be after the sign character. */
start_p = ++str_curr_p;
}
}
const lit_utf8_byte_t *infinity_str_p = lit_get_magic_string_utf8 (LIT_MAGIC_STRING_INFINITY_UL);
lit_utf8_byte_t *infinity_str_curr_p = (lit_utf8_byte_t *) infinity_str_p;
lit_utf8_byte_t *infinity_str_end_p = infinity_str_curr_p + sizeof (*infinity_str_p);
/* Check if string is equal to "Infinity". */
while (str_curr_p < str_end_p
&& *str_curr_p++ == *infinity_str_curr_p++)
{
if (infinity_str_curr_p == infinity_str_end_p)
{
/* String matched Infinity. */
return ecma_make_number_value (ecma_number_make_infinity (sign));
}
}
/* Reset to starting position. */
str_curr_p = start_p;
/* String ended after sign character, or was empty after removing leading whitespace. */
if (str_curr_p >= str_end_p)
{
return ecma_make_nan_value ();
}
/* Reset to starting position. */
str_curr_p = start_p;
current = *str_curr_p;
bool has_whole_part = false;
bool has_fraction_part = false;
/* Check digits of whole part. */
if (lit_char_is_decimal_digit (current))
{
has_whole_part = true;
str_curr_p++;
while (str_curr_p < str_end_p)
{
current = *str_curr_p++;
if (!lit_char_is_decimal_digit (current))
{
str_curr_p--;
break;
}
}
}
/* Set end position to the end of whole part. */
end_p = str_curr_p;
if (str_curr_p < str_end_p)
{
current = *str_curr_p;
/* Check decimal point. */
if (current == LIT_CHAR_DOT)
{
str_curr_p++;
if (str_curr_p < str_end_p)
{
current = *str_curr_p;
if (lit_char_is_decimal_digit (current))
{
has_fraction_part = true;
/* Check digits of fractional part. */
while (str_curr_p < str_end_p)
{
current = *str_curr_p++;
if (!lit_char_is_decimal_digit (current))
{
str_curr_p--;
break;
}
}
/* Set end position to end of fraction part. */
end_p = str_curr_p;
}
}
}
}
if (str_curr_p < str_end_p)
{
current = *str_curr_p++;
}
/* Check exponent. */
if ((current == LIT_CHAR_LOWERCASE_E || current == LIT_CHAR_UPPERCASE_E)
&& (has_whole_part || has_fraction_part)
&& str_curr_p < str_end_p)
{
current = *str_curr_p++;
/* Check sign of exponent. */
if ((current == LIT_CHAR_PLUS || current == LIT_CHAR_MINUS)
&& str_curr_p < str_end_p)
{
current = *str_curr_p++;
}
if (lit_char_is_decimal_digit (current))
{
/* Check digits of exponent part. */
while (str_curr_p < str_end_p)
{
current = *str_curr_p++;
if (!lit_char_is_decimal_digit (current))
{
str_curr_p--;
break;
}
}
/* Set end position to end of exponent part. */
end_p = str_curr_p;
}
}
/* String did not contain a valid number. */
if (start_p == end_p)
{
return ecma_make_nan_value ();
}
/* 5. */
ecma_number_t ret_num = ecma_utf8_string_to_number (start_p, (lit_utf8_size_t) (end_p - start_p));
if (sign)
{
ret_num *= ECMA_NUMBER_MINUS_ONE;
}
return ecma_make_number_value (ret_num);
} /* ecma_builtin_global_object_parse_float */
/**
* The Global object's 'isNaN' routine
*
@ -592,13 +223,13 @@ ecma_builtin_global_object_decode_uri_helper (lit_utf8_byte_t *input_start_p, /*
continue;
}
ecma_char_t decoded_byte;
if (!lit_read_code_unit_from_hex (input_char_p + 1, 2, &decoded_byte))
uint32_t hex_value = lit_char_hex_lookup (input_char_p + 1, input_end_p, 2);
if (hex_value == UINT32_MAX)
{
return ecma_raise_uri_error (ECMA_ERR_MSG ("Invalid hexadecimal value."));
}
ecma_char_t decoded_byte = (ecma_char_t) hex_value;
input_char_p += URI_ENCODED_BYTE_SIZE;
if (decoded_byte <= LIT_UTF8_1_BYTE_CODE_POINT_MAX)
@ -641,20 +272,18 @@ ecma_builtin_global_object_decode_uri_helper (lit_utf8_byte_t *input_start_p, /*
/* Input decode. */
if (*input_char_p != '%')
{
*output_char_p = *input_char_p;
output_char_p++;
input_char_p++;
*output_char_p++ = *input_char_p++;
continue;
}
ecma_char_t decoded_byte;
if (!lit_read_code_unit_from_hex (input_char_p + 1, 2, &decoded_byte))
uint32_t hex_value = lit_char_hex_lookup (input_char_p + 1, input_end_p, 2);
if (hex_value == UINT32_MAX)
{
ret_value = ecma_raise_uri_error (ECMA_ERR_MSG ("Invalid hexadecimal value."));
break;
}
ecma_char_t decoded_byte = (ecma_char_t) hex_value;
input_char_p += URI_ENCODED_BYTE_SIZE;
if (decoded_byte <= LIT_UTF8_1_BYTE_CODE_POINT_MAX)
@ -706,17 +335,16 @@ ecma_builtin_global_object_decode_uri_helper (lit_utf8_byte_t *input_start_p, /*
}
else
{
ecma_char_t chr;
hex_value = lit_char_hex_lookup (input_char_p + 1, input_end_p, 2);
if (!lit_read_code_unit_from_hex (input_char_p + 1, 2, &chr)
|| ((chr & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER))
if (hex_value == UINT32_MAX || (hex_value & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
{
is_valid = false;
break;
}
octets[i] = (lit_utf8_byte_t) chr;
input_char_p += URI_ENCODED_BYTE_SIZE;
octets[i] = (lit_utf8_byte_t) hex_value;
}
}
@ -970,7 +598,7 @@ ecma_builtin_global_object_escape (lit_utf8_byte_t *input_start_p, /**< routine'
while (input_curr_p < input_end_p)
{
ecma_char_t chr = lit_utf8_read_next (&input_curr_p);
ecma_char_t chr = lit_cesu8_read_next (&input_curr_p);
if (chr <= LIT_UTF8_1_BYTE_CODE_POINT_MAX)
{
@ -1005,7 +633,7 @@ ecma_builtin_global_object_escape (lit_utf8_byte_t *input_start_p, /**< routine'
while (input_curr_p < input_end_p)
{
ecma_char_t chr = lit_utf8_read_next (&input_curr_p);
ecma_char_t chr = lit_cesu8_read_next (&input_curr_p);
if (chr <= LIT_UTF8_1_BYTE_CODE_POINT_MAX)
{
@ -1091,7 +719,7 @@ ecma_builtin_global_object_unescape (lit_utf8_byte_t *input_start_p, /**< routin
while (input_curr_p < input_end_p)
{
/* 6. */
ecma_char_t chr = lit_utf8_read_next (&input_curr_p);
ecma_char_t chr = lit_cesu8_read_next (&input_curr_p);
/* 7-8. */
if (status == 0 && chr == LIT_CHAR_PERCENT)
@ -1185,15 +813,13 @@ ecma_builtin_global_dispatch_routine (uint16_t builtin_routine_id, /**< built-in
return ecma_builtin_global_object_is_finite (arg_num);
}
ecma_value_t string_value = ecma_op_to_string (routine_arg_1);
ecma_string_t *str_p = ecma_op_to_string (routine_arg_1);
if (ECMA_IS_VALUE_ERROR (string_value))
if (JERRY_UNLIKELY (str_p == NULL))
{
return string_value;
return ECMA_VALUE_ERROR;
}
ecma_string_t *str_p = ecma_get_string_from_value (string_value);
ecma_value_t ret_value;
if (builtin_routine_id <= ECMA_GLOBAL_PARSE_FLOAT)
@ -1202,15 +828,15 @@ ecma_builtin_global_dispatch_routine (uint16_t builtin_routine_id, /**< built-in
if (builtin_routine_id == ECMA_GLOBAL_PARSE_INT)
{
ret_value = ecma_builtin_global_object_parse_int (string_buff,
string_buff_size,
arguments_list_p[1]);
ret_value = ecma_number_parse_int (string_buff,
string_buff_size,
arguments_list_p[1]);
}
else
{
JERRY_ASSERT (builtin_routine_id == ECMA_GLOBAL_PARSE_FLOAT);
ret_value = ecma_builtin_global_object_parse_float (string_buff,
string_buff_size);
ret_value = ecma_number_parse_float (string_buff,
string_buff_size);
}
ECMA_FINALIZE_UTF8_STRING (string_buff, string_buff_size);

View File

@ -139,6 +139,12 @@ OBJECT_VALUE (LIT_MAGIC_STRING_MATH_UL,
ECMA_BUILTIN_ID_MATH,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_BUILTIN_MATH) */
#if ENABLED (JERRY_ES2015_BUILTIN_REFLECT)
/* ECMA-262 v6, 26.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_REFLECT_UL,
ECMA_BUILTIN_ID_REFLECT,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_REFLECT) */
#if ENABLED (JERRY_BUILTIN_JSON)
/* ECMA-262 v5, 15.1.5.2 */
@ -212,12 +218,26 @@ OBJECT_VALUE (LIT_MAGIC_STRING_SET_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP)
/* ECMA-262 v6, 23.1.1.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_WEAKMAP_UL,
ECMA_BUILTIN_ID_WEAKMAP,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */
#if ENABLED (JERRY_ES2015_BUILTIN_WEAKSET)
/* ECMA-262 v6, 23.1.1.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_WEAKSET_UL,
ECMA_BUILTIN_ID_WEAKSET,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 19.4.1.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_SYMBOL_UL,
ECMA_BUILTIN_ID_SYMBOL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/* ECMA-262 v6, 23.1.1.1 */
@ -226,19 +246,31 @@ OBJECT_VALUE (LIT_MAGIC_STRING_DATAVIEW_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
/* ECMA-262 v6, 26.2.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_PROXY_UL,
ECMA_BUILTIN_ID_PROXY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_EVAL, ECMA_GLOBAL_EVAL, 1, 1)
ROUTINE (LIT_MAGIC_STRING_PARSE_FLOAT, ECMA_GLOBAL_PARSE_FLOAT, 1, 1)
ROUTINE (LIT_MAGIC_STRING_IS_NAN, ECMA_GLOBAL_IS_NAN, 1, 1)
ROUTINE (LIT_MAGIC_STRING_IS_FINITE, ECMA_GLOBAL_IS_FINITE, 1, 1)
ROUTINE (LIT_MAGIC_STRING_DECODE_URI, ECMA_GLOBAL_DECODE_URI, 1, 1)
ROUTINE (LIT_MAGIC_STRING_DECODE_URI_COMPONENT, ECMA_GLOBAL_DECODE_URI_COMPONENT, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ENCODE_URI, ECMA_GLOBAL_ENCODE_URI, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ENCODE_URI_COMPONENT, ECMA_GLOBAL_ENCODE_URI_COMPONENT, 1, 1)
ROUTINE (LIT_MAGIC_STRING_PARSE_INT, ECMA_GLOBAL_PARSE_INT, 2, 2)
#if ENABLED (JERRY_ES2015)
INTRINSIC_PROPERTY (LIT_MAGIC_STRING_PARSE_FLOAT, LIT_MAGIC_STRING_PARSE_FLOAT, ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
INTRINSIC_PROPERTY (LIT_MAGIC_STRING_PARSE_INT, LIT_MAGIC_STRING_PARSE_INT, ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#else /* !ENABLED (JERRY_ES2015) */
ROUTINE (LIT_MAGIC_STRING_PARSE_FLOAT, ECMA_GLOBAL_PARSE_FLOAT, 1, 1)
ROUTINE (LIT_MAGIC_STRING_PARSE_INT, ECMA_GLOBAL_PARSE_INT, 2, 2)
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_BUILTIN_ANNEXB)
ROUTINE (LIT_MAGIC_STRING_ESCAPE, ECMA_GLOBAL_ESCAPE, 1, 1)
ROUTINE (LIT_MAGIC_STRING_UNESCAPE, ECMA_GLOBAL_UNESCAPE, 1, 1)

View File

@ -33,6 +33,16 @@
* @{
*/
const char day_names_p[7][3] =
{
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
const char month_names_p[12][3] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
/**
* Helper function to get day number from time value.
*
@ -583,16 +593,6 @@ static ecma_value_t
ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
const char *format_p) /**< format buffer */
{
static const char * const day_names_p[8] =
{
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char * const month_names_p[13] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
const uint32_t date_buffer_length = 37;
JERRY_VLA (lit_utf8_byte_t, date_buffer, date_buffer_length);
@ -702,7 +702,7 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
number_length = 3;
break;
}
case LIT_CHAR_LOWERCASE_Z: /* Time zone minutes part. */
case LIT_CHAR_LOWERCASE_Z: /* Time zone hours part. */
{
int32_t time_zone = (int32_t) ecma_date_local_time_zone_adjustment (datetime_number);
@ -722,7 +722,7 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
}
default:
{
JERRY_ASSERT (*format_p == LIT_CHAR_UPPERCASE_Z); /* Time zone seconds part. */
JERRY_ASSERT (*format_p == LIT_CHAR_UPPERCASE_Z); /* Time zone minutes part. */
int32_t time_zone = (int32_t) ecma_date_local_time_zone_adjustment (datetime_number);
@ -731,7 +731,7 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
time_zone = -time_zone;
}
number = time_zone % (int32_t) ECMA_DATE_MS_PER_HOUR;
number = time_zone % (int32_t) ECMA_DATE_MS_PER_HOUR / (int32_t) ECMA_DATE_MS_PER_MINUTE;
number_length = 2;
break;
}
@ -741,13 +741,9 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
if (str_p != NULL)
{
/* Print string values. */
do
{
*dest_p++ = (lit_utf8_byte_t) *str_p++;
}
while (*str_p != LIT_CHAR_NULL);
/* Print string values: month or day name which is always 3 characters */
memcpy (dest_p, str_p, 3);
dest_p += 3;
continue;
}
@ -797,7 +793,7 @@ ecma_value_t
ecma_date_value_to_string (ecma_number_t datetime_number) /**< datetime */
{
datetime_number += ecma_date_local_time_zone_adjustment (datetime_number);
return ecma_date_to_string_format (datetime_number, "$W $M $D $Y $h:$m:$s GMT$z:$Z");
return ecma_date_to_string_format (datetime_number, "$W $M $D $Y $h:$m:$s GMT$z$Z");
} /* ecma_date_value_to_string */
/**

View File

@ -47,31 +47,26 @@ ecma_builtin_helper_error_dispatch_call (ecma_standard_error_t error_type, /**<
if (arguments_list_len != 0
&& !ecma_is_value_undefined (arguments_list_p[0]))
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_string_t *message_string_p = ecma_op_to_string (arguments_list_p[0]);
ECMA_TRY_CATCH (msg_str_value,
ecma_op_to_string (arguments_list_p[0]),
ret_value);
if (JERRY_UNLIKELY (message_string_p == NULL))
{
return ECMA_VALUE_ERROR;
}
ecma_string_t *message_string_p = ecma_get_string_from_value (msg_str_value);
ecma_object_t *new_error_object_p = ecma_new_standard_error_with_message (error_type,
message_string_p);
ret_value = ecma_make_object_value (new_error_object_p);
ECMA_FINALIZE (msg_str_value);
return ret_value;
}
else
{
ecma_object_t *new_error_object_p = ecma_new_standard_error (error_type);
ecma_deref_ecma_string (message_string_p);
return ecma_make_object_value (new_error_object_p);
}
ecma_object_t *new_error_object_p = ecma_new_standard_error (error_type);
return ecma_make_object_value (new_error_object_p);
} /* ecma_builtin_helper_error_dispatch_call */
/**
* @}
* @}
*/

View File

@ -25,11 +25,19 @@
#define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
#ifndef SYMBOL_VALUE
#define SYMBOL_VALUE(name, desc_string_id)
#define SYMBOL_VALUE(symbol, desc_magic_string_id)
#endif /* !SYMBOL_VALUE */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#ifndef INTRINSIC_PROPERTY
#define INTRINSIC_PROPERTY(name, magic_string_id, prop_attributes)
#endif /* !INTRINSIC_PROPERTY */
#ifndef ACCESSOR_BUILTIN_FUNCTION_OBJECT
#define ACCESSOR_BUILTIN_FUNCTION_OBJECT(name, getter_builtin_id, setter_builtin_id, prop_attributes)
#endif /* !ACCESSOR_BUILTIN_FUNCTION_OBJECT */
#endif /* ENABLED (JERRY_ES2015) */
#ifndef OBJECT_VALUE
#define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
@ -43,6 +51,10 @@
#define ROUTINE_CONFIGURABLE_ONLY(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE_CONFIGURABLE_ONLY */
#ifndef ROUTINE_WITH_FLAGS
#define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags)
#endif /* !ROUTINE_WITH_FLAGS */
#ifndef ACCESSOR_READ_WRITE
#define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes)
#endif /* !ACCESSOR_READ_WRITE */

View File

@ -16,11 +16,14 @@
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
#undef SYMBOL_VALUE
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#undef INTRINSIC_PROPERTY
#undef ACCESSOR_BUILTIN_FUNCTION_OBJECT
#endif /* ENABLED (JERRY_ES2015) */
#undef OBJECT_VALUE
#undef ROUTINE
#undef ROUTINE_CONFIGURABLE_ONLY
#undef ROUTINE_WITH_FLAGS
#undef ACCESSOR_READ_WRITE
#undef ACCESSOR_READ_ONLY

View File

@ -18,6 +18,7 @@
#include "ecma-alloc.h"
#include "ecma-array-object.h"
#include "ecma-builtins.h"
#include "ecma-builtin-object.h"
#include "ecma-conversion.h"
#include "ecma-function-object.h"
#include "ecma-exceptions.h"
@ -27,6 +28,7 @@
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "lit-magic-strings.h"
#include "lit-char-helpers.h"
/** \addtogroup ecma ECMA
* @{
@ -35,7 +37,7 @@
* @{
*/
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/**
* Helper function for Object.prototype.toString routine when
* the @@toStringTag property is present
@ -96,7 +98,7 @@ ecma_builtin_helper_object_to_string_tag_helper (ecma_value_t tag_value) /**< st
return ecma_make_string_value (ret_string_p);
} /* ecma_builtin_helper_object_to_string_tag_helper */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* Common implementation of the Object.prototype.toString routine
@ -140,8 +142,8 @@ ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this arg
type_string = ecma_object_get_class_name (obj_p);
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
ecma_value_t tag_value = ecma_op_object_get_by_symbol_id (obj_p, LIT_MAGIC_STRING_TO_STRING_TAG);
#if ENABLED (JERRY_ES2015)
ecma_value_t tag_value = ecma_op_object_get_by_symbol_id (obj_p, LIT_GLOBAL_SYMBOL_TO_STRING_TAG);
if (ECMA_IS_VALUE_ERROR (tag_value))
{
@ -156,7 +158,7 @@ ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this arg
}
ecma_free_value (tag_value);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
ecma_deref_object (obj_p);
}
@ -201,63 +203,68 @@ ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this arg
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_string_t *
ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /**< this object */
uint32_t index) /**< array index */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t index_value = ecma_op_object_get_by_uint32_index (obj_p, index);
ECMA_TRY_CATCH (index_value,
ecma_op_object_get (obj_p, index_string_p),
ret_value);
if (ECMA_IS_VALUE_ERROR (index_value))
{
return NULL;
}
if (ecma_is_value_undefined (index_value) || ecma_is_value_null (index_value))
{
ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
return ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
}
else
ecma_value_t index_obj_value = ecma_op_to_object (index_value);
if (ECMA_IS_VALUE_ERROR (index_obj_value))
{
ECMA_TRY_CATCH (index_obj_value,
ecma_op_to_object (index_value),
ret_value);
ecma_object_t *index_obj_p = ecma_get_object_from_value (index_obj_value);
ECMA_TRY_CATCH (to_locale_value,
ecma_op_object_get_by_magic_id (index_obj_p, LIT_MAGIC_STRING_TO_LOCALE_STRING_UL),
ret_value);
if (ecma_op_is_callable (to_locale_value))
{
ecma_object_t *locale_func_obj_p = ecma_get_object_from_value (to_locale_value);
ECMA_TRY_CATCH (call_value,
ecma_op_function_call (locale_func_obj_p,
ecma_make_object_value (index_obj_p),
NULL,
0),
ret_value);
ret_value = ecma_op_to_string (call_value);
ECMA_FINALIZE (call_value);
}
else
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("'toLocaleString' is missing or not a function."));
}
ECMA_FINALIZE (to_locale_value);
ECMA_FINALIZE (index_obj_value);
ecma_free_value (index_value);
return NULL;
}
ECMA_FINALIZE (index_value);
ecma_string_t *ret_string_p = NULL;
ecma_object_t *index_obj_p = ecma_get_object_from_value (index_obj_value);
ecma_value_t to_locale_value = ecma_op_object_get_by_magic_id (index_obj_p, LIT_MAGIC_STRING_TO_LOCALE_STRING_UL);
ecma_deref_ecma_string (index_string_p);
if (ECMA_IS_VALUE_ERROR (to_locale_value))
{
goto cleanup;
}
return ret_value;
if (!ecma_op_is_callable (to_locale_value))
{
ecma_free_value (to_locale_value);
ecma_raise_type_error (ECMA_ERR_MSG ("'toLocaleString' is missing or not a function."));
goto cleanup;
}
ecma_object_t *locale_func_obj_p = ecma_get_object_from_value (to_locale_value);
ecma_value_t call_value = ecma_op_function_call (locale_func_obj_p,
index_obj_value,
NULL,
0);
ecma_deref_object (locale_func_obj_p);
if (ECMA_IS_VALUE_ERROR (call_value))
{
goto cleanup;
}
ret_string_p = ecma_op_to_string (call_value);
ecma_free_value (call_value);
cleanup:
ecma_deref_object (index_obj_p);
ecma_free_value (index_value);
return ret_string_p;
} /* ecma_builtin_helper_get_to_locale_string_at_index */
/**
* The Object.keys and Object.getOwnPropertyNames routine's common part.
*
@ -274,26 +281,23 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
{
JERRY_ASSERT (obj_p != NULL);
ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, opts);
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (props_p == NULL)
{
return ECMA_VALUE_ERROR;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
if (props_p->item_count == 0)
{
ecma_collection_destroy (props_p);
return new_array;
return ecma_op_create_array_object (NULL, 0, false);
}
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);
ecma_value_t new_array = ecma_op_create_array_object (props_p->buffer_p, props_p->item_count, false);
ecma_collection_free (props_p);
return new_array;
} /* ecma_builtin_helper_object_get_properties */
@ -301,93 +305,49 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
/**
* Helper function to normalizing an array index
*
* This function clamps the given index to the [0, length] range.
* 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
* ECMA-262 v5, 15.4.4.14 steps 5
* ECMA-262 v5, 15.5.4.13 steps 4, 5 (part 2) and 6-7
* ECMA-262 v5, 15.4.4.10 steps 5, 6, 7 part 2, 8
* ECMA-262 v5, 15.4.4.12 steps 5, 6
* ECMA-262 v5, 15.5.4.13 steps 4 - 7
* ECMA-262 v6, 22.1.3.6 steps 5 - 7, 8 part 2, 9, 10
* ECMA-262 v6, 22.1.3.3 steps 5 - 10, 11 part 2, 12, 13
* ECMA-262 v6, 22.2.3.5 steps 5 - 10, 11 part 2, 12, 13
* ECMA-262 v6, 22.2.3.23 steps 5 - 10
* ECMA-262 v6, 24.1.4.3 steps 6 - 8, 9 part 2, 10, 11
* ECMA-262 v6, 22.2.3.26 steps 7 - 9, 10 part 2, 11, 12
* ECMA-262 v6, 22.2.3.8 steps 5 - 7, 8 part 2, 9, 10
*
* Used by:
* - The Array.prototype.slice routine.
* - 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
* - The Array.prototype.fill routine.
* - The Array.prototype.copyWithin routine.
* - The TypedArray.prototype.copyWithin routine.
* - The TypedArray.prototype.slice routine.
* - The ArrayBuffer.prototype.slice routine.
* - The TypedArray.prototype.subarray routine.
* - The TypedArray.prototype.fill routine.
*
* @return uint32_t - the normalized value of the index
* @return ECMA_VALUE_EMPTY if successful
* conversion error otherwise
*/
uint32_t
ecma_builtin_helper_array_index_normalize (ecma_number_t index, /**< index */
ecma_builtin_helper_array_index_normalize (ecma_value_t arg, /**< index */
uint32_t length, /**< array's length */
bool is_last_index_of) /**< true - normalize for lastIndexOf method*/
uint32_t *number_p) /**< [out] uint32_t */
{
uint32_t norm_index;
ecma_number_t to_int;
if (!ecma_number_is_nan (index))
if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arg, &to_int)))
{
if (ecma_number_is_zero (index))
{
norm_index = 0;
}
else if (ecma_number_is_infinity (index))
{
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
{
if (ecma_number_is_negative (index))
{
ecma_number_t index_neg = -index;
if (is_last_index_of)
{
norm_index = length - ecma_number_to_uint32 (index_neg);
}
else
{
if (index_neg > length)
{
norm_index = 0;
}
else
{
norm_index = length - ecma_number_to_uint32 (index_neg);
}
}
}
else
{
if (index > length)
{
norm_index = is_last_index_of ? length - 1 : length;
}
else
{
norm_index = ecma_number_to_uint32 (index);
}
}
}
}
else
{
norm_index = 0;
return ECMA_VALUE_ERROR;
}
return norm_index;
*number_p = ((to_int < 0) ? (uint32_t) JERRY_MAX ((length + to_int), 0)
: (uint32_t) JERRY_MIN (to_int, length));
return ECMA_VALUE_EMPTY;
} /* ecma_builtin_helper_array_index_normalize */
/**
@ -403,80 +363,80 @@ ecma_builtin_helper_array_index_normalize (ecma_number_t index, /**< index */
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */
ecma_builtin_helper_array_concat_value (ecma_object_t *array_obj_p, /**< array */
uint32_t *length_p, /**< [in,out] array's length */
ecma_value_t value) /**< value to concat */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 5.b */
if (ecma_is_value_object (value)
&& (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_ARRAY_UL))
#if ENABLED (JERRY_ES2015)
ecma_value_t is_spreadable = ecma_op_is_concat_spreadable (value);
if (ECMA_IS_VALUE_ERROR (is_spreadable))
{
/* 5.b.ii */
ECMA_TRY_CATCH (arg_len_value,
ecma_op_object_get_by_magic_id (ecma_get_object_from_value (value),
LIT_MAGIC_STRING_LENGTH),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_len_number, arg_len_value, ret_value);
return is_spreadable;
}
uint32_t arg_len = ecma_number_to_uint32 (arg_len_number);
bool spread_object = is_spreadable == ECMA_VALUE_TRUE;
#else /* !ENABLED (JERRY_ES2015) */
bool spread_object = ecma_is_value_true (ecma_is_value_array (value));
#endif /* ENABLED (JERRY_ES2015) */
/* 5.b.iii */
for (uint32_t array_index = 0;
array_index < arg_len && ecma_is_value_empty (ret_value);
array_index++)
if (spread_object)
{
ecma_object_t *obj_p = ecma_get_object_from_value (value);
#if ENABLED (JERRY_ES2015)
uint32_t arg_len;
ecma_value_t error = ecma_op_object_get_length (obj_p, &arg_len);
if (ECMA_IS_VALUE_ERROR (error))
{
return error;
}
#else /* !ENABLED (JERRY_ES2015) */
/* 5.b.ii */
uint32_t arg_len = ecma_array_get_length (obj_p);
#endif /* ENABLED (JERRY_ES2015) */
/* 5.b.iii */
for (uint32_t array_index = 0; array_index < arg_len; array_index++)
{
ecma_string_t *array_index_string_p = ecma_new_ecma_string_from_uint32 (array_index);
/* 5.b.iii.2 */
ECMA_TRY_CATCH (get_value,
ecma_op_object_find (ecma_get_object_from_value (value),
array_index_string_p),
ret_value);
ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, array_index);
if (ecma_is_value_found (get_value))
if (ECMA_IS_VALUE_ERROR (get_value))
{
/* 5.b.iii.3.a */
ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 (*length_p + array_index);
/* 5.b.iii.3.b */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
ecma_value_t put_comp = ecma_builtin_helper_def_prop (obj_p,
new_array_index_string_p,
get_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (new_array_index_string_p);
return get_value;
}
ECMA_FINALIZE (get_value);
if (!ecma_is_value_found (get_value))
{
continue;
}
ecma_deref_ecma_string (array_index_string_p);
/* 5.b.iii.3.b */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (array_obj_p,
*length_p + array_index,
get_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_free_value (get_value);
}
*length_p += arg_len;
ECMA_OP_TO_NUMBER_FINALIZE (arg_len_number);
ECMA_FINALIZE (arg_len_value);
}
else
{
ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 ((*length_p)++);
/* 5.c.i */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
ecma_value_t put_comp = ecma_builtin_helper_def_prop (obj_p,
new_array_index_string_p,
value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (new_array_index_string_p);
return ECMA_VALUE_EMPTY;
}
return ret_value;
/* 5.c.i */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (array_obj_p,
(*length_p)++,
value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
return ECMA_VALUE_EMPTY;
} /* ecma_builtin_helper_array_concat_value */
/**
@ -559,31 +519,48 @@ ecma_builtin_helper_string_prototype_object_index_of (ecma_string_t *original_st
/* 5 (indexOf) -- 6 (lastIndexOf) */
const ecma_length_t original_len = ecma_string_get_length (original_str_p);
#if ENABLED (JERRY_ES2015_BUILTIN)
#if ENABLED (JERRY_ES2015)
/* 4, 6 (startsWith, includes, endsWith) */
if (mode >= ECMA_STRING_STARTS_WITH
&& (ecma_is_value_object (arg1)
&& ecma_object_class_is (ecma_get_object_from_value (arg1), LIT_MAGIC_STRING_REGEXP_UL)))
if (mode >= ECMA_STRING_STARTS_WITH)
{
JERRY_ASSERT (ECMA_STRING_LAST_INDEX_OF < mode && mode <= ECMA_STRING_ENDS_WITH);
return ecma_raise_type_error (ECMA_ERR_MSG ("Search string can't be of type: RegExp"));
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
ecma_value_t regexp = ecma_op_is_regexp (arg1);
/* 3 */
ecma_value_t search_str_val = ecma_op_to_string (arg1);
if (ECMA_IS_VALUE_ERROR (regexp))
{
return regexp;
}
if (ECMA_IS_VALUE_ERROR (search_str_val))
{
return search_str_val;
if (regexp == ECMA_VALUE_TRUE)
{
JERRY_ASSERT (ECMA_STRING_LAST_INDEX_OF < mode && mode <= ECMA_STRING_ENDS_WITH);
return ecma_raise_type_error (ECMA_ERR_MSG ("Search string can't be of type: RegExp"));
}
}
#endif /* ENABLED (JERRY_ES2015) */
/* 7, 8 */
ecma_string_t *search_str_p = ecma_get_string_from_value (search_str_val);
ecma_string_t *search_str_p = ecma_op_to_string (arg1);
if (JERRY_UNLIKELY (search_str_p == NULL))
{
return ECMA_VALUE_ERROR;
}
/* 4 (indexOf, lastIndexOf), 9 (startsWith, includes), 10 (endsWith) */
ecma_number_t pos_num;
ecma_value_t ret_value = ecma_get_number (arg2, &pos_num);
ecma_value_t ret_value;
#if ENABLED (JERRY_ES2015)
if (mode > ECMA_STRING_LAST_INDEX_OF)
{
ret_value = ecma_op_to_integer (arg2, &pos_num);
}
else
{
#endif /* ENABLED (JERRY_ES2015) */
ret_value = ecma_get_number (arg2, &pos_num);
#if ENABLED (JERRY_ES2015)
}
#endif /* ENABLED (JERRY_ES2015) */
/* 10 (startsWith, includes), 11 (endsWith) */
if (ECMA_IS_VALUE_ERROR (ret_value))
@ -605,10 +582,12 @@ ecma_builtin_helper_string_prototype_object_index_of (ecma_string_t *original_st
switch (mode)
{
#if ENABLED (JERRY_ES2015_BUILTIN)
#if ENABLED (JERRY_ES2015)
case ECMA_STRING_STARTS_WITH:
{
if (pos_num + start > original_len)
const ecma_length_t search_len = ecma_string_get_length (search_str_p);
if (search_len + start > original_len)
{
break;
}
@ -656,7 +635,7 @@ ecma_builtin_helper_string_prototype_object_index_of (ecma_string_t *original_st
}
break;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
#endif /* ENABLED (JERRY_ES2015) */
case ECMA_STRING_INDEX_OF:
case ECMA_STRING_LAST_INDEX_OF:
@ -710,7 +689,7 @@ ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, /**< index
if (!search_len)
{
match_found = true;
*ret_index_p = first_index ? 0 : original_len;
*ret_index_p = first_index ? start_pos : original_len;
}
else
{
@ -732,7 +711,7 @@ ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, /**< index
/* iterate original string and try to match at each position */
bool searching = true;
ecma_char_t first_char = lit_utf8_read_next (&search_str_curr_p);
ecma_char_t first_char = lit_cesu8_read_next (&search_str_curr_p);
while (searching)
{
/* match as long as possible */
@ -741,14 +720,14 @@ ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, /**< index
if (match_len < search_len &&
index + match_len < original_len &&
lit_utf8_read_next (&original_str_curr_p) == first_char)
lit_cesu8_read_next (&original_str_curr_p) == first_char)
{
const lit_utf8_byte_t *nested_search_str_curr_p = search_str_curr_p;
match_len++;
while (match_len < search_len &&
index + match_len < original_len &&
lit_utf8_read_next (&original_str_curr_p) == lit_utf8_read_next (&nested_search_str_curr_p))
lit_cesu8_read_next (&original_str_curr_p) == lit_cesu8_read_next (&nested_search_str_curr_p))
{
match_len++;
}
@ -838,7 +817,7 @@ ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, /**< object */
*/
ecma_value_t
ecma_builtin_helper_def_prop (ecma_object_t *obj_p, /**< object */
ecma_string_t *index_p, /**< index string */
ecma_string_t *name_p, /**< name string */
ecma_value_t value, /**< value */
uint32_t opts) /**< any combination of ecma_property_flag_t bits
* with the optional ECMA_IS_THROW flag */
@ -850,10 +829,189 @@ ecma_builtin_helper_def_prop (ecma_object_t *obj_p, /**< object */
prop_desc.value = value;
return ecma_op_object_define_own_property (obj_p,
index_p,
name_p,
&prop_desc);
} /* ecma_builtin_helper_def_prop */
/**
* GetSubstitution abstract operation
*
* See:
* ECMA-262 v6.0 21.1.3.14.1
*/
void
ecma_builtin_replace_substitute (ecma_replace_context_t *ctx_p) /**< replace context */
{
JERRY_ASSERT (ctx_p->string_p != NULL);
JERRY_ASSERT (ctx_p->matched_p == NULL
|| (ctx_p->matched_p >= ctx_p->string_p
&& ctx_p->matched_p <= ctx_p->string_p + ctx_p->string_size));
lit_utf8_size_t replace_size;
uint8_t replace_flags = ECMA_STRING_FLAG_IS_ASCII;
const lit_utf8_byte_t *replace_buf_p = ecma_string_get_chars (ctx_p->replace_str_p,
&replace_size,
NULL,
NULL,
&replace_flags);
const lit_utf8_byte_t *const replace_end_p = replace_buf_p + replace_size;
const lit_utf8_byte_t *curr_p = replace_buf_p;
const lit_utf8_byte_t *last_inserted_end_p = replace_buf_p;
while (curr_p < replace_end_p)
{
if (*curr_p++ == LIT_CHAR_DOLLAR_SIGN)
{
ecma_stringbuilder_append_raw (&(ctx_p->builder),
last_inserted_end_p,
(lit_utf8_size_t) (curr_p - last_inserted_end_p - 1));
if (curr_p >= replace_end_p)
{
last_inserted_end_p = curr_p - 1;
break;
}
const lit_utf8_byte_t c = *curr_p++;
switch (c)
{
case LIT_CHAR_DOLLAR_SIGN:
{
ecma_stringbuilder_append_byte (&(ctx_p->builder), LIT_CHAR_DOLLAR_SIGN);
break;
}
case LIT_CHAR_AMPERSAND:
{
#if ENABLED (JERRY_ES2015)
if (JERRY_UNLIKELY (ctx_p->matched_p == NULL))
{
JERRY_ASSERT (ctx_p->capture_count == 0);
JERRY_ASSERT (ctx_p->u.collection_p != NULL);
JERRY_ASSERT (ctx_p->u.collection_p->item_count > 0);
const ecma_value_t match_value = ctx_p->u.collection_p->buffer_p[0];
JERRY_ASSERT (ecma_is_value_string (match_value));
ecma_stringbuilder_append (&(ctx_p->builder), ecma_get_string_from_value (match_value));
break;
}
#endif /* ENABLED (JERRY_ES2015) */
JERRY_ASSERT (ctx_p->matched_p != NULL);
ecma_stringbuilder_append_raw (&(ctx_p->builder), ctx_p->matched_p, ctx_p->matched_size);
break;
}
case LIT_CHAR_GRAVE_ACCENT:
{
ecma_stringbuilder_append_raw (&(ctx_p->builder), ctx_p->string_p, ctx_p->match_byte_pos);
break;
}
case LIT_CHAR_SINGLE_QUOTE:
{
#if ENABLED (JERRY_ES2015)
if (JERRY_UNLIKELY (ctx_p->matched_p == NULL))
{
JERRY_ASSERT (ctx_p->capture_count == 0);
JERRY_ASSERT (ctx_p->u.collection_p != NULL);
JERRY_ASSERT (ctx_p->u.collection_p->item_count > 0);
const ecma_value_t match_value = ctx_p->u.collection_p->buffer_p[0];
JERRY_ASSERT (ecma_is_value_string (match_value));
const ecma_string_t *const matched_p = ecma_get_string_from_value (match_value);
const lit_utf8_size_t match_size = ecma_string_get_size (matched_p);
const lit_utf8_byte_t *const begin_p = ctx_p->string_p + ctx_p->match_byte_pos + match_size;
ecma_stringbuilder_append_raw (&(ctx_p->builder),
begin_p,
(lit_utf8_size_t) (ctx_p->string_p + ctx_p->string_size - begin_p));
break;
}
#endif /* ENABLED (JERRY_ES2015) */
JERRY_ASSERT (ctx_p->matched_p != NULL);
ecma_stringbuilder_append_raw (&(ctx_p->builder),
ctx_p->matched_p + ctx_p->matched_size,
ctx_p->string_size - ctx_p->match_byte_pos - ctx_p->matched_size);
break;
}
default:
{
const lit_utf8_byte_t *const number_begin_p = curr_p - 1;
if (lit_char_is_decimal_digit (c))
{
uint32_t capture_count = ctx_p->capture_count;
#if ENABLED (JERRY_ES2015)
if (capture_count == 0 && ctx_p->u.collection_p != NULL)
{
capture_count = ctx_p->u.collection_p->item_count;
}
#endif /* ENABLED (JERRY_ES2015) */
uint8_t idx = (uint8_t) (c - LIT_CHAR_0);
if (curr_p < replace_end_p && lit_char_is_decimal_digit (*(curr_p)))
{
uint8_t two_digit_index = (uint8_t) (idx * 10 + (uint8_t) (*(curr_p) - LIT_CHAR_0));
if (two_digit_index < capture_count)
{
idx = two_digit_index;
curr_p++;
}
}
if (idx > 0 && idx < capture_count)
{
if (ctx_p->capture_count > 0)
{
#if ENABLED (JERRY_BUILTIN_REGEXP)
JERRY_ASSERT (ctx_p->u.captures_p != NULL);
const ecma_regexp_capture_t *const capture_p = ctx_p->u.captures_p + idx;
if (ECMA_RE_IS_CAPTURE_DEFINED (capture_p))
{
ecma_stringbuilder_append_raw (&(ctx_p->builder),
capture_p->begin_p,
(lit_utf8_size_t) (capture_p->end_p - capture_p->begin_p));
}
break;
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
}
#if ENABLED (JERRY_ES2015)
else if (ctx_p->u.collection_p != NULL)
{
const ecma_value_t capture_value = ctx_p->u.collection_p->buffer_p[idx];
if (!ecma_is_value_undefined (capture_value))
{
ecma_stringbuilder_append (&(ctx_p->builder), ecma_get_string_from_value (capture_value));
}
break;
}
#endif /* ENABLED (JERRY_ES2015) */
}
}
ecma_stringbuilder_append_byte (&(ctx_p->builder), LIT_CHAR_DOLLAR_SIGN);
curr_p = number_begin_p;
break;
}
}
last_inserted_end_p = curr_p;
}
}
ecma_stringbuilder_append_raw (&(ctx_p->builder),
last_inserted_end_p,
(lit_utf8_size_t) (replace_end_p - last_inserted_end_p));
if (replace_flags & ECMA_STRING_FLAG_MUST_BE_FREED)
{
jmem_heap_free_block ((void *) replace_buf_p, replace_size);
}
} /* ecma_builtin_replace_substitute */
/**
* @}
* @}

View File

@ -18,6 +18,8 @@
#include "ecma-globals.h"
#include "ecma-exceptions.h"
#include "ecma-helpers.h"
#include "ecma-regexp-object.h"
/** \addtogroup ecma ECMA
* @{
@ -32,8 +34,8 @@
typedef enum
{
/** These routines must be in this order */
ECMA_STRING_INDEX_OF, /**< String.indexOf: ECMA-262 v5, 15.5.4.7 */
ECMA_STRING_LAST_INDEX_OF, /**< String.lastIndexOf: ECMA-262 v5, 15.5.4.8 */
ECMA_STRING_INDEX_OF, /**< String.indexOf: ECMA-262 v5, 15.5.4.7 */
ECMA_STRING_STARTS_WITH, /**< String.startsWith: ECMA-262 v6, 21.1.3.18 */
ECMA_STRING_INCLUDES, /**< String.includes: ECMA-262 v6, 21.1.3.7 */
ECMA_STRING_ENDS_WITH /**< String.includes: ECMA-262 v6, 21.1.3.6 */
@ -41,14 +43,14 @@ typedef enum
ecma_value_t
ecma_builtin_helper_object_to_string (const ecma_value_t this_arg);
ecma_value_t
ecma_string_t *
ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, uint32_t index);
ecma_value_t
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, bool last_index_of);
ecma_builtin_helper_array_index_normalize (ecma_value_t arg, uint32_t length, uint32_t *number_p);
uint32_t
ecma_builtin_helper_string_index_normalize (ecma_number_t index, uint32_t length, bool nan_to_zero);
ecma_value_t
@ -58,11 +60,47 @@ 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);
ecma_builtin_helper_def_prop (ecma_object_t *obj_p, ecma_string_t *name_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);
/**
* Context for replace substitutions
*/
typedef struct
{
ecma_stringbuilder_t builder; /**< result string builder */
const lit_utf8_byte_t *string_p; /**< source string */
lit_utf8_size_t string_size; /**< source string size */
const lit_utf8_byte_t *matched_p; /**< matched string */
lit_utf8_size_t matched_size; /**< matcehd string size */
lit_utf8_size_t match_byte_pos; /**< byte position of the match in the source string */
ecma_length_t index; /**< current match index */
/**
* Capture results
*/
union
{
#if ENABLED (JERRY_BUILTIN_REGEXP)
const ecma_regexp_capture_t *captures_p; /**< array of regexp capturing groups */
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
const ecma_collection_t *collection_p; /**< collection of captured substrings */
} u;
uint32_t capture_count; /**< number of captures in the capturing group array */
ecma_string_t *replace_str_p; /**< replacement string */
} ecma_replace_context_t;
void
ecma_builtin_replace_substitute (ecma_replace_context_t *ctx_p);
#if ENABLED (JERRY_ES2015)
bool
ecma_builtin_is_regexp_exec (ecma_extended_object_t *obj_p);
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_BUILTIN_DATE)
/**
@ -109,6 +147,9 @@ typedef enum
} ecma_date_timezone_t;
/* ecma-builtin-helpers-date.c */
extern const char day_names_p[7][3];
extern const char month_names_p[12][3];
ecma_number_t ecma_date_day (ecma_number_t time);
ecma_number_t ecma_date_time_within_day (ecma_number_t time);
ecma_number_t ecma_date_year_from_time (ecma_number_t time);
@ -193,9 +234,9 @@ ecma_builtin_helper_error_dispatch_call (ecma_standard_error_t error_type, const
/**
* Comparison callback function header for sorting helper routines.
*/
typedef ecma_value_t (*ecma_builtin_helper_sort_compare_fn_t)(ecma_value_t lhs, /**< left value */
ecma_value_t rhs, /**< right value */
ecma_value_t compare_func); /**< compare function */
typedef ecma_value_t (*ecma_builtin_helper_sort_compare_fn_t) (ecma_value_t lhs, /**< left value */
ecma_value_t rhs, /**< right value */
ecma_value_t compare_func); /**< compare function */
ecma_value_t ecma_builtin_helper_array_heap_sort_helper (ecma_value_t *array_p,
uint32_t right,

View File

@ -45,6 +45,8 @@
static ecma_value_t c_function_name (ROUTINE_ARG_LIST_ ## args_number);
#define ROUTINE_CONFIGURABLE_ONLY(name, c_function_name, args_number, length_prop_value) \
static ecma_value_t c_function_name (ROUTINE_ARG_LIST_ ## args_number);
#define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \
static ecma_value_t c_function_name (ROUTINE_ARG_LIST_ ## args_number);
#define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
static ecma_value_t c_getter_func_name (ROUTINE_ARG_LIST_0); \
static ecma_value_t c_setter_func_name (ROUTINE_ARG_LIST_1);
@ -68,6 +70,8 @@ enum
ECMA_ROUTINE_ ## name ## c_function_name,
#define ROUTINE_CONFIGURABLE_ONLY(name, c_function_name, args_number, length_prop_value) \
ECMA_ROUTINE_ ## name ## c_function_name,
#define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \
ECMA_ROUTINE_ ## name ## c_function_name,
#define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
ECMA_ACCESSOR_ ## name ## c_getter_func_name, \
ECMA_ACCESSOR_ ## name ## c_setter_func_name,
@ -98,6 +102,13 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
ECMA_PROPERTY_FLAG_CONFIGURABLE, \
ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \
},
#define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ROUTINE, \
flags, \
ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \
},
#define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
{ \
name, \
@ -105,6 +116,14 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
prop_attributes, \
ECMA_ACCESSOR_ ## name ## c_getter_func_name \
},
#define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_WRITE, \
prop_attributes, \
ECMA_ACCESSOR_READ_WRITE (ECMA_ACCESSOR_ ## name ## c_getter_func_name, \
ECMA_ACCESSOR_ ## name ## c_setter_func_name) \
},
#else /* BUILTIN_CUSTOM_DISPATCH */
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
{ \
@ -120,6 +139,13 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
ECMA_PROPERTY_FLAG_CONFIGURABLE, \
ECMA_ROUTINE_VALUE (c_function_name, length_prop_value) \
},
#define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ROUTINE, \
flags, \
ECMA_ROUTINE_VALUE (c_function_name, length_prop_value) \
},
#define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
{ \
name, \
@ -127,6 +153,13 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
prop_attributes, \
c_getter_func_name \
},
#define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_WRITE, \
prop_attributes, \
ECMA_ACCESSOR_READ_WRITE (c_getter_func_name, c_setter_func_name) \
},
#endif /* !BUILTIN_CUSTOM_DISPATCH */
#define OBJECT_VALUE(name, obj_builtin_id, prop_attributes) \
{ \
@ -156,22 +189,29 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
prop_attributes, \
magic_string_id \
},
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#define SYMBOL_VALUE(name, desc_string_id) \
#if ENABLED (JERRY_ES2015)
#define SYMBOL_VALUE(symbol, desc_magic_string_id) \
{ \
name, \
symbol, \
ECMA_BUILTIN_PROPERTY_SYMBOL, \
ECMA_PROPERTY_FIXED, \
desc_string_id \
desc_magic_string_id \
},
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#define ACCESSOR_READ_WRITE(name, c_getter_name, c_setter_name, prop_attributes) \
#define INTRINSIC_PROPERTY(name, magic_string_id, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_WRITE, \
ECMA_BUILTIN_PROPERTY_INTRINSIC_PROPERTY, \
prop_attributes, \
ECMA_ACCESSOR_READ_WRITE (ECMA_ACCESSOR_ ## name ## c_getter_name, ECMA_ACCESSOR_ ## name ## c_setter_name) \
magic_string_id \
},
#define ACCESSOR_BUILTIN_FUNCTION(name, getter_builtin_id, setter_builtin_id, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ACCESSOR_BUILTIN_FUNCTION, \
prop_attributes, \
ECMA_ACCESSOR_READ_WRITE (getter_builtin_id, setter_builtin_id) \
},
#endif /* ENABLED (JERRY_ES2015) */
#include BUILTIN_INC_HEADER_NAME
{
LIT_MAGIC_STRING__COUNT,
@ -222,6 +262,11 @@ DISPATCH_ROUTINE_ROUTINE_NAME (uint16_t builtin_routine_id, /**< built-in wide r
{ \
return c_function_name (this_arg_value ROUTINE_ARG_LIST_ ## args_number); \
}
#define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \
case ECMA_ROUTINE_ ## name ## c_function_name: \
{ \
return c_function_name (this_arg_value ROUTINE_ARG_LIST_ ## args_number); \
}
#define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
case ECMA_ACCESSOR_ ## name ## c_getter_func_name: \
{ \

View File

@ -0,0 +1,143 @@
/* 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-builtins.h"
#include "ecma-array-object.h"
#include "ecma-gc.h"
#include "lit-char-helpers.h"
#if ENABLED (JERRY_ES2015)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
/**
* This object has a custom dispatch function.
*/
#define BUILTIN_CUSTOM_DISPATCH
/**
* List of built-in routine identifiers.
*/
enum
{
ECMA_INTRINSIC_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1,
ECMA_INTRINSIC_PARSE_FLOAT,
ECMA_INTRINSIC_PARSE_INT,
ECMA_INTRINSIC_ARRAY_PROTOTYPE_VALUES
};
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-intrinsic.inc.h"
#define BUILTIN_UNDERSCORED_ID intrinsic
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup intrinsic ECMA Intrinsic object built-in
* @{
*/
/**
* The %ArrayProto_values% intrinsic routine
*
* See also:
* ECMA-262 v5, 15.4.4.4
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_intrinsic_array_prototype_values (ecma_value_t this_value) /**< this argument */
{
ecma_value_t this_obj = ecma_op_to_object (this_value);
if (ECMA_IS_VALUE_ERROR (this_obj))
{
return this_obj;
}
ecma_object_t *this_obj_p = ecma_get_object_from_value (this_obj);
ecma_value_t ret_value = ecma_op_create_array_iterator (this_obj_p, ECMA_ITERATOR_VALUES);
ecma_deref_object (this_obj_p);
return ret_value;
} /* ecma_builtin_intrinsic_array_prototype_values */
/**
* Dispatcher of the built-in's routines
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_intrinsic_dispatch_routine (uint16_t builtin_routine_id, /**< built-in wide routine identifier */
ecma_value_t this_arg, /**< 'this' argument value */
const ecma_value_t arguments_list_p[], /**< list of arguments
* passed to routine */
ecma_length_t arguments_number) /**< length of arguments' list */
{
JERRY_UNUSED (arguments_number);
ecma_value_t routine_arg_1 = arguments_list_p[0];
ecma_value_t routine_arg_2 = arguments_list_p[1];
if (builtin_routine_id == ECMA_INTRINSIC_ARRAY_PROTOTYPE_VALUES)
{
return ecma_builtin_intrinsic_array_prototype_values (this_arg);
}
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
if (builtin_routine_id <= ECMA_INTRINSIC_PARSE_INT)
{
ecma_string_t *str_p = ecma_op_to_string (routine_arg_1);
if (JERRY_UNLIKELY (str_p == NULL))
{
return ECMA_VALUE_ERROR;
}
ECMA_STRING_TO_UTF8_STRING (str_p, string_buff, string_buff_size);
if (builtin_routine_id == ECMA_INTRINSIC_PARSE_INT)
{
ret_value = ecma_number_parse_int (string_buff,
string_buff_size,
routine_arg_2);
}
else
{
JERRY_ASSERT (builtin_routine_id == ECMA_INTRINSIC_PARSE_FLOAT);
ret_value = ecma_number_parse_float (string_buff,
string_buff_size);
}
ECMA_FINALIZE_UTF8_STRING (string_buff, string_buff_size);
ecma_deref_ecma_string (str_p);
}
return ret_value;
} /* ecma_builtin_intrinsic_dispatch_routine */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015) */

View File

@ -0,0 +1,73 @@
/* 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.
*/
/*
* Intrinsic built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 19.4.2.2 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_HAS_INSTANCE,
LIT_MAGIC_STRING_HAS_INSTANCE)
/* ECMA-262 v6, 19.4.2.3 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE,
LIT_MAGIC_STRING_IS_CONCAT_SPREADABLE)
/* ECMA-262 v6, 19.4.2.4 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_ITERATOR,
LIT_MAGIC_STRING_ITERATOR)
/* ECMA-262 v6, 19.4.2.6 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_MATCH,
LIT_MAGIC_STRING_MATCH)
/* ECMA-262 v6, 19.4.2.8 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_REPLACE,
LIT_MAGIC_STRING_REPLACE)
/* ECMA-262 v6, 19.4.2.9 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_SEARCH,
LIT_MAGIC_STRING_SEARCH)
/* ECMA-262 v6, 19.4.2.10 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_SPECIES,
LIT_MAGIC_STRING_SPECIES)
/* ECMA-262 v6, 19.4.2.11 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_SPLIT,
LIT_MAGIC_STRING_SPLIT)
/* ECMA-262 v6, 19.4.2.12 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_TO_PRIMITIVE,
LIT_MAGIC_STRING_TO_PRIMITIVE)
/* ECMA-262 v6, 19.4.2.13 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_TO_STRING_TAG)
/* ECMA-262 v6, 19.4.2.14 */
SYMBOL_VALUE (LIT_GLOBAL_SYMBOL_UNSCOPABLES,
LIT_MAGIC_STRING_UNSCOPABLES)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_PARSE_FLOAT, ECMA_INTRINSIC_PARSE_FLOAT, 1, 1)
ROUTINE (LIT_MAGIC_STRING_PARSE_INT, ECMA_INTRINSIC_PARSE_INT, 2, 2)
ROUTINE (LIT_INTERNAL_MAGIC_STRING_ARRAY_PROTOTYPE_VALUES, ECMA_INTRINSIC_ARRAY_PROTOTYPE_VALUES, 0, 0)
#endif /* ENABLED (JERRY_ES2015) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -17,7 +17,7 @@
#include "ecma-builtins.h"
#include "ecma-iterator-object.h"
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#if ENABLED (JERRY_ES2015)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
@ -60,4 +60,4 @@ ecma_builtin_iterator_prototype_object_iterator (ecma_value_t this_val) /**< thi
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
#endif /* ENABLED (JERRY_ES2015) */

View File

@ -19,12 +19,12 @@
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#if ENABLED (JERRY_ES2015)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_GLOBAL_SYMBOL_ITERATOR, ecma_builtin_iterator_prototype_object_iterator, 0, 0)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
#endif /* ENABLED (JERRY_ES2015) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -174,18 +174,13 @@ ecma_builtin_json_parse_string (ecma_json_token_t *token_p) /**< token argument
}
case LIT_CHAR_LOWERCASE_U:
{
if ((end_p - current_p <= ECMA_JSON_HEX_ESCAPE_SEQUENCE_LENGTH))
uint32_t hex_value = lit_char_hex_lookup (current_p + 1, end_p, ECMA_JSON_HEX_ESCAPE_SEQUENCE_LENGTH);
if (hex_value == UINT32_MAX)
{
goto invalid_string;
}
ecma_char_t code_unit;
if (!(lit_read_code_unit_from_hex (current_p + 1, ECMA_JSON_HEX_ESCAPE_SEQUENCE_LENGTH, &code_unit)))
{
goto invalid_string;
}
ecma_stringbuilder_append_char (&result_builder, code_unit);
ecma_stringbuilder_append_char (&result_builder, (ecma_char_t) hex_value);
current_p += ECMA_JSON_HEX_ESCAPE_SEQUENCE_LENGTH + 1;
break;
}
@ -204,7 +199,7 @@ ecma_builtin_json_parse_string (ecma_json_token_t *token_p) /**< token argument
ecma_stringbuilder_append_raw (&result_builder,
unappended_p,
(lit_utf8_size_t)(current_p - unappended_p));
(lit_utf8_size_t) (current_p - unappended_p));
token_p->u.string_p = ecma_stringbuilder_finalize (&result_builder);
token_p->current_p = current_p + 1;
token_p->type = TOKEN_STRING;
@ -571,13 +566,12 @@ ecma_builtin_json_parse_value (ecma_json_token_t *token_p) /**< token argument *
break;
}
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (length);
ecma_value_t completion = ecma_builtin_helper_def_prop (array_p,
index_str_p,
value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_value_t completion;
completion = ecma_builtin_helper_def_prop_by_index (array_p,
length,
value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (completion));
ecma_deref_ecma_string (index_str_p);
ecma_free_value (value);
ecma_builtin_json_parse_next_token (token_p, false);
@ -738,15 +732,13 @@ ecma_builtin_json_parse (ecma_value_t this_arg, /**< 'this' argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t text_value = ecma_op_to_string (arg1);
ecma_string_t *text_string_p = ecma_op_to_string (arg1);
if (ECMA_IS_VALUE_ERROR (text_value))
if (JERRY_UNLIKELY (text_string_p == NULL))
{
return text_value;
return ECMA_VALUE_ERROR;
}
ecma_string_t *text_string_p = ecma_get_string_from_value (text_value);
ECMA_STRING_TO_UTF8_STRING (text_string_p, str_start_p, string_size);
ecma_value_t result = ecma_builtin_json_parse_buffer (str_start_p, string_size);
ECMA_FINALIZE_UTF8_STRING (str_start_p, string_size);
@ -907,6 +899,13 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /*
else
{
property_keys_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ENUMERABLE);
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (property_keys_p == NULL)
{
return ECMA_VALUE_ERROR;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
}
/* 8. */
@ -1001,7 +1000,12 @@ static ecma_value_t
ecma_builtin_json_serialize_array (ecma_json_stringify_context_t *context_p, /**< context*/
ecma_object_t *obj_p) /**< the array object*/
{
JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY);
#ifndef JERRY_NDEBUG
ecma_value_t obj_value = ecma_make_object_value (obj_p);
ecma_value_t is_array = ecma_is_value_array (obj_value);
JERRY_ASSERT (ecma_is_value_true (is_array));
#endif /* !JERRY_NDEBUG */
/* 1. */
if (ecma_json_has_object_in_stack (context_p->occurence_stack_last_p, obj_p))
@ -1023,7 +1027,23 @@ ecma_builtin_json_serialize_array (ecma_json_stringify_context_t *context_p, /**
const bool has_gap = !ecma_compare_ecma_string_to_magic_id (context_p->gap_str_p, LIT_MAGIC_STRING__EMPTY);
/* 6. */
uint32_t array_length = ((ecma_extended_object_t *) obj_p)->u.array.length;
uint32_t array_length;
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (ECMA_OBJECT_IS_PROXY (obj_p))
{
ecma_value_t length_value = ecma_op_object_get_length (obj_p, &array_length);
if (ECMA_IS_VALUE_ERROR (length_value))
{
return length_value;
}
}
else
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
{
array_length = ((ecma_extended_object_t *) obj_p)->u.array.length;
}
ecma_stringbuilder_append_byte (&context_p->result_builder, LIT_CHAR_LEFT_SQUARE);
@ -1166,35 +1186,36 @@ ecma_builtin_json_serialize_property (ecma_json_stringify_context_t *context_p,
ecma_object_t *obj_p = ecma_get_object_from_value (value);
lit_magic_string_id_t class_name = ecma_object_get_class_name (obj_p);
ecma_value_t result = ECMA_VALUE_EMPTY;
/* 5.a */
if (class_name == LIT_MAGIC_STRING_NUMBER_UL)
{
result = ecma_op_to_number (value);
value = ecma_op_to_number (value);
ecma_deref_object (obj_p);
if (ECMA_IS_VALUE_ERROR (value))
{
return value;
}
}
/* 5.b */
else if (class_name == LIT_MAGIC_STRING_STRING_UL)
{
result = ecma_op_to_string (value);
ecma_string_t *str_p = ecma_op_to_string (value);
ecma_deref_object (obj_p);
if (JERRY_UNLIKELY (str_p == NULL))
{
return ECMA_VALUE_ERROR;
}
value = ecma_make_string_value (str_p);
}
/* 5.c */
else if (class_name == LIT_MAGIC_STRING_BOOLEAN_UL)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
result = ext_object_p->u.class_prop.u.value;
}
if (!ecma_is_value_empty (result))
{
value = ext_object_p->u.class_prop.u.value;
ecma_deref_object (obj_p);
if (ECMA_IS_VALUE_ERROR (result))
{
return result;
}
value = result;
}
}
@ -1236,9 +1257,8 @@ ecma_builtin_json_serialize_property (ecma_json_stringify_context_t *context_p,
/* 10.a */
if (!ecma_number_is_nan (num_value) && !ecma_number_is_infinity (num_value))
{
ecma_value_t result_value = ecma_op_to_string (value);
JERRY_ASSERT (ecma_is_value_string (result_value));
ecma_string_t *result_string_p = ecma_get_string_from_value (result_value);
ecma_string_t *result_string_p = ecma_op_to_string (value);
JERRY_ASSERT (result_string_p != NULL);
ecma_stringbuilder_append (&context_p->result_builder, result_string_p);
ecma_deref_ecma_string (result_string_p);
@ -1256,12 +1276,21 @@ ecma_builtin_json_serialize_property (ecma_json_stringify_context_t *context_p,
/* 11. */
if (ecma_is_value_object (value) && !ecma_op_is_callable (value))
{
ecma_value_t is_array = ecma_is_value_array (value);
#if ENABLED (JERRY_ES2015)
if (ECMA_IS_VALUE_ERROR (is_array))
{
ecma_free_value (value);
return is_array;
}
#endif /* ENABLED (JERRY_ES2015) */
ecma_object_t *obj_p = ecma_get_object_from_value (value);
lit_magic_string_id_t class_name = ecma_object_get_class_name (obj_p);
ecma_value_t ret_value;
/* 10.a */
if (class_name == LIT_MAGIC_STRING_ARRAY_UL)
if (ecma_is_value_true (is_array))
{
ret_value = ecma_builtin_json_serialize_array (context_p, obj_p);
}
@ -1375,7 +1404,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
context.replacer_function_p = obj_p;
}
/* 4.b */
else if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_ARRAY_UL)
else if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY)
{
ecma_extended_object_t *array_object_p = (ecma_extended_object_t *) obj_p;
uint32_t array_length = array_object_p->u.array.length;
@ -1384,9 +1413,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
/* 4.b.iii.5 */
while (index < array_length)
{
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t value = ecma_op_object_get (obj_p, index_str_p);
ecma_deref_ecma_string (index_str_p);
ecma_value_t value = ecma_op_object_get_by_uint32_index (obj_p, index);
if (ECMA_IS_VALUE_ERROR (value))
{
@ -1406,25 +1433,29 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
/* 4.b.iii.5.e */
else if (ecma_is_value_number (value))
{
ecma_value_t number_str_value = ecma_op_to_string (value);
JERRY_ASSERT (ecma_is_value_string (number_str_value));
item = number_str_value;
ecma_string_t *number_str_p = ecma_op_to_string (value);
JERRY_ASSERT (number_str_p != NULL);
item = ecma_make_string_value (number_str_p);
}
/* 4.b.iii.5.f */
else if (ecma_is_value_object (value)
&& (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_NUMBER_UL
|| ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_STRING_UL))
else if (ecma_is_value_object (value))
{
ecma_value_t str_val = ecma_op_to_string (value);
ecma_object_t *value_obj_p = ecma_get_object_from_value (value);
lit_magic_string_id_t class_id = ecma_object_get_class_name (value_obj_p);
if (ECMA_IS_VALUE_ERROR (str_val))
if (class_id == LIT_MAGIC_STRING_NUMBER_UL || class_id == LIT_MAGIC_STRING_STRING_UL)
{
ecma_collection_free (context.property_list_p);
ecma_free_value (value);
return str_val;
}
ecma_string_t *str_p = ecma_op_to_string (value);
item = str_val;
if (JERRY_UNLIKELY (str_p == NULL))
{
ecma_collection_free (context.property_list_p);
ecma_free_value (value);
return ECMA_VALUE_ERROR;
}
item = ecma_make_string_value (str_p);
}
}
ecma_free_value (value);
@ -1474,15 +1505,15 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
/* 5.b */
else if (class_name == LIT_MAGIC_STRING_STRING_UL)
{
ecma_value_t value = ecma_op_to_string (arg3);
ecma_string_t *value_str_p = ecma_op_to_string (arg3);
if (ECMA_IS_VALUE_ERROR (value))
if (JERRY_UNLIKELY (value_str_p == NULL))
{
ecma_collection_free (context.property_list_p);
return value;
return ECMA_VALUE_ERROR;
}
space = value;
space = ecma_make_string_value (value_str_p);
}
else
{
@ -1497,9 +1528,10 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
/* 6. */
if (ecma_is_value_number (space))
{
ecma_number_t number = ecma_get_number_from_value (space);
/* 6.a */
int32_t num_of_spaces = ecma_number_to_int32 (number);
ecma_number_t num_of_spaces;
ecma_op_to_integer (space, &num_of_spaces);
num_of_spaces = JERRY_MIN (10, num_of_spaces);
/* 6.b */

View File

@ -21,12 +21,12 @@
#if ENABLED (JERRY_BUILTIN_JSON)
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 24.3.3 */
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_JSON_U,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */

View File

@ -19,10 +19,6 @@
#if ENABLED (JERRY_ES2015_BUILTIN_MAP)
#if !ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#error "Map iterator builtin requires ES2015 iterator builtin"
#endif /* !ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"

View File

@ -96,7 +96,7 @@ static ecma_value_t
ecma_builtin_map_prototype_object_get (ecma_value_t this_arg, /**< this argument */
ecma_value_t key_arg) /**< key argument */
{
return ecma_op_container_get (this_arg, key_arg);
return ecma_op_container_get (this_arg, key_arg, LIT_MAGIC_STRING_MAP_UL);
} /* ecma_builtin_map_prototype_object_get */
/**
@ -147,7 +147,8 @@ ecma_builtin_map_prototype_object_size_getter (ecma_value_t this_arg) /**< this
return ecma_op_container_size (this_arg, LIT_MAGIC_STRING_MAP_UL);
} /* ecma_builtin_map_prototype_object_size_getter */
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#if ENABLED (JERRY_ES2015)
/**
* The Map.prototype object's 'entries' routine
*
@ -205,7 +206,7 @@ ecma_builtin_map_prototype_object_values (ecma_value_t this_arg) /**< this argum
ECMA_PSEUDO_MAP_ITERATOR);
} /* ecma_builtin_map_prototype_object_values */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* @}

View File

@ -29,12 +29,12 @@ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_MAP,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 23.1.3.13 */
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_MAP_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
@ -44,17 +44,17 @@ ROUTINE (LIT_MAGIC_STRING_FOR_EACH_UL, ecma_builtin_map_prototype_object_foreach
ROUTINE (LIT_MAGIC_STRING_GET, ecma_builtin_map_prototype_object_get, 1, 1)
ROUTINE (LIT_MAGIC_STRING_HAS, ecma_builtin_map_prototype_object_has, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET, ecma_builtin_map_prototype_object_set, 2, 2)
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#if ENABLED (JERRY_ES2015)
ROUTINE (LIT_MAGIC_STRING_ENTRIES, ecma_builtin_map_prototype_object_entries, 0, 0)
ROUTINE (LIT_MAGIC_STRING_VALUES, ecma_builtin_map_prototype_object_values, 0, 0)
ROUTINE (LIT_MAGIC_STRING_KEYS, ecma_builtin_map_prototype_object_keys, 0, 0)
ROUTINE (LIT_GLOBAL_SYMBOL_ITERATOR, ecma_builtin_map_prototype_object_values, 0, 0)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
ROUTINE (LIT_GLOBAL_SYMBOL_ITERATOR, ecma_builtin_map_prototype_object_entries, 0, 0)
#endif /* ENABLED (JERRY_ES2015) */
/* ECMA-262 v6, 23.1.3.10 */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_SIZE,
ecma_builtin_map_prototype_object_size_getter,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */

View File

@ -65,6 +65,18 @@ ecma_builtin_map_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
ECMA_BUILTIN_ID_MAP_PROTOTYPE);
} /* ecma_builtin_map_dispatch_construct */
/**
* 23.1.2.2 get Map [ @@species ] accessor
*
* @return ecma_value
* returned value must be freed with ecma_free_value
*/
ecma_value_t
ecma_builtin_map_species_get (ecma_value_t this_value) /**< This Value */
{
return ecma_copy_value (this_value);
} /* ecma_builtin_map_species_get */
/**
* @}
* @}

View File

@ -27,7 +27,7 @@
/* ECMA-262 v6, 23.1.2 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
0,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v6, 23.1 */
STRING_VALUE (LIT_MAGIC_STRING_NAME,
@ -42,6 +42,11 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_MAP_PROTOTYPE,
ECMA_PROPERTY_FIXED)
/* ECMA-262 v6, 23.1.2.2 */
ACCESSOR_READ_ONLY (LIT_GLOBAL_SYMBOL_SPECIES,
ecma_builtin_map_species_get,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -29,6 +29,10 @@
#include "jrt.h"
#include "jrt-libc-includes.h"
#if defined (WIN32)
#include <intrin.h>
#endif
#if ENABLED (JERRY_BUILTIN_MATH)
#define ECMA_BUILTINS_INTERNAL
@ -55,21 +59,37 @@ enum
ECMA_MATH_OBJECT_EXP, /* ECMA-262 v5, 15.8.2.8 */
ECMA_MATH_OBJECT_FLOOR, /* ECMA-262 v5, 15.8.2.9 */
ECMA_MATH_OBJECT_LOG, /* ECMA-262 v5, 15.8.2.10 */
#if ENABLED (JERRY_ES2015_BUILTIN)
ECMA_MATH_OBJECT_TRUNC, /* ECMA-262 v6, 20.2.2.35 */
ECMA_MATH_OBJECT_SIGN, /* ECMA-262 v6, 20.2.2.29 */
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
ECMA_MATH_OBJECT_ROUND, /* ECMA-262 v5, 15.8.2.15 */
ECMA_MATH_OBJECT_SIN, /* ECMA-262 v5, 15.8.2.16 */
ECMA_MATH_OBJECT_SQRT, /* ECMA-262 v5, 15.8.2.17 */
ECMA_MATH_OBJECT_TAN, /* ECMA-262 v5, 15.8.2.18 */
ECMA_MATH_OBJECT_ATAN2, /* ECMA-262 v5, 15.8.2.5 */
ECMA_MATH_OBJECT_POW, /* ECMA-262 v5, 15.8.2.13 */
#if ENABLED (JERRY_ES2015)
ECMA_MATH_OBJECT_ACOSH, /* ECMA-262 v6, 20.2.2.3 */
ECMA_MATH_OBJECT_ASINH, /* ECMA-262 v6, 20.2.2.5 */
ECMA_MATH_OBJECT_ATANH, /* ECMA-262 v6, 20.2.2.7 */
ECMA_MATH_OBJECT_CBRT, /* ECMA-262 v6, 20.2.2.9 */
ECMA_MATH_OBJECT_CLZ32, /* ECMA-262 v6, 20.2.2.11 */
ECMA_MATH_OBJECT_COSH, /* ECMA-262 v6, 20.2.2.13 */
ECMA_MATH_OBJECT_EXPM1, /* ECMA-262 v6, 20.2.2.15 */
ECMA_MATH_OBJECT_FROUND, /* ECMA-262 v6, 20.2.2.17 */
ECMA_MATH_OBJECT_LOG1P, /* ECMA-262 v6, 20.2.2.21 */
ECMA_MATH_OBJECT_LOG10, /* ECMA-262 v6, 20.2.2.22 */
ECMA_MATH_OBJECT_LOG2, /* ECMA-262 v6, 20.2.2.23 */
ECMA_MATH_OBJECT_SIGN, /* ECMA-262 v6, 20.2.2.29 */
ECMA_MATH_OBJECT_SINH, /* ECMA-262 v6, 20.2.2.31 */
ECMA_MATH_OBJECT_TANH, /* ECMA-262 v6, 20.2.2.34 */
ECMA_MATH_OBJECT_TRUNC, /* ECMA-262 v6, 20.2.2.35 */
#endif /* ENABLED (JERRY_ES2015) */
ECMA_MATH_OBJECT_ATAN2, /* ECMA-262 v5, 15.8.2.5 */ /* first routine with 2 arguments */
#if ENABLED (JERRY_ES2015)
ECMA_MATH_OBJECT_IMUL, /* ECMA-262 v6, 20.2.2.19 */
#endif /* ENABLED (JERRY_ES2015) */
ECMA_MATH_OBJECT_POW, /* ECMA-262 v5, 15.8.2.13 */ /* last routine with 1 or 2 arguments*/
ECMA_MATH_OBJECT_MAX, /* ECMA-262 v5, 15.8.2.11 */
ECMA_MATH_OBJECT_MIN, /* ECMA-262 v5, 15.8.2.12 */
#if ENABLED (JERRY_ES2015)
ECMA_MATH_OBJECT_HYPOT, /* ECMA-262 v6, 20.2.2.18 */
#endif /* ENABLED (JERRY_ES2015) */
ECMA_MATH_OBJECT_RANDOM, /* ECMA-262 v5, 15.8.2.14 */
};
@ -103,6 +123,7 @@ ecma_builtin_math_object_max_min (bool is_max, /**< 'max' or 'min' operation */
ecma_length_t args_number) /**< number of arguments */
{
ecma_number_t result_num = ecma_number_make_infinity (is_max);
bool nan_found = false;
while (args_number > 0)
{
@ -126,10 +147,13 @@ ecma_builtin_math_object_max_min (bool is_max, /**< 'max' or 'min' operation */
ecma_fast_free_value (value);
}
if (JERRY_UNLIKELY (ecma_number_is_nan (arg_num)))
arg++;
args_number--;
if (JERRY_UNLIKELY (nan_found || ecma_number_is_nan (arg_num)))
{
result_num = arg_num;
break;
nan_found = true;
continue;
}
if (ecma_number_is_zero (arg_num)
@ -149,15 +173,88 @@ ecma_builtin_math_object_max_min (bool is_max, /**< 'max' or 'min' operation */
result_num = arg_num;
}
}
}
arg++;
args_number--;
if (JERRY_UNLIKELY (nan_found))
{
result_num = ecma_number_make_nan ();
}
return ecma_make_number_value (result_num);
} /* ecma_builtin_math_object_max_min */
#if ENABLED (JERRY_ES2015_BUILTIN)
#if ENABLED (JERRY_ES2015)
/**
* The Math object's 'hypot' routine
*
* See also:
* ECMA-262 v6, 20.2.2.18
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_math_object_hypot (const ecma_value_t *arg, /**< arguments list */
ecma_length_t args_number) /**< number of arguments */
{
if (args_number == 0)
{
return ecma_make_number_value (0.0);
}
bool nan_found = false;
bool inf_found = false;
ecma_number_t result_num = 0;
while (args_number > 0)
{
ecma_number_t arg_num;
if (ecma_is_value_number (*arg))
{
arg_num = ecma_get_number_from_value (*arg);
}
else
{
ecma_value_t value = ecma_op_to_number (*arg);
if (ECMA_IS_VALUE_ERROR (value))
{
return value;
}
arg_num = ecma_get_number_from_value (value);
ecma_fast_free_value (value);
}
arg++;
args_number--;
if (JERRY_UNLIKELY (inf_found || ecma_number_is_infinity (arg_num)))
{
inf_found = true;
continue;
}
if (JERRY_UNLIKELY (nan_found || ecma_number_is_nan (arg_num)))
{
nan_found = true;
continue;
}
result_num += arg_num * arg_num;
}
if (JERRY_UNLIKELY (inf_found))
{
return ecma_make_number_value (ecma_number_make_infinity (false));
}
if (JERRY_UNLIKELY (nan_found))
{
return ecma_make_nan_value ();
}
return ecma_make_number_value (sqrt (result_num));
} /* ecma_builtin_math_object_hypot */
/**
* The Math object's 'trunc' routine
*
@ -176,12 +273,12 @@ ecma_builtin_math_object_trunc (ecma_number_t arg)
if ((arg > 0) && (arg < 1))
{
return (ecma_number_t) 0;
return (ecma_number_t) 0.0;
}
if ((arg < 0) && (arg > -1))
{
return (ecma_number_t) -0;
return (ecma_number_t) -0.0;
}
return (ecma_number_t) arg - fmod (arg, 1);
@ -210,7 +307,8 @@ ecma_builtin_math_object_sign (ecma_number_t arg)
return (ecma_number_t) 1.0;
} /* ecma_builtin_math_object_sign */
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* The Math object's 'random' routine.
@ -341,7 +439,7 @@ ecma_builtin_math_dispatch_routine (uint16_t builtin_routine_id, /**< built-in w
x = DOUBLE_TO_ECMA_NUMBER_T (log (x));
break;
}
#if ENABLED (JERRY_ES2015_BUILTIN)
#if ENABLED (JERRY_ES2015)
case ECMA_MATH_OBJECT_TRUNC:
{
x = ecma_builtin_math_object_trunc (x);
@ -352,12 +450,13 @@ ecma_builtin_math_dispatch_routine (uint16_t builtin_routine_id, /**< built-in w
x = ecma_builtin_math_object_sign (x);
break;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
#endif /* ENABLED (JERRY_ES2015) */
case ECMA_MATH_OBJECT_ROUND:
{
if (ecma_number_is_nan (x)
|| ecma_number_is_zero (x)
|| ecma_number_is_infinity (x))
|| ecma_number_is_infinity (x)
|| fmod (x, 1.0) == 0)
{
/* Do nothing. */
}
@ -406,27 +505,100 @@ ecma_builtin_math_dispatch_routine (uint16_t builtin_routine_id, /**< built-in w
}
case ECMA_MATH_OBJECT_POW:
{
if (ecma_number_is_nan (y) ||
(ecma_number_is_infinity (y) && (x == 1.0 || x == -1.0)))
{
/* Handle differences between ES5.1 and ISO C standards for pow. */
x = ecma_number_make_nan ();
}
else if (ecma_number_is_zero (y))
{
/* Handle differences between ES5.1 and ISO C standards for pow. */
x = (ecma_number_t) 1.0;
}
else
{
x = DOUBLE_TO_ECMA_NUMBER_T (pow (x, y));
}
x = ecma_number_pow (x, y);
break;
}
#if ENABLED (JERRY_ES2015)
case ECMA_MATH_OBJECT_ACOSH:
{
x = DOUBLE_TO_ECMA_NUMBER_T (acosh (x));
break;
}
case ECMA_MATH_OBJECT_ASINH:
{
x = DOUBLE_TO_ECMA_NUMBER_T (asinh (x));
break;
}
case ECMA_MATH_OBJECT_ATANH:
{
x = DOUBLE_TO_ECMA_NUMBER_T (atanh (x));
break;
}
case ECMA_MATH_OBJECT_CBRT:
{
x = DOUBLE_TO_ECMA_NUMBER_T (cbrt (x));
break;
}
case ECMA_MATH_OBJECT_COSH:
{
x = DOUBLE_TO_ECMA_NUMBER_T (cosh (x));
break;
}
case ECMA_MATH_OBJECT_EXPM1:
{
x = DOUBLE_TO_ECMA_NUMBER_T (expm1 (x));
break;
}
case ECMA_MATH_OBJECT_LOG1P:
{
x = DOUBLE_TO_ECMA_NUMBER_T (log1p (x));
break;
}
case ECMA_MATH_OBJECT_LOG10:
{
x = DOUBLE_TO_ECMA_NUMBER_T (log10 (x));
break;
}
case ECMA_MATH_OBJECT_LOG2:
{
x = DOUBLE_TO_ECMA_NUMBER_T (log2 (x));
break;
}
case ECMA_MATH_OBJECT_SINH:
{
x = DOUBLE_TO_ECMA_NUMBER_T (sinh (x));
break;
}
case ECMA_MATH_OBJECT_TANH:
{
x = DOUBLE_TO_ECMA_NUMBER_T (tanh (x));
break;
}
case ECMA_MATH_OBJECT_CLZ32:
{
uint32_t n = ecma_number_to_uint32 (x);
#if defined (__GNUC__) || defined (__clang__)
x = n ? __builtin_clz (n) : 32;
#elif defined (WIN32)
unsigned long ret;
x = _BitScanReverse (&ret, n) ? 31 - ret : 32;
#else
x = 32;
for (int i = 31; i >= 0; i--)
{
if (n >> i)
{
x = 31 - i;
break;
}
}
#endif
break;
}
case ECMA_MATH_OBJECT_FROUND:
{
x = (float) x;
break;
}
case ECMA_MATH_OBJECT_IMUL:
{
x = (int32_t) (ecma_number_to_uint32 (x) * ecma_number_to_uint32 (y));
break;
}
#endif /* ENABLED (JERRY_ES2015) */
}
return ecma_make_number_value (x);
}
} /* if (builtin_routine_id <= ECMA_MATH_OBJECT_POW) */
if (builtin_routine_id <= ECMA_MATH_OBJECT_MIN)
{
@ -435,6 +607,12 @@ ecma_builtin_math_dispatch_routine (uint16_t builtin_routine_id, /**< built-in w
arguments_number);
}
#if ENABLED (JERRY_ES2015)
if (builtin_routine_id == ECMA_MATH_OBJECT_HYPOT)
{
return ecma_builtin_math_object_hypot (arguments_list, arguments_number);
}
#endif /* ENABLED (JERRY_ES2015) */
JERRY_ASSERT (builtin_routine_id == ECMA_MATH_OBJECT_RANDOM);

View File

@ -64,12 +64,12 @@ NUMBER_VALUE (LIT_MAGIC_STRING_SQRT2_U,
ECMA_BUILTIN_NUMBER_SQRT2,
ECMA_PROPERTY_FIXED)
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 20.2.1.9 */
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_MATH_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
#endif /* ENABLED (JERRY_ES2015) */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
@ -91,10 +91,25 @@ ROUTINE (LIT_MAGIC_STRING_ROUND, ECMA_MATH_OBJECT_ROUND, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SIN, ECMA_MATH_OBJECT_SIN, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SQRT, ECMA_MATH_OBJECT_SQRT, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TAN, ECMA_MATH_OBJECT_TAN, 1, 1)
#if ENABLED (JERRY_ES2015_BUILTIN)
#if ENABLED (JERRY_ES2015)
ROUTINE (LIT_MAGIC_STRING_ACOSH, ECMA_MATH_OBJECT_ACOSH, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ASINH, ECMA_MATH_OBJECT_ASINH, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ATANH, ECMA_MATH_OBJECT_ATANH, 1, 1)
ROUTINE (LIT_MAGIC_STRING_CBRT, ECMA_MATH_OBJECT_CBRT, 1, 1)
ROUTINE (LIT_MAGIC_STRING_CLZ32, ECMA_MATH_OBJECT_CLZ32, 1, 1)
ROUTINE (LIT_MAGIC_STRING_COSH, ECMA_MATH_OBJECT_COSH, 1, 1)
ROUTINE (LIT_MAGIC_STRING_EXPM1, ECMA_MATH_OBJECT_EXPM1, 1, 1)
ROUTINE (LIT_MAGIC_STRING_FROUND, ECMA_MATH_OBJECT_FROUND, 1, 1)
ROUTINE (LIT_MAGIC_STRING_HYPOT, ECMA_MATH_OBJECT_HYPOT, NON_FIXED, 2)
ROUTINE (LIT_MAGIC_STRING_IMUL, ECMA_MATH_OBJECT_IMUL, 2, 2)
ROUTINE (LIT_MAGIC_STRING_LOG1P, ECMA_MATH_OBJECT_LOG1P, 1, 1)
ROUTINE (LIT_MAGIC_STRING_LOG10, ECMA_MATH_OBJECT_LOG10, 1, 1)
ROUTINE (LIT_MAGIC_STRING_LOG2, ECMA_MATH_OBJECT_LOG2, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SIGN, ECMA_MATH_OBJECT_SIGN, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SINH, ECMA_MATH_OBJECT_SINH, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TANH, ECMA_MATH_OBJECT_TANH, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TRUNC, ECMA_MATH_OBJECT_TRUNC, 1, 1)
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
#endif /* ENABLED (JERRY_ES2015) */
#endif /* ENABLED (JERRY_BUILTIN_MATH) */

View File

@ -249,16 +249,6 @@ ecma_builtin_number_prototype_object_to_string (ecma_number_t this_arg_number, /
const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
if (arguments_list_len == 0
|| ecma_number_is_nan (this_arg_number)
|| ecma_number_is_infinity (this_arg_number)
|| ecma_number_is_zero (this_arg_number)
|| (arguments_list_len > 0 && ecma_is_value_undefined (arguments_list_p[0])))
{
ecma_string_t *ret_str_p = ecma_new_ecma_string_from_number (this_arg_number);
return ecma_make_string_value (ret_str_p);
}
static const lit_utf8_byte_t digit_chars[36] =
{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
@ -267,27 +257,33 @@ ecma_builtin_number_prototype_object_to_string (ecma_number_t this_arg_number, /
'u', 'v', 'w', 'x', 'y', 'z'
};
ecma_number_t arg_num;
ecma_value_t radix_num = ecma_get_number (arguments_list_p[0], &arg_num);
if (!ecma_is_value_empty (radix_num))
uint32_t radix = 10;
if (arguments_list_len > 0 && !ecma_is_value_undefined (arguments_list_p[0]))
{
return radix_num;
ecma_number_t arg_num;
if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arguments_list_p[0], &arg_num)))
{
return ECMA_VALUE_ERROR;
}
radix = ecma_number_to_uint32 (arg_num);
if (radix < 2 || radix > 36)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Radix must be between 2 and 36."));
}
}
uint32_t radix = ecma_number_to_uint32 (arg_num);
if (radix < 2 || radix > 36)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Radix must be between 2 and 36."));
}
if (radix == 10)
if (ecma_number_is_nan (this_arg_number)
|| ecma_number_is_infinity (this_arg_number)
|| ecma_number_is_zero (this_arg_number)
|| radix == 10)
{
ecma_string_t *ret_str_p = ecma_new_ecma_string_from_number (this_arg_number);
return ecma_make_string_value (ret_str_p);
}
int buff_size = 0;
bool is_number_negative = false;
@ -373,14 +369,14 @@ ecma_builtin_number_prototype_object_to_string (ecma_number_t this_arg_number, /
{
for (int i = 0; i < magnitude; i++)
{
this_arg_number /= (ecma_number_t) radix;
this_arg_number /= radix;
}
}
else if (exponent < 0)
{
for (int i = 0; i < magnitude; i++)
{
this_arg_number *= (ecma_number_t) radix;
this_arg_number *= radix;
}
}
@ -443,7 +439,7 @@ ecma_builtin_number_prototype_object_to_string (ecma_number_t this_arg_number, /
/* Calculate digits for fractional part. */
while (buff_index < required_digits)
{
fraction *= (ecma_number_t) radix;
fraction *= radix;
lit_utf8_byte_t digit = (lit_utf8_byte_t) floor (fraction);
buff[buff_index++] = digit;
@ -596,9 +592,9 @@ ecma_builtin_number_prepare_conversion (ecma_number_t *this_num_p, /**< [out] th
JERRY_ASSERT (mode < NUMBER_ROUTINE__COUNT);
ecma_number_t arg_num;
arg_1 = ecma_get_number (arg_1, &arg_num);
arg_1 = ecma_op_to_integer (arg_1, &arg_num);
if (!ecma_is_value_empty (arg_1))
if (ECMA_IS_VALUE_ERROR (arg_1))
{
return arg_1;
}
@ -677,6 +673,7 @@ ecma_builtin_number_prototype_object_to_fixed (ecma_number_t this_num, /**< this
if (!ecma_number_is_zero (this_num))
{
num_digits = ecma_number_to_binary_floating_point_number (this_num, digits, &exponent);
JERRY_ASSERT (exponent >= 0);
}
else
{
@ -696,7 +693,7 @@ ecma_builtin_number_prototype_object_to_fixed (ecma_number_t this_num, /**< this
/* 8. */
num_digits = ecma_builtin_number_prototype_helper_round (digits,
num_digits + 1,
num_digits + (lit_utf8_size_t) exponent,
exponent + frac_digits,
&exponent,
ecma_number_is_zero (this_num));

View File

@ -93,7 +93,8 @@ ecma_builtin_number_dispatch_construct (const ecma_value_t *arguments_list_p, /*
}
} /* ecma_builtin_number_dispatch_construct */
#if ENABLED (JERRY_ES2015_BUILTIN)
#if ENABLED (JERRY_ES2015)
/**
* The Number object 'isFinite' routine
*
@ -173,7 +174,8 @@ ecma_builtin_number_object_is_integer (ecma_value_t this_arg, /**< this argument
return ECMA_VALUE_FALSE;
}
ecma_number_t int_num = ecma_number_trunc (num);
ecma_number_t int_num;
ecma_op_to_integer (arg, &int_num);
if (int_num != num)
{
@ -219,7 +221,8 @@ ecma_builtin_number_object_is_safe_integer (ecma_value_t this_arg, /**< this arg
return ECMA_VALUE_FALSE;
} /* ecma_builtin_number_object_is_safe_integer */
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
#endif /* ENABLED (JERRY_ES2015) */
/**
* @}

View File

@ -24,10 +24,9 @@
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
/* ECMA-262 v5, 15.7.3 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
ECMA_PROPERTY_FLAG_DEFAULT_LENGTH)
/* ECMA-262 v5, 15.7.3.4 */
NUMBER_VALUE (LIT_MAGIC_STRING_NAN,
@ -54,6 +53,25 @@ NUMBER_VALUE (LIT_MAGIC_STRING_NEGATIVE_INFINITY_U,
ECMA_BUILTIN_NUMBER_NEGATIVE_INFINITY,
ECMA_PROPERTY_FIXED)
#if ENABLED (JERRY_ES2015)
/* ECMA-262 v6, 20.1.2.1 */
NUMBER_VALUE (LIT_MAGIC_STRING_EPSILON_U,
ECMA_BUILTIN_NUMBER_EPSILON,
ECMA_PROPERTY_FIXED)
/* ECMA-262 v6, 20.1.2.6 */
NUMBER_VALUE (LIT_MAGIC_STRING_MAX_SAFE_INTEGER_U,
ECMA_BUILTIN_NUMBER_MAX_SAFE_INTEGER,
ECMA_PROPERTY_FIXED)
/* ECMA-262 v6, 20.1.2.8 */
NUMBER_VALUE (LIT_MAGIC_STRING_MIN_SAFE_INTEGER_U,
ECMA_BUILTIN_NUMBER_MIN_SAFE_INTEGER,
ECMA_PROPERTY_FIXED)
#endif /* ENABLED (JERRY_ES2015) */
/* Object properties:
* (property name, object pointer getter) */
@ -66,10 +84,12 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
#if ENABLED (JERRY_ES2015_BUILTIN)
#if ENABLED (JERRY_ES2015)
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) */
INTRINSIC_PROPERTY (LIT_MAGIC_STRING_PARSE_FLOAT, LIT_MAGIC_STRING_PARSE_FLOAT, ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
INTRINSIC_PROPERTY (LIT_MAGIC_STRING_PARSE_INT, LIT_MAGIC_STRING_PARSE_INT, ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_ES2015) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -16,6 +16,7 @@
#include "ecma-alloc.h"
#include "ecma-builtin-helpers.h"
#include "ecma-builtins.h"
#include "ecma-builtin-object.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
@ -23,6 +24,7 @@
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-proxy-object.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
@ -45,12 +47,13 @@ enum
ECMA_OBJECT_PROTOTYPE_TO_STRING,
ECMA_OBJECT_PROTOTYPE_VALUE_OF,
ECMA_OBJECT_PROTOTYPE_TO_LOCALE_STRING,
ECMA_OBJECT_PROTOTYPE_GET_PROTO,
ECMA_OBJECT_PROTOTYPE_IS_PROTOTYPE_OF,
ECMA_OBJECT_PROTOTYPE_HAS_OWN_PROPERTY,
ECMA_OBJECT_PROTOTYPE_PROPERTY_IS_ENUMERABLE,
ECMA_OBJECT_PROTOTYPE_SET_PROTO
};
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-object-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID object_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
@ -144,7 +147,23 @@ static ecma_value_t
ecma_builtin_object_prototype_object_has_own_property (ecma_object_t *obj_p, /**< this argument */
ecma_string_t *prop_name_p) /**< first argument */
{
return ecma_make_boolean_value (ecma_op_object_has_own_property (obj_p, prop_name_p));
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (ECMA_OBJECT_IS_PROXY (obj_p))
{
ecma_property_descriptor_t prop_desc;
ecma_value_t status = ecma_proxy_object_get_own_property_descriptor (obj_p, prop_name_p, &prop_desc);
if (ecma_is_value_true (status))
{
ecma_free_property_descriptor (&prop_desc);
}
return status;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
return ecma_make_boolean_value (ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p));
} /* ecma_builtin_object_prototype_object_has_own_property */
/**
@ -170,7 +189,7 @@ ecma_builtin_object_prototype_object_is_prototype_of (ecma_object_t *obj_p, /**<
ecma_object_t *v_obj_p = ecma_get_object_from_value (v_obj_value);
ecma_value_t ret_value = ecma_make_boolean_value (ecma_op_object_is_prototype_of (obj_p, v_obj_p));
ecma_value_t ret_value = ecma_op_object_is_prototype_of (obj_p, v_obj_p);
ecma_deref_object (v_obj_p);
@ -190,19 +209,19 @@ static ecma_value_t
ecma_builtin_object_prototype_object_property_is_enumerable (ecma_object_t *obj_p, /**< this argument */
ecma_string_t *prop_name_p) /**< first argument */
{
/* 3. */
ecma_property_t property = ecma_op_object_get_own_property (obj_p,
prop_name_p,
NULL,
ECMA_PROPERTY_GET_NO_OPTIONS);
ecma_property_descriptor_t prop_desc;
ecma_value_t status = ecma_op_object_get_own_property_descriptor (obj_p, prop_name_p, &prop_desc);
/* 4. */
if (property != ECMA_PROPERTY_TYPE_NOT_FOUND && property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP)
if (!ecma_is_value_true (status))
{
return ecma_make_boolean_value (ecma_is_property_enumerable (property));
return status;
}
return ECMA_VALUE_FALSE;
bool is_enumerable = (prop_desc.flags & ECMA_PROP_IS_ENUMERABLE);
ecma_free_property_descriptor (&prop_desc);
return ecma_make_boolean_value (is_enumerable);
} /* ecma_builtin_object_prototype_object_property_is_enumerable */
/**
@ -260,6 +279,14 @@ ecma_builtin_object_prototype_dispatch_routine (uint16_t builtin_routine_id, /**
{
ret_value = ecma_builtin_object_prototype_object_is_prototype_of (obj_p, arguments_list_p[0]);
}
#if ENABLED (JERRY_ES2015)
else if (builtin_routine_id == ECMA_OBJECT_PROTOTYPE_GET_PROTO)
{
ret_value = ecma_builtin_object_object_get_prototype_of (obj_p);
}
#endif /* ENABLED (JERRY_ES2015)*/
else
{
ret_value = ecma_builtin_object_prototype_object_to_locale_string (obj_p);
@ -272,6 +299,13 @@ ecma_builtin_object_prototype_dispatch_routine (uint16_t builtin_routine_id, /**
JERRY_ASSERT (builtin_routine_id >= ECMA_OBJECT_PROTOTYPE_HAS_OWN_PROPERTY);
#if ENABLED (JERRY_ES2015)
if (builtin_routine_id == ECMA_OBJECT_PROTOTYPE_SET_PROTO)
{
return ecma_builtin_object_object_set_proto (this_arg, arguments_list_p[0]);
}
#endif /* ENABLED (JERRY_ES2015)*/
ecma_string_t *prop_name_p = ecma_op_to_prop_name (arguments_list_p[0]);
if (prop_name_p == NULL)

View File

@ -27,6 +27,11 @@ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_OBJECT,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
ACCESSOR_READ_WRITE (LIT_MAGIC_STRING__PROTO__,
ECMA_OBJECT_PROTOTYPE_GET_PROTO,
ECMA_OBJECT_PROTOTYPE_SET_PROTO,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ECMA_OBJECT_PROTOTYPE_TO_STRING, 0, 0)

Some files were not shown because too many files have changed in this diff Show More