4 Commits

Author SHA1 Message Date
László Langó 63f739e5a0 Add documentation to port API
JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com
2016-09-01 14:52:10 +02:00
Zsolt Borbély a59cbfe1a2 [nuttx-stm32f4] Fix jerry_port_log function
JerryScript-DCO-1.0-Signed-off-by: Zsolt Borbély zsborbely.u-szeged@partner.samsung.com
2016-09-01 14:51:59 +02:00
Sergio Martinez de9c27b122 Remove problems with gettimeofday, newlibc and zephyr SDK
Fix Zephyr build

With the changes to the zephyr sdk, gettimeofday is being guarded
by XOPEN_SOURCE_EXTENDED which requires at least 700 on XOPEN_SOURCE to be active

This little patch also helps on removing most of the warnings we had before
related to that issue.

More info on this feature:
http://man7.org/linux/man-pages/man7/feature_test_macros.7.html

Another option was to enable _GNU_SOURCE for this port.

There are still some harmless warnings related to __sputc_r for which we still require
the convertion warning.

Tested on qemu_cortex_m3, qemu_x86, arduino_101 and frdm_k64f.
Zephyr Sdk 0.8.2, Zephyr 1.5.0-rc4 & Zephyr ec39b216

Closes #1311.

JerryScript-DCO-1.0-Signed-off-by: Sergio Martinez sergio.martinez.rodriguez@intel.com
2016-08-31 17:19:08 +02:00
Peter Gal 57d8b39f3f Improve the Curie build file generator a bit
Works with python 2 and 3.

JerryScript-DCO-1.0-Signed-off-by: Peter Gal pgal.u-szeged@partner.samsung.com
2016-08-31 06:26:24 -07:00
2930 changed files with 35827 additions and 116459 deletions
-77
View File
@@ -1,77 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
---
First of all, when reporting a bug, give the issue a descriptive title.
In the body of the issue, optionally give a free-form text description of the
bug. Give the context necessary for others to understand the problem.
Then, provide information necessary to reproduce the bug.
Omit sections that are irrelevant for the bug report, but note that information
like git revision, build platform, build command, and test case are required in
almost all cases.
###### JerryScript revision
Identify the git hash(es) or tag(s) where the issue was observed.
###### Build platform
Name the build platform. E.g., copy the output of
`echo "$(lsb_release -ds) ($(uname -mrs))"` (on Linux),
`echo "$(sw_vers -productName) $(sw_vers -productVersion) ($(uname -mrs))"` (on macOS), or
`python -c "import platform; print(platform.platform())"` (should work everywhere).
###### Build steps
Describe how to build JerryScript. Give all the necessary details of the build
(e.g., environment variables, command(s), profile, command line options, etc.).
E.g.:
```sh
tools/build.py --clean --debug
```
Or:
```sh
mkdir build && cmake -H. -Bbuild && make -C build
```
Even if the bug was originally observed when JerryScript was integrated into a
larger project, try to reproduce it with as few external code as possible,
preferably by building the `jerry` command line tool.
###### Build log
Copy the build log if the reported issue is a build problem. Do a verbose build
if necessary. Try and trim the log to relevant parts.
###### Test case
Give the JavaScript input that should be passed to the engine to trigger the
bug. Try and post a reduced test case that is minimally necessary to reproduce
the issue. As a rule of thumb, use Markdown's fenced code block syntax for the
test case. Attach the file (renamed to .txt) if the test case contains
'problematic' bytes that cannot be copied in the bug report directly.
###### Execution platform
Unnecessary if the same as the build platform.
###### Execution steps
List the steps that trigger the bug.
E.g., if a bug is snapshot-specific:
```sh
build/bin/jerry-snapshot generate -o testcase.js.snapshot testcase.js
build/bin/jerry --exec-snapshot testcase.js.snapshot
```
Unnecessary if trivial (i.e., `build/bin/jerry testcase.js`).
###### Output
Copy relevant output from the standard output and/or error channels.
###### Backtrace
In case of a crash (assertion failure, etc.), try to copy the backtrace from a
debugger at the point of failure.
###### Expected behavior
Describe what should happen instead of current behavior. Unnecessary if trivial
(e.g., in case of a crash, the trivial expected behavior is not to crash).
-19
View File
@@ -1,19 +0,0 @@
**PLEASE REMOVE THIS TEMPLATE BEFORE SUBMITTING**
Before submitting a PR, please, make sure that:
- Changes are in a separate branch, not in master.
- The branch contains only one commit on top of master (if not, squash them into
one commit).
- The commit has a descriptive commit message with a concise title (first line).
- The commit message contains `fixes #XXXX` or `closes #XXXX` to auto-close the
issue(s) that the PR fixes (if any).
- Tests for the changes have been added (for bug fixes / features).
- Documentation has been added / updated (if applicable).
- All new and existing tests passed locally (if not, fix them first and amend
the commit).
IMPORTANT: Please review the CONTRIBUTING.md file for detailed contributing
guidelines.
**PLEASE REMOVE THIS TEMPLATE BEFORE SUBMITTING**
+11 -12
View File
@@ -1,11 +1,11 @@
# Produced files
.mbedignore
build/*
# IDE related files
nbproject
*.sublime-project
*.sublime-workspace
**.sublime-project
**.sublime-workspace
.idea
# Random Trash
@@ -14,28 +14,27 @@ nbproject
*~
core
vgcore.*
*.orig
*.directory
*.patch
**.orig
**.directory
**.patch
.tags*
cscope.*
__pycache__
*.pyc
.DS_Store
# ctags and ID database
tags
ID
# targets
jerry-targetjs.h
jerry_targetjs.h
targets/mbedk64f/libjerry
targets/mbedk64f/build
targets/mbedk64f/yotta_modules
targets/mbedk64f/yotta_targets
.output
targets/esp8266/output.map
targets/esp8266/libs
# Generated documentation
docs/doxygen
# Tests
tests/test262/
.vs
+22 -182
View File
@@ -1,190 +1,30 @@
language: c
# Default environment: Ubuntu Trusty 14.04.
os: linux
dist: trusty
sudo: required
# Default job task: run tests as defined in the $OPT environment variable.
# Jobs can redefine the 'script' stage in the matrix below.
script: tools/run-tests.py $OPTS
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then tools/apt-get-install-deps.sh; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then tools/apt-get-install-qemu-arm.sh; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then tools/brew-install-deps.sh; fi
install:
script: "python tools/run-tests.py $OPTS"
env:
- OPTS="--check-signed-off --check-cppcheck --check-vera"
- OPTS="--jerry-tests --jerry-test-suite"
- OPTS="--jerry-tests --jerry-test-suite --toolchain=cmake/toolchain_linux_armv7l.cmake" TIMEOUT=300
- OPTS=--buildoption-test
- OPTS=--unittests
# All the job definitions in the matrix.
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++]
- name: "Linux/x86-64 Build & Correctness Tests"
env:
- OPTS="--quiet --jerry-tests --jerry-test-suite"
- name: "Linux/x86 (cpointer-32bit) Build & Correctness Tests"
env:
- OPTS="--quiet --jerry-tests --jerry-test-suite --buildoptions=--compile-flag=-m32,--cpointer-32bit=on"
addons:
apt:
packages: [gcc-multilib]
- name: "Linux/ARM Build & Correctness Tests"
env:
- OPTS="--quiet --jerry-tests --jerry-test-suite --toolchain=cmake/toolchain_linux_armv7l.cmake --buildoptions=--linker-flag=-static"
- RUNTIME=qemu-arm-static
- TIMEOUT=300
addons:
apt:
packages: [gcc-arm-linux-gnueabihf, libc6-dev-armhf-cross, qemu-user-static]
- name: "OSX/x86-64 Build, Correctness & Unit Tests"
env:
- OPTS="--quiet --jerry-tests --jerry-test-suite --unittests"
os: osx
addons:
homebrew:
packages: [cmake, cppcheck, vera++]
- name: "Build Tests"
env:
- OPTS="--buildoption-test"
addons:
apt:
packages: [gcc-multilib]
- name: "Unit Tests"
env:
- OPTS="--unittests"
- name: "Unit Tests (INIT_FINI)"
env:
- OPTS="--unittests --buildoptions=--cmake-param=-DFEATURE_INIT_FINI=ON"
- name: "Debugger Tests"
env:
- OPTS="--jerry-debugger"
- name: "Conformance Tests"
env:
- OPTS="--test262"
- name: "ASAN Tests"
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"
- 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]
- 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]
- name: "Coverity Scan"
env:
# Declaration of the encrypted COVERITY_SCAN_TOKEN, created via the
# "travis encrypt" command using the project repo's public key.
- secure: "V7BdXv3FCVkFGEfKfWto6I+Sytou1zTCGyn49xurkBfKNsG/3vbkXfsbK1m6lCZxmY7W/1odpfjixpAPZgy2L4FgPZK6/UyVvC8pIFjDOubcEniN48haleSvm/ZFPLDifxDL2+VVFtK1oRYPtDBzzSoUCcfwovgk+Wy+tSBnhnyRLqO/WaI6PqFof7ECYMTRlJVjioZARVP4YmkBruIPmGDdR/3EvwowlxfuiFoPheix61ug4x3tpTBW2qWgvFjDyCZXFz4pJrBQPTAIbyKMxHcBykJjl9eR+dWAOsvE1Uw48tFOJxjKDfUttVQUPsyKFllmcCVS0fDYB5pzZOmRUPxJmox1jt8J1FY85Ri1PGY0THBPM2H7to4Yf2418Y3539epbN8p+79dwaM7e2OiJ2owukbWI7PoNqIz5DV5zxpIKsOQfeWuNLJOgsBePEIU7lz133Si/2d5W/7If46B1d+hZRBJfSYksgDqDU6G/voZkPf0K5bKe2O2BxiIW1DYk4yQ1ecZAkqGjZ8jG3zYGMG3mSF4VyuU4UGFG1Pg8fw7Ap5zuHxSVY1H9dtu4T6JQG3aj/x1omlzfw48DjgkwxVhf7Xvl3yfR7pzydYheLX3MZYtcVo7rWnglZFZoUjWDK1StbmzsvPftvwWtoDTWlzo4xeSXhahSJvJyc4U8Wc="
addons:
coverity_scan:
project:
name: "jerryscript-project/jerryscript"
description: "Ultra-lightweight JavaScript engine for the Internet of Things."
notification_email: rsipka.uszeged@partner.samsung.com
build_command: "tools/build.py --clean"
branch_pattern: master
script: skip # Changed to nop, Coverity Scan has already built the project by the time 'script' stage is reached.
- name: "SonarQube"
addons:
sonarcloud:
organization: "jerryscript-project"
script: tools/check-sonarqube.sh
cache:
directories:
- '${HOME}/.sonar/cache'
- name: "ESP8266 Build Test"
install: make -f ./targets/esp8266/Makefile.travis install-noapt
script: make -f ./targets/esp8266/Makefile.travis script
addons:
apt:
packages: [wget]
- name: "Mbed OS 5/K64F Build Test"
addons:
apt:
sources:
- sourceline: ppa:team-gcc-arm-embedded/ppa
packages: [gcc-arm-embedded]
language: python # NOTE: only way to ensure python>=2.7.10 on Trusty image
python: 3.6
install: make -f ./targets/mbedos5/Makefile.travis install
script: make -f ./targets/mbedos5/Makefile.travis script
- name: "NuttX/STM32F4 Build Test"
install: make -f targets/nuttx-stm32f4/Makefile.travis install-noapt
script: make -f targets/nuttx-stm32f4/Makefile.travis script
addons:
apt:
packages: [gcc-arm-none-eabi, libnewlib-arm-none-eabi, gperf]
- name: "RIOT/STM32F4 Build Test"
install: make -f ./targets/riot-stm32f4/Makefile.travis install-noapt
script: make -f ./targets/riot-stm32f4/Makefile.travis script
compiler: clang-3.9
addons:
apt:
sources:
- sourceline: ppa:team-gcc-arm-embedded/ppa
packages: [clang-3.9, gcc-arm-embedded, gcc-multilib]
- name: "Tizen RT/Artik053 Build Test"
addons:
apt:
sources:
- sourceline: ppa:team-gcc-arm-embedded/ppa
packages: [gcc-arm-embedded, genromfs]
install: make -f ./targets/tizenrt-artik053/Makefile.travis install
script: make -f ./targets/tizenrt-artik053/Makefile.travis script
- name: "Zephyr/Arduino 101 Build Test"
install: make -f ./targets/zephyr/Makefile.travis install-noapt
script: make -f ./targets/zephyr/Makefile.travis script
addons:
apt:
packages: [gperf, dfu-util, device-tree-compiler, python3-ply, python3-pip]
fast_finish: true
# The channel name "chat.freenode.net#jerryscript"
# is encrypted against Samsung/jerryscript
# to prevent IRC spam of forks.
#
# travis encrypt -r "Samsung/jerryscript" "chat.freenode.net#jerryscript"
notifications:
irc:
channels:
- secure: "4kML4uZywOPaT3r/bHCvZCeQWooyzZumESmKuHG2Y8/B29WtMBobsoRQZRfOmlUP5kshfjh0Itp5WFpdACiBCoorHch/8z3VT7fIbKF4UnxrAvNiFArqxXC0OWGIu93e7uyyXJCsQ/JiOXU7bD31Mh8LbnfS1z3wBAMXi+AwcaGiVVH4VTL6O8sR3ij5WmsqpECWhyWTgTP3MiLquZ+09Lv9mp5GGciEemq4p8VnaQt2BdyEBmUJJ1EAyMCJlKNObQudegOzYsY3CVON9C87dCuHf7DYstsxb8AzwRAKn8LHiaWhYaWLfvHqoXmc4w1ZgN0HZ5Qyx8KMkZkXKUiHxuCSoXDxNAHWTGQBsTDid5drZeqOFucOHEKJzkqaWSUKUF3pY/hq/h2kjAn230DlBNkJt+ikSxwy6Mm8GG8LnH5gRMl37zHDHrtyRsKR8GIst9B1B95LAOLA5t8U/ucGKXqLsohS8glXaM4jjh69it3GeHj6NhB8NbC/LsmRrhjKzV+VnjPI6gZvN+5tDiuxMbsMal+0DdWVNCst/aO3Jz0iaA5ahyo2ZwBb2efw3CekRLMKmHtnjqB0SWWXT3/t2+5zNoM6gBjo4RPOg7k5eTOXcfk8okWtQ5d3n8UtvZ5rSiDl3rssHwp1yHuuC8rGGov74DLvyDlpM6p/dmtu2o8="
on_success: always
on_failure: always
use_notice: true
template:
- "%{repository_name} (%{branch}@%{commit}): %{author} - %{commit_subject} [%{result}]"
- "Commit: %{compare_url}"
- "Build: %{build_url}"
- os: osx
env: OPTS="--jerry-tests --jerry-test-suite"
- os: osx
env: OPTS=--unittests
allow_failures:
- os: osx
+128 -172
View File
@@ -1,4 +1,5 @@
# Copyright JS Foundation and other contributors, http://js.foundation
# Copyright 2015-2016 Samsung Electronics Co., Ltd.
# Copyright 2016 University of Szeged.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,121 +14,72 @@
# limitations under the License.
cmake_minimum_required (VERSION 2.8.12)
project (Jerry C)
project (Jerry C ASM)
# Determining platform
set(PLATFORM "${CMAKE_SYSTEM_NAME}")
string(TOUPPER "${PLATFORM}" PLATFORM)
# Determining compiler
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
set(USING_GCC 1)
endif()
# Remove rdynamic option
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS )
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(USING_CLANG 1)
endif()
if(CMAKE_C_COMPILER_ID MATCHES "TI")
set(USING_TI 1)
endif()
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
set(USING_MSVC 1)
endif()
# Determining build type
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "MinSizeRel")
endif()
# Optional components
set(JERRY_CMDLINE ON CACHE BOOL "Build jerry command line tool?")
set(JERRY_CMDLINE_TEST OFF CACHE BOOL "Build jerry test command line tool?")
set(JERRY_CMDLINE_SNAPSHOT OFF CACHE BOOL "Build jerry snapshot command line tool?")
set(JERRY_LIBFUZZER OFF CACHE BOOL "Build jerry with libfuzzer support?")
set(JERRY_PORT_DEFAULT ON CACHE BOOL "Build default jerry port implementation?")
set(JERRY_EXT ON CACHE BOOL "Build jerry-ext?")
set(JERRY_LIBM ON CACHE BOOL "Build and use jerry-libm?")
set(UNITTESTS OFF CACHE BOOL "Build unit tests?")
set(DOCTESTS OFF CACHE BOOL "Build doc tests?")
# Components
set(JERRY_CORE ON CACHE BOOL "Use jerry-core?")
set(JERRY_LIBC ON CACHE BOOL "Use jerry-libc?")
set(JERRY_LIBM ON CACHE BOOL "Use jerry-libm?")
set(JERRY_CMDLINE ON CACHE BOOL "Use jerry command line tool?")
set(UNITTESTS OFF CACHE BOOL "Use unit tests?")
# Optional build settings
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries?")
set(ENABLE_LTO ON CACHE BOOL "Enable LTO build?")
set(ENABLE_STRIP ON CACHE BOOL "Enable stripping all symbols from release binary?")
set(PORT_DIR "${CMAKE_SOURCE_DIR}/targets/default" CACHE STRING "Should we use default or external port?")
set(COMPILER_DEFAULT_LIBC OFF CACHE BOOL "Enable compiler default libc?")
set(ENABLE_LTO OFF CACHE BOOL "Enable LTO build?")
set(ENABLE_ALL_IN_ONE ON CACHE BOOL "Enable all-in-one build?")
set(ENABLE_STRIP ON CACHE BOOL "Discards all symbols from object files?")
# Option overrides
if(NOT USING_CLANG)
set(JERRY_LIBFUZZER OFF)
set(JERRY_LIBFUZZER_MESSAGE " (FORCED BY COMPILER)")
endif()
if(JERRY_CMDLINE OR JERRY_CMDLINE_TEST OR JERRY_CMDLINE_SNAPSHOT OR JERRY_LIBFUZZER OR UNITTESTS OR DOCTESTS)
set(JERRY_PORT_DEFAULT ON)
set(JERRY_PORT_DEFAULT_MESSAGE " (FORCED BY CMDLINE OR LIBFUZZER OR TESTS)")
endif()
if(JERRY_CMDLINE OR DOCTESTS)
set(JERRY_EXT ON)
set(JERRY_EXT_MESSAGE " (FORCED BY CMDLINE OR TESTS)")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
if("${PLATFORM}" STREQUAL "DARWIN")
set(JERRY_LIBM OFF)
set(ENABLE_LTO OFF)
set(ENABLE_STRIP OFF)
set(JERRY_LIBM_MESSAGE " (FORCED BY PLATFORM)")
set(ENABLE_LTO_MESSAGE " (FORCED BY PLATFORM)")
set(ENABLE_STRIP_MESSAGE " (FORCED BY PLATFORM)")
set(ENABLE_LTO "OFF")
set(ENABLE_ALL_IN_ONE "ON")
set(JERRY_LIBC "OFF")
set(JERRY_LIBM "OFF")
set(COMPILER_DEFAULT_LIBC "ON")
endif()
if(USING_TI)
set(ENABLE_STRIP OFF)
set(ENABLE_STRIP_MESSAGE " (FORCED BY COMPILER)")
endif()
if(USING_MSVC)
set(JERRY_LIBM OFF)
set(ENABLE_STRIP OFF)
set(JERRY_LIBM_MESSAGE " (FORCED BY COMPILER)")
set(ENABLE_STRIP_MESSAGE " (FORCED BY COMPILER)")
if(JERRY_LIBC AND COMPILER_DEFAULT_LIBC)
message(FATAL_ERROR "JERRY_LIBC and COMPILER_DEFAULT_LIBC is enabled at the same time!")
endif()
# Status messages
message(STATUS "CMAKE_BUILD_TYPE " ${CMAKE_BUILD_TYPE})
message(STATUS "CMAKE_C_COMPILER_ID " ${CMAKE_C_COMPILER_ID})
message(STATUS "CMAKE_SYSTEM_NAME " ${CMAKE_SYSTEM_NAME})
message(STATUS "CMAKE_SYSTEM_PROCESSOR " ${CMAKE_SYSTEM_PROCESSOR})
message(STATUS "BUILD_SHARED_LIBS " ${BUILD_SHARED_LIBS})
message(STATUS "ENABLE_LTO " ${ENABLE_LTO} ${ENABLE_LTO_MESSAGE})
message(STATUS "ENABLE_STRIP " ${ENABLE_STRIP} ${ENABLE_STRIP_MESSAGE})
message(STATUS "JERRY_CMDLINE " ${JERRY_CMDLINE} ${JERRY_CMDLINE_MESSAGE})
message(STATUS "JERRY_CMDLINE_TEST " ${JERRY_CMDLINE_TEST} ${JERRY_CMDLINE_TEST_MESSAGE})
message(STATUS "JERRY_CMDLINE_SNAPSHOT " ${JERRY_CMDLINE_SNAPSHOT} ${JERRY_CMDLINE_SNAPSHOT_MESSAGE})
message(STATUS "JERRY_LIBFUZZER " ${JERRY_LIBFUZZER} ${JERRY_LIBFUZZER_MESSAGE})
message(STATUS "JERRY_PORT_DEFAULT " ${JERRY_PORT_DEFAULT} ${JERRY_PORT_DEFAULT_MESSAGE})
message(STATUS "JERRY_EXT " ${JERRY_EXT} ${JERRY_EXT_MESSAGE})
message(STATUS "JERRY_LIBM " ${JERRY_LIBM} ${JERRY_LIBM_MESSAGE})
message(STATUS "UNITTESTS " ${UNITTESTS})
message(STATUS "DOCTESTS " ${DOCTESTS})
message(STATUS "CMAKE_SYSTEM_NAME " ${CMAKE_SYSTEM_NAME})
message(STATUS "CMAKE_SYSTEM_PROCESSOR " ${CMAKE_SYSTEM_PROCESSOR})
message(STATUS "CMAKE_BUILD_TYPE " ${CMAKE_BUILD_TYPE})
message(STATUS "JERRY_CORE " ${JERRY_CORE})
message(STATUS "JERRY_LIBC " ${JERRY_LIBC})
message(STATUS "JERRY_LIBM " ${JERRY_LIBM})
message(STATUS "JERRY_CMDLINE " ${JERRY_CMDLINE})
message(STATUS "UNITTESTS " ${UNITTESTS})
message(STATUS "PORT_DIR " ${PORT_DIR})
message(STATUS "COMPILER_DEFAULT_LIBC " ${COMPILER_DEFAULT_LIBC})
message(STATUS "ENABLE_LTO " ${ENABLE_LTO})
message(STATUS "ENABLE_ALL_IN_ONE " ${ENABLE_ALL_IN_ONE})
message(STATUS "ENABLE_STRIP " ${ENABLE_STRIP})
# Setup directories
# Note: This mimics a conventional file system layout in the build directory for
# the sake of convenient location of build artefacts. Proper installation to
# traditional locations is also supported, e.g., to /usr/local.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/")
# Project binary dir
set(PROJECT_BINARY_DIR "${CMAKE_BINARY_DIR}")
# Remove rdynamic option
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS )
# Library output directory
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib/")
# Executable output directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/")
# Archive targets output Directory
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib/")
# Compile/link flags
# Helper macros
@@ -144,7 +96,9 @@ endmacro()
macro(jerry_add_compile_warnings)
foreach(_warning ${ARGV})
jerry_add_compile_flags(-W${_warning})
jerry_add_compile_flags(-Werror=${_warning})
if(CMAKE_COMPILER_IS_GNUCC)
jerry_add_compile_flags(-Werror=${_warning})
endif()
endforeach()
endmacro()
@@ -152,77 +106,88 @@ macro(jerry_add_link_flags)
jerry_add_flags(LINKER_FLAGS_COMMON ${ARGV})
endmacro()
# build mode specific compile/link flags
set(CMAKE_C_FLAGS_RELEASE "-Os")
# Architecture-specific compile/link flags
jerry_add_compile_flags(${FLAGS_COMMON_ARCH})
jerry_add_flags(CMAKE_EXE_LINKER_FLAGS ${FLAGS_COMMON_ARCH})
# LTO
if(ENABLE_LTO)
if(USING_GCC OR USING_CLANG)
jerry_add_compile_flags(-flto)
jerry_add_link_flags(-flto)
endif()
if(USING_GCC)
jerry_add_compile_flags(-fno-fat-lto-objects)
jerry_add_compile_flags(-flto)
jerry_add_link_flags(-flto)
if(CMAKE_COMPILER_IS_GNUCC)
if(NOT "${PLATFORM}" STREQUAL "DARWIN")
jerry_add_compile_flags(-fno-fat-lto-objects)
endif()
# Use gcc-ar and gcc-ranlib to support LTO
set(CMAKE_AR "gcc-ar")
set(CMAKE_RANLIB "gcc-ranlib")
endif()
if(USING_TI)
jerry_add_link_flags(-lto)
endif()
endif()
# Define _BSD_SOURCE if we use default port and compiler default libc
if(${PORT_DIR} STREQUAL "${CMAKE_SOURCE_DIR}/targets/default" AND COMPILER_DEFAULT_LIBC)
set(DEFINES_JERRY ${DEFINES_JERRY} _BSD_SOURCE)
endif()
# Imported targets prefix
set(PREFIX_IMPORTED_LIB imported_)
# Imported libraries
if(("${PLATFORM}" STREQUAL "DARWIN") AND (NOT CMAKE_COMPILER_IS_GNUCC))
# libclang_rt.osx
set(IMPORTED_LIB "${PREFIX_IMPORTED_LIB}libclang_rt.osx")
add_library(${IMPORTED_LIB} STATIC IMPORTED)
execute_process(COMMAND ${CMAKE_C_COMPILER} ${FLAGS_COMMON_ARCH} -print-file-name=
OUTPUT_VARIABLE IMPORTED_LIBCLANG_RT_LOCATION
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(IMPORTED_LIBCLANG_RT_LOCATION "${IMPORTED_LIBCLANG_RT_LOCATION}/lib/darwin/libclang_rt.osx.a")
set_property(TARGET ${IMPORTED_LIB}
PROPERTY IMPORTED_LOCATION ${IMPORTED_LIBCLANG_RT_LOCATION})
else()
# libgcc
set(IMPORTED_LIB "${PREFIX_IMPORTED_LIB}libgcc")
add_library(${IMPORTED_LIB} STATIC IMPORTED)
execute_process(COMMAND ${CMAKE_C_COMPILER} ${FLAGS_COMMON_ARCH} -print-file-name=libgcc.a
OUTPUT_VARIABLE IMPORTED_LIBGCC_LOCATION
OUTPUT_STRIP_TRAILING_WHITESPACE)
set_property(TARGET ${IMPORTED_LIB}
PROPERTY IMPORTED_LOCATION ${IMPORTED_LIBGCC_LOCATION})
endif()
# Compiler / Linker flags
if("${PLATFORM}" STREQUAL "DARWIN")
jerry_add_compile_flags(-fno-builtin)
if(("${PLATFORM}" STREQUAL "DARWIN"))
jerry_add_link_flags(-lSystem)
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Sqc <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
set(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup")
elseif(USING_GCC OR USING_CLANG)
else()
jerry_add_link_flags(-Wl,-z,noexecstack)
endif()
if(USING_GCC OR USING_CLANG)
jerry_add_compile_flags(-std=c99 -pedantic)
# Turn off stack protector
jerry_add_compile_flags(-fno-builtin -fno-stack-protector)
jerry_add_compile_warnings(all extra format-nonliteral init-self conversion sign-conversion format-security missing-declarations shadow strict-prototypes undef old-style-definition)
jerry_add_compile_flags(-Wno-stack-protector -Wno-attributes -Werror)
# Turn off linking to compiler's default libc, in case jerry-libc or external is used
if(NOT COMPILER_DEFAULT_LIBC)
jerry_add_link_flags(-nostdlib)
endif()
if(USING_GCC)
jerry_add_compile_warnings(logical-op)
# TODO: Remove workaround for gcc 7 bug if the fallthrough comment detection is fixed.
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 7.0)
jerry_add_compile_flags(-Wno-implicit-fallthrough)
# Turn off stack protector
jerry_add_compile_flags(-fno-stack-protector)
# Debug information
jerry_add_compile_flags(-g -gdwarf-4)
jerry_add_compile_warnings(all extra format-nonliteral init-self conversion sign-conversion format-security missing-declarations)
jerry_add_compile_flags(-Wno-stack-protector -Wno-attributes)
if(CMAKE_COMPILER_IS_GNUCC)
if(JERRY_LIBC)
jerry_add_compile_flags(-Werror)
endif()
jerry_add_compile_warnings(logical-op)
else()
jerry_add_compile_flags(-Wno-nested-anon-types)
endif()
if(USING_CLANG)
jerry_add_compile_flags(-Wno-nested-anon-types -Wno-static-in-inline)
endif()
if(USING_TI)
jerry_add_compile_flags(--c99)
endif()
if(USING_MSVC)
jerry_add_link_flags(/OPT:NOREF)
# Disable MSVC warning 4996 globally because it stops us from using standard C functions.
jerry_add_compile_flags(/wd4996)
endif()
if(JERRY_LIBFUZZER)
jerry_add_compile_flags(-fsanitize=fuzzer-no-link)
endif()
# Strip binary
if(ENABLE_STRIP AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
jerry_add_link_flags(-s)
endif()
# External compiler & linker flags
if(DEFINED EXTERNAL_COMPILE_FLAGS)
jerry_add_compile_flags(${EXTERNAL_COMPILE_FLAGS})
endif()
@@ -231,8 +196,18 @@ if(DEFINED EXTERNAL_LINKER_FLAGS)
jerry_add_link_flags(${EXTERNAL_LINKER_FLAGS})
endif()
# Used for placeholder to attach single source build targets
add_custom_target(generate-single-source)
# C
jerry_add_compile_flags(-std=c99 -pedantic)
# Strip binary
if(ENABLE_STRIP AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
jerry_add_link_flags(-s)
endif()
# Jerry's libc
if(JERRY_LIBC)
add_subdirectory(jerry-libc)
endif()
# Jerry's libm
if(JERRY_LIBM)
@@ -240,35 +215,16 @@ if(JERRY_LIBM)
endif()
# Jerry's core
add_subdirectory(jerry-core)
# Jerry's extension tools
if(JERRY_EXT)
add_subdirectory(jerry-ext)
if(JERRY_CORE)
add_subdirectory(jerry-core)
endif()
# Jerry's default port implementation
if(JERRY_PORT_DEFAULT)
add_subdirectory(jerry-port/default)
endif()
# Jerry command line tool
if(JERRY_CMDLINE OR JERRY_CMDLINE_TEST OR JERRY_CMDLINE_SNAPSHOT OR JERRY_LIBFUZZER)
# Jerry commandline tool
if(JERRY_CMDLINE)
add_subdirectory(jerry-main)
endif()
# Unittests
if(UNITTESTS)
add_subdirectory(tests/unit-core)
if(JERRY_LIBM)
add_subdirectory(tests/unit-libm)
endif()
if(JERRY_EXT)
add_subdirectory(tests/unit-ext)
endif()
endif()
# Doctests
if(DOCTESTS)
add_subdirectory(tests/unit-doc)
add_subdirectory(tests/unit)
endif()
-98
View File
@@ -1,98 +0,0 @@
# Contribution Guidelines
## Patch Submission Process
The following guidelines on the submission process are provided to help you be more effective when submitting code to the JerryScript project.
When development is complete, a patch set should be submitted via GitHub pull requests. A review of the patch set will take place. When accepted, the patch set will be integrated into the master branch, verified, and tested. It is then the responsibility of the authoring developer to maintain the code throughout its lifecycle.
Please submit all patches in public by opening a pull request. Patches sent privately to Maintainers and Committers will not be considered. Because the JerryScript Project is an Open Source project, be prepared for feedback and criticism-it happens to everyone-. If asked to rework your code, be persistent and resubmit after making changes.
### 1. Scope the patch
Smaller patches are generally easier to understand and test, so please submit changes in the smallest increments possible, within reason. Smaller patches are less likely to have unintended consequences, and if they do, getting to the root cause is much easier for you and the Maintainers and Committers. Additionally, smaller patches are much more likely to be accepted.
### 2. Ensure all files have a proper license header and copyright notice
Any code that you want to contribute to the project must be licensed under the [Apache License 2.0](LICENSE). Contributions under a different license can not be accepted. Each file should start with the following header:
```c
/* 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.
*/
```
Adding copyright notices other than the project-wide notice ("Copyright JS Foundation and other contributors, http://js.foundation") is not permitted. The only exception is adding third-party code which requires copyright notices to be preserved. Adding third-party code to the project generally requires a strong justification.
### 3. Sign your work with the JerryScript [Developer's Certificate of Origin](DCO.md)
The sign-off is a simple line at the end of the commit message of the patch, which certifies that you wrote it or otherwise have the right to pass it on as an Open Source patch. The sign-off is required for a patch to be accepted.
We have the same requirements for using the signed-off-by process as the Linux kernel.
In short, you need to include a signed-off-by tag in every patch.
You should use your real name and email address in the format below:
> JerryScript-DCO-1.0-Signed-off-by: Random J Developer random@developer.example.org
"JerryScript-DCO-1.0-Signed-off-by:" this is a developer's certification that he or she has the right to submit the patch for inclusion into the project. It is an agreement to the JerryScript [Developer's Certificate of Origin](DCO.md). **Code without a proper signoff cannot be merged into the mainline.**
### 4. Open a GitHub [pull request](https://github.com/jerryscript-project/jerryscript/pulls)
You can find instructions about opening a pull request [here](https://help.github.com/articles/creating-a-pull-request).
### 5. What if my patch is rejected?
It happens all the time, for many reasons, and not necessarily because the code is bad. Take the feedback, adapt your code, and try again. Remember, the ultimate goal is to preserve the quality of the code and maintain the focus of the Project through intensive review.
Maintainers and Committers typically have to process a lot of submissions, and the time for any individual response is generally limited. If the reason for rejection is unclear, please ask for more information from the Maintainers and Committers.
If you have a solid technical reason to disagree with feedback and you feel that reason has been overlooked, take the time to thoroughly explain it in your response.
### 6. Code review
Code review can be performed by all the members of the Project (not just Maintainers and Committers). Members can review code changes and share their opinion through comments guided by the following principles:
* Discuss code; never discuss the code's author
* Respect and acknowledge contributions, suggestions, and comments
* Listen and be open to all different opinions
* Help each other
Changes are submitted via pull requests and only the Maintainers and Committers should approve or reject the pull request (note that only Maintainers can give binding review scores).
Changes should be reviewed in reasonable amount of time. Maintainers and Committers should leave changes open for some time (at least 1 full business day) so others can offer feedback. Review times increase with the complexity of the review.
## Tips on GitHub Pull Requests
* [Fork](https://guides.github.com/activities/forking) the GitHub repository and clone it locally
* Connect your local repository to the original upstream repository by adding it as a remote
* Create a [branch](https://guides.github.com/introduction/flow) for your edits
* Pull in upstream changes often to stay up-to-date so that when you submit your pull request, merge conflicts will be less likely
For more details, see the GitHub [fork syncing](https://help.github.com/articles/syncing-a-fork) guidelines.
## How to add the DCO line to every single commit automatically
It is easy to forget adding the DCO line to the end of every commit message. Fortunately there is a nice way to do it automatically. Once you've cloned the repository into your local machine, you can add `prepare commit message hook` in `.git/hooks` directory like this:
```
#!/usr/bin/env python
import sys
commit_msg_filepath = sys.argv[1]
with open(commit_msg_filepath, "r+") as f:
content = f.read()
f.seek(0, 0)
f.write("%s\n\nJerryScript-DCO-1.0-Signed-off-by: <Your Name> <Your Email>" % content)
```
Please refer [Git Hooks](http://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) for more information.
-22
View File
@@ -1,22 +0,0 @@
# JerryScript Developer's Certificate of Origin
The JerryScript project uses the signed-off-by language and process to give us a clear chain of trust for every patch received.
> By making a contribution to this project, I certify that:
> (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or
> (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
> (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
> (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project, under the same open source license.
We have the same requirements for using the signed-off-by process as the Linux kernel.
In short, you need to include a signed-off-by tag in the commit message of every patch.
You should use your real name and email address in the format below:
> JerryScript-DCO-1.0-Signed-off-by: Random J Developer random@developer.example.org
"JerryScript-DCO-1.0-Signed-off-by:" this is a developer's certification that he or she has the right to submit the patch for inclusion into the project. It is an agreement to the Developer's Certificate of Origin (above). **Code without a proper signoff cannot be merged into the mainline.**
+20 -34
View File
@@ -76,7 +76,7 @@ CREATE_SUBDIRS = NO
# U+3044.
# The default value is: NO.
# ALLOW_UNICODE_NAMES = NO
ALLOW_UNICODE_NAMES = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
@@ -341,7 +341,7 @@ IDL_PROPERTY_SUPPORT = YES
# all members of a group must be documented explicitly.
# The default value is: NO.
DISTRIBUTE_GROUP_DOC = YES
DISTRIBUTE_GROUP_DOC = NO
# Set the SUBGROUPING tag to YES to allow class member groups of the same type
# (for instance a group of public functions) to be put as a subgroup of that
@@ -409,7 +409,7 @@ LOOKUP_CACHE_SIZE = 0
# normally produced when WARNINGS is set to YES.
# The default value is: NO.
EXTRACT_ALL = NO
EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
# be included in the documentation.
@@ -512,7 +512,7 @@ HIDE_SCOPE_NAMES = NO
# YES the compound reference will be hidden.
# The default value is: NO.
# HIDE_COMPOUND_REFERENCE= NO
HIDE_COMPOUND_REFERENCE= NO
# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
# the files that are included by a file in the documentation of that file.
@@ -730,7 +730,7 @@ WARN_IF_DOC_ERROR = YES
# parameter documentation, but not about the absence of documentation.
# The default value is: NO.
WARN_NO_PARAMDOC = YES
WARN_NO_PARAMDOC = NO
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
@@ -758,7 +758,7 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = jerry-core jerry-ext jerry-port
INPUT = jerry-core jerry-libc
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -778,7 +778,7 @@ INPUT_ENCODING = UTF-8
# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
# *.qsf, *.as and *.js.
FILE_PATTERNS = *.h *.c
FILE_PATTERNS =
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
@@ -793,21 +793,7 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
# FIXME: None of these files are excluded light-heartedly. They should be
# removed one-by-one and warnings reported by doxygen should be fixed by those
# 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 \
jerry-core/parser/js/byte-code.h \
jerry-core/parser/js/common.h \
jerry-core/parser/js/js-lexer.h \
jerry-core/parser/js/js-parser-internal.h \
jerry-core/parser/regexp/re-parser.h \
jerry-core/vm/vm-stack.h
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
@@ -823,7 +809,7 @@ EXCLUDE_SYMLINKS = NO
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
EXCLUDE_PATTERNS = *.inc.h
EXCLUDE_PATTERNS =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@@ -1005,7 +991,7 @@ VERBATIM_HEADERS = YES
# compiled with the --with-libclang option.
# The default value is: NO.
# CLANG_ASSISTED_PARSING = NO
CLANG_ASSISTED_PARSING = NO
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
@@ -1013,7 +999,7 @@ VERBATIM_HEADERS = YES
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
# CLANG_OPTIONS =
CLANG_OPTIONS =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
@@ -1682,7 +1668,7 @@ LATEX_FOOTER =
# list).
# This tag requires that the tag GENERATE_LATEX is set to YES.
# LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_STYLESHEET =
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the LATEX_OUTPUT output
@@ -1807,7 +1793,7 @@ RTF_EXTENSIONS_FILE =
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
# RTF_SOURCE_CODE = NO
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
@@ -1842,7 +1828,7 @@ MAN_EXTENSION = .3
# MAN_EXTENSION with the initial . removed.
# This tag requires that the tag GENERATE_MAN is set to YES.
# MAN_SUBDIR =
MAN_SUBDIR =
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
# will generate one additional man file for each entity documented in the real
@@ -1905,7 +1891,7 @@ DOCBOOK_OUTPUT = docbook
# The default value is: NO.
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
# DOCBOOK_PROGRAMLISTING = NO
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
@@ -1974,7 +1960,7 @@ ENABLE_PREPROCESSING = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
MACRO_EXPANSION = YES
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
@@ -1982,7 +1968,7 @@ MACRO_EXPANSION = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = YES
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
@@ -2014,7 +2000,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = JERRY_STATIC_ASSERT(x,y)= JERRY_ATTR_FORMAT(x,y,z)=
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
@@ -2330,12 +2316,12 @@ DIAFILE_DIRS =
# generate a warning when it encounters a \startuml command in this case and
# will not generate output for the diagram.
# PLANTUML_JAR_PATH =
PLANTUML_JAR_PATH =
# When using plantuml, the specified paths are searched for files specified by
# the !include statement in a plantuml block.
# PLANTUML_INCLUDE_PATH =
PLANTUML_INCLUDE_PATH =
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
# that will be shown in the graph. If the number of nodes in a graph becomes
+10 -200
View File
@@ -1,203 +1,13 @@
Copyright JS Foundation and other contributors, http://js.foundation
Copyright 2014-2016 Samsung Electronics Co., Ltd.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
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
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
http://www.apache.org/licenses/LICENSE-2.0
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
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.
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.
+10 -30
View File
@@ -1,12 +1,7 @@
![](https://github.com/jerryscript-project/jerryscript/blob/master/LOGO.png)
![](https://github.com/Samsung/jerryscript/blob/master/LOGO.png)
# JerryScript: JavaScript engine for the Internet of Things
[![License](https://img.shields.io/badge/licence-Apache%202.0-brightgreen.svg?style=flat)](LICENSE)
[![Travis CI Build Status](https://travis-ci.org/jerryscript-project/jerryscript.svg?branch=master)](https://travis-ci.org/jerryscript-project/jerryscript)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/ct8reap35u2vooa5/branch/master?svg=true)](https://ci.appveyor.com/project/jerryscript-project/jerryscript/branch/master)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/12127/badge.svg)](https://scan.coverity.com/projects/jerryscript-project)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fjerryscript-project%2Fjerryscript.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fjerryscript-project%2Fjerryscript?ref=badge_shield)
[![SonarQube](https://sonarcloud.io/api/project_badges/measure?project=jerryscript-project_jerryscript&metric=ncloc)](https://sonarcloud.io/dashboard?id=jerryscript-project_jerryscript)
[![IRC Channel](https://img.shields.io/badge/chat-on%20freenode-brightgreen.svg)](https://kiwiirc.com/client/irc.freenode.net/#jerryscript)
[![Build Status](https://travis-ci.org/Samsung/jerryscript.svg?branch=master)](https://travis-ci.org/Samsung/jerryscript)
JerryScript is a lightweight JavaScript engine for resource-constrained devices such as microcontrollers. It can run on devices with less than 64 KB of RAM and less than 200 KB of flash memory.
@@ -18,23 +13,15 @@ Key characteristics of JerryScript:
* Snapshot support for precompiling JavaScript source code to byte code
* Mature C API, easy to embed in applications
Additional information can be found on our [project page](http://jerryscript.net) and [Wiki](https://github.com/jerryscript-project/jerryscript/wiki).
Additional information can be found on our [project page](http://samsung.github.io/jerryscript) and [Wiki](https://github.com/Samsung/jerryscript/wiki).
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:
| 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) |
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).
IRC channel: #jerryscript on [freenode](https://freenode.net)
Mailing list: jerryscript-dev@gna.org, you can subscribe [here](https://mail.gna.org/listinfo/jerryscript-dev) and access the mailing list archive [here](https://mail.gna.org/public/jerryscript-dev).
## Quick Start
### Getting the sources
```bash
git clone https://github.com/jerryscript-project/jerryscript.git
git clone https://github.com/Samsung/jerryscript.git
cd jerryscript
```
@@ -43,24 +30,17 @@ cd jerryscript
python tools/build.py
```
For additional information see [Getting Started](docs/00.GETTING-STARTED.md).
For additional information see [Getting Started](docs/01.GETTING-STARTED.md).
## Documentation
- [Getting Started](docs/00.GETTING-STARTED.md)
- [Configuration](docs/01.CONFIGURATION.md)
- [Getting Started](docs/01.GETTING-STARTED.md)
- [API Reference](docs/02.API-REFERENCE.md)
- [API Example](docs/03.API-EXAMPLE.md)
- [Internals](docs/04.INTERNALS.md)
- [Migration Guide](docs/16.MIGRATION-GUIDE.md)
## Contributing
The project can only accept contributions which are licensed under the [Apache License 2.0](LICENSE) and are signed according to the JerryScript [Developer's Certificate of Origin](DCO.md). For further information please see our [Contribution Guidelines](CONTRIBUTING.md).
## License
JerryScript is open source software under the [Apache License 2.0](LICENSE). Complete license and copyright information can be found in the source code.
JerryScript is Open Source software under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). Complete license and copyright information can be found in the source code.
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fjerryscript-project%2Fjerryscript.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fjerryscript-project%2Fjerryscript?ref=badge_large)
> Copyright JS Foundation and other contributors, http://js.foundation
> Copyright 2015 Samsung Electronics 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.
-36
View File
@@ -1,36 +0,0 @@
version: "{build}"
branches:
except:
- coverity_scan
- gh_pages
skip_tags: true
# Build matrix setup.
image:
- Visual Studio 2017
configuration:
- Debug
- Release
platform:
- x64
- Win32
environment:
matrix:
- FEATURE_DEBUGGER: ON
- FEATURE_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%
build:
project: build\Jerry.sln
parallel: true
verbosity: minimal
artifacts:
- path: build\bin\$(configuration)\
name: JerryScriptBinary
@@ -1,4 +1,4 @@
# Copyright JS Foundation and other contributors, http://js.foundation
# Copyright 2015 Samsung Electronics Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,7 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
set(CMAKE_SYSTEM_NAME Openwrt)
set(CMAKE_SYSTEM_PROCESSOR mips)
include(CMakeForceCompiler)
set(CMAKE_C_COMPILER mipsel-openwrt-linux-gcc)
set(CMAKE_SYSTEM_NAME EXTERNAL)
set(CMAKE_SYSTEM_PROCESSOR "${EXTERNAL_CMAKE_SYSTEM_PROCESSOR}")
CMAKE_FORCE_C_COMPILER(${EXTERNAL_CMAKE_C_COMPILER} ${EXTERNAL_CMAKE_C_COMPILER_ID})
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright JS Foundation and other contributors, http://js.foundation
# Copyright 2015-2016 Samsung Electronics Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright JS Foundation and other contributors, http://js.foundation
# Copyright 2015-2016 Samsung Electronics Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+2 -1
View File
@@ -1,4 +1,5 @@
# Copyright JS Foundation and other contributors, http://js.foundation
# Copyright 2016 Samsung Electronics Co., Ltd.
# Copyright 2016 University of Szeged.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
+4 -3
View File
@@ -1,4 +1,4 @@
# Copyright JS Foundation and other contributors, http://js.foundation
# Copyright 2015 Samsung Electronics Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,11 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
include(CMakeForceCompiler)
set(CMAKE_SYSTEM_NAME MCU)
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(CMAKE_SYSTEM_VERSION STM32F3)
set(FLAGS_COMMON_ARCH -mlittle-endian -mthumb -mcpu=cortex-m4 -march=armv7e-m -mfpu=fpv4-sp-d16 -mfloat-abi=hard)
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_C_COMPILER_WORKS TRUE)
CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)
+4 -3
View File
@@ -1,4 +1,4 @@
# Copyright JS Foundation and other contributors, http://js.foundation
# Copyright 2015 Samsung Electronics Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,11 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
include(CMakeForceCompiler)
set(CMAKE_SYSTEM_NAME MCU)
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(CMAKE_SYSTEM_VERSION STM32F4)
set(FLAGS_COMMON_ARCH -mlittle-endian -mthumb -mcpu=cortex-m4 -march=armv7e-m -mfpu=fpv4-sp-d16 -mfloat-abi=hard)
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_C_COMPILER_WORKS TRUE)
CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)
-22
View File
@@ -1,22 +0,0 @@
# Copyright JS Foundation and other contributors, http://js.foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(CMAKE_SYSTEM_NAME MCU)
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(CMAKE_SYSTEM_VERSION STM32F7)
set(FLAGS_COMMON_ARCH -mthumb -mcpu=cortex-m7 -march=armv7e-m -mfloat-abi=hard)
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_C_COMPILER_WORKS TRUE)
-33
View File
@@ -1,33 +0,0 @@
# Copyright JS Foundation and other contributors, http://js.foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include(CMakeForceCompiler)
set(CMAKE_SYSTEM_NAME MCU)
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(CMAKE_SYSTEM_VERSION TIM4F)
set(FLAGS_COMMON_ARCH --little_endian --silicon_version=7M4 --float_support=FPv4SPD16)
CMAKE_FORCE_C_COMPILER(armcl TI)
SET (CMAKE_C_FLAGS_DEBUG_INIT "-g")
SET (CMAKE_C_FLAGS_MINSIZEREL_INIT "-o4 -mf0 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE_INIT "-o4 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-o2 -g")
SET (CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-o4 -mf0 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE_INIT "-o4 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-o2 -g")
+2 -2
View File
@@ -1,4 +1,4 @@
# Copyright JS Foundation and other contributors, http://js.foundation
# Copyright 2016 Samsung Electronics Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,4 +15,4 @@
set(CMAKE_SYSTEM_NAME Openwrt)
set(CMAKE_SYSTEM_PROCESSOR mips)
set(CMAKE_C_COMPILER mips-openwrt-linux-gcc)
set(CMAKE_C_COMPILER mipsel-openwrt-linux-gcc)
-289
View File
@@ -1,289 +0,0 @@
# Configuration
JerryScript provides a large number of configuration options which can be used to enable or disable specific features, allowing users to fine tune the engine to best suit their needs.
A configuration option's value can be changed either by providing specific C preprocessor definitions, by adding CMake defininitions, or by using the arguments of the `tools/build.py` script.
This document lists the available configuration options, shows the configuration name for C, CMake, and python, and provides a brief description that explains the effect of the options.
### All-in-one build
Enables the All-in-one build process, which aggregates the contents of each source file, and uses this combined file to compile the JerryScript library.
This process can provide comparable results to link time optimization, and can be useful when LTO is not available otherwise.
| Options | |
|---------|----------------------------------------------|
| C: | `<none>` |
| CMake: | `-DENABLE_ALL_IN_ONE=ON/OFF` |
| Python: | `--all-in-one=ON/OFF` |
### Jerry debugger
Enables debugger support in the engine, which can be used to debug running JavaScript code. For more information on using the debugger see [Debugger](07.DEBUGGER.md).
The debugger is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_DEBUGGER=0/1` |
| CMake: | `-DJERRY_DEBUGGER=ON/OFF` |
| Python: | `--jerry-debugger=ON/OFF` |
### Line information
By default, all source code information is discarded after parsing is complete. This option can be used to augment the created bytecode to provide line information during runtime,
that can be used by the debugger to identify the currently executed source context. See [Debugger](07.DEBUGGER.md).
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_LINE_INFO=0/1` |
| CMake: | `-DJERRY_LINE_INFO=ON/OFF` |
| Python: | `--line-info=ON/OFF` |
### Profiles
This option can be used to enable/disable available JavaScript language features by providing profile files. Profile files contain a list of C definitions that configure each individual feature.
The `path` value for CMake and Python arguments should be a file path to the profile file, or one of `es2015-subset`, `es5.1`, or `minimal`, which are the pre-defined profiles.
To see how a profile file should be created, or what configuration options are available in C, see the profile [README](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-core/profiles/README.md).
| Options | |
|---------|----------------------------------------------|
| C: | `<see description>` |
| CMake: | `-DJERRY_PROFILE="path"` |
| Python: | `--profile="path"` |
### External context
Enables external context support in the engine. By default, JerryScript uses a statically allocated context to store the current state of the engine internals.
When this option is enabled, an externally allocated memory region can be provided through the port API to the engine, to be used as the context.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_EXTERNAL_CONTEXT=0/1` |
| CMake: | `-DJERRY_EXTERNAL_CONTEXT=ON/OFF` |
| Python: | `--external-context=ON/OFF` |
### Snapshot execution
This option can be used to enable snapshot execution in the engine.
This option is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_SNAPSHOT_EXEC=0/1` |
| CMake: | `-DJERRY_SNAPSHOT_EXEC=ON/OFF` |
| Python: | `--snapshot-exec=ON/OFF` |
### Snapshot saving
This option can be used to enable snapshot saving in the engine.
This option is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_SNAPSHOT_SAVE=0/1` |
| CMake: | `-DJERRY_SNAPSHOT_SAVE=ON/OFF` |
| Python: | `--snapshot-save=ON/OFF` |
### Jerry parser
This option can be used to enable or disable the parser. When the parser is disabled all features that depend on source parsing are unavailable (eg. `jerry_parse`, `eval`, Function constructor).
This option can be useful in combination with the snapshot feature. The parser is enabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_PARSER=0/1` |
| CMake: | `-DJERRY_PARSER=ON/OFF` |
| Python: | `--js-parser=ON/OFF` |
### Dump bytecode
This option can be used to display created bytecode in a human readable format. See [Internals](04.INTERNALS.md#byte-code) for more details.
This option is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_PARSER_DUMP_BYTE_CODE=0/1` |
| CMake: | `-DJERRY_PARSER_DUMP_BYTE_CODE=ON/OFF` |
| Python: | `--show-opcodes=ON/OFF` |
### Dump RegExp bytecode
This option can be used to display created RegExp bytecode in a human readable format. The RegExp bytecode is different from the bytecode used by the virtual machine.
This option is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_REGEXP_DUMP_BYTE_CODE=0/1` |
| CMake: | `-DJERRY_REGEXP_DUMP_BYTE_CODE=ON/OFF` |
| Python: | `--show-regexp-opcodes=ON/OFF` |
### Strict RegExp
This option can be used to enable strict RegExp mode. The standard RegExp syntax is a lot stricter than what is common in current JavaScript implementations.
When enabled, this flag disables all of the non-standard, quality-of-life RegExp features, that are implemented to provide compatibility with other commonly used engines.
This option is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_REGEXP_STRICT_MODE=0/1` |
| CMake: | `-DJERRY_REGEXP_STRICT_MODE=ON/OFF` |
| Python: | `--regexp-strict-mode=ON/OFF` |
### Error messages
Enables error messages for thrown Error objects. By default, error messages are omitted to reduce memory usage.
Enabling this feature provides detailed error messages where available, like line information for Syntax errors, variable names for Reference errors, Type/Range error messages for built-in routines, etc.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_ERROR_MESSAGES=0/1` |
| CMake: | `--DJERRY_ERROR_MESSAGES=ON/OFF` |
| Python: | `--error-messages=ON/OFF` |
### Logging
This option can be used to enable log messages during runtime. When enabled the engine will use the `jerry_port_log` port API function to print relevant log messages.
This feature is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_LOGGING=0/1` |
| CMake: | `-DJERRY_LOGGING=ON/OFF` |
| Python: | `--logging=ON/OFF` |
### LCache
This option enables the LCache, allowing faster access to object properties. The LCache usases a statically allocated hash-map, which increases memory consumption.
See [Internals](04.INTERNALS.md#lcache) for further details.
This option is enabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_LCACHE=0/1` |
| CMake: | `<none>` |
| Python: | `<none>` |
### Property hashmaps
This option enables the creation of hashmaps for object properties, which allows faster property access, at the cost of increased memory consumption.
See [Internals](04.INTERNALS.md#property-hashmap) for further details.
This option is enabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_PROPRETY_HASHMAP=0/1` |
| CMake: | `<none>` |
| Python: | `<none>` |
### Memory statistics
This option can be used to provide memory usage statistics either upon engine termination, or during runtime using the `jerry_get_memory_stats` jerry API function.
The feature can create a significant performance overhead, and should only be used for measurement purposes. This option is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_MEM_STATS=0/1` |
| CMake: | `-DJERRY_MEM_STATS=ON/OFF` |
| Python: | `--mem-stats=ON/OFF` |
### Heap size
This option can be used to adjust the size of the internal heap, represented in kilobytes. The provided value should be an integer. Values larger than 512 require 32-bit compressed pointers to be enabled.
The default value is 512.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_GLOBAL_HEAP_SIZE=(int)` |
| CMake: | `--DJERRY_GLOBAL_HEAP_SIZE=(int)` |
| Python: | `--heap-size=(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.
The default value is 0 (unlimited).
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_STACK_LIMIT=(int)` |
| CMake: | `-DJERRY_STACK_LIMIT=(int)` |
| Python: | `--stack-limit=(int)` |
### 32-bit compressed pointers
Enables 32-bit pointers instead of the default 16-bit compressed pointers. This allows the engine to use a much larger heap, but also comes with slightly increased memory usage, as objects can't be packed as tightly.
This option must be enabled when using the system allocator.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_CPOINTER_32_BIT=0/1` |
| CMake: | `-DJERRY_CPOINTER_32_BIT=ON/OFF` |
| Python: | `--cpointer-32bit=ON/OFF` |
### System allocator
This option enables the use of malloc/free instead of the internal JerryScript allocator. This feature requires 32-bit compressed pointers, and is unsupported on 64-bit architectures.
This option is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_SYSTEM_ALLOCATOR=0/1` |
| CMake: | `-DJERRY_SYSTEM_ALLOCATOR=ON/OFF` |
| Python: | `--system-allocator=ON/OFF` |
### Valgrind support
This option enables valgrind support for the internal allocator. When enabled, valgrind will be able to properly identify allocated memory regions, and report leaks or out-of-bounds memory accesses.
This option is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_VALGRIND=0/1` |
| CMake: | `-DJERRY_VALGRIND=ON/OFF` |
| Python: | `--valgrind=ON/OFF` |
### Memory stress test
This option can be used to stress test memory management, by running garbage collection before every allocation attempt.
This option is disabled by default.
| Options | |
|---------|----------------------------------------------|
| C: | `-DJERRY_MEM_GC_BEFORE_EACH_ALLOC=0/1` |
| CMake: | `-DJERRY_MEM_GC_BEFORE_EACH_ALLOC=ON/OFF` |
| Python: | `--mem-stress-test=ON/OFF` |
# Single source build mode
There is a special mode to use/"build" JerryScript. That is generating a single C file which can be
included into projects quickly. To achive this the following command can be executed to create
a set of files into the `gen_src` directory (Note that the command is executed in the jerryscript root directory
but can be adapted to run outside of the project root dir):
```sh
$ python tools/srcgenerator.py --output-dir gen_src --jerry-core --jerry-port-default --jerry-libm
```
The command creates the following files in the `gen_src` dir:
* `jerryscript.c`
* `jerryscript.h`
* `jerryscript-config.h`
* `jerryscript-port-default.c`
* `jerryscript-port-default.h`
* `jerryscript-libm.c`
* `math.h`
**Important**: the `jerryscript-config.h` contains the configurations mentioned above and
should be adapted to the required use-case. See the file contents for more details and for the
default configuration. (Note: This config file is created from the the `jerry-core/config.h` file.)
These files can be directly compiled with an application using the JerryScript API.
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/
```
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.
@@ -2,20 +2,19 @@
Currently, only Ubuntu 14.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:
There are several dependencies, that should be installed manually. The following list is required for building:
- `gcc` or any C99-compliant compiler (native or cross, e.g., arm-none-eabi)
- `gcc` or any C99-compliant compiler
- native
- arm-none-eabi
- `cmake` >= `2.8.12.2`
Several scripts and tools help the building and development process, thus it is recommended to have the following installed as well:
- `bash` >= `4.3.11`
- `cppcheck` >= `1.61`
- `vera++` >= `1.2.1`
- `python` >= `2.7.6`
```bash
sudo apt-get install gcc gcc-arm-none-eabi cmake cppcheck vera++ python
sudo apt-get install gcc g++ gcc-arm-none-eabi cmake cppcheck vera++ python
```
To make our scripts run correctly, several shell utilities should be available on the system:
@@ -39,40 +38,32 @@ python tools/build.py --debug
python tools/build.py --debug --lto=off
```
**To enable more verbose outputs for debugging**
```bash
tools/build.py --debug --logging=on --error-messages=on --line-info=on
```
**Add custom arguments to CMake**
```bash
python tools/build.py --cmake-param=CMAKE_PARAM
```
**Set a profile mode (ES5.1, subset of ES2015, minimal)**
**Set a profile mode (full, minimal)**
```bash
python tools/build.py --profile=es5.1|es2015-subset|minimal
python tools/build.py --feature=full|minimal
```
See also the related [README.md](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-core/profiles/README.md).
**Use (jerry, compiler-default, external) libc**
**Use (compiler-default, external) libc**
The default libc is the compiler-default libc but you can use an external libc as well:
The default libc is jerry-libc, but you can use compiler-default libc or an external libc:
- compiler-default libc:
```bash
python tools/build.py
python tools/build.py --jerry-libc=off --compiler-default-libc=on
```
- external libc:
```bash
python tools/build.py --compile-flag="-nostdlib -I/path/to/ext-libc/include" --link-lib="ext-c"
python tools/build.py --jerry-libc=off --compiler-default-libc=off --compile-flag="-I/path/to/libc/include"
```
**Add toolchain file**
@@ -89,46 +80,6 @@ For example the cross-compile to RaspberryPi 2 is something like this:
python tools/build.py --toolchain=cmake/toolchain_linux_armv7l.cmake
```
**Use system memory allocator**
```bash
python tools/build.py --system-allocator=on
```
*Note*: System allocator is only supported on 32 bit systems.
**Enable 32bit compressed pointers**
```bash
python tools/build.py --cpointer-32bit=on
```
*Note*: There is no compression/decompression on 32 bit systems, if enabled.
**Change default heap size (512K)**
```bash
python tools/build.py --mem-heap=256
```
If you would like to use more than 512K, then you must enable the 32 bit compressed pointers.
```bash
python tools/build.py --cpointer-32bit=on --mem-heap=1024
```
*Note*: The heap size will be allocated statically at compile time, when JerryScript memory
allocator is used.
**To build with libfuzzer support**
```bash
CC=clang python tools/build.py --libfuzzer=on --compile-flag=-fsanitize=address --lto=off
```
Check the documentation of libfuzzer to get the runtime settings of the created fuzzer
binary: https://llvm.org/docs/LibFuzzer.html.
**To get a list of all the available buildoptions for Linux**
```bash
+239 -4902
View File
File diff suppressed because it is too large Load Diff
+152 -738
View File
File diff suppressed because it is too large Load Diff
+24 -26
View File
@@ -23,7 +23,7 @@ Expression parser is responsible for parsing JavaScript expressions. It is imple
JavaScript statements are parsed by this component. It uses the [Expression parser](#expression-parser) to parse the constituent expressions. The implementation of Statement parser is located in `./jerry-core/parser/js/js-parser-statm.c`.
Function `parser_parse_source` carries out the parsing and compiling of the input ECMAScript source code. When a function appears in the source `parser_parse_source` calls `parser_parse_function` which is responsible for processing the source code of functions recursively including argument parsing and context handling. After the parsing, function `parser_post_processing` dumps the created opcodes and returns an `ecma_compiled_code_t*` that points to the compiled bytecode sequence.
Function `parser_parse_source` carries out the parsing and compiling of the input EcmaScript source code. When a function appears in the source `parser_parse_source` calls `parser_parse_function` which is responsible for processing the source code of functions recursively including argument parsing and context handling. After the parsing, function `parser_post_processing` dumps the created opcodes and returns an `ecma_compiled_code_t*` that points to the compiled bytecode sequence.
The interactions between the major components shown on the following figure.
@@ -31,21 +31,21 @@ The interactions between the major components shown on the following figure.
# Byte-code
This section describes the compact byte-code (CBC) representation. The key focus is reducing memory consumption of the byte-code representation without sacrificing considerable performance. Other byte-code representations often focus on performance only so inventing this representation is an original research.
This section describes the compact byte-code (CBC) byte-code representation. The key focus is reducing memory consumption of the byte-code representation without sacrificing considerable performance. Other byte-code representations often focus on performance only so inventing this representation is an original research.
CBC is a CISC like instruction set which assigns shorter instructions for frequent operations. Many instructions represent multiple atomic tasks which reduces the bytecode size. This technique is basically a data compression method.
CBC is a CISC like instruction set which assigns shorter instructions for frequent operations. Many instructions represent multiple atomic tasks which reduces the byte code size. This technique is basically a data compression method.
## Compiled Code Format
The memory layout of the compiled bytecode is the following.
The memory layout of the compiled byte code is the following.
![CBC layout](img/CBC_layout.png)
The header is a `cbc_compiled_code` structure with several fields. These fields contain the key properties of the compiled code.
The literals part is an array of ecma values. These values can contain any ECMAScript value types, e.g. strings, numbers, functions and regexp templates. The number of literals is stored in the `literal_end` field of the header.
The literals part is an array of ecma values. These values can contain any EcmaScript value types, e.g. strings, numbers, function and regexp templates. The number of literals is stored in the `literal_end` field of the header.
CBC instruction list is a sequence of bytecode instructions which represents the compiled code.
CBC instruction list is a sequence of byte code instructions which represents the compiled code.
## Byte-code Format
@@ -55,7 +55,7 @@ The memory layout of a byte-code is the following:
Each byte-code starts with an opcode. The opcode is one byte long for frequent and two byte long for rare instructions. The first byte of the rare instructions is always zero (`CBC_EXT_OPCODE`), and the second byte represents the extended opcode. The name of common and rare instructions start with `CBC_` and `CBC_EXT_` prefix respectively.
The maximum number of opcodes is 511, since 255 common (zero value excluded) and 256 rare instructions can be defined. Currently around 215 frequent and 70 rare instructions are available.
The maximum number of opcodes is 511, since 255 common (zero value excluded) and 256 rare instructions can be defined. Currently around 230 frequent and 120 rare instructions are available.
There are three types of bytecode arguments in CBC:
@@ -63,7 +63,7 @@ There are three types of bytecode arguments in CBC:
* __literal argument__: An integer index which is greater or equal than zero and less than the `literal_end` field of the header. For further information see next section Literals (next).
* __relative branch__: An 1-3 byte long offset. The branch argument might also represent the end of an instruction range. For example the branch argument of `CBC_EXT_WITH_CREATE_CONTEXT` shows the end of a `with` statement. More precisely the position after the last instruction in the with clause.
* __relative branch__: An 1-3 byte long offset. The branch argument might also represent the end of an instruction range. For example the branch argument of `CBC_EXT_WITH_CREATE_CONTEXT` shows the end of a `with` statement. More precisely the position after the last instruction.
Argument combinations are limited to the following seven forms:
@@ -137,12 +137,12 @@ Byte-codes of this category serve for placing objects onto the stack. As there a
<span class="CSSTableGenerator" markdown="block">
| byte-code | description |
| --------------------- | ----------------------------------------------------- |
| CBC_PUSH_LITERAL | Pushes the value of the given literal argument. |
| CBC_PUSH_TWO_LITERALS | Pushes the values of the given two literal arguments. |
| CBC_PUSH_UNDEFINED | Pushes an undefined value. |
| CBC_PUSH_TRUE | Pushes a logical true. |
| byte-code | description |
| --------------------- | ---------------------------------------------------- |
| CBC_PUSH_LITERAL | Pushes the value of the given literal argument. |
| CBC_PUSH_TWO_LITERALS | Pushes the value of the given two literal arguments. |
| CBC_PUSH_UNDEFINED | Pushes an undefined value. |
| CBC_PUSH_TRUE | Pushes a logical true. |
| CBC_PUSH_PROP_LITERAL | Pushes a property whose base object is popped from the stack, and the property name is passed as a literal argument. |
</span>
@@ -196,7 +196,7 @@ Branch byte-codes are used to perform conditional and unconditional jumps in the
| CBC_JUMP_BACKWARD | Jumps backward by the 1 byte long relative offset argument. |
| CBC_JUMP_BACKWARD_2 | Jumps backward by the 2 byte long relative offset argument. |
| CBC_JUMP_BACKWARD_3 | Jumps backward by the 3 byte long relative offset argument. |
| CBC_BRANCH_IF_TRUE_FORWARD | Jumps forward if the value on the top of the stack is true by the 1 byte long relative offset argument. |
| CBC_BRANCH_IF_TRUE_FORWARD | Jumps if the value on the top of the stack is true by the 1 byte long relative offset argument. |
</span>
@@ -219,14 +219,12 @@ ECMA component of the engine is responsible for the following notions:
## Data Representation
The major structure for data representation is `ECMA_value`. The lower three bits of this structure encode value tag, which determines the type of the value:
The major structure for data representation is `ECMA_value`. The lower two bits of this structure encode value tag, which determines the type of the value:
* simple
* number
* string
* object
* symbol
* error
![ECMA value representation](img/ecma_value.png)
@@ -245,17 +243,16 @@ Compressed pointers were introduced to save heap space.
![Compressed Pointer](img/ecma_compressed.png)
These pointers are 8 byte aligned 16 bit long pointers which can address 512 Kb of
memory which is also the maximum size of the JerryScript heap. To support even more
memory the size of compressed pointers can be extended to 32 bit to cover the entire
address space of a 32 bit system by passing "--cpointer_32_bit on" to the build
system. These "uncompressed pointers" increases the memory consumption by around 20%.
These pointers are 8 byte aligned 16 bit long pointers which can address 512 Kb of memory which is also the maximum size of the JerryScript heap.
ECMA data elements are allocated in pools (pools are allocated on heap)
Chunk size of the pool is 8 bytes (reduces fragmentation).
### Number
There are two possible representation of numbers according to standard IEEE 754:
The default is 8-byte (double),
but the engine supports the 4-byte (single precision) representation by setting JERRY_NUMBER_TYPE_FLOAT64 to 0 as well.
but the engine supports the 4-byte (single precision) representation by setting CONFIG_ECMA_NUMBER_TYPE as well.
![Number](img/number.png)
@@ -263,7 +260,7 @@ Several references to single allocated number are not supported. Each reference
### String
Strings in JerryScript are not just character sequences, but can hold numbers and so-called magic ids too. For common character sequences (defined in `./jerry-core/lit/lit-magic-strings.ini`) there is a table in the read only memory that contains magic id and character sequence pairs. If a string is already in this table, the magic id of its string is stored, not the character sequence itself. Using numbers speeds up the property access. These techniques save memory.
Strings in JerryScript are not just character sequences, but can hold numbers and so-called magic ids too. For common character sequences there is a table in the read only memory that contains magic id and character sequence pairs. If a string is already in this table, the magic id of its string is stored, not the character sequence itself. Using numbers speeds up the property access. These techniques save memory.
### Object / Lexical Environment
@@ -277,6 +274,7 @@ The objects are represented as following structure:
* Reference counter - number of hard (non-property) references
* Next object pointer for the garbage collector
* GC's visited flag
* type (function object, lexical environment, etc.)
### Properties of Objects
@@ -324,7 +322,7 @@ Collections are array-like data structures, which are optimized to save memory.
### Exception Handling
In order to implement a sense of exception handling, the return values of JerryScript functions are able to indicate their faulty or "exceptional" operation. The return values are ECMA values (see section [Data Representation](#data-representation)) and if an erroneous operation occurred the ECMA_VALUE_ERROR simple value is returned.
In order to implement a sense of exception handling, the return values of JerryScript functions are able to indicate their faulty or "exceptional" operation. The return values are actually ECMA values (see section [Data Representation](#data-representation)) in which the error bit is set if an erroneous operation is occurred.
### Value Management and Ownership
+71 -232
View File
@@ -11,8 +11,7 @@ It is questionable whether a library should be able to terminate an application.
*
* @param code gives the cause of the error.
*
* Note:
* Jerry expects the function not to return.
* Note: jerry expects the function not to return.
*
* Example: a libc-based port may implement this with exit() or abort(), or both.
*/
@@ -25,8 +24,8 @@ Error codes
typedef enum
{
ERR_OUT_OF_MEMORY = 10,
ERR_SYSCALL = 11,
ERR_REF_COUNT_LIMIT = 12,
ERR_DISABLED_BYTE_CODE = 13,
ERR_FAILED_INTERNAL_ASSERTION = 120
} jerry_fatal_code_t;
```
@@ -36,6 +35,20 @@ typedef enum
These are the only I/O functions jerry calls.
```c
/**
* Print a string to the console. The function should implement a printf-like
* interface, where the first argument specifies a format string on how to
* stringify the rest of the parameter list.
*
* This function is only called with strings coming from the executed ECMAScript
* wanting to print something as the result of its normal operation.
*
* It should be the port that decides what a "console" is.
*
* Example: a libc-based port may implement this with vprintf().
*/
void jerry_port_console (const char *fmt, ...);
/**
* Jerry log levels. The levels are in severity order
* where the most serious levels come first.
@@ -49,171 +62,52 @@ typedef enum
} jerry_log_level_t;
/**
* Display or log a debug/error message, and sends it to the debugger client as well.
* The function should implement a printf-like interface, where the first argument
* specifies the log level and the second argument specifies a format string on how
* to stringify the rest of the parameter list.
* Display or log a debug/error message. The function should implement a printf-like
* interface, where the first argument specifies the log level
* and the second argument specifies a format string on how to stringify the rest
* of the parameter list.
*
* This function is only called with messages coming from the jerry engine as
* the result of some abnormal operation or describing its internal operations
* the result of some abnormal operation or describing its internal operations
* (e.g., data structure dumps or tracing info).
*
* It should be the port that decides whether error and debug messages are logged to
* the console, or saved to a database or to a file.
*
* Example: a libc-based port may implement this with vfprintf(stderr) or
*
* Example: a libc-based port may implement this with vfprintf(stderr) or
* vfprintf(logfile), or both, depending on log level.
*
* Note:
* This port function is called by jerry-core when JERRY_LOGGING is
* enabled. It is also common practice though to use this function in
* application code.
*/
void jerry_port_log (jerry_log_level_t level, const char *fmt, ...);
```
The `jerry_port_print_char` is currenlty not used by the jerry-core directly.
However, it provides a port specifc way for `jerry-ext` components to print
information.
```c
/**
* Print a character to stdout.
*/
void jerry_port_print_char (char c);
```
### ES2015 Module system helper functions
The module system requires two specific functions for opening and closing files.
It also requires a platform specific way of normalizing file paths.
```c
/**
* Opens file with the given path and reads its source.
* @return the source of the file
*/
uint8_t *
jerry_port_read_source (const char *file_name_p, /**< file name */
size_t *out_size_p) /**< [out] read bytes */
{
// open file from given path
// return its source
} /* jerry_port_read_source */
/**
* Release the previously opened file's content.
*/
void
jerry_port_release_source (uint8_t *buffer_p) /**< buffer to free */
{
free (buffer_p);
} /* jerry_port_release_source */
/**
* Normalize a file path
*
* @return length of the path written to the output buffer
*/
size_t
jerry_port_normalize_path (const char *in_path_p, /**< input file path */
char *out_buf_p, /**< output buffer */
size_t out_buf_size, /**< size of output buffer */
char *base_file_p) /**< base file path */
{
// normalize in_path_p by expanding relative paths etc.
// if base_file_p is not NULL, in_path_p is relative to that file
// write to out_buf_p the normalized path
// return length of written path
} /* jerry_port_normalize_path */
```
## Date
```c
/**
* Get local time zone adjustment, in milliseconds, for the given timestamp.
* The timestamp can be specified in either UTC or local time, depending on
* the value of is_utc. Adding the value returned from this function to
* a timestamp in UTC time should result in local time for the current time
* zone, and subtracting it from a timestamp in local time should result in
* UTC time.
*
* Ideally, this function should satisfy the stipulations applied to LocalTZA
* in section 20.3.1.7 of the ECMAScript version 9.0 spec.
*
* See Also:
* ECMA-262 v9, 20.3.1.7
*
* Note:
* This port function is called by jerry-core when
* JERRY_BUILTIN_DATE is set to 1. Otherwise this function is
* not used.
*
* @param unix_ms The unix timestamp we want an offset for, given in
* millisecond precision (could be now, in the future,
* or in the past). As with all unix timestamps, 0 refers to
* 1970-01-01, a day is exactly 86 400 000 milliseconds, and
* leap seconds cause the same second to occur twice.
* @param is_utc Is the given timestamp in UTC time? If false, it is in local
* time.
*
* @return milliseconds between local time and UTC for the given timestamp,
* if available
*. 0 if not available / we are in UTC.
* Jerry time zone structure
*/
double jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc);
typedef struct
{
int offset; /**< minutes from west */
int daylight_saving_time; /**< daylight saving time (1 - DST applies, 0 - not on DST) */
} jerry_time_zone_t;
/**
* Get timezone and daylight saving data
*
* @return true - if success
* false - otherwise
*/
bool jerry_port_get_time_zone (jerry_time_zone_t *);
/**
* Get system time
*
* Note:
* This port function is called by jerry-core when
* JERRY_BUILTIN_DATE is set to 1. It is also common practice
* in application code to use this function for the initialization of the
* random number generator.
*
* @return milliseconds since Unix epoch
*/
double jerry_port_get_current_time (void);
```
## External context
Allow user to provide external buffer for isolated engine contexts, so that user
can configure the heap size at runtime and run multiple JS applications
simultaneously.
```c
/**
* Get the current context of the engine. Each port should provide its own
* implementation of this interface.
*
* Note:
* This port function is called by jerry-core when
* JERRY_EXTERNAL_CONTEXT is enabled. Otherwise this function is not
* used.
*
* @return the pointer to the engine context.
*/
struct jerry_context_t *jerry_port_get_current_context (void);
```
## Sleep
```c
/**
* Makes the process sleep for a given time.
*
* Note:
* This port function is called by jerry-core when JERRY_DEBUGGER is set to 1.
* Otherwise this function is not used.
*
* @param sleep_time milliseconds to sleep.
*/
void jerry_port_sleep (uint32_t sleep_time);
```
# How to port JerryScript
This section describes a basic port implementation which was created for Unix based systems.
@@ -222,7 +116,7 @@ This section describes a basic port implementation which was created for Unix ba
```c
#include <stdlib.h>
#include "jerryscript-port.h"
#include "jerry-port.h"
/**
* Default implementation of jerry_port_fatal.
@@ -237,7 +131,20 @@ void jerry_port_fatal (jerry_fatal_code_t code)
```c
#include <stdarg.h>
#include "jerryscript-port.h"
#include "jerry-port.h"
/**
* Provide console message implementation for the engine.
*/
void
jerry_port_console (const char *format, /**< format string */
...) /**< parameters */
{
va_list args;
va_start (args, format);
vfprintf (stdout, format, args);
va_end (args);
} /* jerry_port_console */
/**
* Provide log message implementation for the engine.
@@ -257,45 +164,39 @@ jerry_port_log (jerry_log_level_t level, /**< log level */
} /* jerry_port_log */
```
```c
/**
* Print a character to stdout with putchar.
*/
void
jerry_port_print_char (char c)
{
putchar (c);
} /* jerr_port_print_char */
```
## Date
```c
#include <time.h>
#include <sys/time.h>
#include "jerryscript-port.h"
#include "jerry-port.h"
/**
* Default implementation of jerry_port_get_local_time_zone_adjustment.
* Default implementation of jerry_port_get_time_zone.
*/
double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */
bool is_utc) /**< is the time above in UTC? */
bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p)
{
struct tm tm;
time_t now = (time_t) (unix_ms / 1000);
localtime_r (&now, &tm);
if (!is_utc)
struct timeval tv;
struct timezone tz;
/* gettimeofday may not fill tz, so zero-initializing */
tz.tz_minuteswest = 0;
tz.tz_dsttime = 0;
if (gettimeofday (&tv, &tz) != 0)
{
now -= tm.tm_gmtoff;
localtime_r (&now, &tm);
return false;
}
return ((double) tm.tm_gmtoff) * 1000;
} /* jerry_port_get_local_time_zone_adjustment */
tz_p->offset = tz.tz_minuteswest;
tz_p->daylight_saving_time = tz.tz_dsttime > 0 ? 1 : 0;
return true;
} /* jerry_port_get_time_zone */
/**
* Default implementation of jerry_port_get_current_time.
*/
double jerry_port_get_current_time (void)
double jerry_port_get_current_time ()
{
struct timeval tv;
@@ -307,65 +208,3 @@ double jerry_port_get_current_time (void)
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
} /* jerry_port_get_current_time */
```
## External context
```c
#include "jerryscript-port.h"
#include "jerryscript-port-default.h"
/**
* Pointer to the current context.
* Note that it is a global variable, and is not a thread safe implementation.
*/
static jerry_context_t *current_context_p = NULL;
/**
* Set the current_context_p as the passed pointer.
*/
void
jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */
{
current_context_p = context_p;
} /* jerry_port_default_set_current_context */
/**
* Get the current context.
*
* @return the pointer to the current context
*/
jerry_context_t *
jerry_port_get_current_context (void)
{
return current_context_p;
} /* jerry_port_get_current_context */
```
## Sleep
```c
#include "jerryscript-port.h"
#include "jerryscript-port-default.h"
#ifdef HAVE_TIME_H
#include <time.h>
#elif defined (HAVE_UNISTD_H)
#include <unistd.h>
#endif /* HAVE_TIME_H */
#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
void jerry_port_sleep (uint32_t sleep_time)
{
#ifdef HAVE_TIME_H
nanosleep (&(const struct timespec)
{
(time_t) sleep_time / 1000, ((long int) sleep_time % 1000) * 1000000L /* Seconds, nanoseconds */
}
, NULL);
#elif defined (HAVE_UNISTD_H)
usleep ((useconds_t) sleep_time * 1000);
#endif /* HAVE_TIME_H */
(void) sleep_time;
} /* jerry_port_sleep */
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
```
-176
View File
@@ -1,176 +0,0 @@
## Reference counting in JerryScript
In JerryScript all `jerry_value_t` values are independent
references to internal objects. Values returned by JerryScript
API functions are always live references and must be released
by `jerry_release_value`.
```c
jerry_value_t global = jerry_get_global_object ();
/* The value stored in the 'global' variable contains a live
* reference to the global object. The system also keeps its
* own live reference to the global object. These two references
* are independent, and both must be destroyed before the global
* object can be freed. */
jerry_release_value (global);
/* Without jerry_release_value() the global object will not
* be freed even by jerry_cleanup(). After the reference
* is released it becomes a dead reference and cannot be
* used anymore. */
```
Multiple references might refer to the same internal object
even though their `jerry_value_t` representation might be different.
```c
jerry_value_t pi_ref1 = jerry_create_number (3.14);
jerry_value_t pi_ref2 = jerry_acquire_value (pi_ref1);
/* Both pi_ref1 and pi_ref2 refer to the same 3.14 value
* although they might not be equal in C (pi_ref1 != pi_ref2). */
/* Both references must be released. */
jerry_release_value (pi_ref1);
jerry_release_value (pi_ref2);
```
Releasing the same `jerry_value_t` twice to release two live
references is not allowed and it might cause crashes. Hence the
following code is an **INCORRECT WAY** of releasing the 3.14 value.
```c
jerry_release_value (pi_ref1);
jerry_release_value (pi_ref1);
```
JerryScript API functions returning with a `jerry_value_t` always
return with a new live reference. Passing a `jerry_value_t` to
an API function never releases its reference (unless explicitly
stated in the documentation). The next example shows this
behaviour through property getting and setting.
```c
jerry_value_t prop_value = jerry_get_property (...);
/* The prop_value must be released later because both the base
* object and the prop_value have an independent reference to
* the same JavaScript value. When the operation fails, the
* prop_value contains a live reference to an error object.
* This reference must be released as well. */
if (jerry_value_is_error (prop_value))
{
/* Errors can be handled here. */
}
else
{
/* The application has a live reference to the property
* value even if the base object is freed by the garbage
* collector. */
}
/* The prop_value must be released. */
jerry_release_value (prop_value);
/* Property setting is the same. */
jerry_value_t new_prop_value = jerry_create_number (2.718);
jerry_value_t result = jerry_set_property (..., new_prop_value);
/* If the property set is successful, a new reference is created
* for the value referenced by new_prop_value. The new_prop_value
* reference must be released regardless of whether the operation
* is successful. */
/* The new_prop_value can be passed to other JerryScript API
* functions before the jerry_release_value () call. */
jerry_release_value (new_prop_value);
/* The reference stored in the 'result' variable is live whether
* the operation is successful or not, and must also be freed. */
if (jerry_value_is_error (result))
{
/* Errors can be handled here. */
}
else
{
/* A reference to a true primitive value is returned. */
}
jerry_release_value (result);
```
The simplest form of setting a property without error checking
is the following:
```c
/* There are no 'ifs' in this snippet. */
jerry_release_value (jerry_set_property (..., new_prop_value));
jerry_release_value (new_prop_value);
```
The reference returned by a `jerry_external_handler_t` callback
transfers the ownership of the live reference. Otherwise the
referenced object could be freed by the garbage collector.
```c
jerry_value_t my_external_handler (const jerry_value_t function_obj,
const jerry_value_t this_val,
const jerry_value_t args_p[],
const jerry_length_t args_count
{
/* Do not release function_obj, this_val, and args_p because
* these references are automatically released after the handler
* is returned. This approach reduces code size which is useful
* on embedded systems. However you can create other references
* to them by calling jerry_acquire_value () if needed. */
/* Since the ownership of the reference is transferred to the
* caller the following snippet is valid. */
/* If the value to be returned is needed for other purposes the
* jerry_acquire_value () can be used to create new references. */
return jerry_create_string (...);
}
```
Duplicating a `jerry_value_t` in C does not create another live reference.
```c
jerry_value_t undef = jerry_create_undefined ();
jerry_value_t undef2 = undef;
/* Releasing either undef or undef2 is valid but not both.
* After the release both references become dead (invalid). */
jerry_release_value (undef2);
/* Dead references can be reassigned again. */
undef = jerry_create_boolean (true);
```
References can be duplicated in C as long as only one of them is freed.
```c
jerry_value_t a = jerry_create_boolean (true);
jerry_value_t b = a;
jerry_value_t c = a;
/* A new reference is assigned to 'a'. */
a = jerry_create_boolean (false);
[...]
jerry_release_value (a);
/* The 'a' (boolean false) reference becomes dead (invalid). */
jerry_release_value (c);
/* Both 'b' and 'c' (boolean true) references become dead. */
/* Since all references are released, no memory leak occurs. */
```
-441
View File
@@ -1,441 +0,0 @@
## JerryScript debugger interface
JerryScript provides a remote debugger which allows debugging
JavaScript programs. The debugger has two main components:
a server which is part of the JerryScript binary and a
separate client application. Currently a Python-based debugger
client is available in the /jerry-debugger subdirectory.
This simple application demonstrates the communication protocol
between the client and server, and can be reused by integrated
development environments.
## Setting up the debugger server
The following arguments must be passed to `tools/build.py`:
`--jerry-debugger=on`
The transport layer of the communication protocol is pluggable.
At the moment, a WebSocket-based implementation is provided as a
JerryScript extension, which transmits messages over TCP/IP networks.
If necessary/implemented, any reliable stream or datagram based
protocol can be used for transmitting debugger messages.
## Debugging JavaScript applications
The debugger client must be connected to the server before the
JavaScript application runs. On-the-fly attachment is supported
for more than one file, right after the engine initialization
(this feature is available with the python client). The debugging
information (e.g. line index of each possible breakpoint location)
is not preserved by JerryScript. The client is expected to be run
on a system with much more resources and it should be capable of
storing this information. JerryScript frees all debug information
after it is transmitted to the client to save memory.
The following argument makes JerryScript wait for a client
connection:
`--start-debug-server`
The following argument makes JerryScript wait for a client
source code:
`--debugger-wait-source`
It is also recommended to increase the log level to see
the *Waiting for client connection* message:
`--log-level 2`
The Python client can connect to the server by specifying its
IP address on the command line. The address can be localhost
if the server and the client are running on the same machine.
After the connection is established the execution can be
controlled by the debugger. The debugger always stops at
the first possible breakpoint location. The effect is the
same as using the `stop` command. This allows inserting
breakpoints right before the meaningful part of the execution
starts.
All available commands of the client can be queried by the
`help` command.
## Integrating debugger support into applications using JerryScript
When using the extension-provided WebSocket transport layer, the
debugger can be enabled by calling `jerryx_debugger_after_connect
(jerryx_debugger_tcp_create (debug_port) && jerryx_debugger_ws_create ())`
after the `jerry_init ()` function. It initializes the debugger and
blocks until a client connects.
(Custom transport layers may be implemented and initialized similarly.
Currently, `jerryx_debugger_rp_create ()` for raw packet transport layer and
`jerryx_debugger_serial_create (const char* config)` for serial protocol
are also available.)
The resource name provided to `jerry_parse ()` is used by the client
to identify the resource name of the source code. This resource name
is usually a file name.
## JerryScript debugger C-API interface
The following section describes the debugger functions
available to the host application.
## JerryScript debugger types
## jerry_debugger_wait_for_source_callback_t
**Summary**
This callback function is called by
[jerry_debugger_wait_for_client_source](#jerry_debugger_wait_for_client_source)
when a source code is received successfully.
**Prototype**
```c
typedef jerry_value_t
(*jerry_debugger_wait_for_source_callback_t) (const jerry_char_t *resource_name_p,
size_t resource_name_size,
const jerry_char_t *source_p,
size_t source_size, void *user_p);
```
- `resource_name_p` - resource (usually a file) name of the source code
- `resource_name_size` - size of resource name
- `source_p` - source code character data
- `source_size` - size of source code
- `user_p` - custom pointer passed to [jerry_debugger_wait_for_client_source](#jerry_debugger_wait_for_client_source)
## JerryScript debugger functions
### jerry_debugger_is_connected
**Summary**
Returns true if a remote debugger client is connected.
**Prototype**
```c
bool
jerry_debugger_is_connected (void);
```
**Example**
[doctest]: # (test="link")
```c
#include "jerryscript.h"
#include "jerryscript-ext/debugger.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
&& jerryx_debugger_ws_create ());
if (jerry_debugger_is_connected ())
{
printf ("A remote debugger client is connected.");
}
jerry_cleanup ();
}
```
### jerry_debugger_stop
**Summary**
Stops execution at the next available breakpoint if a remote
debugger client is connected and the engine is not waiting at
a breakpoint. The engine will stop regardless the breakpoint
is enabled or not.
**Prototype**
```c
void
jerry_debugger_stop (void)
```
**Example**
[doctest]: # (test="link")
```c
#include "jerryscript.h"
#include "jerryscript-ext/debugger.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
&& jerryx_debugger_ws_create ());
jerry_debugger_stop ();
jerry_cleanup ();
}
```
**See also**
- [jerry_debugger_continue](#jerry_debugger_continue)
### jerry_debugger_continue
**Summary**
If the engine would stop at the next available breakpoint it
cancels this effect. The engine will still stop at enabled
breakpoints. This function effectively negates the effect of
[jerry_debugger_stop ()](#jerry_debugger_stop) calls or stop
requests issued by the debugger client.
**Prototype**
```c
void
jerry_debugger_continue (void)
```
**Example**
[doctest]: # (test="link")
```c
#include "jerryscript.h"
#include "jerryscript-ext/debugger.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
&& jerryx_debugger_ws_create ());
jerry_debugger_continue ();
jerry_cleanup ();
}
```
**See also**
- [jerry_debugger_stop](#jerry_debugger_stop)
### jerry_debugger_stop_at_breakpoint
**Summary**
Enables or disables stopping at breakpoints. When stopping is
disabled all breakpoints are ignored including user enabled
breakpoints. This allows hidden execution of ECMAScript code.
**Prototype**
```c
void
jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint)
```
- `enable_stop_at_breakpoint` - enable (=`true`) or disable (=`false`) stopping at breakpoints
**Example**
[doctest]: # (test="link")
```c
#include "jerryscript.h"
#include "jerryscript-ext/debugger.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
&& jerryx_debugger_ws_create ());
jerry_debugger_stop_at_breakpoint (true);
// Protected execution of JavaScript code.
const jerry_char_t script[] = "42";
jerry_eval (script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
jerry_debugger_stop_at_breakpoint (false);
jerry_cleanup ();
}
```
### jerry_debugger_wait_for_client_source
**Summary**
Asks the client to provide the next source code. The function
waits until the whole source code is received. As a reply the
the client may request a context reset or notify that no more
source is available. These notifications are passed back as the
return value of the function.
**Prototype**
```c
jerry_debugger_wait_for_source_status_t
jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t callback_p,
void *user_p, jerry_value_t *return_value)
```
**Example**
[doctest]: # (test="link")
```c
#include "jerryscript.h"
#include "jerryscript-ext/debugger.h"
/**
* Runs the source code received by jerry_debugger_wait_for_client_source.
*/
static jerry_value_t
wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resource name */
size_t resource_name_size, /**< size of resource name */
const jerry_char_t *source_p, /**< source code */
size_t source_size, /**< source code size */
void *user_p __attribute__((unused))) /**< user pointer */
{
jerry_value_t ret_val = jerry_parse (resource_name_p,
resource_name_size,
source_p,
source_size,
JERRY_PARSE_NO_OPTS);
if (!jerry_value_is_error (ret_val))
{
jerry_value_t func_val = ret_val;
ret_val = jerry_run (func_val);
jerry_release_value (func_val);
}
return ret_val;
} /* wait_for_source_callback */
int
main (void)
{
jerry_debugger_wait_for_source_status_t receive_status;
do
{
/* Create a new JerryScript instance when a context reset is
* received. Applications usually registers their core bindings
* here as well (e.g. print, setTimeout). */
jerry_init (JERRY_INIT_EMPTY);
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
&& jerryx_debugger_ws_create ());
do
{
jerry_value_t run_result;
receive_status = jerry_debugger_wait_for_client_source (wait_for_source_callback,
NULL,
&run_result);
jerry_release_value (run_result);
}
while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
jerry_cleanup ();
}
while (receive_status == JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED);
if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
{
// Handle the failure (e.g. display an error).
}
return 0;
}
```
### jerry_debugger_send_output
**Summary**
Sends the program's output to the debugger client.
**Prototype**
```c
void
jerry_debugger_send_output (const jerry_char_t *buffer, jerry_size_t string_size)
```
**Example**
[doctest]: # (test="link")
```c
#include "jerryscript.h"
#include "jerryscript-ext/debugger.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
&& jerryx_debugger_ws_create ());
jerry_char_t my_output[] = "Hey, this should be sent too!";
jerry_size_t my_output_size = sizeof (my_output);
jerry_debugger_send_output (my_output, my_output_size);
jerry_cleanup ();
}
```
### jerry_debugger_send_log
**Summary**
Sends the program's log to the debugger client.
**Prototype**
```c
void
jerry_debugger_send_log (jerry_log_level_t level, const jerry_char_t *buffer, jerry_size_t string_size)
```
**Example**
[doctest]: # (test="link")
```c
#include "jerryscript.h"
#include "jerryscript-ext/debugger.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
&& jerryx_debugger_ws_create ());
jerry_char_t my_log[] = "Custom diagnostics";
jerry_size_t my_log_size = sizeof (my_log);
jerry_debugger_send_log (JERRY_LOG_LEVEL_DEBUG, my_log, my_log_size);
jerry_cleanup ();
}
```
-797
View File
@@ -1,797 +0,0 @@
# JerryScript Coding Standards
This text is a brief overview of JerryScript Coding Standards.
Each rule starts with a short description followed by several
examples. We believe examples are better than long explanations.
Please follow these guidelines when you submit a patch for
review.
## General rules
* Indentation is two spaces.
* Tab characters are not allowed.
* Maximum line length is 120 characters (excluding newline).
* No trailing white space is allowed.
* Run `tools/run-tests.py --check-vera` to check several
of the coding conventions automatically.
## Comments
Only block comments (`/* */`) are allowed in JerryScript.
Comments should be complete sentences (e.g. start with an
upper case letter), except for return value, field and
argument descriptions (see the exceptions below). The
text part of a comment should focus on explaining *why*
the code is doing something rather than *what* the code
is doing.
```diff
+++ Good +++
```
```c
/* A perfect comment. */
/* A perfect multiline
* comment. Each line should
* start with an asterisk. */
```
```diff
--- Bad ---
```
```c
// Double slash comments are not allowed.
/* not a complete sentence */
/* A bad mulitiline
comment. */
```
All types, constants and functions require a description in
JerryScript. These comments should start with `/**`. The starting
`/**` and ending `*/` must be on separate lines.
```diff
+++ Good +++
```
```c
/**
* A correct description.
*/
```
```diff
--- Bad ---
```
```c
/** An incorrect description. */
```
## Preprocessor defines
The name of a preprocessor macro must be an uppercase string
and these macros must be preceded by a description.
Abbreviations are allowed but not preferred in new code.
```diff
+++ Good +++
```
```c
/**
* Short description about the constant.
*/
#define JERRY_VALUE_SEVEN 7
/**
* Short description about the macro function.
*/
#define JERRY_ADD_TWO_NUMBERS(arg1, arg2) \
((arg1) + (arg2))
/**
* Although this is correct, a reviewer might request
* to change NUMS to NUMBERS. Hence it is recommended
* to use NUMBERS in the first place.
*/
#define JERRY_ADD_TWO_NUMS(arg1, arg2) \
((arg1) + (arg2))
```
```diff
--- Bad ---
```
```c
#define JERRY_CONSTANT_WITHOUT_DESCRIPTION 5
#define JeRrY_mIxEd_CaSe_NaMe "str"
```
## Conditional preprocessor directives
A comment is required after `#else` and `#endif` in JerryScript.
The defined keyword should be omitted from these comments.
```diff
+++ Good +++
```
```c
#ifdef JERRY_A
#else /* !JERRY_A */
#endif /* JERRY_A */
#ifdef JERRY_A
#if defined JERRY_B && defined JERRY_C && (JERRY_C > 6)
#else /* !(JERRY_B && JERRY_C && (JERRY_C > 6)) */
#endif /* JERRY_B && JERRY_C && (JERRY_C > 6) */
#endif /* JERRY_A */
```
```diff
--- Bad ---
```
```c
#ifdef JERRY_A
#endif
#ifdef JERRY_A
#endif /* defined JERRY_A */
#ifdef JERRY_B
/* Missing comment after else. */
#else
#endif /* JERRY_B */
```
## Code blocks
Each code block must be enclosed in curly braces even
if it is a single line statement. These braces must
be on separate lines. There must be a single space
before the opening parenthesis of the expression
after if/while/switch keywords.
```diff
+++ Good +++
```
```c
if (value > 6)
{
function_call ();
}
if (value > 1)
{
function_call_a ();
}
else
{
function_call_b ();
}
do
{
function_call ();
value++;
}
while (value < 6);
switch (value)
{
case A:
{
/* FALLTHRU comment is allowed if a
* switch-case is not terminated by
* break/continue/return. */
/* FALLTHRU */
}
case B:
case C:
{
break;
}
case D:
{
/* We can use continue if we are in a loop. */
continue;
}
default:
{
return;
}
}
```
```diff
--- Bad ---
```
```c
if (value > 6)
function_call_a ();
else
function_call_b ();
if (value > 6) {
function_call_a ();
}
if (value > 6) function_call_a ();
else { function_call_b (); }
if
(value > 6)
{
}
switch (value) {
case 0: break;
default: {
return 5;
}
}
switch (value)
{
case A:
{
if (value > 6)
{
CASE B:
{
/* This is allowed in C but
* not in JerryScript. */
break;
}
}
}
}
do
value++;
while (value < 5);
do {
value++;
} while (value < 5);
do
{
value++;
} while (value < 5);
```
## Newlines
A newline in JerryScript is a separator which separates different
parts of the source code. Its primary purpose is to improve
readability. Unlike other rules developers have some freedom
to add newlines to their code. However there are some rules.
* Only a single newline separator is allowed.
* Source files must be terminated by a newline.
* Global declarations must be separated by a newline.
* Newlines are not allowed after an opening curly brace or before
a closing curly brace
* No newlines are allowed between control statements (if-else, while,
for, switch, etc.) and their code blocks.
* There should be a newline after the variable declarations
if they are the first statements of a block.
```diff
+++ Good +++
```
```c
if (a > 5)
{
/* Newline must be present after the first
* variable declarations of a code block. */
int j = a - 1;
int k = a * 2;
return j + k;
}
while (a < 5)
{
a++;
/* It is recommended to put a newline after
* intermediate variable declarations. */
int i = a * 2;
b = i - 3;
}
/* It is a recommended to put newlines around asserts. */
a = b + 5;
JERRY_ASSERT (a < 20);
c = a + 7;
/* It is a good practice to put a newline after a multiline
* function call (see Function calls later). */
f (a,
b,
c);
a = 6;
```
```diff
--- Bad ---
```
```c
/* No newlines are allowed after an opening curly
* brace or before a closing curly brace */
while (a > 0)
{
a = 6;
}
if (a > 5)
{
while (b < 6)
{
b++;
}
}
/* Two or more newlines are not allowed. */
a = 6;
b = 7;
/* No newlines are allowed between control staments
* and their code blocks. */
if (a > 6)
{
}
else
{
}
do
{
}
while (a < 6);
```
## Expressions
Spaces are required around binary operators. No space is
needed otherwise.
```diff
+++ Good +++
```
```c
a = b + c;
a = (b + c) << 3;
a = b = c + ~d;
a += ++c + d++;
call_function (a * (b + !!c) - d + (e % f));
if (a)
{
}
```
```diff
--- Bad ---
```
```c
a=b+c;
a = b+c;
a += c + ( d );
/* Introduce temporary variables or macros
* if the expression is too long. Occures rarely.. */
a = b
+ c;
if ( a + b > 0 )
{
}
```
## Logical operators
All expressions with && and || logical operators must be
enclosed in parentheses. A single and multiline form is
allowed for these expressions. In the latter case each
line must start with the logical operator and each line
must be aligned to the column right after the opening
parenthesis.
```diff
+++ Good +++
```
```c
/* Single line form. */
a = ((c && d) || (e && f));
a = (c
&& d);
a = (c
&& (d || e)
&& f);
do
{
}
while (a
&& b);
/* This form is rarely used but it is ok. */
if (a
&& (b
|| c
|| d)
&& e)
{
}
```
```diff
--- Bad ---
```
```c
if (a || b ||
c)
{
}
/* Parentheses are missing. */
a = b || c;
/* Misaligned &&. */
if (a
&& b)
{
}
```
## Ternary conditional operators
A special form of ternary conditional operators are allowed
in JerryScript where the ? and : operators are on separate
lines in the same column.
```diff
+++ Good +++
```
```c
a = (b ? c
: d);
/* Single line form is accepted as well. */
a = (b ? c : d);
/* This form is rarely used but it is ok. */
if (a ? b
: (c ? d
: e))
{
}
```
```diff
--- Bad ---
```
```c
a = b ?
c : d;
while (a ? b
: c)
{
}
if (a
? b
: c)
{
}
```
## Function calls
There must be a space after the function name. Each argument
must be in the same or separated lines. In the former case
there must be a space before the next argument and in the
latter case all arguments must be aligned to the same column.
```diff
+++ Good +++
```
```c
function_a ();
function_b (a);
function_c (a, b, c);
function_c (a,
b,
c);
function_c (a,
b,
function_c (a,
b,
c);
```
```diff
--- Bad ---
```
```c
/* No space before the opening parenthesis. */
function_f();
function_f (
);
function_g(a);
function_g
(a
);
/* Two arguments on the same line. */
function_h (a, b,
c);
function_h (a,
b, c);
/* Misaligned arguments. */
function_h (a,
b,
c);
```
## Variable declarations
JerryScript is a pure C99 codebase so variable
declarations can be anywhere in the code including
inside for-loops. It is recommended to declare a
variable before the first use.
```diff
+++ Good +++
```
```c
for (int i = 0; i < 10; i++)
{
int j = i + 1;
while (j < 10)
{
++j;
}
}
/* Multiline form of for loops. */
for (int i = 0;
i < 10;
i++)
{
}
```
## Type casting
There must be a space after the closing parenthesis
of the type cast. Type casting has no multiline form
in JerryScript.
```diff
+++ Good +++
```
```c
int a = (int) double_variable;
int a = (int) (long) (float) double_variable;
```
```diff
--- Bad ---
```
```c
/* Wrong spaces. */
int a = ( int )double_variable;
/* No multiline form. */
int a = (int)
double_variable;
```
## Pointers and asterisk character
Each pointer in JerryScript must be a lowercase string
which is ending with a `_p` suffix. Furthermore there
must be a space before the asterisk character.
```diff
+++ Good +++
```
```c
int *int_p;
/* No need to add multiple _p-s for multiple indirections.
* It is recommended to avoid these constructs using typedef
* declarations. A reviewer might request such a change. */
int ***int_p;
/* This rule applies for type casting as well. */
char = *(char *) type_p;
```
```diff
--- Bad ---
```
```c
/* No _p after the name. */
int *ptr;
/* Wrong asterisk position. */
int* ptr_p;
char_p = * (char*)type_p;
```
## Types
Each type in JerryScript must be a lowercase string
which ends with a `_t` suffix. Furthermore each type
declaration must be preceded by a short description
of the type and each field must have a short description
as well.
```diff
+++ Good +++
```
```c
/**
* Short description of the following structure.
*/
typedef struct
{
/* Field descriptions do not start with capital letters
* and there is no full stop at the end. */
field1_t field1; /**< description of field 1 */
field2_t field2; /**< description of field 2 */
field_n_t field_n; /**< description of field n */
} structure_name_t;
/**
* Another integer type.
*/
typedef int jerry_int;
```
```diff
--- Bad ---
```
```c
typedef struct
{
field_t field_without_description;
} structure_without_description_t;
typedef struct { int a; } single_line_struct;
typedef
union {
}
wrong_newlines_t;
/*
* Bad comment format.
*/
typedef
char wrong_newlines_again_t;
```
## Function declarations
Function declarations in JerryScript are verbose but this format
reduces the maintenance cost and allows faster understanding of
the code.
```diff
+++ Good +++
```
```c
/**
* Short overview about the purpose of this function.
*
* A more detailed explanation if needed.
*
* Note:
* Extra notes if needed.
*
* @return short description about the value
* returned by the function
*/
return_value_type_t
function_name (argument1, /**< description of argument1 */
argument2, /**< description of argument2 */
...
argument_n, /**< description of argument n */
{
/* Function body. */
} /* function_name */
```
```diff
--- Bad ---
```
```c
static int
print (char *text) /**< description of text argument */
{
/* Missing comment before the function. */
} /* print */
/**
* Prints the text received by the function.
*
* @return number of characters printed by the function
*/
int print(char *text)
{
/* No description of text argument. */
/* Missing comment at the end of the function. */
}
```
-855
View File
@@ -1,855 +0,0 @@
# jerryx_arg types
## jerryx_arg_t
**Summary**
The structure defining a single validation/transformation step.
*Note*: For commonly used validators, `arg.h` provides helpers to create the `jerryx_arg_t`s.
For example, `jerryx_arg_number ()`, `jerryx_arg_boolean ()`, etc.
**Prototype**
```c
typedef struct
{
/** the transform function */
jerryx_arg_transform_func_t func;
/** pointer to destination where func should store the result */
void *dest;
/** extra information, specific to func */
uintptr_t extra_info;
} jerryx_arg_t;
```
**See also**
- [jerryx_arg_number](#jerryx_arg_number)
- [jerryx_arg_boolean](#jerryx_arg_boolean)
- [jerryx_arg_string](#jerryx_arg_string)
- [jerryx_arg_utf8_string](#jerryx_arg_utf8_string)
- [jerryx_arg_function](#jerryx_arg_function)
- [jerryx_arg_native_pointer](#jerryx_arg_native_pointer)
- [jerryx_arg_ignore](#jerryx_arg_ignore)
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
## jerryx_arg_object_props_t
**Summary**
The structure is used in `jerryx_arg_object_properties`. It provides the properties' names,
its corresponding JS-to-C mapping and other related information.
**Prototype**
```c
typedef struct
{
const jerry_char_t **name_p; /**< property name list of the JS object */
jerry_length_t name_cnt; /**< count of the name list */
const jerryx_arg_t *c_arg_p; /**< points to the array of transformation steps */
jerry_length_t c_arg_cnt; /**< the count of the `c_arg_p` array */
} jerryx_arg_object_props_t;
```
**See also**
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
## jerryx_arg_array_items_t
**Summary**
The structure is used in `jerryx_arg_array`. It provides the array items' corresponding
JS-to-C mappings and count.
**Prototype**
```c
typedef struct
{
const jerryx_arg_t *c_arg_p; /**< points to the array of transformation steps */
jerry_length_t c_arg_cnt; /**< the count of the `c_arg_p` array */
} jerryx_arg_array_items_t;
```
**See also**
- [jerryx_arg_array](#jerryx_arg_array)
## jerryx_arg_transform_func_t
**Summary**
Signature of the transform function.
Users can create custom transformations by implementing a transform function
and using `jerryx_arg_custom ()`.
The function is expected to return `undefined` if it ran successfully or
return an `Error` in case it failed. The function can use the iterator and the
helpers `jerryx_arg_js_iterator_pop ()` and `jerryx_arg_js_iterator_peek ()` to
get the next input value.
*Note*: A transform function is allowed to consume any number of input values!
This enables complex validation like handling different JS function signatures,
mapping multiple input arguments to a C struct, etc.
The function is expected to store the result of
a successful transformation into `c_arg_p->dest`. In case the validation did
not pass, the transform should not modify `c_arg_p->dest`.
Additional parameters can be provided to the function through `c_arg_p->extra_info`.
**Prototype**
```c
typedef jerry_value_t (*jerryx_arg_transform_func_t) (jerryx_arg_js_iterator_t *js_arg_iter_p,
const jerryx_arg_t *c_arg_p);
```
**See also**
- [jerryx_arg_custom](#jerryx_arg_custom)
- [jerryx_arg_js_iterator_pop](#jerryx_arg_js_iterator_pop)
- [jerryx_arg_js_iterator_peek](#jerryx_arg_js_iterator_peek)
## jerryx_arg_coerce_t
Enum that indicates whether an argument is allowed to be coerced into the expected JS type.
- JERRYX_ARG_COERCE - the transform will invoke toNumber, toBoolean, toString, etc.
- JERRYX_ARG_NO_COERCE - the type coercion is not allowed. The transform will fail if the type does not match the expectation.
**See also**
- [jerryx_arg_number](#jerryx_arg_number)
- [jerryx_arg_boolean](#jerryx_arg_boolean)
- [jerryx_arg_string](#jerryx_arg_string)
## jerryx_arg_optional_t
Enum that indicates whether an argument is optional or required.
- JERRYX_ARG_OPTIONAL - The argument is optional. If the argument is `undefined` the transform is successful and `c_arg_p->dest` remains untouched.
- JERRYX_ARG_REQUIRED - The argument is required. If the argument is `undefined` the transform will fail and `c_arg_p->dest` remains untouched.
**See also**
- [jerryx_arg_number](#jerryx_arg_number)
- [jerryx_arg_boolean](#jerryx_arg_boolean)
- [jerryx_arg_string](#jerryx_arg_string)
- [jerryx_arg_function](#jerryx_arg_function)
- [jerryx_arg_native_pointer](#jerryx_arg_native_pointer)
## jerryx_arg_round_t
Enum that indicates the rounding policy which will be chosen to transform an integer.
- JERRYX_ARG_ROUND - use round() method.
- JERRYX_ARG_FLOOR - use floor() method.
- JERRYX_ARG_CEIL - use ceil() method.
**See also**
- [jerryx_arg_uint8](#jerryx_arg_uint8)
- [jerryx_arg_uint16](#jerryx_arg_uint16)
- [jerryx_arg_uint32](#jerryx_arg_uint32)
- [jerryx_arg_int8](#jerryx_arg_int8)
- [jerryx_arg_int16](#jerryx_arg_int16)
- [jerryx_arg_int32](#jerryx_arg_int32)
## jerryx_arg_clamp_t
Indicates the clamping policy which will be chosen to transform an integer.
If the policy is NO_CLAMP, and the number is out of range,
then the transformer will throw a range error.
- JERRYX_ARG_CLAMP - clamp the number when it is out of range
- JERRYX_ARG_NO_CLAMP - throw a range error
**See also**
- [jerryx_arg_uint8](#jerryx_arg_uint8)
- [jerryx_arg_uint16](#jerryx_arg_uint16)
- [jerryx_arg_uint32](#jerryx_arg_uint32)
- [jerryx_arg_int8](#jerryx_arg_int8)
- [jerryx_arg_int16](#jerryx_arg_int16)
- [jerryx_arg_int32](#jerryx_arg_int32)
# Main functions
## jerryx_arg_transform_this_and_args
**Summary**
Validate the this value and the JS arguments, and assign them to the native arguments.
This function is useful to perform input validation inside external function handlers (see `jerry_external_handler_t`).
**Prototype**
```c
jerry_value_t
jerryx_arg_transform_this_and_args (const jerry_value_t this_val,
const jerry_value_t *js_arg_p,
const jerry_length_t js_arg_cnt,
const jerryx_arg_t *c_arg_p,
jerry_length_t c_arg_cnt)
```
- `this_val` - `this` value. Note this is processed as the first value, before the array of arguments.
- `js_arg_p` - points to the array with JS arguments.
- `js_arg_cnt` - the count of the `js_arg_p` array.
- `c_arg_p` - points to the array of validation/transformation steps
- `c_arg_cnt` - the count of the `c_arg_p` array.
- return value - a `jerry_value_t` representing `undefined` if all validators passed or an `Error` if a validator failed.
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
#include "jerryscript-ext/arg.h"
/* JS signature: function (requiredBool, requiredString, optionalNumber) */
static jerry_value_t
my_external_handler (const jerry_value_t function_obj,
const jerry_value_t this_val,
const jerry_value_t args_p[],
const jerry_length_t args_count)
{
bool required_bool;
char required_str[16];
double optional_num = 1234.567; // default value
/* "mapping" defines the steps to transform input arguments to C variables. */
const jerryx_arg_t mapping[] =
{
/* `this` is the first value. No checking needed on `this` for this function. */
jerryx_arg_ignore (),
jerryx_arg_boolean (&required_bool, JERRYX_ARG_NO_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_string (required_str, sizeof (required_str), JERRYX_ARG_NO_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&optional_num, JERRYX_ARG_NO_COERCE, JERRYX_ARG_OPTIONAL),
};
/* Validate and transform. */
const jerry_value_t rv = jerryx_arg_transform_this_and_args (this_val,
args_p,
args_count,
mapping,
4);
if (jerry_value_is_error (rv))
{
/* Handle error. */
return rv;
}
/*
* Validated and transformed successfully!
* required_bool, required_str and optional_num can now be used.
*/
return jerry_create_undefined (); /* Or return something more meaningful. */
}
```
**See also**
- [jerryx_arg_ignore](#jerryx_arg_ignore)
- [jerryx_arg_number](#jerryx_arg_number)
- [jerryx_arg_boolean](#jerryx_arg_boolean)
- [jerryx_arg_string](#jerryx_arg_string)
- [jerryx_arg_function](#jerryx_arg_function)
- [jerryx_arg_native_pointer](#jerryx_arg_native_pointer)
- [jerryx_arg_custom](#jerryx_arg_custom)
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
## jerryx_arg_transform_args
**Summary**
Validate an array of `jerry_value_t` and assign them to the native arguments.
**Prototype**
```c
jerry_value_t
jerryx_arg_transform_args (const jerry_value_t *js_arg_p,
const jerry_length_t js_arg_cnt,
const jerryx_arg_t *c_arg_p,
jerry_length_t c_arg_cnt)
```
- `js_arg_p` - points to the array with JS arguments.
- `js_arg_cnt` - the count of the `js_arg_p` array.
- `c_arg_p` - points to the array of validation/transformation steps
- `c_arg_cnt` - the count of the `c_arg_p` array.
- return value - a `jerry_value_t` representing `undefined` if all validators passed or an `Error` if a validator failed.
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_transform_object_properties
**Summary**
Validate the properties of a JS object and assign them to the native arguments.
*Note*: This function transforms properties of a single JS object into native C values.
To transform multiple objects in one pass (for example when converting multiple arguments
to an external handler), please use `jerryx_arg_object_properties` together with
`jerryx_arg_transform_this_and_args` or `jerryx_arg_transform_args`.
**Prototype**
```c
jerry_value_t
jerryx_arg_transform_object_properties (const jerry_value_t obj_val,
const jerry_char_t **name_p,
const jerry_length_t name_cnt,
const jerryx_arg_t *c_arg_p,
jerry_length_t c_arg_cnt);
```
- `obj_val` - the JS object.
- `name_p` - points to the array of property names.
- `name_cnt` - the count of the `name_p` array.
- `c_arg_p` - points to the array of validation/transformation steps
- `c_arg_cnt` - the count of the `c_arg_p` array.
- return value - a `jerry_value_t` representing `undefined` if all validators passed or an `Error` if a validator failed.
**See also**
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
## jerryx_arg_transform_array
**Summary**
Validate the JS array and assign its items to the native arguments.
*Note*: This function transforms items of a single JS array into native C values.
To transform multiple JS arguments in one pass, please use `jerryx_arg_array` together with
`jerryx_arg_transform_this_and_args` or `jerryx_arg_transform_args`.
**Prototype**
```c
jerry_value_t
jerryx_arg_transform_array (const jerry_value_t array_val,
const jerryx_arg_t *c_arg_p,
jerry_length_t c_arg_cnt);
```
- `array_val` - the JS array.
- `c_arg_p` - points to the array of validation/transformation steps
- `c_arg_cnt` - the count of the `c_arg_p` array.
- return value - a `jerry_value_t` representing `undefined` if all validators passed or an `Error` if a validator failed.
**See also**
- [jerryx_arg_array](#jerryx_arg_array)
# Helpers for commonly used validations
## jerryx_arg_uint8
## jerryx_arg_uint16
## jerryx_arg_uint32
## jerryx_arg_int8
## jerryx_arg_int16
## jerryx_arg_int32
**Summary**
All above jerryx_arg_[u]intX functions are used to create a validation/transformation step
(`jerryx_arg_t`) that expects to consume one `number` JS argument
and stores it into a C integer (uint8, int8, uint16, ...)
**Prototype**
Take jerryx_arg_int32 as an example
```c
static inline jerryx_arg_t
jerryx_arg_int32 (int32_t *dest,
jerryx_arg_round_t round_flag,
jerryx_arg_clamp_t clamp_flag,
jerryx_arg_coerce_t coerce_flag,
jerryx_arg_optional_t opt_flag);
```
- return value - the created `jerryx_arg_t` instance.
- `dest` - pointer to the `int32_t` where the result should be stored.
- `round_flag` - the rounding policy.
- `clamp_flag` - the clamping policy.
- `coerce_flag` - whether type coercion is allowed.
- `opt_flag` - whether the argument is optional.
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_number
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to consume
one `number` JS argument and stores it into a C `double`.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_number (double *dest,
jerryx_arg_coerce_t coerce_flag,
jerryx_arg_optional_t opt_flag)
```
- return value - the created `jerryx_arg_t` instance.
- `dest` - pointer to the `double` where the result should be stored.
- `coerce_flag` - whether type coercion is allowed.
- `opt_flag` - whether the argument is optional.
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_boolean
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `boolean` JS argument and stores it into a C `bool`.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_boolean (bool *dest,
jerryx_arg_coerce_t coerce_flag,
jerryx_arg_optional_t opt_flag)
```
- return value - the created `jerryx_arg_t` instance.
- `dest` - pointer to the `bool` where the result should be stored.
- `coerce_flag` - whether type coercion is allowed.
- `opt_flag` - whether the argument is optional.
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_string
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `string` JS argument and stores it into a CESU-8 C `char` array.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_string (char *dest,
uint32_t size,
jerryx_arg_coerce_t coerce_flag,
jerryx_arg_optional_t opt_flag)
```
- return value - the created `jerryx_arg_t` instance.
- `dest` - pointer to the native char array where the result should be stored.
- `size` - the size of native char array.
- `coerce_flag` - whether type coercion is allowed.
- `opt_flag` - whether the argument is optional.
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
- [jerry_arg_utf8_string](#jerry_arg_utf8_string)
## jerryx_arg_utf8_string
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `string` JS argument and stores it into a UTF-8 C `char` array.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_utf8_string (char *dest,
uint32_t size,
jerryx_arg_coerce_t coerce_flag,
jerryx_arg_optional_t opt_flag)
```
- return value - the created `jerryx_arg_t` instance.
- `dest` - pointer to the native char array where the result should be stored.
- `size` - the size of native char array.
- `coerce_flag` - whether type coercion is allowed.
- `opt_flag` - whether the argument is optional.
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
- [jerry_arg_string](#jerry_arg_string)
## jerryx_arg_function
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `function` JS argument and stores it into a C `jerry_value_t`.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_function (jerry_value_t *dest,
jerryx_arg_optional_t opt_flag)
```
- return value - the created `jerryx_arg_t` instance.
- `dest` - pointer to the `jerry_value_t` where the result should be stored.
- `opt_flag` - whether the argument is optional.
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_native_pointer
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `object` JS argument that is 'backed' with a native pointer with
a given type info. In case the native pointer info matches, the transform
will succeed and the object's native pointer will be assigned to `*dest`.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_native_pointer (void **dest,
const jerry_object_native_info_t *info_p,
jerryx_arg_optional_t opt_flag)
```
- return value - the created `jerryx_arg_t` instance.
- `dest` - pointer to where the resulting native pointer should be stored.
- `info_p` - expected the type info.
- `opt_flag` - whether the argument is optional.
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_object_properties
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `object` JS argument and call `jerryx_arg_transform_object_properties` inside
to transform its properties to native arguments.
User should prepare the `jerryx_arg_object_props_t` instance, and pass it to this function.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_object_properties (const jerryx_arg_object_props_t *object_props_p,
jerryx_arg_optional_t opt_flag);
```
- return value - the created `jerryx_arg_t` instance.
- `object_props_p` - provides information for properties transform.
- `opt_flag` - whether the argument is optional.
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
#include "jerryscript-ext/arg.h"
/**
* The binding function expects args_p[0] is an object, which has 3 properties:
* "enable": boolean
* "data": number
* "extra_data": number, optional
*/
static jerry_value_t
my_external_handler (const jerry_value_t function_obj,
const jerry_value_t this_val,
const jerry_value_t args_p[],
const jerry_length_t args_count)
{
bool required_bool;
double required_num;
double optional_num = 1234.567; // default value
/* "prop_name_p" defines the name list of the expected properties' names. */
const char *prop_name_p[] = { "enable", "data", "extra_data" };
/* "prop_mapping" defines the steps to transform properties to C variables. */
const jerryx_arg_t prop_mapping[] =
{
jerryx_arg_boolean (&required_bool, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&required_num, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&optional_num, JERRYX_ARG_COERCE, JERRYX_ARG_OPTIONAL)
};
/* Prepare the jerryx_arg_object_props_t instance. */
const jerryx_arg_object_props_t prop_info =
{
.name_p = (const jerry_char_t **) prop_name_p,
.name_cnt = 3,
.c_arg_p = prop_mapping,
.c_arg_cnt = 3
};
/* It is the mapping used in the jerryx_arg_transform_args. */
const jerryx_arg_t mapping[] =
{
jerryx_arg_object_properties (&prop_info, JERRYX_ARG_REQUIRED)
};
/* Validate and transform. */
const jerry_value_t rv = jerryx_arg_transform_args (args_p,
args_count,
mapping,
1);
if (jerry_value_is_error (rv))
{
/* Handle error. */
return rv;
}
/*
* Validated and transformed successfully!
* required_bool, required_num and optional_num can now be used.
*/
return jerry_create_undefined (); /* Or return something more meaningful. */
}
```
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
- [jerryx_arg_transform_object_properties](#jerryx_arg_transform_object_properties)
## jerryx_arg_array
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `array` JS argument and call `jerryx_arg_transform_array_items` inside
to transform its items to native arguments.
User should prepare the `jerryx_arg_array_items_t` instance, and pass it to this function.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_array (const jerryx_arg_array_items_t *array_items_p, jerryx_arg_optional_t opt_flag);
```
- return value - the created `jerryx_arg_t` instance.
- `array_items_p` - provides items information for transform.
- `opt_flag` - whether the argument is optional.
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
#include "jerryscript-ext/arg.h"
/**
* The binding function expects args_p[0] is an array, which has 3 items:
* first: boolean
* second: number
* third: number, optional
*/
static jerry_value_t
my_external_handler (const jerry_value_t function_obj,
const jerry_value_t this_val,
const jerry_value_t args_p[],
const jerry_length_t args_count)
{
bool required_bool;
double required_num;
double optional_num = 1234.567; // default value
/* "item_mapping" defines the steps to transform array items to C variables. */
const jerryx_arg_t item_mapping[] =
{
jerryx_arg_boolean (&required_bool, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&required_num, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&optional_num, JERRYX_ARG_COERCE, JERRYX_ARG_OPTIONAL)
};
/* Prepare the jerryx_arg_array_items_t instance. */
const jerryx_arg_array_items_t array_info =
{
.c_arg_p = item_mapping,
.c_arg_cnt = 3
};
/* It is the mapping used in the jerryx_arg_transform_args. */
const jerryx_arg_t mapping[] =
{
jerryx_arg_array (&array_info, JERRYX_ARG_REQUIRED)
};
/* Validate and transform. */
const jerry_value_t rv = jerryx_arg_transform_args (args_p,
args_count,
mapping,
1);
if (jerry_value_is_error (rv))
{
/* Handle error. */
return rv;
}
/*
* Validated and transformed successfully!
* required_bool, required_num and optional_num can now be used.
*/
return jerry_create_undefined (); /* Or return something more meaningful. */
}
```
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
- [jerryx_arg_transform_object_properties](#jerryx_arg_transform_object_properties)
# Functions to create custom validations
## jerryx_arg_custom
**Summary**
Create a jerryx_arg_t instance with custom transform.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_custom (void *dest,
uintptr_t extra_info,
jerryx_arg_transform_func_t func)
```
- return value - the created `jerryx_arg_t` instance.
- `dest` - pointer to the native argument where the result should be stored.
- `extra_info` - the extra parameter data, specific to the transform function.
- `func` - the custom transform function.
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_js_iterator_pop
**Summary**
Pop the current `jerry_value_t` argument from the iterator.
It will change the `js_arg_idx` and `js_arg_p` value in the iterator.
**Prototype**
```c
jerry_value_t
jerryx_arg_js_iterator_pop (jerryx_arg_js_iterator_t *js_arg_iter_p)
```
- return value - the `jerry_value_t` argument that was popped.
- `js_arg_iter_p` - the JS arg iterator from which to pop.
## jerryx_arg_js_iterator_peek
**Summary**
Get the current JS argument from the iterator, without moving the iterator forward.
*Note:* Unlike `jerryx_arg_js_iterator_pop ()`, it will not change `js_arg_idx` and
`js_arg_p` value in the iterator.
**Prototype**
```c
jerry_value_t
jerryx_arg_js_iterator_peek (jerryx_arg_js_iterator_t *js_arg_iter_p)
```
- return value - the current `jerry_value_t` argument.
- `js_arg_iter_p` - the JS arg iterator from which to peek.
## jerryx_arg_js_iterator_restore
**Summary**
Restore the last item popped from the stack. This can be called as
many times as there are arguments on the stack -- if called when the
first element in the array is the current top of the stack, this
function does nothing.
*Note:* This function relies on the underlying implementation of the
arg stack as an array, as its function is to simply back up the "top
of stack" pointer to point to the previous element of the array.
*Note:* Like `jerryx_arg_js_iterator_pop ()`, this function will
change the `js_arg_idx` and `js_arg_p` values in the iterator.
**Prototype**
```c
jerry_value_t
jerryx_arg_js_iterator_restore (jerryx_arg_js_iterator_t *js_arg_iter_p)
```
- return value - the the new top of the stack.
- `js_arg_iter_p` - the JS arg iterator to restore.
## jerryx_arg_js_iterator_index
**Summary**
Get the index of the current JS argument from the iterator.
**Prototype**
```c
jerry_length_t
jerryx_arg_js_iterator_index (jerryx_arg_js_iterator_t *js_arg_iter_p)
```
- return value - the index of current JS argument.
- `js_arg_iter_p` - the JS arg iterator from which to peek.
-601
View File
@@ -1,601 +0,0 @@
# Common methods to handle properties
The `jerryscript-ext/handler.h` header defines a set of convenience methods
which makes the property access a bit straightforward.
## jerryx_set_property_str
**Summary**
Set a property on a target object with a given name.
*Note*:
- The property name must be a zero terminated UTF-8 string.
- There should be no '\0' (NULL) character in the name excluding the string terminator.
- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
is no longer needed.
**Prototype**
```c
jerry_value_t
jerryx_set_property_str (const jerry_value_t target_object,
const char *name,
const jerry_value_t value);
```
- `target_object` - the object where the property should be set
- `name` - name of the property
- `value` - property value to be set
- return value
- JS true value, if success
- thrown error, if there was a problem setting the property
**Example**
[doctest]: # ()
```c
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
int
main (int argc, char **argv)
{
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t global = jerry_get_global_object ();
jerry_value_t value = jerry_create_number (3.3);
jerry_value_t result = jerryx_set_property_str (global, "value", value);
if (jerry_value_is_error (result))
{
/* The error type/reason can be extracted via the `jerry_get_value_from_error` method */
printf ("Error during property configuration\r\n");
}
jerry_release_value (result);
jerry_release_value (value);
jerry_release_value (global);
jerry_cleanup();
return 0;
}
```
## jerryx_get_property_str
**Summary**
Get the value of a property from the specified object with the given name.
*Notes*:
- The property name must be a zero terminated UTF-8 string.
- There should be no '\0' (NULL) character in the name excluding the string terminator.
- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
is no longer needed.
**Prototype**
```
jerry_value_t
jerryx_get_property_str (const jerry_value_t target_object,
const char *name);
```
- `target_object` - object on which the property name is accessed
- `name` - property name as an UTF-8 `char*`
- return value
- value of property, if success
- thrown error, if there was a problem accessing the property
**Example**
[doctest]: # ()
```c
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
int
main (int argc, char **argv)
{
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t global = jerry_get_global_object ();
jerry_value_t math_object = jerryx_get_property_str (global, "Math");
/* use math_object */
jerry_release_value (math_object);
jerry_release_value (global);
jerry_cleanup();
return 0;
}
```
## jerryx_has_property_str
**Summary**
Check if a property exists on an object.
*Notes*:
- The operation performed is the same as what the `jerry_has_property` method.
- The property name must be a zero terminated UTF-8 string.
- There should be no '\0' (NULL) character in the name excluding the string terminator.
**Prototype**
```
bool
jerryx_has_property_str (const jerry_value_t target_object,
const char *name);
```
- `target_object` - object on which the property name is accessed
- `name` - property name as an UTF-8 `char*`
- return value
- true, if the given property name exsits on the object
- false, if there is no such property name or there was an error accessing the property
**Example**
[doctest]: # ()
```c
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
int
main (int argc, char **argv)
{
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t global = jerry_get_global_object ();
bool have_math = jerryx_has_property_str (global, "Math");
jerry_release_value (global);
jerry_cleanup();
return have_math ? 0 : 1;
}
```
# Utility to register multiple properties in bulk
In some cases it is useful to register multiple properties for a given object
for this the following utility structures and methods are provided.
## jerryx_property_entry
**Summary**
Structure to define an array of properties with `name` and `value` fields which
can be registered to a target object.
The engine must be initialied before specifying the `jerry_value_t` in the struct.
**Prototype**
```c
typedef struct {
const char *name;
jerry_value_t value;
} jerryx_function_list_entry;
```
**See also**
- [jerryx_set_properties](#jerryx_set_properties)
## jerryx_register_result
**Summary**
Structure returned as the result of the [jerryx_set_properties](#jerryx_set_properties) operation.
The `result` field will either be a JavaScript undefined value or an error object.
In every case the `registered` field is used to indicated the number of
successfully registered methods.
This must be passed for the [jerryx_release_property_entry](#jerryx_release_property_entry) method
after the property registration.
If any error occured during the property registration the `result` field of the structure
must be manually released after processing the error value.
**Prototype**
```c
typedef struct {
jerry_value_t result;
uint32_t registered;
} jerryx_register_result;
```
**See also**
- [jerryx_set_properties](#jerryx_set_properties)
- [jerryx_release_property_entry](#jerryx_release_property_entry)
## jerryx_set_properties
**Summary**
Set multiple properties on a target object.
The properties are an array of (name, jerry_value_t) pairs and
this list must end with a (NULL, 0) entry.
Important notes:
* Each property value in the input array is released after a successful property registration.
* The method [jerryx_release_property_entry](#jerryx_release_property_entry) must be called if there is any failed registration
to release the values in the entries array.
It is safe to call this cleanup method in every case not just in case of failure.
* If the error value is reported via the result it must be freed manually.
**Prototype**
```c
jerryx_register_result
jerryx_set_properties (const jerry_value_t target_object,
const jerryx_property_entry entries[]);
```
- `target_object` - object on which the entries will be set.
- `entries` - array of (name, jerry_value_t) pairs.
- return a [jerryx_register_result](#jerryx_register_result).
- if everything is ok, the struct's `result` field is set to a JS undefined value.
- otherwise the `result` field is an error object indicating the problem.
- in every case the `registered` field contains the number of successfully registered properties.
**Example**
[doctest]: # ()
```c
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
static jerry_value_t
handler (const jerry_value_t function_obj,
const jerry_value_t this_val,
const jerry_value_t args_p[],
const jerry_length_t args_cnt)
{
printf ("native handler called!\n");
return jerry_create_boolean (true);
}
int
main (int argc, char **argv)
{
jerry_init (JERRY_INIT_EMPTY);
jerryx_property_entry methods[] =
{
{ "demo", jerry_create_external_function (handler) },
{ NULL, 0 },
};
jerry_value_t global = jerry_get_global_object ();
jerryx_register_result reg = jerryx_set_properties (global, methods);
/* if `reg.result` is undefined all methods are registered */
if (jerry_value_is_error (reg.result))
{
printf ("Only registered %d properties\r\n", reg.registered);
/* clean up not registered property values */
jerryx_release_property_entry (methods, reg);
/* clean up the error */
jerry_release_value (reg.result);
}
jerry_release_value (global);
jerry_cleanup();
return 0;
}
```
**Convenience macros**
To make property registration convenient, there are a set of macros to use
when setting a property entry:
* `JERRYX_PROPERTY_NUMBER(NAME, NUMBER)` - creates a number entry.
* `JERRYX_PROPERTY_STRING(NAME, STR)` - creates an UTF-8 string entry. This string must be zero terminated.
* `JERRYX_PROPERTY_STRING_SZ(NAME, STR, SIZE)` - creates an UTF-8 string entry using only `SIZE` bytes from the string.
* `JERRYX_PROPERTY_BOOLEAN(NAME, VALUE)` - creates a boolean entry.
* `JERRYX_PROPERTY_FUNCTION(NAME, NATIVE)` - creates a native C function entry.
* `JERRYX_PROPERTY_UNDEFINED(NAME)` - creates an undefined property entry.
* `JERRYX_PROPERTY_LIST_END()` - indicates the end of the property list.
**Example usage of Convenience macros**
[doctest]: # ()
```c
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
static jerry_value_t
handler (const jerry_value_t function_obj,
const jerry_value_t this_val,
const jerry_value_t args_p[],
const jerry_length_t args_cnt)
{
printf ("native handler called!\n");
return jerry_create_boolean (true);
}
int
main (int argc, char **argv)
{
jerry_init (JERRY_INIT_EMPTY);
/**
* Create a array of properties to be registered.
* This must be done after initializing the engine as creating `jerry_value_t`
* elements are invalid before `jerry_init`.
*/
jerryx_property_entry methods[] =
{
JERRYX_PROPERTY_FUNCTION ("demo", handler),
JERRYX_PROPERTY_NUMBER ("test_num", 2.3),
JERRYX_PROPERTY_UNDEFINED ("this_is_undefined"),
JERRYX_PROPERTY_LIST_END(),
};
jerry_value_t global = jerry_get_global_object ();
jerryx_register_result reg = jerryx_set_properties (global, methods);
/* if `reg.result` is undefined all methods are registered */
if (jerry_value_is_error (reg.result))
{
printf ("Only registered %d properties\r\n", reg.registered);
/* clean up not registered property values */
jerryx_release_property_entry (methods, reg);
/* clean up the error */
jerry_release_value (reg.result);
}
jerry_release_value (global);
jerry_cleanup();
return 0;
}
```
**See also**
- [jerryx_property_entry](#jerryx_property_entry)
- [jerryx_release_property_entry](#jerryx_release_property_entry)
- [jerryx_register_result](#jerryx_register_result)
## jerryx_release_property_entry
**Summary**
Release all `jerry_value_t` in a `jerryx_property_entry` array based on a previous [jerryx_set_properties](#jerryx_set_properties) call
and also the error value (if any) in the `jerryx_register_result` structure.
In case of a successful registration it is safe to call this method.
After the method call the `ęntries` array should not be used as all values are released.
**Prototype**
```
void
jerryx_release_property_entry (const jerryx_property_entry entries[],
const jerryx_register_result register_result);
```
- `entires` - array of [jerryx_property_entry](#jerryx_property_entry).
- `register_result` - result of a previous [jerryx_set_properties](#jerryx_set_properties) call.
**Example**
For example usage see [jerryx_set_properties](#jerryx_set_properties).
# Common external function handlers
## jerryx_handler_assert_fatal
**Summary**
Hard assert for scripts. The routine calls `jerry_port_fatal` on assertion failure.
**Prototype**
```c
jerry_value_t
jerryx_handler_assert_fatal (const jerry_value_t func_obj_val, const jerry_value_t this_p,
const jerry_value_t args_p[], const jerry_length_t args_cnt);
```
- `func_obj_val` - the function object that was called (unused).
- `this_p` - the `this` value of the call (unused).
- `args_p` - the array of function arguments.
- `args_cnt` - the number of function arguments.
- return value - `jerry_value_t` representing boolean true, if only one argument
was passed and that argument was a boolean true. Note that the function does
not return otherwise.
**See also**
- [jerryx_handler_register_global](#jerryx_handler_register_global)
## jerryx_handler_assert_throw
**Summary**
Soft assert for scripts. The routine throws an error on assertion failure.
**Prototype**
```c
jerry_value_t
jerryx_handler_assert_throw (const jerry_value_t func_obj_val, const jerry_value_t this_p,
const jerry_value_t args_p[], const jerry_length_t args_cnt);
```
- `func_obj_val` - the function object that was called (unused).
- `this_p` - the `this` value of the call (unused).
- `args_p` - the array of function arguments.
- `args_cnt` - the number of function arguments.
- return value - `jerry_value_t` representing boolean true, if only one argument
was passed and that argument was a boolean true, an error otherwise.
**See also**
- [jerryx_handler_register_global](#jerryx_handler_register_global)
## jerryx_handler_assert
**Summary**
An alias to `jerryx_handler_assert_fatal`.
**See also**
- [jerryx_handler_assert_fatal](#jerryx_handler_assert_fatal)
## jerryx_handler_gc
**Summary**
Expose garbage collector to scripts. If the first argument of the function
is logical true, it performs a high pressure gc. Otherwise a low pressure
gc is performed, which is also the default if no parameters passed.
**Prototype**
```c
jerry_value_t
jerryx_handler_gc (const jerry_value_t func_obj_val, const jerry_value_t this_p,
const jerry_value_t args_p[], const jerry_length_t args_cnt);
```
- `func_obj_val` - the function object that was called (unused).
- `this_p` - the `this` value of the call (unused).
- `args_p` - the array of function arguments (unused).
- `args_cnt` - the number of function arguments (unused).
- return value - `jerry_value_t` representing `undefined`.
**See also**
- [jerryx_handler_register_global](#jerryx_handler_register_global)
## jerryx_handler_print
**Summary**
Provide a `print` implementation for scripts. The routine converts all of its
arguments to strings and outputs them char-by-char using
`jerry_port_print_char`. The NUL character is output as "\u0000",
other characters are output bytewise.
*Note*: This implementation does not use standard C `printf` to print its
output. This allows more flexibility but also extends the core JerryScript
engine port API. Applications that want to use `jerryx_handler_print` must
ensure that their port implementation also provides
`jerry_port_print_char`.
**Prototype**
```c
jerry_value_t
jerryx_handler_print (const jerry_value_t func_obj_val, const jerry_value_t this_p,
const jerry_value_t args_p[], const jerry_length_t args_cnt);
```
- `func_obj_val` - the function object that was called (unused).
- `this_p` - the `this` value of the call (unused).
- `args_p` - the array of function arguments.
- `args_cnt` - the number of function arguments.
- return value - `jerry_value_t` representing `undefined` if all arguments could
be converted to strings, an `Error` otherwise.
**See also**
- [jerryx_handler_register_global](#jerryx_handler_register_global)
- [jerry_port_print_char](05.PORT-API.md#jerry_port_print_char)
# Handler registration helper
## jerryx_handler_register_global
**Summary**
Register a JavaScript function in the global object.
*Note*: Returned value must be freed with `jerry_release_value`, when it is no
longer needed.
**Prototype**
```c
jerry_value_t
jerryx_handler_register_global (const jerry_char_t *name_p,
jerry_external_handler_t handler_p);
```
- `name_p` - the name of the function to be registered.
- `handler_p` - the address of the external function handler.
- return value - `jerry_value_t` representing boolean true, if the operation was
successful, an `Error` otherwise.
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
static const struct {
const char *name_p;
jerry_external_handler_t handler_p;
} common_functions[] =
{
{ "assert", jerryx_handler_assert },
{ "gc", jerryx_handler_gc },
{ "print", jerryx_handler_print },
{ NULL, NULL }
};
static void
register_common_functions (void)
{
jerry_value_t ret = jerry_create_undefined ();
for (int i = 0; common_functions[i].name_p != NULL && !jerry_value_is_error (ret); i++)
{
ret = jerryx_handler_register_global ((const jerry_char_t *) common_functions[i].name_p,
common_functions[i].handler_p);
}
jerry_release_value (ret);
}
```
-50
View File
@@ -1,50 +0,0 @@
# Autorelease values
## JERRYX_AR_VALUE_T
**Summary**
Macro for `const jerry_value_t` for which jerry_release_value() is
automatically called when the variable goes out of scope.
*Note*: The macro depends on compiler support. For GCC and LLVM/clang, the macro is implemented
using the `__cleanup__` variable attribute. For other compilers, no support has been added yet.
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
#include "jerryscript-ext/autorelease.h"
static void
foo (bool enable)
{
JERRYX_AR_VALUE_T bar = jerry_create_string ((const jerry_char_t *) "...");
if (enable)
{
JERRYX_AR_VALUE_T baz = jerry_get_global_object ();
/* bar and baz can now be used. */
/*
* jerry_release_value (baz) and jerry_release_value (bar) is called automatically before
* returning, because `baz` and `bar` go out of scope.
*/
return;
}
/*
* jerry_release_value (bar) is called automatically when the function returns,
* because `bar` goes out of scope.
*/
}
```
**See also**
- [jerry_value_t](../docs/02.API-REFERENCE.md#jerry_value_t)
- [jerry_acquire_value](../docs/02.API-REFERENCE.md#jerry_acquire_value)
- [jerry_release_value](../docs/02.API-REFERENCE.md#jerry_release_value)
-313
View File
@@ -1,313 +0,0 @@
# Module API
This is a JerryScript extension that provides a means of loading modules. Fundamentally, a module is a name (stored as
a string) that resolves to a `jerry_value_t`. This extension provides the function `jerryx_module_resolve()` which
accepts the name of the module being requested as well as an array of so-called "resolvers" - structures containing two
function pointers: one for a function which computes a canonical name for the requested module or returns a reference
to the requested name, and one that converts a canonical name to a `jerry_value_t`, thus "resolving" or "loading" the
requested module.
The resolvers are first called in sequence to each compute the canonical name of the requested module. This is
accomplished by calling the `get_canonical_name` function pointer they provide. If the function pointer is `NULL`, the
requested module name is assumed to be what the resolver considers to be its canonical name. `jerryx_module_resolve`
searches its cache of loaded modules for each canonical name as returned by a `get_canonical_name` function pointer. If
one of the loaded modules in the cache corresponds to a canonical name, it is returned.
If no cached module is found, `jerryx_module_resolve` calls each resolver's `resolve` function pointer, passing it its
previously computed interpretation of the requested module's canonical name. If the resolver successfully creates the
`jerry_value_t` that represents the loaded module, it returns `true` and the `jerry_value_t` in its out parameter.
When `jerryx_module_resolve` receives a value of `true` from a resolver, it stops iterating over the remaining
resolvers in the sequence and, if the `jerry_value_t` returned from the resolver's `resolve` does not have the error
flag set, it will add the `jerry_value_t` to its cache under the module's canonical name and return it. Thus, on
subsequent calls to `jerryx_module_resolve` with a module name whose canonical name is associated with the
`jerry_value_t`, no `resolve` callback need be called again.
The purpose of having resolvers is to be able to account for the fact that different types of modules may be structured
differently and thus, for each type of module a module resolver must be supplied at the point where an instance of that
type of module is requested.
Individual modules may be removed from the cache by calling `jerryx_module_clear_cache`. This function behaves
identically to `jerryx_module_resolve` in that it first checks the cache for the requested module, except that it
removes the module if found. Additionally, it clears the entire cache of all modules if called using a JavaScript value
of `undefined` as its first parameter.
Additionally, this extension provides a means of easily defining so-called "native" JerryScript modules which can be
resolved using the native JerryScript module resolver `jerryx_module_native_resolver`, which can be passed to
`jerryx_module_resolve()`. Native modules are registered during application startup and by calling `dlopen()` by means
of library constructors, support for which can be turned on using the `FEATURE_INIT_FINI` build flag. In the absence of
such a flag, the module registration and unregistration functions are exposed as global symbols which can be called
explicitly.
## jerryx_module_resolve
**Summary**
Load a copy of a module into the current context or return one that was already loaded if it is found.
For each resolver passed in via `resolvers_p`, its `get_canonical_name` function pointer gets called in order to
establish the resolver's interpretation of what the canonical name for the module should be. If `get_canonical_name` is
`NULL`, it is assumed that the requested module's name as passed in is its canonical name.
Then, for each resolver passed in via `resolvers_p`, its `resolve` function pointer gets called with its interpretation
of what the module's canonical name should be, as computed in the previous step.
If the resolver's `resolve` function pointer returns `true`, the `jerry_value_t` returned in its out-parameter will be
returned by `jerryx_module_resolve` as the result of the request. If no error flag is set on the `jerry_value_t` it
will be cached under its canonical name so as to avoid loading the same module twice in the event of a subsequent call
to `jerryx_module_resolve` with a module name whose canonical name matches an already loaded module.
**Prototype**
```c
jerry_value_t
jerryx_module_resolve (const jerry_value_t name,
const jerryx_module_resolver_t *resolvers_p,
size_t resolver_count);
```
- `name` - the name of the module to load
- `resolvers_p` - the list of resolvers to call in sequence
- `resolver_count` - the number of resolvers in `resolvers_p`
- return value - `jerry_value_t` representing the module that was loaded, or the error that occurred in the process.
## jerryx_module_clear_cache
**Summary**
Remove a module from the current context's cache, or clear the cache entirely.
**Prototype**
```c
void
jerryx_module_clear_cache (const jerry_value_t name,
const jerryx_module_resolver_t *resolvers_p,
size_t resolver_count);
```
- `name` - the name of the module to remove from cache or a JavaScript `undefined` to clear the entire cache
- `resolvers_p` - the list of resolvers to call in sequence
- `resolver_count` - the number of resolvers in `resolvers_p`
## jerryx_module_native_resolver
**Summary**
The resolver for native JerryScript modules. A pointer to this structure can be passed in the second parameter to
`jerryx_module_resolve` to search for the module among the native JerryScript modules built into the binary. This
function is available only if the preprocessor directive `JERRYX_NATIVE_MODULES_SUPPORTED` is defined.
**Prototype**
```c
extern jerry_module_resolver_t jerryx_native_module_resolver;
```
# Module data types
## jerryx_module_get_canonical_name_t
**Summary**
The function pointer type for converting a module's requested name to its canonical name.
**Prototype**
```c
typedef jerry_value_t (*jerryx_module_get_canonical_name_t) (const jerry_value_t name);
```
## jerryx_module_resolve_t
**Summary**
Function pointer type for module resolution.
**Prototype**
```c
typedef bool (*jerryx_module_resolve_t) (const jerry_value_t canonical_name,
jerry_value_t *result);
```
## jerryx_module_resolver_t
**Summary**
Structure defining a module resolver.
**Prototype**
```c
typedef struct
{
jerryx_module_get_canonical_name_t get_canonical_name_p;
jerryx_module_resolve_t resolve_p;
} jerryx_module_resolver_t;
```
- `get_canonical_name_p` - function pointer to be called when the canonical name corresponding to the requested name
of a module must be established.
- `resolve_p` - function pointer to be called when a module with the given canonical name needs to be converted to the
`jerry_value_t` that will become the loaded module.
**Example**
```c
static bool
load_and_evaluate_js_file (const jerry_value_t name, jerry_value_t *result)
{
bool return_value = false;
char *js_file_contents = NULL;
int file_size = 0;
jerry_size_t name_size = jerry_get_utf8_string_size (name);
jerry_char_t name_string[name_size + 1];
jerry_string_to_utf8_char_buffer (name, name_string, name_size);
name_string[name_size] = 0;
FILE *js_file = fopen (name_string, "r");
if (js_file)
{
/* We have successfully opened the file. Now, we establish its size. */
file_size = fseek (js_file, 0, SEEK_END);
fseek (js_file, 0, SEEK_SET);
/* We allocate enough memory to store the contents of the file. */
js_file_contents = malloc (file_size);
if (js_file_contents)
{
/* We read the file into memory and call jerry_eval (), assigning the result to the out-parameter. */
fread (js_file_contents, file_size, 1, js_file);
(*result) = jerry_eval (js_file_contents, file_size, JERRY_PARSE_NO_OPTS);
/* We release the memory holding the contents of the file. */
free (js_file_contents);
return_value = true;
}
/* We close the file. */
fclose (js_file);
}
return return_value;
}
static jerry_value_t
canonicalize_file_path (const jerry_value_t name)
{
jerry_value_t absolute_path;
/**
* Since a file on the file system can be referred to by multiple relative paths, but only by one absolute path, the
* absolute path becomes the canonical name for the module. Thus, to establish this canonical name, we must search
* name for "./" and "../", follow symlinks, etc., then create absolute_path via jerry_create_string () and return
* it, because it is the canonical name for this module. Thus, we avoid loading the same JavaScript file twice.
*/
return absolute_path;
}
static jerryx_module_resolver_t js_file_loader
{
canonicalize_file_path,
load_and_evaluate_js_file
};
```
We can now load JavaScript files:
```c
static const jerryx_module_resolver_t *resolvers[] =
{
/*
* Consult the resolver for native JerryScript modules first, in case the requested module is a native JerryScript
* module.
*/
&jerryx_module_native_resolver,
/*
* If the requested module is not a native JerryScript module, assume it is a JavaScript file on disk and use the
* above-defined JavaScript file loader to load it.
*/
&js_file_loader
};
jerry_value_t js_module = jerryx_module_resolve (requested_module, resolvers, 2);
```
# Module helper macros
## JERRYX_NATIVE_MODULE
**Summary**
Helper macro to define a native JerryScript module. Currently declares a global static structure of type
`jerryx_native_module_t` and a constructor/destructor pair that calls `jerryx_native_module_register()` resp.
`jerryx_native_module_unregister()`. If the extension is built without the FEATURE_INIT_FINI flag, indicating that
support for library constructors and destructors is absent, the constructor and destructor are declared as global
symbols so that they may be called explicitly from within the application.
**Note**: The helper macro must appear at the bottom of a source file, and no semicolon must follow it.
**Prototype**
```c
#define JERRYX_NATIVE_MODULE(module_name, on_resolve_cb)
```
- `module_name` - the name of the module without quotes. This value is used as the prefix for the registration and unregistration funtions. For example, when `module_name` is `example_module`, this results in the declaration of two functions `example_module_register()` and `example_module_unregister()`. These functions are declared global if support for library constructors/destructors is absent, allowing you to call them from other parts of the code by
first forward-declaring them.
- `on_resolve_cb` - the function of type `jerryx_native_module_on_resolve_t` that will be called when the module needs to be
loaded.
**Example**
```c
#include "jerryscript.h"
#include "jerryscript-ext/module.h"
static jerry_value_t
my_module_on_resolve (void)
{
return jerry_create_external_function (very_useful_function);
} /* my_module_on_resolve */
/* Note that there is no semicolon at the end of the next line. This is how it must be. */
JERRYX_NATIVE_MODULE (my_module, my_module_on_resolve)
```
**Example Usage When Library Constructors Are Unavailable**
```c
#include "jerryscript.h"
#include "jerryscript-ext/module.h"
/**
* Forward-declare the module registration and unregistration function.
*/
extern void my_module_register (void);
extern void my_module_unregister (void);
int
main (int argc, char **argv)
{
jerryx_module_resolver_t resolvers[] =
{
jerryx_native_module_resolver
};
/* This plays the role of the library constructor. */
my_module_register ();
jerry_init (JERRY_INIT_EMPTY);
...
jerry_value_t my_module = jerryx_module_resolve ("my_module", resolvers, 1);
...
jerry_cleanup ();
/* This plays the role of the library destructor */
my_module_unregister();
return 0;
}
```
-217
View File
@@ -1,217 +0,0 @@
# JerryScript debugger transport interface
The transport interface support allows dynamic selection of transportation
layers which can encode/decode or send/receive messages transmitted between
the debugger client and server.
# Types
## jerry_debugger_transport_receive_context_t
**Summary**
This context represents the current status of processing received data.
The final state is returned by
[jerry_debugger_transport_receive](#jerry_debugger_transport_receive)
and must be passed to
[jerry_debugger_transport_receive_completed](#jerry_debugger_transport_receive_completed)
after the message is processed.
**Prototype**
```c
typedef struct
{
uint8_t *buffer_p; /**< buffer for storing the received data */
size_t received_length; /**< number of currently received bytes */
uint8_t *message_p; /**< start of the received message */
size_t message_length; /**< length of the received message */
size_t message_total_length; /**< total length for datagram protocols,
* 0 for stream protocols */
} jerry_debugger_transport_receive_context_t;
```
## jerry_debugger_transport_header_t
**Summary**
Shared header for each transport interface. It mostly contains callback functions
used by the JerryScript debugger server.
**Prototype**
```c
typedef struct jerry_debugger_transport_layer_t
{
/* The following fields must be filled before calling jerry_debugger_transport_add(). */
jerry_debugger_transport_close_t close; /**< close connection callback */
jerry_debugger_transport_send_t send; /**< send data callback */
jerry_debugger_transport_receive_t receive; /**< receive data callback */
/* The following fields are filled by jerry_debugger_transport_add(). */
struct jerry_debugger_transport_layer_t *next_p; /**< next transport layer */
} jerry_debugger_transport_header_t;
```
## jerry_debugger_transport_close_t
**Summary**
Called when the connection is closed. Must release all resources (including the
memory area for the transport interface) allocated for the transport interface.
**Prototype**
```c
typedef void (*jerry_debugger_transport_close_t) (struct jerry_debugger_transport_interface_t *header_p);
```
## jerry_debugger_transport_send_t
**Summary**
Called when a message needs to be sent. Must either transmit the message or call
the `header_p->next_p->send()` method.
**Prototype**
```c
typedef bool (*jerry_debugger_transport_send_t) (struct jerry_debugger_transport_interface_t *header_p,
uint8_t *message_p, size_t message_length);
```
## jerry_debugger_transport_receive_t
**Summary**
Called during message processing. If messages are available it must return with
the next message.
**Prototype**
```c
typedef bool (*jerry_debugger_transport_receive_t) (struct jerry_debugger_transport_interface_t *header_p,
jerry_debugger_transport_receive_context_t *context_p);
```
# Transport interface API functions
## jerry_debugger_transport_add
**Summary**
Add a new interface to the transporation interface chain. The interface
will be the first item of the interface chain.
**Prototype**
```c
void jerry_debugger_transport_add (jerry_debugger_transport_header_t *header_p,
size_t send_message_header_size, size_t max_send_message_size,
size_t receive_message_header_size, size_t max_receive_message_size);
```
- `header_p`: header of a transporation interface.
- `send_message_header_size`: size of the outgoing message header, can be 0.
- `max_send_message_size`: maximum outgoing message size supported by the interface.
- `receive_message_header_size`: size of the incoming message header, can be 0.
- `max_receive_message_size`: maximum incoming message size supported by the interface.
## jerry_debugger_transport_start
**Summary**
Starts the communication to the debugger client. Must be called after the
connection is successfully established.
**Prototype**
```c
void jerry_debugger_transport_start (void);
```
## jerry_debugger_transport_is_connected
**Summary**
Tells whether a debugger client is connected to the debugger server.
**Prototype**
```c
bool jerry_debugger_transport_is_connected (void);
```
- return value: `true`, if a client is connected, `false` otherwise.
## jerry_debugger_transport_close
**Summary**
Disconnect from the current debugger client. It does nothing if a client is
not connected.
**Prototype**
```c
void jerry_debugger_transport_close (void);
```
## jerry_debugger_transport_send
**Summary**
Send message to the client.
**Prototype**
```c
bool jerry_debugger_transport_send (const uint8_t *message_p, size_t message_length);
```
- `message_p`: message to be sent.
- `message_length`: message length in bytes.
- return value: `true`, if a client is still connected, `false` otherwise.
## jerry_debugger_transport_receive
**Summary**
Receive message from the client.
**Prototype**
```c
bool jerry_debugger_transport_receive (jerry_debugger_transport_receive_context_t *context_p);
```
- `context_p`: an unused [jerry_debugger_transport_receive_context_t](#jerry_debugger_transport_receive_context_t).
- return value: `true`, if a client is still connected, `false` otherwise.
## jerry_debugger_transport_receive_completed
**Summary**
Must be called after [jerry_debugger_transport_receive](#jerry_debugger_transport_receive)
returns with a valid message. Must not be called otherwise.
**Prototype**
```c
void jerry_debugger_transport_receive_completed (jerry_debugger_transport_receive_context_t *context_p);
```
- `context_p`: a [jerry_debugger_transport_receive_context_t](#jerry_debugger_transport_receive_context_t)
passed to [jerry_debugger_transport_receive](#jerry_debugger_transport_receive).
## jerry_debugger_transport_sleep
**Summary**
Can be used to wait for incoming messages. Currently the delay is 100ms.
**Prototype**
```c
void jerry_debugger_transport_sleep (void);
```
-112
View File
@@ -1,112 +0,0 @@
# Handle Scope
## jerryx_handle_scope
**Summary**
It is often necessary to make the lifespan of handles shorter than the lifespan of a native method. Even though the native code could only use the most recent handle, all of the associated objects would also be kept alive since they all share the same scope.
To handle this case, JerryScript HandleScope extension provides the ability to establish a new 'scope' to which newly created handles will be associated. Once those handles are no longer required, the scope can be 'closed' and any handles associated with the scope are invalidated. The methods available to open/close scopes are `jerryx_open_handle_scope` and `jerryx_close_handle_scope`.
JerryScript only supports a single nested hierarchy of scopes. There is only one active scope at any time, and all new handles will be associated with that scope while it is active. Scopes must be closed in the reverse order from which they are opened. In addition, all scopes created within a native method must be closed before returning from that method.
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
#include "jerryscript-ext/handle-scope.h"
static jerry_value_t
create_object (void)
{
jerry_value_t obj = jerry_create_object ();
return obj;
} /* create_object */
static void
test_handle_scope_val (void)
{
jerryx_handle_scope scope;
jerryx_open_handle_scope (&scope);
jerry_value_t obj = jerryx_create_handle (create_object ());
jerryx_close_handle_scope (scope);
// now obj has been released
} /* test_handle_scope_val */
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
test_handle_scope_val ();
jerry_gc (JERRY_GC_PRESSURE_LOW);
jerry_cleanup ();
} /* main */
```
## jerryx_escapable_handle_scope
**Summary**
It is necessary in common cases that a handle has to be promote to outer scope and prevent from been garbage collected. To handle this case, a escapable handle scope has been proposed from which one object can be promoted to the outer scope. The method available to escape an object from been release at current scope is `jerryx_escape_handle`.
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
#include "jerryscript-ext/handle-scope.h"
static jerry_value_t
create_object (void)
{
jerryx_escapable_handle_scope scope;
jerryx_open_escapable_handle_scope (&scope);
jerry_value_t obj = jerryx_create_handle (jerry_create_object ());
jerry_value_t escaped_obj;
jerryx_escape_handle(scope, obj, &escaped_obj);
jerryx_close_handle_scope (scope);
// escaped_obj has now been escaped to outer scope, thus not released at this point
return escaped_obj;
} /* create_object */
static void
test_handle_scope_val (void)
{
jerryx_handle_scope scope;
jerryx_open_handle_scope (&scope);
jerry_value_t obj = create_object ();
jerryx_close_handle_scope (scope);
// now obj has been released
} /* test_handle_scope_val */
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
test_handle_scope_val ();
jerry_gc (JERRY_GC_PRESSURE_LOW);
jerry_cleanup ();
} /* main */
```
**See also**
- [jerry_value_t](../docs/02.API-REFERENCE.md#jerry_value_t)
- [jerry_acquire_value](../docs/02.API-REFERENCE.md#jerry_acquire_value)
- [jerry_release_value](../docs/02.API-REFERENCE.md#jerry_release_value)
## Pre-allocated list of handle scopes and handles
To prevent trapping into system calls frequently, a pre-allocated dedicated list mechanism has been introduced to the implementation of JerryX handle scope.
To change the size of pre-allocation list, use build definition `JERRYX_HANDLE_PRELIST_SIZE` and `JERRYX_SCOPE_PRELIST_SIZE` to alter the default value of 20.
-158
View File
@@ -1,158 +0,0 @@
# ES6 module support for JerryScript
The module system allows users to write import and export statements in scripts, which can be used to separate the logic of the application into custom modules.
The standard's relevant part can be found [here](https://www.ecma-international.org/ecma-262/6.0/#sec-modules).
## General
If a script contains import statements, then JerryScript will open and evaluate the the referenced modules before the main script runs, resolving and creating bindings for the referenced identifiers in the process.
It is not necessary to use any specific filename extensions for modules, JerryScript will try to open the given file paths as they are, but will try to normalize them before doing so. The exact normalization process is dependant on the port implementation provided. It is the user's responsibility to verify that the given files are valid EcmaScript modules.
main.js
```js
import { exported_value } from "./module.js"
print (exported_value);
```
module.js
```js
var exported_value = 42;
export exported_value;
```
## Supported features
* exporting identifiers from the module's lexical environment
* specifying export names for the exported values
* importing exported identifiers from a module
* specifying local binding names for the imported values
* module namespace imports
* `import * as module from 'module.js`
* indirect export statements
* `export {variable} from 'module.js'`
* star export statements
* `export * from 'module.js'`
* importing a module for side-effects
* `import 'module.js'`
* default import and export statements
* `export default local_identifier`
* `import def from 'module.js'`
* anonymous default exports
* `export default function () {}`
### Example
```js
import {
engine,
version as v
} from "./module.js"
import { getFeatureDetails } from "./module_2.js"
var version = "v3.1415";
print("> main.js");
print(">> Engine: " + engine);
print(">> Version: " + v);
print (">> " + getFeatureDetails());
print (">> Script version: " + version);
```
```js
// module.js
var _engine = "JerryScript";
export _engine as engine;
export var version = "1.0 (e92ae0fb)";
```
```js
// module_2.js
var featureName = "EcmaScript 2015 modules";
var year = 2018;
export function getFeatureDetails() {
return "Feature name: " + featureName + " | developed in " + year;
}
```
### Module namespace import statements
A module namespace object can be imported. In this case the local binding will contain an object holding the exported values of the module, including local exports and all indirect exports. Ambiguous exported names are exluded from the namespace object.
```js
import * as module from './module.js';
print(">> Engine: " + module.engine);
print(">> Version: " + module.version);
```
### Indirect export statements
An export statement can transitively export variables from another module, either via named indirect exports or a star export statement. In this case the resolving process will follow the chain until it reaches a module containing a local binding for that export name. If there are multiple modules which satisfy the export, that means the export is ambiguous, and will result in a SyntaxError.
```js
import { a, b } from 'module.js'
print (a + b);
```
```js
// module.js
export var a = 2;
export { b } from 'module2.js'
```
```js
// module2.js
export var b = 40;
```
### Default imports and exports
Each module can optionally provide a single default export by using the `export default` statement. Default exports can either reference identifiers in the module's lexical environment, or be an anonymous default export, in which case they will only be accessible by an importing script.
```js
import defaultExport, { b as c } from 'module.js'
print (defaultExport); // 2
print (c ()); // 42
```
```js
// module.js
export default 2;
export function b () {
return 42;
}
```
### Importing modules for side-effects
Evaluate a module without importing anything. Any errors encountered in the module will be propagated.
```js
import 'module.js' // > module.js
// "> module.js" is printed
b (); // (ReferenceError) b is not defined
```
```js
// module.js
export function b () {
print ("> module.js");
return 42;
}
b ();
```
## Unsupported features
* **snapshot**
-772
View File
@@ -1,772 +0,0 @@
# Migration guide
This guide intends to describe the major changes between the JerryScript 1.0 and 2.0 versions.
In addtion it is designed to provide a guide on how to modify the 1.0 version code to a
2.0 compliant code.
During the development it was important to minimize the changes in the API functions and types.
Each API method removal or chang is described below providing a ***before*** and ***after***
code example.
For more information on the current API methods please check the [API reference](02.API-REFERENCE.md) document.
# Short list of removed/renamed headers, types, functions, and macros
***Removed legacy headers***
- `jerry-internal.h`
***Renamed headers***
- `jerry-api.h` to `jerryscript.h`
- `jerry-port.h` to `jerryscript-port.h`
***Removed API types***
- `jerry_char_ptr_t` usage replaced with `jerry_char_t *`
- `jerry_object_free_callback_t` replaced by `jerry_object_native_free_callback_t`
***Removed API methods***
- `jerry_get_memory_limits`
- `jerry_get_object_native_handle` replaced by `jerry_get_object_native_pointer`
- `jerry_set_object_native_handle` replaced by `jerry_set_object_native_pointer`
- `jerry_value_set_abort_flag` replaced by `jerry_create_abort_from_value`
- `jerry_value_has_abort_flag` replaced by `jerry_value_is_abort`
- `jerry_value_set_error_flag` replaced by `jerry_create_error_from_value`
- `jerry_value_has_error_flag` replaced by `jerry_value_is_error`
- `jerry_value_clear_error_flag` replaced by `jerry_get_value_from_error`
- `jerry_get_value_without_error_flag` replaced by `jerry_get_value_from_error`
- `jerry_parse_and_save_snapshot` replaced by `jerry_generate_snapshot`
- `jerry_parse_and_save_function_snapshot` replaced by `jerry_generate_function_snapshot`
***Removed unused configuration macros***
- `CONFIG_MEM_DATA_LIMIT_MINUS_HEAP_SIZE`
- `CONFIG_MEM_STACK_LIMIT`
- `CONFIG_VM_STACK_FRAME_INLINED_VALUES_NUMBER`
- `CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE`
- All `CONFIG_..` macros have been renamed to use the `JERRY_` prefix format.
# Modified API functions
## Error manipulating functions
The most important changes in the API are releated to error handling and manipulation.
### jerry_value_set_abort_flag
This function was replaced with [`jerry_create_abort_from_value`](02.API-REFERENCE.md#jerry_create_abort_from_value).
Take note of the second argument of the new `jerry_create_abort_from_value` function which controls if the
first argument should be usable after the call or not.
**Before**
```c
{
jerry_value_t value;
// create or acquire value
// ...
jerry_value_set_abort_flag (&value);
jerry_release_value (value);
}
```
**After**
```c
{
jerry_value_t value;
// create or acquire value
// ...
jerry_value_t abort = jerry_create_abort_from_value (value, true);
// using the 'value' variable after release is invalid
jerry_release_value (abort);
}
```
- OR
```c
{
jerry_value_t value;
... // create or acquire value
jerry_value_t abort = jerry_create_abort_from_value (value, false);
// both 'abort' and 'value' can be used and must be released when they are no longer needed
jerry_release_value (abort);
jerry_release_value (value);
}
```
### jerry_value_has_abort_flag
This function was renamed to [`jerry_value_is_abort`](02.API-REFERENCE.md#jerry_value_is_abort).
**Before**
```c
{
jerry_value_t value;
// create or acquire value
// ...
if (jerry_value_has_abort_flag (value))
{
// ...
}
jerry_release_value (value);
}
```
**After**
```c
{
jerry_value_t value;
// create or acquire value
// ...
if (jerry_value_is_abort (value))
{
// ...
}
jerry_release_value (value);
}
```
### jerry_value_set_error_flag
This function was replaced with [`jerry_create_error_from_value`](02.API-REFERENCE.md#jerry_create_error_from_value).
Take note of the second argument of the new `jerry_create_error_from_value` function which controls if the
first argument should be usable after the call or not.
**Before**
```c
{
jerry_value_t value;
// create or acquire value
// ...
jerry_value_set_error_flag (&value);
jerry_release_value (value);
}
```
**After**
```c
{
jerry_value_t value;
// create or acquire value
// ...
jerry_value_t error = jerry_create_error_from_value (value, true);
// using the 'value' variable after release is invalid
jerry_release_value (error);
}
```
- OR
```c
{
jerry_value_t value;
// create or acquire value
// ...
jerry_value_t error = jerry_create_error_from_value (value, false);
// both 'error' and 'value' can be used and must be released when they are no longer needed
jerry_release_value (error);
jerry_release_value (value);
}
```
### jerry_value_has_error_flag
This function was renamed to [`jerry_value_is_error`](02.API-REFERENCE.md#jerry_value_is_error).
**Before**
```c
{
jerry_value_t value;
// create or acquire value
// ...
if (jerry_value_has_error_flag (value))
{
// ...
}
jerry_release_value (value);
}
```
**After**
```c
{
jerry_value_t value;
// create or acquire value
// ...
if (jerry_value_is_error (value))
{
// ...
}
jerry_release_value (value);
}
```
### jerry_value_clear_error_flag AND jerry_get_value_without_error_flag
These functions were merged into [`jerry_get_value_from_error`](02.API-REFERENCE.md#jerry_get_value_from_error).
Please note the second argument of the new function which controls if the first argument passed should be released
or not.
**Before**
```c
{
jerry_value_t value;
// create or acquire value
// ...
jerry_value_set_error_flag (&value);
jerry_value_clear_error_flag (&value);
// or
jerry_value_t real_value = jerry_get_value_without_error_flag (value);
jerry_release_value (value);
jerry_release_value (real_value);
}
```
**After**
```c
{
jerry_value_t value;
// create or acquire value
// ...
jerry_value_t error = jerry_create_error_from_value (value, true);
jerry_value_t real_value = jerry_get_value_from_error (error, true);
jerry_release_value (real_value);
}
```
## Other functions changed
### jerry_register_magic_strings
In case of the `jerry_register_magic_strings` function the change is that
the first argument's base type `jerry_char_ptr_t` was changed to `jerry_char_t*`.
For more details see: [`jerry_register_magic_strings`](02.API-REFERENCE.md#jerry_register_magic_strings).
In the following code parts please take note of the type used for the `magic_string_items` array.
**Before**
```c
{
// must be static, because 'jerry_register_magic_strings' does not copy
// the items must be sorted by size at first, then lexicographically
static const jerry_char_ptr_t magic_string_items[] = {
(const jerry_char_ptr_t) "magicstring1",
(const jerry_char_ptr_t) "magicstring2",
(const jerry_char_ptr_t) "magicstring3"
};
uint32_t num_magic_string_items = (uint32_t) (sizeof (magic_string_items) / sizeof (jerry_char_ptr_t));
// must be static, because 'jerry_register_magic_strings' does not copy
static const jerry_length_t magic_string_lengths[] = { 12, 12, 12 };
jerry_register_magic_strings (magic_string_items, num_magic_string_items, magic_string_lengths);
}
```
**After**
```c
{
// must be static, because 'jerry_register_magic_strings' does not copy
// the items must be sorted by size at first, then lexicographically
static const jerry_char_t *magic_string_items[] = {
(const jerry_char_t *) "magicstring1",
(const jerry_char_t *) "magicstring2",
(const jerry_char_t *) "magicstring3"
};
uint32_t num_magic_string_items = (uint32_t) (sizeof (magic_string_items) / sizeof (jerry_char_t *));
// must be static, because 'jerry_register_magic_strings' does not copy
static const jerry_length_t magic_string_lengths[] = { 12, 12, 12 };
jerry_register_magic_strings (magic_string_items, num_magic_string_items, magic_string_lengths);
}
```
## Snapshot generating API
### jerry_parse_and_save_snapshot
This function was replaced with [`jerry_generate_snapshot`](02.API-REFERENCE.md#jerry_generate_snapshot).
The function returns an error object if there was any problem during snapshot generation and
if there was no problem the return value is a number value containing the snapshot size in bytes.
**Before**
```c
{
static uint32_t global_mode_snapshot_buffer[256];
const jerry_char_t *code_to_snapshot_p = (const jerry_char_t *) "(function () { return 'string from snapshot'; }) ();";
size_t global_mode_snapshot_size =
jerry_parse_and_save_snapshot (code_to_snapshot_p,
strlen ((const char *) code_to_snapshot_p),
true,
false,
global_mode_snapshot_buffer,
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
// use "global_mode_snapshot_buffer"
}
```
**After**
```c
{
static uint32_t global_mode_snapshot_buffer[256];
const jerry_char_t *code_to_snapshot_p = (const jerry_char_t *) "(function () { return 'string from snapshot'; }) ();";
jerry_value_t generate_result;
generate_result = jerry_generate_snapshot (NULL,
0,
code_to_snapshot_p,
strlen ((const char *) code_to_snapshot_p),
global_mode_snapshot_buffer,
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
if (jerry_value_is_error (generate_result))
{
// There was a problem during snapshot generation, for example there is a SyntaxError.
// Use the "generate_result" to check the error.
}
else
{
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
// use "global_mode_snapshot_buffer"
}
jerry_release_value (generate_result);
}
```
### jerry_parse_and_save_function_snapshot
This function was replaced with [`jerry_generate_function_snapshot`](02.API-REFERENCE.md#jerry_parse_and_save_function_snapshot).
The function returns an error object if there was any problem during snapshot generation and
if there was no problem the return value is a number value containing the snapshot size in bytes.
**Before**
```c
{
static uint32_t func_snapshot_buffer[1024];
const jerry_char_t *args_p = (const jerry_char_t *) "a, b";
const jerry_char_t *src_p = (const jerry_char_t *) "return a + b;";
size_t func_snapshot_size =
jerry_parse_and_save_function_snapshot (src_p,
strlen ((const char *) src_p),
args_p,
strlen ((const char *) args_p),
false,
func_snapshot_buffer,
sizeof (func_snapshot_buffer) / sizeof (uint32_t));
// check "function_snapshot_size" and use "func_snapshot_buffer"
}
```
**After**
```c
{
static uint32_t func_snapshot_buffer[1024];
const jerry_char_t *args_p = (const jerry_char_t *) "a, b";
const jerry_char_t *src_p = (const jerry_char_t *) "return a + b;";
jerry_value_t generate_result;
generate_result = jerry_generate_function_snapshot (NULL,
0,
src_p,
strlen ((const char *) src_p),
args_p,
strlen ((const char *) args_p),
0,
func_snapshot_buffer,
sizeof (func_snapshot_buffer) / sizeof (uint32_t));
if (jerry_value_is_error (generate_result))
{
// There was a problem during snapshot generation, for example there is a SyntaxError.
// Use the "generate_result" to check the error.
}
else
{
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
// use "func_snapshot_buffer"
}
jerry_release_value (generate_result)
}
```
## Garbage collection
### jerry_gc
The [`jerry_gc`](02.API-REFERENCE.md#jerry_gc) function was modified to handle an argument which represents the pressure for the garbage collector.
For more information checkout the [`jerry_gc_mode_t`](02.API-REFERENCE.md#jerry_gc_mode_t) reference.
**Before**
```c
{
jerry_gc ();
}
```
**After**
```c
{
jerry_gc (JERRY_GC_PRESSURE_LOW);
}
```
## jerry_eval
The third argument of [`jerry_eval`](02.API-REFERENCE.md#jerry_eval) has been changed
from `bool` to [`jerry_parse_opts_t`](02.API-REFERENCE.md#jerry_parse_opts_t).
**Before**
```c
const jerry_char_t *str_to_eval = (const jerry_char_t *) "1 + 1";
jerry_value_t ret_val = jerry_eval (str_to_eval,
strlen ((const char *) str_to_eval),
false);
```
**After**
```c
const jerry_char_t *str_to_eval = (const jerry_char_t *) "1 + 1";
jerry_value_t ret_val = jerry_eval (str_to_eval,
strlen ((const char *) str_to_eval),
JERRY_PARSE_NO_OPTS);
```
## Port API
### jerry_port_get_time_zone
The port API of handling timezones has been changed. The previous interface did not
allow timezones to be handled correctly, even if the host system was up to the task.
Check [the related issue](https://github.com/jerryscript-project/jerryscript/issues/1661)
for more details.
The new port API function name is [jerry_port_get_local_time_zone_adjustment](05.PORT-API.md#date-1].
Below is the default implementations for both versions:
**Before**
```c
bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p)
{
struct timeval tv;
struct timezone tz;
/* gettimeofday may not fill tz, so zero-initializing */
tz.tz_minuteswest = 0;
tz.tz_dsttime = 0;
if (gettimeofday (&tv, &tz) != 0)
{
return false;
}
tz_p->offset = tz.tz_minuteswest;
tz_p->daylight_saving_time = tz.tz_dsttime > 0 ? 1 : 0;
return true;
} /* jerry_port_get_time_zone */
```
**After**
```c
double jerry_port_get_local_time_zone_adjustment (double unix_ms,
bool is_utc)
{
struct tm tm;
time_t now = (time_t) (unix_ms / 1000);
localtime_r (&now, &tm);
if (!is_utc)
{
now -= tm.tm_gmtoff;
localtime_r (&now, &tm);
}
return ((double) tm.tm_gmtoff) * 1000;
} /* jerry_port_get_local_time_zone_adjustment */
```
## Native pointers
The assignment of native pointers (previously called handles) have been changed
since v1.0. In the previous version only one native pointer could be assigned to
a `jerry_value_t`. Now it is allowed to register multiple native infos, which
can be accessed with the corresponding
[`jerry_object_native_info_t`](02.API-REFERENCE.md#jerry_object_native_info_t).
The old functions were removed and replaced by new ones.
- `jerry_object_free_callback_t` callback type is replaced by `jerry_object_native_info_t`
- `jerry_get_object_native_handle` is replaced by [`jerry_get_object_native_pointer`](02.API-REFERENCE.md#jerry_get_object_native_pointer)
- `jerry_set_object_native_handle` is replaced by [`jerry_set_object_native_pointer`](02.API-REFERENCE.md#jerry_set_object_native_pointer)
**Before**
```c
struct
{
int data;
} my_info;
static void
handler_construct_freecb (uintptr_t native_p)
{
// Invoked when the JS object is released and the
// native data should be freed.
struct my_info *info = (struct my_info *) native_p;
free (info);
}
void
demo (void)
{
jerry_value_t this_val;
// create or acquire this_val
// ...
struct my_info *info = (struct my_info *) malloc (sizeof (struct my_info));
info->data = 11;
// setting the native handle
jerry_set_object_native_handle (this_val,
(uintptr_t) info,
handler_construct_freecb);
// ...
// reading back the native handle
uintptr_t ptr = (uintptr_t) NULL;
bool is_ok = jerry_get_object_native_handle (this_val, &ptr);
if (is_ok)
{
struct my_info *obj_info = (struct my_info *) ptr;
// use "obj_info"
}
}
```
**After**
```c
struct
{
int data;
} my_info;
static void
handler_construct_freecb (void *native_p)
{
// Invoked when the JS object is released and the
// native data should be freed.
struct my_info *info = (struct my_info *) native_p;
free (info);
}
static const jerry_object_native_info_t my_info_type_info =
{
.free_cb = handler_construct_freecb
};
void
demo (void)
{
jerry_value_t this_val;
// create or acquire this_val
// ...
struct my_info *info = (struct my_info *) malloc (sizeof (struct my_info));
info->data = 11;
// setting the native handle
jerry_set_object_native_pointer (this_val,
info,
&my_info_type_info);
// ...
// reading back the native handle pointed by the "my_info_type_info" variable
void *ptr = NULL;
bool has_p = jerry_get_object_native_pointer (this_val, &ptr, &my_info_type_info);
if (has_p)
{
struct my_info *obj_info = (struct my_info *) ptr;
// use "obj_info"
}
}
```
# New API functions
In this section the new API functions are listed.
## Built-in objects
***ArrayBuffer***
- [`jerry_create_arraybuffer`](02.API-REFERENCE.md#jerry_create_arraybuffer)
- [`jerry_create_arraybuffer_external`](02.API-REFERENCE.md#jerry_create_arraybuffer_external)
- [`jerry_get_arraybuffer_pointer`](02.API-REFERENCE.md#jerry_get_arraybuffer_pointer)
***DataView***
- [`jerry_create_dataview`](02.API-REFERENCE.md#jerry_create_dataview)
- [`jerry_value_is_dataview`](02.API-REFERENCE.md#jerry_value_is_dataview)
- [`jerry_get_dataview_buffer`](02.API-REFERENCE.md#jerry_get_dataview_buffer)
***JSON***
- [`jerry_json_parse`](02.API-REFERENCE.md#jerry_json_parse)
- [`jerry_json_stringify`](02.API-REFERENCE.md#jerry_json_stringify)
***Number***
- [`jerry_create_number_infinity`](02.API-REFERENCE.md#jerry_create_number_infinity)
- [`jerry_create_number_nan`](02.API-REFERENCE.md#jerry_create_number_nan)
***Promise***
- [`jerry_run_all_enqueued_jobs`](02.API-REFERENCE.md#jerry_run_all_enqueued_jobs)
- [`jerry_create_promise`](02.API-REFERENCE.md#jerry_create_promise)
- [`jerry_resolve_or_reject_promise`](02.API-REFERENCE.md#jerry_resolve_or_reject_promise)
- [`jerry_value_is_promise`](02.API-REFERENCE.md#jerry_value_is_promise)
***RegExp***
- [`jerry_create_regexp`](02.API-REFERENCE.md#jerry_create_regexp)
- [`jerry_create_regexp_sz`](02.API-REFERENCE.md#jerry_create_regexp_sz)
***String***
- [`jerry_substring_to_utf8_char_buffer`](02.API-REFERENCE.md#jerry_substring_to_utf8_char_buffer)
- [`jerry_get_utf8_string_size`](02.API-REFERENCE.md#jerry_get_utf8_string_size)
- [`jerry_get_utf8_string_length`](02.API-REFERENCE.md#jerry_get_utf8_string_length)
- [`jerry_create_string_from_utf8`](02.API-REFERENCE.md#jerry_create_string_from_utf8)
- [`jerry_create_string_sz_from_utf8`](02.API-REFERENCE.md#jerry_create_string_sz_from_utf8)
***Symbol***
- [`jerry_create_symbol`](02.API-REFERENCE.md#jerry_create_symbol)
- [`jerry_get_symbol_descriptive_string`](02.API-REFERENCE.md#jerry_get_symbol_descriptive_string)
- [`jerry_value_is_symbol`](02.API-REFERENCE.md#jerry_value_is_symbol)
***TypedArray***
- [`jerry_create_typedarray`](02.API-REFERENCE.md#jerry_create_typedarray)
- [`jerry_create_typedarray_for_arraybuffer`](02.API-REFERENCE.md#jerry_create_typedarray_for_arraybuffer)
- [`jerry_create_typedarray_for_arraybuffer_sz`](02.API-REFERENCE.md#jerry_create_typedarray_for_arraybuffer_sz)
- [`jerry_get_typedarray_type`](02.API-REFERENCE.md#jerry_get_typedarray_type)
- [`jerry_get_typedarray_length`](02.API-REFERENCE.md#jerry_get_typedarray_length)
- [`jerry_get_typedarray_buffer`](02.API-REFERENCE.md#jerry_get_typedarray_buffer)
- [`jerry_value_is_typedarray`](02.API-REFERENCE.md#jerry_value_is_typedarray)
## Instances and memory management
***JerryScript instances***
- [`jerry_create_context`](02.API-REFERENCE.md#jerry_create_context)
- [`jerry_get_context_data`](02.API-REFERENCE.md#jerry_get_context_data)
***Memory management***
- [`jerry_heap_alloc`](02.API-REFERENCE.md#jerry_heap_alloc)
- [`jerry_heap_free`](02.API-REFERENCE.md#jerry_heap_free)
## Operations with JavaScript values
***Binary operations***
- [`jerry_binary_operation`](02.API-REFERENCE.md#jerry_binary_operation)
***Error manipulating***
- [`jerry_get_error_type`](02.API-REFERENCE.md#jerry_get_error_type)
- [`jerry_get_backtrace`](02.API-REFERENCE.md#jerry_get_backtrace)
***Native pointers***
- [`jerry_delete_object_native_pointer`](02.API-REFERENCE.md#jerry_delete_object_native_pointer)
- [`jerry_objects_foreach_by_native_info`](02.API-REFERENCE.md#jerry_objects_foreach_by_native_info)
***Property***
- [`jerry_delete_property_by_index`](02.API-REFERENCE.md#jerry_delete_property_by_index)
- [`jerry_objects_foreach`](02.API-REFERENCE.md#jerry_objects_foreach)
## Debugger
- [`jerry_debugger_is_connected`](07.DEBUGGER.md#jerry_debugger_is_connected)
- [`jerry_debugger_stop`](07.DEBUGGER.md#jerry_debugger_stop)
- [`jerry_debugger_continue`](07.DEBUGGER.md#jerry_debugger_continue)
- [`jerry_debugger_stop_at_breakpoint`](07.DEBUGGER.md#jerry_debugger_stop_at_breakpoint)
- [`jerry_debugger_wait_for_client_source`](07.DEBUGGER.md#jerry_debugger_wait_for_client_source)
- [`jerry_debugger_send_output`](07.DEBUGGER.md#jerry_debugger_send_output)
- [`jerry_debugger_send_log`](07.DEBUGGER.md#jerry_debugger_send_log)
## Other
- [`jerry_is_feature_enabled`](02.API-REFERENCE.md#jerry_is_feature_enabled)
- [`jerry_parse_and_save_literals`](02.API-REFERENCE.md#jerry_parse_and_save_literals)
- [`jerry_set_vm_exec_stop_callback`](02.API-REFERENCE.md#jerry_set_vm_exec_stop_callback)
## Port API functions
- [`jerry_port_normalize_path`](05.PORT-API.md#jerry_port_normalize_path)
- [`jerry_port_read_source`](05.PORT-API.md#jerry_port_read_source)
- [`jerry_port_release_source`](05.PORT-API.md#jerry_port_release_source)
- [`jerry_port_print_char`](05.PORT-API.md#jerry_port_print_char)
- [`jerry_port_get_current_context`](05.PORT-API.md#jerry_port_get_current_context)
- [`jerry_port_fatal`](05.PORT-API.md#jerry_port_fatal)
- [`jerry_port_sleep`](05.PORT-API.md#jerry_port_sleep)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

+156 -335
View File
@@ -1,4 +1,5 @@
# Copyright JS Foundation and other contributors, http://js.foundation
# Copyright 2015-2016 Samsung Electronics Co., Ltd.
# Copyright 2016 University of Szeged.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,102 +17,37 @@ cmake_minimum_required (VERSION 2.8.12)
set(JERRY_CORE_NAME jerry-core)
project (${JERRY_CORE_NAME} C)
# Optional build settings
set(ENABLE_ALL_IN_ONE OFF CACHE BOOL "Enable all-in-one build?")
# Optional features
set(JERRY_CPOINTER_32_BIT OFF CACHE BOOL "Enable 32 bit compressed pointers?")
set(JERRY_DEBUGGER OFF CACHE BOOL "Enable JerryScript debugger?")
set(JERRY_ERROR_MESSAGES OFF CACHE BOOL "Enable error messages?")
set(JERRY_EXTERNAL_CONTEXT OFF CACHE BOOL "Enable external context?")
set(JERRY_PARSER ON CACHE BOOL "Enable javascript-parser?")
set(JERRY_LINE_INFO OFF CACHE BOOL "Enable line info?")
set(JERRY_LOGGING OFF CACHE BOOL "Enable logging?")
set(JERRY_MEM_STATS OFF CACHE BOOL "Enable memory statistics?")
set(JERRY_MEM_GC_BEFORE_EACH_ALLOC OFF CACHE BOOL "Enable mem-stress test?")
set(JERRY_PARSER_DUMP_BYTE_CODE OFF CACHE BOOL "Enable parser byte-code dumps?")
set(JERRY_PROFILE "es5.1" CACHE STRING "Use default or other profile?")
set(JERRY_REGEXP_STRICT_MODE OFF CACHE BOOL "Enable regexp strict mode?")
set(JERRY_REGEXP_DUMP_BYTE_CODE OFF CACHE BOOL "Enable regexp byte-code dumps?")
set(JERRY_SNAPSHOT_EXEC OFF CACHE BOOL "Enable executing snapshot files?")
set(JERRY_SNAPSHOT_SAVE OFF CACHE BOOL "Enable saving snapshot files?")
set(JERRY_SYSTEM_ALLOCATOR OFF CACHE BOOL "Enable system allocator?")
set(JERRY_VALGRIND OFF CACHE BOOL "Enable Valgrind support?")
set(JERRY_VM_EXEC_STOP OFF CACHE BOOL "Enable VM execution stopping?")
set(JERRY_GLOBAL_HEAP_SIZE "(512)" CACHE STRING "Size of memory heap, in kilobytes")
set(JERRY_STACK_LIMIT "(0)" CACHE STRING "Maximum stack usage size, in kilobytes")
# Option overrides
if(USING_MSVC)
set(ENABLE_ALL_IN_ONE ON) # FIXME: This should not be needed but right now it is. To be tracked down and followed up.
set(ENABLE_ALL_IN_ONE_MESSAGE " (FORCED BY COMPILER)")
endif()
if(JERRY_SYSTEM_ALLOCATOR)
set(JERRY_CPOINTER_32_BIT ON)
set(JERRY_CPOINTER_32_BIT_MESSAGE " (FORCED BY SYSTEM ALLOCATOR)")
endif()
if (JERRY_GLOBAL_HEAP_SIZE GREATER 512)
set(JERRY_CPOINTER_32_BIT ON)
set(JERRY_CPOINTER_32_BIT_MESSAGE " (FORCED BY HEAP SIZE)")
endif()
if(NOT JERRY_PARSER)
set(JERRY_SNAPSHOT_EXEC ON)
set(JERRY_PARSER_DUMP OFF)
set(JERRY_SNAPSHOT_EXEC_MESSAGE " (FORCED BY DISABLED JS PARSER)")
set(JERRY_PARSER_DUMP_MESSAGE " (FORCED BY DISABLED JS PARSER)")
endif()
if(JERRY_CMDLINE_SNAPSHOT)
set(JERRY_SNAPSHOT_SAVE ON)
set(JERRY_SNAPSHOT_SAVE_MESSAGE " (FORCED BY SNAPSHOT TOOL)")
endif()
if(JERRY_MEM_STATS OR JERRY_PARSER_DUMP_BYTE_CODE OR JERRY_REGEXP_DUMP_BYTE_CODE)
set(JERRY_LOGGING ON)
set(JERRYRE_LOGGING_MESSAGE " (FORCED BY STATS OR DUMP)")
endif()
set(FEATURE_PROFILE "full" CACHE STRING "Profile types: full, minimal")
set(FEATURE_ERROR_MESSAGES OFF CACHE BOOL "Enable error messages?")
set(FEATURE_VALGRIND OFF CACHE BOOL "Enable Valgrind support?")
set(FEATURE_VALGRIND_FREYA OFF CACHE BOOL "Enable Valgrind-Freya support?")
set(FEATURE_MEM_STRESS_TEST OFF CACHE BOOL "Enable mem-stress test?")
set(FEATURE_MEM_STATS OFF CACHE BOOL "Enable memory statistics?")
set(FEATURE_PARSER_DUMP OFF CACHE BOOL "Enable parser byte-code dumps?")
set(FEATURE_REGEXP_DUMP OFF CACHE BOOL "Enable regexp byte-code dumps?")
set(FEATURE_SNAPSHOT_SAVE OFF CACHE BOOL "Allow to save snapshot files?")
set(FEATURE_SNAPSHOT_EXEC OFF CACHE BOOL "Allow to execute snapshot files?")
set(MEM_HEAP_SIZE_KB "512" CACHE STRING "Size of memory heap, in kilobytes")
# Status messages
message(STATUS "ENABLE_ALL_IN_ONE " ${ENABLE_ALL_IN_ONE} ${ENABLE_ALL_IN_ONE_MESSAGE})
message(STATUS "JERRY_CPOINTER_32_BIT " ${JERRY_CPOINTER_32_BIT} ${JERRY_CPOINTER_32_BIT_MESSAGE})
message(STATUS "JERRY_DEBUGGER " ${JERRY_DEBUGGER})
message(STATUS "JERRY_ERROR_MESSAGES " ${JERRY_ERROR_MESSAGES})
message(STATUS "JERRY_EXTERNAL_CONTEXT " ${JERRY_EXTERNAL_CONTEXT})
message(STATUS "JERRY_PARSER " ${JERRY_PARSER})
message(STATUS "JERRY_LINE_INFO " ${JERRY_LINE_INFO})
message(STATUS "JERRY_LOGGING " ${JERRY_LOGGING} ${JERRY_LOGGING_MESSAGE})
message(STATUS "JERRY_MEM_STATS " ${JERRY_MEM_STATS})
message(STATUS "JERRY_MEM_GC_BEFORE_EACH_ALLOC " ${JERRY_MEM_GC_BEFORE_EACH_ALLOC})
message(STATUS "JERRY_PARSER_DUMP_BYTE_CODE " ${JERRY_PARSER_DUMP_BYTE_CODE} ${JERRY_PARSER_DUMP_MESSAGE})
message(STATUS "JERRY_PROFILE " ${JERRY_PROFILE})
message(STATUS "JERRY_REGEXP_STRICT_MODE " ${JERRY_REGEXP_STRICT_MODE})
message(STATUS "JERRY_REGEXP_DUMP_BYTE_CODE " ${JERRY_REGEXP_DUMP_BYTE_CODE})
message(STATUS "JERRY_SNAPSHOT_EXEC " ${JERRY_SNAPSHOT_EXEC} ${JERRY_SNAPSHOT_EXEC_MESSAGE})
message(STATUS "JERRY_SNAPSHOT_SAVE " ${JERRY_SNAPSHOT_SAVE} ${JERRY_SNAPSHOT_SAVE_MESSAGE})
message(STATUS "JERRY_SYSTEM_ALLOCATOR " ${JERRY_SYSTEM_ALLOCATOR})
message(STATUS "JERRY_VALGRIND " ${JERRY_VALGRIND})
message(STATUS "JERRY_VM_EXEC_STOP " ${JERRY_VM_EXEC_STOP})
message(STATUS "JERRY_GLOBAL_HEAP_SIZE " ${JERRY_GLOBAL_HEAP_SIZE})
message(STATUS "JERRY_STACK_LIMIT " ${JERRY_STACK_LIMIT})
message(STATUS "FEATURE_PROFILE " ${FEATURE_PROFILE})
message(STATUS "FEATURE_ERROR_MESSAGES " ${FEATURE_ERROR_MESSAGES})
message(STATUS "FEATURE_VALGRIND " ${FEATURE_VALGRIND})
message(STATUS "FEATURE_VALGRIND_FREYA " ${FEATURE_VALGRIND_FREYA})
message(STATUS "FEATURE_MEM_STRESS_TEST " ${FEATURE_MEM_STRESS_TEST})
message(STATUS "FEATURE_MEM_STATS " ${FEATURE_MEM_STATS})
message(STATUS "FEATURE_PARSER_DUMP " ${FEATURE_PARSER_DUMP})
message(STATUS "FEATURE_REGEXP_DUMP " ${FEATURE_REGEXP_DUMP})
message(STATUS "FEATURE_SNAPSHOT_SAVE " ${FEATURE_SNAPSHOT_SAVE})
message(STATUS "FEATURE_SNAPSHOT_EXEC " ${FEATURE_SNAPSHOT_EXEC})
message(STATUS "MEM_HEAP_SIZE_KB " ${MEM_HEAP_SIZE_KB})
# Include directories
set(INCLUDE_CORE_PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
set(INCLUDE_CORE_PRIVATE
set(INCLUDE_CORE
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/api"
"${CMAKE_CURRENT_SOURCE_DIR}/debugger"
"${CMAKE_CURRENT_SOURCE_DIR}/ecma/base"
"${CMAKE_CURRENT_SOURCE_DIR}/ecma/builtin-objects"
"${CMAKE_CURRENT_SOURCE_DIR}/ecma/builtin-objects/typedarray"
"${CMAKE_CURRENT_SOURCE_DIR}/ecma/operations"
"${CMAKE_CURRENT_SOURCE_DIR}/jcontext"
"${CMAKE_CURRENT_SOURCE_DIR}/jmem"
@@ -121,25 +57,35 @@ set(INCLUDE_CORE_PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/parser/regexp"
"${CMAKE_CURRENT_SOURCE_DIR}/vm")
set(INCLUDE_CORE_PUBLIC ${INCLUDE_CORE_PUBLIC} PARENT_SCOPE) # for jerry-port
set(INCLUDE_CORE_PRIVATE ${INCLUDE_CORE_PRIVATE} PARENT_SCOPE) # for tests/unit-core
# Sources
# Jerry core
file(GLOB SOURCE_CORE_FILES
api/*.c
debugger/*.c
ecma/base/*.c
ecma/builtin-objects/*.c
ecma/builtin-objects/typedarray/*.c
ecma/operations/*.c
jcontext/*.c
jmem/*.c
jrt/*.c
lit/*.c
parser/js/*.c
parser/regexp/*.c
vm/*.c)
file(GLOB SOURCE_CORE_API *.c)
file(GLOB SOURCE_CORE_ECMA_BASE ecma/base/*.c)
file(GLOB SOURCE_CORE_ECMA_BUILTINS ecma/builtin-objects/*.c)
file(GLOB SOURCE_CORE_ECMA_OPERATIONS ecma/operations/*.c)
file(GLOB SOURCE_CORE_JCONTEXT jcontext/*.c)
file(GLOB SOURCE_CORE_JMEM jmem/*.c)
file(GLOB SOURCE_CORE_JRT jrt/*.c)
file(GLOB SOURCE_CORE_LIT lit/*.c)
file(GLOB SOURCE_CORE_PARSER_JS parser/js/*.c)
file(GLOB SOURCE_CORE_PARSER_REGEXP parser/regexp/*.c)
file(GLOB SOURCE_CORE_VM vm/*.c)
set(SOURCE_CORE_FILES
${SOURCE_CORE_API}
${SOURCE_CORE_ECMA_BASE}
${SOURCE_CORE_ECMA_BUILTINS}
${SOURCE_CORE_ECMA_OPERATIONS}
${SOURCE_CORE_JCONTEXT}
${SOURCE_CORE_JMEM}
${SOURCE_CORE_JRT}
${SOURCE_CORE_LIT}
${SOURCE_CORE_PARSER_JS}
${SOURCE_CORE_PARSER_REGEXP}
${SOURCE_CORE_VM})
# Jerry port
file(GLOB SOURCE_PORT_FILES "${PORT_DIR}/*.c")
# All-in-one build
if(ENABLE_ALL_IN_ONE)
@@ -151,258 +97,133 @@ if(ENABLE_ALL_IN_ONE)
file(APPEND ${ALL_IN_FILE} "#include \"${FILE}\"\n")
endforeach()
set(SOURCE_CORE_FILES ${ALL_IN_FILE})
endif()
foreach(FILE ${SOURCE_PORT_FILES})
file(APPEND ${ALL_IN_FILE} "#include \"${FILE}\"\n")
endforeach()
# "Single" JerryScript source/header build.
# The process will create the following files:
# * jerryscript.c
# * jerryscript.h
# * jerryscript-config.h
if(ENABLE_ALL_IN_ONE_SOURCE)
# Create single C/H file
file(GLOB HEADER_CORE_FILES *.h)
# Generated files
set(ALL_IN_FILE "${CMAKE_BINARY_DIR}/src/jerryscript.c")
set(ALL_IN_FILE_H "${CMAKE_BINARY_DIR}/src/jerryscript.h")
set(JERRYSCRIPT_CONFIG_H "${CMAKE_BINARY_DIR}/src/jerryscript-config.h")
add_custom_command(OUTPUT ${ALL_IN_FILE} ${ALL_IN_FILE_H}
COMMAND python ${CMAKE_SOURCE_DIR}/tools/srcgenerator.py
--jerry-core
--output-dir ${CMAKE_BINARY_DIR}/src
DEPENDS ${SOURCE_CORE_FILES}
${HEADER_CORE_FILES}
${CMAKE_SOURCE_DIR}/tools/srcgenerator.py
${CMAKE_SOURCE_DIR}/tools/srcmerger.py
)
# The "true" jerryscript-config.h will be generated by the configure_file below,
# which contains the default options and the ones passed for the CMake.
# The input for this is the jerryscript-config.h generated by the command above.
set(JERRYSCRIPT_GEN_CONFIG_H ${CMAKE_CURRENT_BINARY_DIR}/jerryscript-config.h)
add_custom_command(OUTPUT ${JERRYSCRIPT_CONFIG_H}
COMMAND ${CMAKE_COMMAND} -E copy ${JERRYSCRIPT_GEN_CONFIG_H} ${JERRYSCRIPT_CONFIG_H}
DEPENDS ${ALL_IN_FILE_C} ${ALL_IN_FILE_H})
add_custom_target(generate-single-source-jerry DEPENDS ${ALL_IN_FILE} ${ALL_IN_FILE_H})
add_dependencies(generate-single-source generate-single-source-jerry)
set(SOURCE_CORE_FILES ${ALL_IN_FILE} ${ALL_IN_FILE_H} ${JERRYSCRIPT_CONFIG_H})
set(SOURCE_CORE ${ALL_IN_FILE})
else()
set(SOURCE_CORE ${SOURCE_CORE_FILES} ${SOURCE_PORT_FILES})
endif()
# Third-party
# Valgrind
set(INCLUDE_THIRD_PARTY_VALGRIND "${CMAKE_SOURCE_DIR}/third-party/valgrind")
# Definitions
# Get version information from git
if(IS_DIRECTORY "${CMAKE_SOURCE_DIR}/.git")
execute_process(COMMAND git symbolic-ref -q HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE JERRY_GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND git rev-parse HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE JERRY_GIT_COMMIT
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
set(JERRY_GIT_BRANCH "UNDEFINED")
set(JERRY_GIT_COMMIT "UNDEFINED")
endif()
# Get build date
execute_process(COMMAND date +%d/%m/%Y
OUTPUT_VARIABLE JERRY_BUILD_DATE
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(DEFINES_JERRY
${DEFINES_JERRY}
JERRY_BUILD_DATE="${JERRY_BUILD_DATE}"
JERRY_COMMIT_HASH="${JERRY_GIT_COMMIT}"
JERRY_BRANCH_NAME="${JERRY_GIT_BRANCH}")
# build mode specific compile/link flags
set(DEFINES_JERRY ${DEFINES_JERRY} $<$<NOT:$<CONFIG:Debug>>:JERRY_NDEBUG>)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ENABLE_PRETTY_PRINTER)
else()
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_NDEBUG)
endif()
# Profile modes
# Minimal profile
if(FEATURE_PROFILE STREQUAL "minimal")
set(DEFINES_JERRY ${DEFINES_JERRY}
CONFIG_DISABLE_NUMBER_BUILTIN
CONFIG_DISABLE_STRING_BUILTIN
CONFIG_DISABLE_BOOLEAN_BUILTIN
CONFIG_DISABLE_ERROR_BUILTINS
CONFIG_DISABLE_ARRAY_BUILTIN
CONFIG_DISABLE_MATH_BUILTIN
CONFIG_DISABLE_JSON_BUILTIN
CONFIG_DISABLE_DATE_BUILTIN
CONFIG_DISABLE_REGEXP_BUILTIN
CONFIG_DISABLE_ANNEXB_BUILTIN)
elseif(NOT FEATURE_PROFILE STREQUAL "full")
message(FATAL_ERROR "FEATURE_PROFILE='${FEATURE_PROFILE}' doesn't supported")
endif()
# Jerry heap-section
if(DEFINED JERRY_ATTR_GLOBAL_HEAP)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ATTR_GLOBAL_HEAP=${JERRY_ATTR_GLOBAL_HEAP})
if(DEFINED JERRY_HEAP_SECTION_ATTR)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_HEAP_SECTION_ATTR=${JERRY_HEAP_SECTION_ATTR})
endif()
# Helper macro to set 0/1 switch as Jerry Defines
macro(jerry_add_define01 NAME)
if(${NAME})
set(DEFINES_JERRY ${DEFINES_JERRY} ${NAME}=1)
else()
set(DEFINES_JERRY ${DEFINES_JERRY} ${NAME}=0)
endif()
endmacro(jerry_add_define01)
# Checks the optional features
# Enable 32 bit cpointers
jerry_add_define01(JERRY_CPOINTER_32_BIT)
# Fill error messages for builtin error objects
jerry_add_define01(JERRY_ERROR_MESSAGES)
# Use external context instead of static one
jerry_add_define01(JERRY_EXTERNAL_CONTEXT)
# JS-Parser
jerry_add_define01(JERRY_PARSER)
# JS line info
jerry_add_define01(JERRY_LINE_INFO)
# Logging
jerry_add_define01(JERRY_LOGGING)
# Memory statistics
jerry_add_define01(JERRY_MEM_STATS)
# Enable debugger
jerry_add_define01(JERRY_DEBUGGER)
# Memory management stress-test mode
jerry_add_define01(JERRY_MEM_GC_BEFORE_EACH_ALLOC)
# Parser byte-code dumps
jerry_add_define01(JERRY_PARSER_DUMP_BYTE_CODE)
# Profile
if (NOT IS_ABSOLUTE ${JERRY_PROFILE})
set(JERRY_PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/profiles/${JERRY_PROFILE}.profile")
if(FEATURE_ERROR_MESSAGES)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ENABLE_ERROR_MESSAGES)
endif()
if(EXISTS ${JERRY_PROFILE})
file(READ "${JERRY_PROFILE}" PROFILE_SETTINGS)
string(REGEX REPLACE "^#.*$" "" PROFILE_SETTINGS "${PROFILE_SETTINGS}")
string(REGEX REPLACE "[\r|\n]" ";" PROFILE_SETTINGS "${PROFILE_SETTINGS}")
# Process entries and save them as CMake variables.
# This is required to correctly generate the jerryscript-config.h file.
foreach(PROFILE_ENTRY ${PROFILE_SETTINGS})
string(REPLACE "=" ";" PROFILE_ENTRY "${PROFILE_ENTRY}")
list(GET PROFILE_ENTRY 0 PROFILE_KEY)
list(GET PROFILE_ENTRY 1 PROFILE_VALUE)
set(${PROFILE_KEY} ${PROFILE_VALUE})
endforeach()
set(DEFINES_JERRY ${DEFINES_JERRY} ${PROFILE_SETTINGS})
else()
message(FATAL_ERROR "Profile file: '${JERRY_PROFILE}' doesn't exist!")
endif()
# RegExp strict mode
jerry_add_define01(JERRY_REGEXP_STRICT_MODE)
# RegExp byte-code dumps
jerry_add_define01(JERRY_REGEXP_DUMP_BYTE_CODE)
# Snapshot exec
jerry_add_define01(JERRY_SNAPSHOT_EXEC)
# Snapshot save
jerry_add_define01(JERRY_SNAPSHOT_SAVE)
# Enable system allocator
jerry_add_define01(JERRY_SYSTEM_ALLOCATOR)
# Valgrind
jerry_add_define01(JERRY_VALGRIND)
if(JERRY_VALGRIND)
set(INCLUDE_CORE_PRIVATE ${INCLUDE_CORE_PRIVATE} ${INCLUDE_THIRD_PARTY_VALGRIND})
if(FEATURE_VALGRIND)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_VALGRIND)
set(INCLUDE_CORE ${INCLUDE_CORE} ${INCLUDE_THIRD_PARTY_VALGRIND})
endif()
# Enable VM execution stopping
jerry_add_define01(JERRY_VM_EXEC_STOP)
# Valgrind Freya
if(FEATURE_VALGRIND_FREYA)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_VALGRIND_FREYA)
set(INCLUDE_CORE ${INCLUDE_CORE} ${INCLUDE_THIRD_PARTY_VALGRIND})
endif()
# Memory management stress-test mode
if(FEATURE_MEM_STRESS_TEST)
set(DEFINES_JERRY ${DEFINES_JERRY} JMEM_GC_BEFORE_EACH_ALLOC)
endif()
# Memory statistics
if(FEATURE_MEM_STATS)
set(DEFINES_JERRY ${DEFINES_JERRY} JMEM_STATS)
endif()
# Parser byte-code dumps
if(FEATURE_PARSER_DUMP)
set(DEFINES_JERRY ${DEFINES_JERRY} PARSER_DUMP_BYTE_CODE)
endif()
# RegExp byte-code dumps
if(FEATURE_REGEXP_DUMP)
set(DEFINES_JERRY ${DEFINES_JERRY} REGEXP_DUMP_BYTE_CODE)
endif()
# Snapshot save
if(FEATURE_SNAPSHOT_SAVE)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ENABLE_SNAPSHOT_SAVE)
endif()
# Snapshot exec
if(FEATURE_SNAPSHOT_EXEC)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ENABLE_SNAPSHOT_EXEC)
endif()
# Size of heap
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_GLOBAL_HEAP_SIZE=${JERRY_GLOBAL_HEAP_SIZE})
math(EXPR MEM_HEAP_AREA_SIZE "${MEM_HEAP_SIZE_KB} * 1024")
set(DEFINES_JERRY ${DEFINES_JERRY} CONFIG_MEM_HEAP_AREA_SIZE=${MEM_HEAP_AREA_SIZE})
# Maximum size of stack memory usage
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_STACK_LIMIT=${JERRY_STACK_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)
# match all "#define <PREFIX>\n" lines
# notes:
# * before the "#" there must be a newline and any number of spaces.
# * after the "#" there can be any number of spaces.
string(REGEX MATCHALL "\r?\n[ ]*#[ ]*define ${PREFIX}[^\n]*"
RAW_DEFINES "${INPUT_FILE_CONTENTS}")
set(SELECTED_VARS )
# Transform the defines to a list of (<name>; <value>; <name 2>; <value 2>; ...) list
foreach(DEFINE_ENTRY ${RAW_DEFINES})
# by default every define value is empty
set(DEFINE_VALUE " ")
# split up the define at the space between the define name and value (if there is any)
# first remove "#define" part of the string
string(REGEX REPLACE "\r?\n[ ]*#[ ]*define[ ]+" "" DEFINE_KEY_VALUE "${DEFINE_ENTRY}")
string(FIND "${DEFINE_KEY_VALUE}" " " DEFINE_KEY_IDX)
string(LENGTH "${DEFINE_KEY_VALUE}" DEFINE_LENGTH)
if (DEFINE_KEY_IDX EQUAL "-1")
set(DEFINE_KEY ${DEFINE_KEY_VALUE})
else()
string(SUBSTRING "${DEFINE_KEY_VALUE}" 0 ${DEFINE_KEY_IDX} DEFINE_KEY)
string(SUBSTRING "${DEFINE_KEY_VALUE}" ${DEFINE_KEY_IDX} -1 DEFINE_VALUE)
string(STRIP "${DEFINE_VALUE}" DEFINE_VALUE)
endif()
list(APPEND SELECTED_VARS ${DEFINE_KEY} ${DEFINE_VALUE})
endforeach()
set(${OUTPUTVAR} ${SELECTED_VARS} PARENT_SCOPE)
endfunction(read_set_defines)
# CONFIG_DEFAULTS contains define name and values which have the JERRY_ prefix
# as a list of (<name>; <value>; <name 2>; <value 2>; ...)
read_set_defines("config.h" JERRY_ CONFIG_DEFAULTS)
## Process the default values and build options to generate build config defines
list(LENGTH CONFIG_DEFAULTS CONFIG_DEFAULT_LENGTH)
math(EXPR CONFIG_DEFAULT_LENGTH "${CONFIG_DEFAULT_LENGTH} - 1")
set(JERRY_MODIFIED_OPTIONS)
foreach(CONFIG_IDX RANGE 0 ${CONFIG_DEFAULT_LENGTH} 2)
list(GET CONFIG_DEFAULTS ${CONFIG_IDX} KEY)
math(EXPR VALUE_IDX "${CONFIG_IDX} + 1")
list(GET CONFIG_DEFAULTS ${VALUE_IDX} VALUE)
# ${KEY} is the value for the given variable (aka define)
# normalize ON/OFF cmake values to 1/0 for easier processing.
if(${KEY} STREQUAL "ON")
set(${KEY} 1)
elseif(${KEY} STREQUAL "OFF")
set(${KEY} 0)
endif()
# Generate "#define JERRY_<CONFIG> <CONFIG_VALUE>" entries if it is different from
# the config default.
# If the define loaded from the config file have a different value than the
# relevant option passed for the CMake means that it does not have a default value.
if(DEFINED ${KEY} AND NOT (${KEY} STREQUAL ${VALUE}))
set(JERRY_MODIFIED_OPTIONS "${JERRY_MODIFIED_OPTIONS}#define ${KEY} ${${KEY}}\n")
endif()
endforeach()
# Generate the jerryscript-config.h file into the build directory
# This file will contain the options different from the default (aka it's the build config).
if(JERRY_MODIFIED_OPTIONS)
set(JERRY_BUILD_CFG
"Generated differences from default by CMake based on build options:\n${JERRY_MODIFIED_OPTIONS}")
else()
set(JERRY_BUILD_CFG "JerryScript configuration")
endif()
configure_file(config.h jerryscript-config.h @ONLY)
add_library(${JERRY_CORE_NAME} ${SOURCE_CORE_FILES})
add_library(${JERRY_CORE_NAME} STATIC ${SOURCE_CORE})
target_compile_definitions(${JERRY_CORE_NAME} PUBLIC ${DEFINES_JERRY})
target_include_directories(${JERRY_CORE_NAME} PUBLIC ${INCLUDE_CORE_PUBLIC})
target_include_directories(${JERRY_CORE_NAME} PRIVATE ${INCLUDE_CORE_PRIVATE})
target_include_directories(${JERRY_CORE_NAME} PUBLIC ${INCLUDE_CORE})
set(JERRY_CORE_PKGCONFIG_REQUIRES)
set(JERRY_CORE_PKGCONFIG_LIBS)
if(JERRY_LIBM)
target_link_libraries(${JERRY_CORE_NAME} jerry-libm)
set(JERRY_CORE_PKGCONFIG_REQUIRES libjerry-libm)
if (JERRY_LIBC)
target_include_directories(${JERRY_CORE_NAME} SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/jerry-libc/include")
endif()
separate_arguments(EXTERNAL_LINK_LIBS)
foreach(EXT_LIB ${EXTERNAL_LINK_LIBS})
target_link_libraries(${JERRY_CORE_NAME} ${EXT_LIB})
set(JERRY_CORE_PKGCONFIG_LIBS "${JERRY_CORE_PKGCONFIG_LIBS} -l${EXT_LIB}")
endforeach()
configure_file(libjerry-core.pc.in libjerry-core.pc @ONLY)
install(TARGETS ${JERRY_CORE_NAME} DESTINATION lib)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libjerry-core.pc DESTINATION lib/pkgconfig)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jerryscript-config.h DESTINATION include)
install(DIRECTORY ${INCLUDE_CORE_PUBLIC}/ DESTINATION include)
-250
View File
@@ -1,250 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "debugger.h"
#include "jcontext.h"
#include "jerryscript.h"
#if ENABLED (JERRY_DEBUGGER)
/**
* Minimum number of bytes transmitted or received.
*/
#define JERRY_DEBUGGER_TRANSPORT_MIN_BUFFER_SIZE 64
/**
* Sleep time in milliseconds between each jerry_debugger_receive call
*/
#define JERRY_DEBUGGER_TRANSPORT_TIMEOUT 100
/**
* Add a new transport layer.
*/
void
jerry_debugger_transport_add (jerry_debugger_transport_header_t *header_p, /**< transport implementation */
size_t send_message_header_size, /**< header bytes reserved for outgoing messages */
size_t max_send_message_size, /**< maximum number of bytes transmitted in a message */
size_t receive_message_header_size, /**< header bytes reserved for incoming messages */
size_t max_receive_message_size) /**< maximum number of bytes received in a message */
{
JERRY_ASSERT (max_send_message_size > JERRY_DEBUGGER_TRANSPORT_MIN_BUFFER_SIZE
&& max_receive_message_size > JERRY_DEBUGGER_TRANSPORT_MIN_BUFFER_SIZE);
header_p->next_p = JERRY_CONTEXT (debugger_transport_header_p);
JERRY_CONTEXT (debugger_transport_header_p) = header_p;
uint8_t *payload_p;
size_t max_send_size;
size_t max_receive_size;
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
{
payload_p = JERRY_CONTEXT (debugger_send_buffer_payload_p);
max_send_size = JERRY_CONTEXT (debugger_max_send_size);
max_receive_size = JERRY_CONTEXT (debugger_max_receive_size);
}
else
{
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_CONNECTED);
payload_p = JERRY_CONTEXT (debugger_send_buffer);
max_send_size = JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE;
max_receive_size = JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE;
}
JERRY_ASSERT (max_send_size > JERRY_DEBUGGER_TRANSPORT_MIN_BUFFER_SIZE + send_message_header_size);
JERRY_ASSERT (max_receive_size > JERRY_DEBUGGER_TRANSPORT_MIN_BUFFER_SIZE + receive_message_header_size);
JERRY_CONTEXT (debugger_send_buffer_payload_p) = payload_p + send_message_header_size;
max_send_size = max_send_size - send_message_header_size;
max_receive_size = max_receive_size - receive_message_header_size;
if (max_send_size > max_send_message_size)
{
max_send_size = max_send_message_size;
}
if (max_receive_size > max_receive_message_size)
{
max_receive_size = max_receive_message_size;
}
JERRY_CONTEXT (debugger_max_send_size) = (uint8_t) max_send_size;
JERRY_CONTEXT (debugger_max_receive_size) = (uint8_t) max_receive_size;
} /* jerry_debugger_transport_add */
/**
* Starts the communication to the debugger client.
* Must be called after the connection is successfully established.
*/
void
jerry_debugger_transport_start (void)
{
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
if (jerry_debugger_send_configuration (JERRY_CONTEXT (debugger_max_receive_size)))
{
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
}
} /* jerry_debugger_transport_start */
/**
* Returns true if a debugger client is connected.
*
* @return true - a debugger client is connected,
* false - otherwise
*/
bool
jerry_debugger_transport_is_connected (void)
{
return (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) != 0;
} /* jerry_debugger_transport_is_connected */
/**
* Notifies the debugger server that the connection is closed.
*/
void
jerry_debugger_transport_close (void)
{
if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED))
{
return;
}
JERRY_CONTEXT (debugger_flags) = JERRY_DEBUGGER_VM_IGNORE;
jerry_debugger_transport_header_t *current_p = JERRY_CONTEXT (debugger_transport_header_p);
JERRY_ASSERT (current_p != NULL);
do
{
jerry_debugger_transport_header_t *next_p = current_p->next_p;
current_p->close (current_p);
current_p = next_p;
}
while (current_p != NULL);
jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Debugger client connection closed.\n");
jerry_debugger_free_unreferenced_byte_code ();
} /* jerry_debugger_transport_close */
/**
* Send data over the current connection
*
* @return true - data sent successfully,
* false - connection closed
*/
bool
jerry_debugger_transport_send (const uint8_t *message_p, /**< message to be sent */
size_t message_length) /**< message length in bytes */
{
JERRY_ASSERT (jerry_debugger_transport_is_connected ());
JERRY_ASSERT (message_length > 0);
jerry_debugger_transport_header_t *header_p = JERRY_CONTEXT (debugger_transport_header_p);
uint8_t *payload_p = JERRY_CONTEXT (debugger_send_buffer_payload_p);
size_t max_send_size = JERRY_CONTEXT (debugger_max_send_size);
do
{
size_t fragment_length = (message_length <= max_send_size ? message_length
: max_send_size);
memcpy (payload_p, message_p, fragment_length);
if (!header_p->send (header_p, payload_p, fragment_length))
{
return false;
}
message_p += fragment_length;
message_length -= fragment_length;
}
while (message_length > 0);
return true;
} /* jerry_debugger_transport_send */
/**
* Receive data from the current connection
*
* Note:
* A message is received if message_start_p is not NULL
*
* @return true - function successfully completed,
* false - connection closed
*/
bool
jerry_debugger_transport_receive (jerry_debugger_transport_receive_context_t *context_p) /**< [out] receive
* context */
{
JERRY_ASSERT (jerry_debugger_transport_is_connected ());
context_p->buffer_p = JERRY_CONTEXT (debugger_receive_buffer);
context_p->received_length = JERRY_CONTEXT (debugger_received_length);
context_p->message_p = NULL;
context_p->message_length = 0;
context_p->message_total_length = 0;
jerry_debugger_transport_header_t *header_p = JERRY_CONTEXT (debugger_transport_header_p);
return header_p->receive (header_p, context_p);
} /* jerry_debugger_transport_receive */
/**
* Clear the message buffer after the message is processed
*/
void
jerry_debugger_transport_receive_completed (jerry_debugger_transport_receive_context_t *context_p) /**< receive
* context */
{
JERRY_ASSERT (context_p->message_p != NULL);
JERRY_ASSERT (context_p->buffer_p == JERRY_CONTEXT (debugger_receive_buffer));
size_t message_total_length = context_p->message_total_length;
size_t received_length = context_p->received_length;
JERRY_ASSERT (message_total_length <= received_length);
if (message_total_length == 0 || message_total_length == received_length)
{
/* All received data is processed. */
JERRY_CONTEXT (debugger_received_length) = 0;
return;
}
uint8_t *buffer_p = context_p->buffer_p;
received_length -= message_total_length;
memmove (buffer_p, buffer_p + message_total_length, received_length);
JERRY_CONTEXT (debugger_received_length) = (uint16_t) received_length;
} /* jerry_debugger_transport_receive_completed */
/**
* Suspend execution for a predefined time (JERRY_DEBUGGER_TRANSPORT_TIMEOUT ms).
*/
void
jerry_debugger_transport_sleep (void)
{
jerry_port_sleep (JERRY_DEBUGGER_TRANSPORT_TIMEOUT);
} /* jerry_debugger_transport_sleep */
#endif /* ENABLED (JERRY_DEBUGGER) */
-230
View File
@@ -1,230 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "debugger.h"
#include "jcontext.h"
#include "jerryscript.h"
/**
* Checks whether the debugger is connected.
*
* @return true - if the debugger is connected
* false - otherwise
*/
bool
jerry_debugger_is_connected (void)
{
#if ENABLED (JERRY_DEBUGGER)
return JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED;
#else /* !ENABLED (JERRY_DEBUGGER) */
return false;
#endif /* ENABLED (JERRY_DEBUGGER) */
} /* jerry_debugger_is_connected */
/**
* Stop execution at the next available breakpoint.
*/
void
jerry_debugger_stop (void)
{
#if ENABLED (JERRY_DEBUGGER)
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
&& !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
{
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
}
#endif /* ENABLED (JERRY_DEBUGGER) */
} /* jerry_debugger_stop */
/**
* Continue execution.
*/
void
jerry_debugger_continue (void)
{
#if ENABLED (JERRY_DEBUGGER)
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
&& !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
{
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
}
#endif /* ENABLED (JERRY_DEBUGGER) */
} /* jerry_debugger_continue */
/**
* Sets whether the engine should stop at breakpoints.
*/
void
jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint) /**< enable/disable stop at breakpoint */
{
#if ENABLED (JERRY_DEBUGGER)
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED
&& !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
{
if (enable_stop_at_breakpoint)
{
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
}
else
{
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
}
}
#else /* !ENABLED (JERRY_DEBUGGER) */
JERRY_UNUSED (enable_stop_at_breakpoint);
#endif /* ENABLED (JERRY_DEBUGGER) */
} /* jerry_debugger_stop_at_breakpoint */
/**
* Sets whether the engine should wait and run a source.
*
* @return enum JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED - if the source is not received
* JERRY_DEBUGGER_SOURCE_RECEIVED - if a source code received
* JERRY_DEBUGGER_SOURCE_END - the end of the source codes
* JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED - the end of the context
*/
jerry_debugger_wait_for_source_status_t
jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t callback_p, /**< callback function */
void *user_p, /**< user pointer passed to the callback */
jerry_value_t *return_value) /**< [out] parse and run return value */
{
*return_value = jerry_create_undefined ();
#if ENABLED (JERRY_DEBUGGER)
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
&& !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
{
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
jerry_debugger_uint8_data_t *client_source_data_p = NULL;
jerry_debugger_wait_for_source_status_t ret_type = JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
/* Notify the client about that the engine is waiting for a source. */
jerry_debugger_send_type (JERRY_DEBUGGER_WAIT_FOR_SOURCE);
while (true)
{
if (jerry_debugger_receive (&client_source_data_p))
{
if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED))
{
break;
}
/* Stop executing the current context. */
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONTEXT_RESET_MODE))
{
ret_type = JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED;
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CONTEXT_RESET_MODE);
break;
}
/* Stop waiting for a new source file. */
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_NO_SOURCE))
{
ret_type = JERRY_DEBUGGER_SOURCE_END;
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_CLIENT_SOURCE_MODE);
break;
}
/* The source arrived. */
if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE))
{
JERRY_ASSERT (client_source_data_p != NULL);
jerry_char_t *resource_name_p = (jerry_char_t *) (client_source_data_p + 1);
size_t resource_name_size = strlen ((const char *) resource_name_p);
*return_value = callback_p (resource_name_p,
resource_name_size,
resource_name_p + resource_name_size + 1,
client_source_data_p->uint8_size - resource_name_size - 1,
user_p);
ret_type = JERRY_DEBUGGER_SOURCE_RECEIVED;
break;
}
}
jerry_debugger_transport_sleep ();
}
JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE)
|| !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED));
if (client_source_data_p != NULL)
{
/* The data may partly arrived. */
jmem_heap_free_block (client_source_data_p,
client_source_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
}
return ret_type;
}
return JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
#else /* !ENABLED (JERRY_DEBUGGER) */
JERRY_UNUSED (callback_p);
JERRY_UNUSED (user_p);
return JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
#endif /* ENABLED (JERRY_DEBUGGER) */
} /* jerry_debugger_wait_for_client_source */
/**
* Send the output of the program to the debugger client.
* Currently only sends print output.
*/
void
jerry_debugger_send_output (const jerry_char_t *buffer, /**< buffer */
jerry_size_t str_size) /**< string size */
{
#if ENABLED (JERRY_DEBUGGER)
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
{
jerry_debugger_send_string (JERRY_DEBUGGER_OUTPUT_RESULT,
JERRY_DEBUGGER_OUTPUT_OK,
(const uint8_t *) buffer,
sizeof (uint8_t) * str_size);
}
#else /* !ENABLED (JERRY_DEBUGGER) */
JERRY_UNUSED (buffer);
JERRY_UNUSED (str_size);
#endif /* ENABLED (JERRY_DEBUGGER) */
} /* jerry_debugger_send_output */
/**
* Send the log of the program to the debugger client.
*/
void
jerry_debugger_send_log (jerry_log_level_t level, /**< level of the diagnostics message */
const jerry_char_t *buffer, /**< buffer */
jerry_size_t str_size) /**< string size */
{
#if ENABLED (JERRY_DEBUGGER)
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
{
jerry_debugger_send_string (JERRY_DEBUGGER_OUTPUT_RESULT,
(uint8_t) (level + 2),
(const uint8_t *) buffer,
sizeof (uint8_t) * str_size);
}
#else /* !ENABLED (JERRY_DEBUGGER) */
JERRY_UNUSED (level);
JERRY_UNUSED (buffer);
JERRY_UNUSED (str_size);
#endif /* ENABLED (JERRY_DEBUGGER) */
} /* jerry_debugger_send_log */
File diff suppressed because it is too large Load Diff
-53
View File
@@ -1,53 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef JERRY_SNAPSHOT_H
#define JERRY_SNAPSHOT_H
#include "ecma-globals.h"
/**
* Snapshot header
*/
typedef struct
{
/* The size of this structure is recommended to be divisible by
* uint32_t alignment. Otherwise some bytes after the header are wasted. */
uint32_t magic; /**< four byte magic number */
uint32_t version; /**< version number */
uint32_t global_flags; /**< global configuration and feature flags */
uint32_t lit_table_offset; /**< byte offset of the literal table */
uint32_t number_of_funcs; /**< number of primary ECMAScript functions */
uint32_t func_offsets[1]; /**< function offsets (lowest bit: global(0) or eval(1) context) */
} jerry_snapshot_header_t;
/**
* Jerry snapshot magic marker.
*/
#define JERRY_SNAPSHOT_MAGIC (0x5952524Au)
/**
* Snapshot configuration flags.
*/
typedef enum
{
/* 8 bits are reserved for dynamic features */
JERRY_SNAPSHOT_HAS_REGEX_LITERAL = (1u << 0), /**< byte code has regex literal */
JERRY_SNAPSHOT_HAS_CLASS_LITERAL = (1u << 1), /**< byte code has class literal */
/* 24 bits are reserved for compile time features */
JERRY_SNAPSHOT_FOUR_BYTE_CPOINTER = (1u << 8) /**< deprecated, an unused placeholder now */
} jerry_snapshot_global_flags_t;
#endif /* !JERRY_SNAPSHOT_H */
File diff suppressed because it is too large Load Diff
+84 -627
View File
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,691 +14,147 @@
* limitations under the License.
*/
#ifndef JERRYSCRIPT_CONFIG_H
#define JERRYSCRIPT_CONFIG_H
// @JERRY_BUILD_CFG@
#ifndef CONFIG_H
#define CONFIG_H
/**
* Built-in configurations
*
* Allowed values for built-in defines:
* 0: Disable the given built-in.
* 1: Enable the given built-in.
* Limit of data (system heap, engine's data except engine's own heap)
*/
/*
* By default all built-ins are enabled if they are not defined.
*/
#ifndef JERRY_BUILTINS
# define JERRY_BUILTINS 1
#endif /* !defined (JERRY_BUILTINS) */
#ifndef JERRY_BUILTIN_ANNEXB
# define JERRY_BUILTIN_ANNEXB JERRY_BUILTINS
#endif /* !defined (JERRY_BUILTIN_ANNEXB) */
#ifndef JERRY_BUILTIN_ARRAY
# define JERRY_BUILTIN_ARRAY JERRY_BUILTINS
#endif /* !defined (JERRY_BUILTIN_ARRAY) */
#ifndef JERRY_BUILTIN_DATE
# define JERRY_BUILTIN_DATE JERRY_BUILTINS
#endif /* !defined (JERRY_BUILTIN_DATE) */
#ifndef JERRY_BUILTIN_ERRORS
# define JERRY_BUILTIN_ERRORS JERRY_BUILTINS
#endif /* !defined (JERRY_BUILTIN_ERRORS) */
#ifndef JERRY_BUILTIN_BOOLEAN
# define JERRY_BUILTIN_BOOLEAN JERRY_BUILTINS
#endif /* !defined (JERRY_BUILTIN_BOOLEAN) */
#ifndef JERRY_BUILTIN_JSON
# define JERRY_BUILTIN_JSON JERRY_BUILTINS
#endif /* !defined (JERRY_BUILTIN_JSON) */
#ifndef JERRY_BUILTIN_MATH
# define JERRY_BUILTIN_MATH JERRY_BUILTINS
#endif /* !defined (JERRY_BUILTIN_MATH) */
#ifndef JERRY_BUILTIN_NUMBER
# define JERRY_BUILTIN_NUMBER JERRY_BUILTINS
#endif /* !defined (JERRY_BUILTIN_NUMBER) */
#ifndef JERRY_BUILTIN_REGEXP
# define JERRY_BUILTIN_REGEXP JERRY_BUILTINS
#endif /* !defined (JERRY_BUILTIN_REGEXP) */
#ifndef JERRY_BUILTIN_STRING
# define JERRY_BUILTIN_STRING JERRY_BUILTINS
#endif /* !defined (JERRY_BUILTIN_STRING) */
#define CONFIG_MEM_DATA_LIMIT_MINUS_HEAP_SIZE (1024)
/**
* ES2015 (a.k.a es6) related features, by default all of them are enabled.
* Limit of stack size
*/
#ifndef JERRY_ES2015
# 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) */
#ifndef JERRY_ES2015_BUILTIN_SET
# define JERRY_ES2015_BUILTIN_SET JERRY_ES2015
#endif /* !defined (JERRY_ES2015_BUILTIN_SET) */
#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_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) */
#define CONFIG_MEM_STACK_LIMIT (4096)
/**
* Engine internal and misc configurations.
* Size of pool chunk
*
* Should not be less than size of any of ECMA Object Model's data types.
*/
#define CONFIG_MEM_POOL_CHUNK_SIZE (8)
/**
* Specifies the compressed pointer representation
*
* Allowed values:
* 0: use 16 bit representation
* 1: use 32 bit representation
*
* Default value: 0
* For more details see: jmem/jmem.h
* Size of heap
*/
#ifndef JERRY_CPOINTER_32_BIT
# define JERRY_CPOINTER_32_BIT 0
#endif /* !defined (JERRY_CPOINTER_32_BIT) */
#ifndef CONFIG_MEM_HEAP_AREA_SIZE
# define CONFIG_MEM_HEAP_AREA_SIZE (512 * 1024)
#elif CONFIG_MEM_HEAP_AREA_SIZE > (512 * 1024)
# error "Currently, maximum 512 kilobytes heap size is supported"
#endif /* !CONFIG_MEM_HEAP_AREA_SIZE */
/**
* Enable/Disable the engine's JavaScript debugger interface
*
* Allowed values:
* 0: Disable the debugger parts.
* 1: Enable the debugger.
* Max heap usage limit
*/
#ifndef JERRY_DEBUGGER
# define JERRY_DEBUGGER 0
#endif /* !defined (JERRY_DEBUGGER) */
#define CONFIG_MEM_HEAP_MAX_LIMIT 8192
/**
* Enable/Disable built-in error messages for error objects.
*
* Allowed values:
* 0: Disable error messages.
* 1: Enable error message.
*
* Default value: 0
* Desired limit of heap usage
*/
#ifndef JERRY_ERROR_MESSAGES
# define JERRY_ERROR_MESSAGES 0
#endif /* !defined (JERRY_ERROR_MESSAGES) */
#define CONFIG_MEM_HEAP_DESIRED_LIMIT (JERRY_MIN (CONFIG_MEM_HEAP_AREA_SIZE / 32, CONFIG_MEM_HEAP_MAX_LIMIT))
/**
* Enable/Disable external context.
* Log2 of maximum possible offset in the heap
*
* Allowed values:
* 0: Disable external context.
* 1: Enable external context support.
* The option affects size of compressed pointer that in turn
* affects size of ECMA Object Model's data types.
*
* Default value: 0
* In any case size of any of the types should not exceed CONFIG_MEM_POOL_CHUNK_SIZE.
*
* On the other hand, value 2 ^ CONFIG_MEM_HEAP_OFFSET_LOG should not be less than CONFIG_MEM_HEAP_AREA_SIZE.
*/
#ifndef JERRY_EXTERNAL_CONTEXT
# define JERRY_EXTERNAL_CONTEXT 0
#endif /* !defined (JERRY_EXTERNAL_CONTEXT) */
#define CONFIG_MEM_HEAP_OFFSET_LOG (19)
/**
* Maximum size of heap in kilobytes
*
* Default value: 512 KiB
* Number of lower bits in key of literal hash table.
*/
#ifndef JERRY_GLOBAL_HEAP_SIZE
# define JERRY_GLOBAL_HEAP_SIZE (512)
#endif /* !defined (JERRY_GLOBAL_HEAP_SIZE) */
#define CONFIG_LITERAL_HASH_TABLE_KEY_BITS (7)
/**
* Maximum stack usage size in kilobytes
* Width of fields used for holding counter of references to ecma-strings and ecma-objects
*
* Note: This feature cannot be used when 'detect_stack_use_after_return=1' ASAN option is enabled.
* For more detailed description:
* - https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn#compatibility
* The option affects maximum number of simultaneously existing:
* - references to one string;
* - stack references to one object
* The number is ((2 ^ CONFIG_ECMA_REFERENCE_COUNTER_WIDTH) - 1).
*
* Default value: 0, unlimited
* Also the option affects size of ECMA Object Model's data types.
* In any case size of any of the types should not exceed CONFIG_MEM_POOL_CHUNK_SIZE.
*/
#ifndef JERRY_STACK_LIMIT
# define JERRY_STACK_LIMIT (0)
#endif /* !defined (JERRY_STACK_LIMIT) */
#define CONFIG_ECMA_REFERENCE_COUNTER_WIDTH (12)
/**
* Enable/Disable property lookup cache.
*
* Allowed values:
* 0: Disable lookup cache.
* 1: Enable lookup cache.
*
* Default value: 1
*/
#ifndef JERRY_LCACHE
# define JERRY_LCACHE 1
#endif /* !defined (JERRY_LCACHE) */
/**
* Enable/Disable line-info management inside the engine.
*
* Allowed values:
* 0: Disable line-info in the engine.
* 1: Enable line-info management.
*
* Default value: 0
*/
#ifndef JERRY_LINE_INFO
# define JERRY_LINE_INFO 0
#endif /* !defined (JERRY_LINE_INFO) */
/**
* Enable/Disable logging inside the engine.
*
* Allowed values:
* 0: Disable internal logging.
* 1: Enable internal logging.
*
* Default value: 0
*/
#ifndef JERRY_LOGGING
# define JERRY_LOGGING 0
#endif /* !defined (JERRY_LOGGING) */
/**
* Enable/Disable gc call before every allocation.
*
* Allowed values:
* 0: Disable gc call before each allocation.
* 1: Enable and force gc call before each allocation.
*
* Default value: 0
* Warning!: This is an advanced option and will slow down the engine!
* Only enable it for debugging purposes.
*/
#ifndef JERRY_MEM_GC_BEFORE_EACH_ALLOC
# define JERRY_MEM_GC_BEFORE_EACH_ALLOC 0
#endif /* !defined (JERRY_MEM_GC_BEFORE_EACH_ALLOC) */
/**
* Enable/Disable the collection if run-time memory statistics.
*
* Allowed values:
* 0: Disable run-time memory information collection.
* 1: Enable run-time memory statistics collection.
*
* Default value: 0
*/
#ifndef JERRY_MEM_STATS
# define JERRY_MEM_STATS 0
#endif /* !defined (JERRY_MEM_STATS) */
#define CONFIG_ECMA_REFERENCE_COUNTER_LIMIT ((1u << CONFIG_ECMA_REFERENCE_COUNTER_WIDTH) - 1u)
/**
* Use 32-bit/64-bit float for ecma-numbers
* This option is for expert use only!
*
* Allowed values:
* 1: use 64-bit floating point number mode
* 0: use 32-bit floating point number mode
*
* Default value: 1
*/
#ifndef JERRY_NUMBER_TYPE_FLOAT64
# define JERRY_NUMBER_TYPE_FLOAT64 1
#endif /* !defined (JERRY_NUMBER_TYPE_FLOAT64 */
#define CONFIG_ECMA_NUMBER_FLOAT32 (1u) /* 32-bit float */
#define CONFIG_ECMA_NUMBER_FLOAT64 (2u) /* 64-bit float */
#ifndef CONFIG_ECMA_NUMBER_TYPE
# define CONFIG_ECMA_NUMBER_TYPE CONFIG_ECMA_NUMBER_FLOAT64
#else /* CONFIG_ECMA_NUMBER_TYPE */
# if (CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT32 \
&& CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT64)
# error "ECMA-number storage is configured incorrectly"
# endif /* CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT32
&& CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT64 */
#endif /* !CONFIG_ECMA_NUMBER_TYPE */
/**
* Enable/Disable the JavaScript parser.
*
* Allowed values:
* 0: Disable the JavaScript parser and all related functionallity.
* 1: Enable the JavaScript parser.
*
* Default value: 1
* Representation for ecma-characters
*/
#ifndef JERRY_PARSER
# define JERRY_PARSER 1
#endif /* !defined (JERRY_PARSER) */
#define CONFIG_ECMA_CHAR_ASCII (1) /* ASCII */
#define CONFIG_ECMA_CHAR_UTF16 (2) /* UTF-16 */
#ifndef CONFIG_ECMA_CHAR_ENCODING
# define CONFIG_ECMA_CHAR_ENCODING CONFIG_ECMA_CHAR_ASCII
#else /* CONFIG_ECMA_CHAR_ENCODING */
# if (CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_ASCII \
&& CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_UTF16)
# error "ECMA-char encoding is configured incorrectly"
# endif /* CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_ASCII
&& CONFIG_ECMA_CHAR_ENCODING != CONFIG_ECMA_CHAR_UTF16 */
#endif /* !CONFIG_ECMA_CHAR_ENCODING */
/**
* Enable/Disable JerryScript byte code dump functions during parsing.
* To dump the JerryScript byte code the engine must be initialized with opcodes
* display flag. This option does not influence RegExp byte code dumps.
*
* Allowed values:
* 0: Disable all bytecode dump functions.
* 1: Enable bytecode dump functions.
*
* Default value: 0
* Disable ECMA lookup cache
*/
#ifndef JERRY_PARSER_DUMP_BYTE_CODE
# define JERRY_PARSER_DUMP_BYTE_CODE 0
#endif /* defined (JERRY_PARSER_DUMP_BYTE_CODE) */
// #define CONFIG_ECMA_LCACHE_DISABLE
/**
* Enable/Disable ECMA property hashmap.
*
* Allowed values:
* 0: Disable property hasmap.
* 1: Enable property hashmap.
*
* Default value: 1
* Disable ECMA property hashmap
*/
#ifndef JERRY_PROPRETY_HASHMAP
# define JERRY_PROPRETY_HASHMAP 1
#endif /* !defined (JERRY_PROPRETY_HASHMAP) */
// #define CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
/**
* Enable/Disable byte code dump functions for RegExp objects.
* To dump the RegExp byte code the engine must be initialized with
* regexp opcodes display flag. This option does not influence the
* JerryScript byte code dumps.
* Share of newly allocated since last GC objects among all currently allocated objects,
* after achieving which, GC is started upon low severity try-give-memory-back requests.
*
* Allowed values:
* 0: Disable all bytecode dump functions.
* 1: Enable bytecode dump functions.
*
* Default value: 0
* Share is calculated as the following:
* 1.0 / CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC
*/
#ifndef JERRY_REGEXP_DUMP_BYTE_CODE
# define JERRY_REGEXP_DUMP_BYTE_CODE 0
#endif /* !defined (JERRY_REGEXP_DUMP_BYTE_CODE) */
#define CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC (16)
/**
* Enables/disables the RegExp strict mode
*
* Default value: 0
* Link Global Environment to an empty declarative lexical environment
* instead of lexical environment bound to Global Object.
*/
#ifndef JERRY_REGEXP_STRICT_MODE
# define JERRY_REGEXP_STRICT_MODE 0
#endif /* !defined (JERRY_REGEXP_STRICT_MODE) */
// #define CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE
/**
* Enable/Disable the snapshot execution functions.
*
* Allowed values:
* 0: Disable snapshot execution.
* 1: Enable snapshot execution.
*
* Default value: 0
* Number of ecma values inlined into VM stack frame
*/
#ifndef JERRY_SNAPSHOT_EXEC
# define JERRY_SNAPSHOT_EXEC 0
#endif /* !defined (JERRY_SNAPSHOT_EXEC) */
#define CONFIG_VM_STACK_FRAME_INLINED_VALUES_NUMBER (16)
/**
* Enable/Disable the snapshot save functions.
*
* Allowed values:
* 0: Disable snapshot save functions.
* 1: Enable snapshot save functions.
* Run GC after execution of each byte-code instruction
*/
#ifndef JERRY_SNAPSHOT_SAVE
# define JERRY_SNAPSHOT_SAVE 0
#endif /* !defined (JERRY_SNAPSHOT_SAVE) */
// #define CONFIG_VM_RUN_GC_AFTER_EACH_OPCODE
/**
* Enable/Disable usage of system allocator.
*
* Allowed values:
* 0: Disable usage of system allocator.
* 1: Enable usage of system allocator.
*
* Default value: 0
* Flag, indicating whether to enable parser-time byte-code optimizations
*/
#ifndef JERRY_SYSTEM_ALLOCATOR
# define JERRY_SYSTEM_ALLOCATOR 0
#endif /* !defined (JERRY_SYSTEM_ALLOCATOR) */
#define CONFIG_PARSER_ENABLE_PARSE_TIME_BYTE_CODE_OPTIMIZER
/**
* Enables/disables the unicode case conversion in the engine.
* By default Unicode case conversion is enabled.
*/
#ifndef JERRY_UNICODE_CASE_CONVERSION
# define JERRY_UNICODE_CASE_CONVERSION 1
#endif /* !defined (JERRY_UNICODE_CASE_CONVERSION) */
/**
* Configures if the internal memory allocations are exposed to Valgrind or not.
*
* Allowed values:
* 0: Disable the Valgrind specific memory allocation notifications.
* 1: Enable the Valgrind specific allocation notifications.
*/
#ifndef JERRY_VALGRIND
# define JERRY_VALGRIND 0
#endif /* !defined (JERRY_VALGRIND) */
/**
* Enable/Disable the vm execution stop callback function.
*
* Allowed values:
* 0: Disable vm exec stop callbacks.
* 1: Enable vm exec stop callback functionality.
*/
#ifndef JERRY_VM_EXEC_STOP
# define JERRY_VM_EXEC_STOP 0
#endif /* !defined (JERRY_VM_EXEC_STOP) */
/**
* Advanced section configurations.
*/
/**
* Allow configuring attributes on a few constant data inside the engine.
*
* One of the main usages:
* Normally compilers store const(ant)s in ROM. Thus saving RAM.
* But if your compiler does not support it then the directive below can force it.
*
* For the moment it is mainly meant for the following targets:
* - ESP8266
*
* Example configuration for moving (some) constatns into a given section:
* # define JERRY_ATTR_CONST_DATA __attribute__((section(".rodata.const")))
*/
#ifndef JERRY_ATTR_CONST_DATA
# define JERRY_ATTR_CONST_DATA
#endif /* !defined (JERRY_ATTR_CONST_DATA) */
/**
* The JERRY_ATTR_GLOBAL_HEAP allows adding extra attributes for the Jerry global heap.
*
* Example on how to move the global heap into it's own section:
* #define JERRY_ATTR_GLOBAL_HEAP __attribute__((section(".text.globalheap")))
*/
#ifndef JERRY_ATTR_GLOBAL_HEAP
# define JERRY_ATTR_GLOBAL_HEAP
#endif /* !defined (JERRY_ATTR_GLOBAL_HEAP) */
/**
* Sanity check for macros to see if the values are 0 or 1
*
* If a new feature is added this should be updated.
*/
/**
* Check base builtins.
*/
#if !defined (JERRY_BUILTIN_ANNEXB) \
|| ((JERRY_BUILTIN_ANNEXB != 0) && (JERRY_BUILTIN_ANNEXB != 1))
# error "Invalid value for JERRY_BUILTIN_ANNEXB macro."
#endif
#if !defined (JERRY_BUILTIN_ARRAY) \
|| ((JERRY_BUILTIN_ARRAY != 0) && (JERRY_BUILTIN_ARRAY != 1))
# error "Invalid value for JERRY_BUILTIN_ARRAY macro."
#endif
#if !defined (JERRY_BUILTIN_BOOLEAN) \
|| ((JERRY_BUILTIN_BOOLEAN != 0) && (JERRY_BUILTIN_BOOLEAN != 1))
# error "Invalid value for JERRY_BUILTIN_BOOLEAN macro."
#endif
#if !defined (JERRY_BUILTIN_DATE) \
|| ((JERRY_BUILTIN_DATE != 0) && (JERRY_BUILTIN_DATE != 1))
# error "Invalid value for JERRY_BUILTIN_DATE macro."
#endif
#if !defined (JERRY_BUILTIN_ERRORS) \
|| ((JERRY_BUILTIN_ERRORS != 0) && (JERRY_BUILTIN_ERRORS != 1))
# error "Invalid value for JERRY_BUILTIN_ERRORS macro."
#endif
#if !defined (JERRY_BUILTIN_JSON) \
|| ((JERRY_BUILTIN_JSON != 0) && (JERRY_BUILTIN_JSON != 1))
# error "Invalid value for JERRY_BUILTIN_JSON macro."
#endif
#if !defined (JERRY_BUILTIN_MATH) \
|| ((JERRY_BUILTIN_MATH != 0) && (JERRY_BUILTIN_MATH != 1))
# error "Invalid value for JERRY_BUILTIN_MATH macro."
#endif
#if !defined (JERRY_BUILTIN_NUMBER) \
|| ((JERRY_BUILTIN_NUMBER != 0) && (JERRY_BUILTIN_NUMBER != 1))
# error "Invalid value for JERRY_BUILTIN_NUMBER macro."
#endif
#if !defined (JERRY_BUILTIN_REGEXP) \
|| ((JERRY_BUILTIN_REGEXP != 0) && (JERRY_BUILTIN_REGEXP != 1))
# error "Invalid value for JERRY_BUILTIN_REGEXP macro."
#endif
#if !defined (JERRY_BUILTIN_STRING) \
|| ((JERRY_BUILTIN_STRING != 0) && (JERRY_BUILTIN_STRING != 1))
# error "Invalid value for JERRY_BUILTIN_STRING macro."
#endif
#if !defined (JERRY_BUILTINS) \
|| ((JERRY_BUILTINS != 0) && (JERRY_BUILTINS != 1))
# error "Invalid value for JERRY_BUILTINS macro."
#endif
/**
* Check ES2015 features
*/
#if !defined (JERRY_ES2015) \
|| ((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."
#endif
#if !defined (JERRY_ES2015_BUILTIN_MAP) \
|| ((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_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_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."
#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.
*/
#if !defined (JERRY_CPOINTER_32_BIT) \
|| ((JERRY_CPOINTER_32_BIT != 0) && (JERRY_CPOINTER_32_BIT != 1))
# error "Invalid value for 'JERRY_CPOINTER_32_BIT' macro."
#endif
#if !defined (JERRY_DEBUGGER) \
|| ((JERRY_DEBUGGER != 0) && (JERRY_DEBUGGER != 1))
# error "Invalid value for 'JERRY_DEBUGGER' macro."
#endif
#if !defined (JERRY_ERROR_MESSAGES) \
|| ((JERRY_ERROR_MESSAGES != 0) && (JERRY_ERROR_MESSAGES != 1))
# error "Invalid value for 'JERRY_ERROR_MESSAGES' macro."
#endif
#if !defined (JERRY_EXTERNAL_CONTEXT) \
|| ((JERRY_EXTERNAL_CONTEXT != 0) && (JERRY_EXTERNAL_CONTEXT != 1))
# error "Invalid value for 'JERRY_EXTERNAL_CONTEXT' macro."
#endif
#if !defined (JERRY_GLOBAL_HEAP_SIZE) || (JERRY_GLOBAL_HEAP_SIZE <= 0)
# error "Invalid value for 'JERRY_GLOBAL_HEAP_SIZE' macro."
#endif
#if !defined (JERRY_STACK_LIMIT) || (JERRY_STACK_LIMIT < 0)
# error "Invalid value for 'JERRY_STACK_LIMIT' macro."
#endif
#if !defined (JERRY_LCACHE) \
|| ((JERRY_LCACHE != 0) && (JERRY_LCACHE != 1))
# error "Invalid value for 'JERRY_LCACHE' macro."
#endif
#if !defined (JERRY_LINE_INFO) \
|| ((JERRY_LINE_INFO != 0) && (JERRY_LINE_INFO != 1))
# error "Invalid value for 'JERRY_LINE_INFO' macro."
#endif
#if !defined (JERRY_LOGGING) \
|| ((JERRY_LOGGING != 0) && (JERRY_LOGGING != 1))
# error "Invalid value for 'JERRY_LOGGING' macro."
#endif
#if !defined (JERRY_MEM_GC_BEFORE_EACH_ALLOC) \
|| ((JERRY_MEM_GC_BEFORE_EACH_ALLOC != 0) && (JERRY_MEM_GC_BEFORE_EACH_ALLOC != 1))
# error "Invalid value for 'JERRY_MEM_GC_BEFORE_EACH_ALLOC' macro."
#endif
#if !defined (JERRY_MEM_STATS) \
|| ((JERRY_MEM_STATS != 0) && (JERRY_MEM_STATS != 1))
# error "Invalid value for 'JERRY_MEM_STATS' macro."
#endif
#if !defined (JERRY_NUMBER_TYPE_FLOAT64) \
|| ((JERRY_NUMBER_TYPE_FLOAT64 != 0) && (JERRY_NUMBER_TYPE_FLOAT64 != 1))
# error "Invalid value for 'JERRY_NUMBER_TYPE_FLOAT64' macro."
#endif
#if !defined (JERRY_PARSER) \
|| ((JERRY_PARSER != 0) && (JERRY_PARSER != 1))
# error "Invalid value for 'JERRY_PARSER' macro."
#endif
#if !defined (JERRY_PARSER_DUMP_BYTE_CODE) \
|| ((JERRY_PARSER_DUMP_BYTE_CODE != 0) && (JERRY_PARSER_DUMP_BYTE_CODE != 1))
# error "Invalid value for 'JERRY_PARSER_DUMP_BYTE_CODE' macro."
#endif
#if !defined (JERRY_PROPRETY_HASHMAP) \
|| ((JERRY_PROPRETY_HASHMAP != 0) && (JERRY_PROPRETY_HASHMAP != 1))
# error "Invalid value for 'JERRY_PROPRETY_HASHMAP' macro."
#endif
#if !defined (JERRY_REGEXP_DUMP_BYTE_CODE) \
|| ((JERRY_REGEXP_DUMP_BYTE_CODE != 0) && (JERRY_REGEXP_DUMP_BYTE_CODE != 1))
# error "Invalid value for 'JERRY_REGEXP_DUMP_BYTE_CODE' macro."
#endif
#if !defined (JERRY_REGEXP_STRICT_MODE) \
|| ((JERRY_REGEXP_STRICT_MODE != 0) && (JERRY_REGEXP_STRICT_MODE != 1))
# error "Invalid value for 'JERRY_REGEXP_STRICT_MODE' macro."
#endif
#if !defined (JERRY_SNAPSHOT_EXEC) \
|| ((JERRY_SNAPSHOT_EXEC != 0) && (JERRY_SNAPSHOT_EXEC != 1))
# error "Invalid value for 'JERRY_SNAPSHOT_EXEC' macro."
#endif
#if !defined (JERRY_SNAPSHOT_SAVE) \
|| ((JERRY_SNAPSHOT_SAVE != 0) && (JERRY_SNAPSHOT_SAVE != 1))
# error "Invalid value for 'JERRY_SNAPSHOT_SAVE' macro."
#endif
#if !defined (JERRY_SYSTEM_ALLOCATOR) \
|| ((JERRY_SYSTEM_ALLOCATOR != 0) && (JERRY_SYSTEM_ALLOCATOR != 1))
# error "Invalid value for 'JERRY_SYSTEM_ALLOCATOR' macro."
#endif
#if !defined (JERRY_UNICODE_CASE_CONVERSION) \
|| ((JERRY_UNICODE_CASE_CONVERSION != 0) && (JERRY_UNICODE_CASE_CONVERSION != 1))
# error "Invalid value for 'JERRY_UNICODE_CASE_CONVERSION' macro."
#endif
#if !defined (JERRY_VALGRIND) \
|| ((JERRY_VALGRIND != 0) && (JERRY_VALGRIND != 1))
# error "Invalid value for 'JERRY_VALGRIND' macro."
#endif
#if !defined (JERRY_VM_EXEC_STOP) \
|| ((JERRY_VM_EXEC_STOP != 0) && (JERRY_VM_EXEC_STOP != 1))
# error "Invalid value for 'JERRY_VM_EXEC_STOP' macro."
#endif
#define ENABLED(FEATURE) ((FEATURE) == 1)
#define DISABLED(FEATURE) ((FEATURE) != 1)
/**
* Cross component requirements check.
*/
/**
* The date module can only use the float 64 number types.
* Do a check for this.
*/
#if ENABLED (JERRY_BUILTIN_DATE) && !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
# error "Date does not support float32"
#endif
#endif /* !JERRYSCRIPT_CONFIG_H */
#endif /* !CONFIG_H */
File diff suppressed because it is too large Load Diff
-491
View File
@@ -1,491 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DEBUGGER_H
#define DEBUGGER_H
#include "ecma-globals.h"
#include "jerryscript-debugger-transport.h"
#if ENABLED (JERRY_DEBUGGER)
/* JerryScript debugger protocol is a simplified version of RFC-6455 (WebSockets). */
/**
* Frequency of calling jerry_debugger_receive() by the VM.
*/
#define JERRY_DEBUGGER_MESSAGE_FREQUENCY 5
/**
* This constant represents that the string to be sent has no subtype.
*/
#define JERRY_DEBUGGER_NO_SUBTYPE 0
/**
* Limited resources available for the engine, so it is important to
* check the maximum buffer size. It needs to be between 64 and 256 bytes.
*/
#if JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE < 64 || JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE > 256
#error Please define the MAX_BUFFER_SIZE between 64 and 256 bytes.
#endif /* JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE < 64 || JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE > 256 */
/**
* Calculate the maximum number of items for a given type
* which can be transmitted in one message.
*/
#define JERRY_DEBUGGER_SEND_MAX(type) \
((size_t) ((JERRY_CONTEXT (debugger_max_send_size) - sizeof (jerry_debugger_send_type_t)) / sizeof (type)))
/**
* Calculate the size of a message when a count number of items transmitted.
*/
#define JERRY_DEBUGGER_SEND_SIZE(count, type) \
((size_t) ((count * sizeof (type)) + sizeof (jerry_debugger_send_type_t)))
/**
* Debugger operation modes:
*
* The debugger has two operation modes: run mode and breakpoint mode.
*
* In run mode the debugger server accepts only a limited number of message
* types from the debugger client (e.g. stop execution, set breakpoint).
*
* In breakpoint mode the JavaScript execution is stopped at a breakpoint and
* more message types are accepted (e.g. get backtrace, evaluate expression).
*
* Switching between modes:
*
* When the JavaScript execution stops at a breakpoint the server sends a
* JERRY_DEBUGGER_BREAKPOINT_HIT message to the client. The client can only
* issue breakpoint mode commands after this message is received.
*
* Certain breakpoint mode commands (e.g. continue) resumes the JavaScript
* execution and the client must not send any breakpoint mode messages
* until the JERRY_DEBUGGER_BREAKPOINT_HIT is received again.
*
* The debugger server starts in run mode but stops at the first available
* breakpoint.
*/
/**
* Debugger option flags.
*/
typedef enum
{
JERRY_DEBUGGER_CONNECTED = 1u << 0, /**< debugger is connected */
JERRY_DEBUGGER_BREAKPOINT_MODE = 1u << 1, /**< debugger waiting at a breakpoint */
JERRY_DEBUGGER_VM_STOP = 1u << 2, /**< stop at the next breakpoint even if disabled */
JERRY_DEBUGGER_VM_IGNORE = 1u << 3, /**< ignore all breakpoints */
JERRY_DEBUGGER_VM_IGNORE_EXCEPTION = 1u << 4, /**< debugger doesn't stop at any exception */
JERRY_DEBUGGER_VM_EXCEPTION_THROWN = 1u << 5, /**< no need to stop for this exception */
JERRY_DEBUGGER_PARSER_WAIT = 1u << 6, /**< debugger should wait after parsing is completed */
JERRY_DEBUGGER_PARSER_WAIT_MODE = 1u << 7, /**< debugger is waiting after parsing is completed */
JERRY_DEBUGGER_CLIENT_SOURCE_MODE = 1u << 8, /**< debugger waiting for client code */
JERRY_DEBUGGER_CLIENT_NO_SOURCE = 1u << 9, /**< debugger leaving the client source loop */
JERRY_DEBUGGER_CONTEXT_RESET_MODE = 1u << 10, /**< debugger and engine reinitialization mode */
} jerry_debugger_flags_t;
/**
* Set debugger flags.
*/
#define JERRY_DEBUGGER_SET_FLAGS(flags) \
JERRY_CONTEXT (debugger_flags) = (JERRY_CONTEXT (debugger_flags) | (uint32_t) (flags))
/**
* Clear debugger flags.
*/
#define JERRY_DEBUGGER_CLEAR_FLAGS(flags) \
JERRY_CONTEXT (debugger_flags) = (JERRY_CONTEXT (debugger_flags) & (uint32_t) ~(flags))
/**
* Set and clear debugger flags.
*/
#define JERRY_DEBUGGER_UPDATE_FLAGS(flags_to_set, flags_to_clear) \
JERRY_CONTEXT (debugger_flags) = ((JERRY_CONTEXT (debugger_flags) | (uint32_t) (flags_to_set)) \
& (uint32_t) ~(flags_to_clear))
/**
* Types for the package.
*/
typedef enum
{
/* Messages sent by the server to client. */
/* This is a handshake message, sent once during initialization. */
JERRY_DEBUGGER_CONFIGURATION = 1, /**< debugger configuration */
/* These messages are sent by the parser. */
JERRY_DEBUGGER_PARSE_ERROR = 2, /**< parse error */
JERRY_DEBUGGER_BYTE_CODE_CP = 3, /**< byte code compressed pointer */
JERRY_DEBUGGER_PARSE_FUNCTION = 4, /**< parsing a new function */
JERRY_DEBUGGER_BREAKPOINT_LIST = 5, /**< list of line offsets */
JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6, /**< list of byte code offsets */
JERRY_DEBUGGER_SOURCE_CODE = 7, /**< source code fragment */
JERRY_DEBUGGER_SOURCE_CODE_END = 8, /**< source code last fragment */
JERRY_DEBUGGER_SOURCE_CODE_NAME = 9, /**< source code name fragment */
JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10, /**< source code name last fragment */
JERRY_DEBUGGER_FUNCTION_NAME = 11, /**< function name fragment */
JERRY_DEBUGGER_FUNCTION_NAME_END = 12, /**< function name last fragment */
JERRY_DEBUGGER_WAITING_AFTER_PARSE = 13, /**< engine waiting for a parser resume */
/* These messages are generic messages. */
JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 14, /**< invalidate byte code compressed pointer */
JERRY_DEBUGGER_MEMSTATS_RECEIVE = 15, /**< memstats sent to the client */
JERRY_DEBUGGER_BREAKPOINT_HIT = 16, /**< notify breakpoint hit */
JERRY_DEBUGGER_EXCEPTION_HIT = 17, /**< notify exception hit */
JERRY_DEBUGGER_EXCEPTION_STR = 18, /**< exception string fragment */
JERRY_DEBUGGER_EXCEPTION_STR_END = 19, /**< exception string last fragment */
JERRY_DEBUGGER_BACKTRACE_TOTAL = 20, /**< number of total frames */
JERRY_DEBUGGER_BACKTRACE = 21, /**< backtrace data */
JERRY_DEBUGGER_BACKTRACE_END = 22, /**< last backtrace data */
JERRY_DEBUGGER_EVAL_RESULT = 23, /**< eval result */
JERRY_DEBUGGER_EVAL_RESULT_END = 24, /**< last part of eval result */
JERRY_DEBUGGER_WAIT_FOR_SOURCE = 25, /**< engine waiting for source code */
JERRY_DEBUGGER_OUTPUT_RESULT = 26, /**< output sent by the program to the debugger */
JERRY_DEBUGGER_OUTPUT_RESULT_END = 27, /**< last output result data */
JERRY_DEBUGGER_SCOPE_CHAIN = 28, /**< scope chain */
JERRY_DEBUGGER_SCOPE_CHAIN_END = 29, /**< last output of scope chain */
JERRY_DEBUGGER_SCOPE_VARIABLES = 30, /**< scope variables */
JERRY_DEBUGGER_SCOPE_VARIABLES_END = 31, /**< last output of scope variables */
JERRY_DEBUGGER_CLOSE_CONNECTION = 32, /**< close connection with the client */
JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT, /**< number of different type of output messages by the debugger */
/* Messages sent by the client to server. */
/* The following messages are accepted in both run and breakpoint modes. */
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1, /**< free byte code compressed pointer */
JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2, /**< update breakpoint status */
JERRY_DEBUGGER_EXCEPTION_CONFIG = 3, /**< exception handler config */
JERRY_DEBUGGER_PARSER_CONFIG = 4, /**< parser config */
JERRY_DEBUGGER_MEMSTATS = 5, /**< list memory statistics */
JERRY_DEBUGGER_STOP = 6, /**< stop execution */
/* The following message is only available in waiting after parse mode. */
JERRY_DEBUGGER_PARSER_RESUME = 7, /**< stop waiting after parse */
/* The following four messages are only available in client switch mode. */
JERRY_DEBUGGER_CLIENT_SOURCE = 8, /**< first message of client source */
JERRY_DEBUGGER_CLIENT_SOURCE_PART = 9, /**< next message of client source */
JERRY_DEBUGGER_NO_MORE_SOURCES = 10, /**< no more sources notification */
JERRY_DEBUGGER_CONTEXT_RESET = 11, /**< context reset request */
/* The following messages are only available in breakpoint
* mode and they switch the engine to run mode. */
JERRY_DEBUGGER_CONTINUE = 12, /**< continue execution */
JERRY_DEBUGGER_STEP = 13, /**< next breakpoint, step into functions */
JERRY_DEBUGGER_NEXT = 14, /**< next breakpoint in the same context */
JERRY_DEBUGGER_FINISH = 15, /**< Continue running just after the function in the current stack frame returns */
/* The following messages are only available in breakpoint
* mode and this mode is kept after the message is processed. */
JERRY_DEBUGGER_GET_BACKTRACE = 16, /**< get backtrace */
JERRY_DEBUGGER_EVAL = 17, /**< first message of evaluating a string */
JERRY_DEBUGGER_EVAL_PART = 18, /**< next message of evaluating a string */
JERRY_DEBUGGER_GET_SCOPE_CHAIN = 19, /**< get type names of the scope chain */
JERRY_DEBUGGER_GET_SCOPE_VARIABLES = 20, /**< get variables of a scope */
JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT, /**< number of different type of input messages */
} jerry_debugger_header_type_t;
/**
* Debugger option flags.
*/
typedef enum
{
JERRY_DEBUGGER_LITTLE_ENDIAN = 1u << 0, /**< little endian */
} jerry_debugger_configuration_flags_t;
/**
* Subtypes of eval.
*/
typedef enum
{
JERRY_DEBUGGER_EVAL_EVAL = 0, /**< evaluate expression */
JERRY_DEBUGGER_EVAL_THROW = 1, /**< evaluate expression and throw the result */
JERRY_DEBUGGER_EVAL_ABORT = 2, /**< evaluate expression and abrot with the result */
} jerry_debugger_eval_type_t;
/**
* Subtypes of eval_result.
*/
typedef enum
{
JERRY_DEBUGGER_EVAL_OK = 1, /**< eval result, no error */
JERRY_DEBUGGER_EVAL_ERROR = 2, /**< eval result when an error has occurred */
} jerry_debugger_eval_result_type_t;
/**
* Subtypes of output_result.
*
* Note:
* This enum has to be kept in sync with jerry_log_level_t with an offset
* of +2.
*/
typedef enum
{
JERRY_DEBUGGER_OUTPUT_OK = 1, /**< output result, no error */
JERRY_DEBUGGER_OUTPUT_ERROR = 2, /**< output result, error */
JERRY_DEBUGGER_OUTPUT_WARNING = 3, /**< output result, warning */
JERRY_DEBUGGER_OUTPUT_DEBUG = 4, /**< output result, debug */
JERRY_DEBUGGER_OUTPUT_TRACE = 5, /**< output result, trace */
} jerry_debugger_output_subtype_t;
/**
* Types of scopes.
*/
typedef enum
{
JERRY_DEBUGGER_SCOPE_WITH = 1, /**< with */
JERRY_DEBUGGER_SCOPE_LOCAL = 2, /**< local */
JERRY_DEBUGGER_SCOPE_CLOSURE = 3, /**< closure */
JERRY_DEBUGGER_SCOPE_GLOBAL = 4, /**< global */
JERRY_DEBUGGER_SCOPE_NON_CLOSURE = 5 /**< non closure */
} jerry_debugger_scope_chain_type_t;
/**
* Type of scope variables.
*/
typedef enum
{
JERRY_DEBUGGER_VALUE_NONE = 1,
JERRY_DEBUGGER_VALUE_UNDEFINED = 2,
JERRY_DEBUGGER_VALUE_NULL = 3,
JERRY_DEBUGGER_VALUE_BOOLEAN = 4,
JERRY_DEBUGGER_VALUE_NUMBER = 5,
JERRY_DEBUGGER_VALUE_STRING = 6,
JERRY_DEBUGGER_VALUE_FUNCTION = 7,
JERRY_DEBUGGER_VALUE_ARRAY = 8,
JERRY_DEBUGGER_VALUE_OBJECT = 9
} jerry_debugger_scope_variable_type_t;
/**
* Byte data for evaluating expressions and receiving client source.
*/
typedef struct
{
uint32_t uint8_size; /**< total size of the client source */
uint32_t uint8_offset; /**< current offset in the client source */
} jerry_debugger_uint8_data_t;
/**
* Delayed free of byte code data.
*/
typedef struct
{
uint16_t size; /**< size of the byte code header divided by JMEM_ALIGNMENT */
jmem_cpointer_t prev_cp; /**< previous byte code data to be freed */
} jerry_debugger_byte_code_free_t;
/**
* Outgoing message: JerryScript configuration.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t configuration; /**< configuration option bits */
uint8_t version[sizeof (uint32_t)]; /**< debugger version */
uint8_t max_message_size; /**< maximum incoming message size */
uint8_t cpointer_size; /**< size of compressed pointers */
} jerry_debugger_send_configuration_t;
/**
* Outgoing message: message without arguments.
*/
typedef struct
{
uint8_t type; /**< type of the message */
} jerry_debugger_send_type_t;
/**
* Incoming message: message without arguments.
*/
typedef struct
{
uint8_t type; /**< type of the message */
} jerry_debugger_receive_type_t;
/**
* Outgoing message: string (Source file name or function name).
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t string[]; /**< string data */
} jerry_debugger_send_string_t;
/**
* Outgoing message: uint32 value.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t line[sizeof (uint32_t)]; /**< value data */
uint8_t column[sizeof (uint32_t)]; /**< value data */
} jerry_debugger_send_parse_function_t;
/**
* Outgoing message: byte code compressed pointer.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t byte_code_cp[sizeof (jmem_cpointer_t)]; /**< byte code compressed pointer */
} jerry_debugger_send_byte_code_cp_t;
/**
* Incoming message: byte code compressed pointer.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t byte_code_cp[sizeof (jmem_cpointer_t)]; /**< byte code compressed pointer */
} jerry_debugger_receive_byte_code_cp_t;
/**
* Incoming message: update (enable/disable) breakpoint status.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t is_set_breakpoint; /**< set or clear breakpoint */
uint8_t byte_code_cp[sizeof (jmem_cpointer_t)]; /**< byte code compressed pointer */
uint8_t offset[sizeof (uint32_t)]; /**< breakpoint offset */
} jerry_debugger_receive_update_breakpoint_t;
/**
* Outgoing message: send memory statistics
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t allocated_bytes[sizeof (uint32_t)]; /**< allocated bytes */
uint8_t byte_code_bytes[sizeof (uint32_t)]; /**< byte code bytes */
uint8_t string_bytes[sizeof (uint32_t)]; /**< string bytes */
uint8_t object_bytes[sizeof (uint32_t)]; /**< object bytes */
uint8_t property_bytes[sizeof (uint32_t)]; /**< property bytes */
} jerry_debugger_send_memstats_t;
/**
* Outgoing message: notify breakpoint hit.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t byte_code_cp[sizeof (jmem_cpointer_t)]; /**< byte code compressed pointer */
uint8_t offset[sizeof (uint32_t)]; /**< breakpoint offset */
} jerry_debugger_send_breakpoint_hit_t;
/**
* Stack frame descriptor for sending backtrace information.
*/
typedef struct
{
uint8_t byte_code_cp[sizeof (jmem_cpointer_t)]; /**< byte code compressed pointer */
uint8_t offset[sizeof (uint32_t)]; /**< last breakpoint offset */
} jerry_debugger_frame_t;
/**
* Outgoing message: backtrace information.
*/
typedef struct
{
uint8_t type; /**< type of the message */
jerry_debugger_frame_t frames[]; /**< frames */
} jerry_debugger_send_backtrace_t;
/**
* Outgoing message: scope chain.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t scope_types[]; /**< scope types */
} jerry_debugger_send_scope_chain_t;
/**
* Outgoing message: number of total frames in backtrace.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t frame_count[sizeof (uint32_t)]; /**< total number of frames */
} jerry_debugger_send_backtrace_total_t;
/**
* Incoming message: set behaviour when exception occures.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t enable; /**< non-zero: enable stop at exception */
} jerry_debugger_receive_exception_config_t;
/**
* Incoming message: set parser configuration.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t enable_wait; /**< non-zero: wait after parsing is completed */
} jerry_debugger_receive_parser_config_t;
/**
* Incoming message: get backtrace.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t min_depth[sizeof (uint32_t)]; /**< minimum depth*/
uint8_t max_depth[sizeof (uint32_t)]; /**< maximum depth (0 - unlimited) */
uint8_t get_total_frame_count; /**< non-zero: if total frame count is also requested */
} jerry_debugger_receive_get_backtrace_t;
/**
* Incoming message: first message of evaluating expression.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t eval_size[sizeof (uint32_t)]; /**< total size of the message */
} jerry_debugger_receive_eval_first_t;
/**
* Incoming message: get scope variables
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t chain_index[sizeof (uint32_t)]; /**< index element of the scope */
} jerry_debugger_receive_get_scope_variables_t;
/**
* Incoming message: first message of client source.
*/
typedef struct
{
uint8_t type; /**< type of the message */
uint8_t code_size[sizeof (uint32_t)]; /**< total size of the message */
} jerry_debugger_receive_client_source_first_t;
void jerry_debugger_free_unreferenced_byte_code (void);
bool jerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p);
void jerry_debugger_breakpoint_hit (uint8_t message_type);
void jerry_debugger_send_type (jerry_debugger_header_type_t type);
bool jerry_debugger_send_configuration (uint8_t max_message_size);
void jerry_debugger_send_data (jerry_debugger_header_type_t type, const void *data, size_t size);
bool jerry_debugger_send_string (uint8_t message_type, uint8_t sub_type, const uint8_t *string_p, size_t string_length);
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);
#endif /* ENABLED (JERRY_DEBUGGER) */
#endif /* !DEBUGGER_H */
+52 -125
View File
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,19 +17,30 @@
#include "ecma-alloc.h"
#include "ecma-globals.h"
#include "ecma-gc.h"
#include "ecma-lcache.h"
#include "jrt.h"
#include "jmem.h"
#include "jmem-poolman.h"
JERRY_STATIC_ASSERT (sizeof (ecma_property_value_t) == sizeof (ecma_value_t),
size_of_ecma_property_value_t_must_be_equal_to_size_of_ecma_value_t);
JERRY_STATIC_ASSERT (((sizeof (ecma_property_value_t) - 1) & sizeof (ecma_property_value_t)) == 0,
size_of_ecma_property_value_t_must_be_power_of_2);
JERRY_STATIC_ASSERT (sizeof (ecma_property_pair_t) == sizeof (uint64_t) * 2,
size_of_ecma_property_pair_t_must_be_equal_to_16_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_object_t) <= sizeof (uint64_t),
size_of_ecma_object_t_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_extended_object_t) <= sizeof (uint64_t) * 2,
size_of_ecma_extended_object_t_must_be_less_than_or_equal_to_16_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_collection_header_t) == sizeof (uint64_t),
size_of_ecma_collection_header_t_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_collection_chunk_t) == sizeof (uint64_t),
size_of_ecma_collection_chunk_t_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_string_t) == sizeof (uint64_t),
size_of_ecma_string_t_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_extended_object_t) - sizeof (ecma_object_t) <= sizeof (uint64_t),
size_of_ecma_extended_object_part_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_getter_setter_pointers_t) <= sizeof (uint64_t),
size_of_ecma_getter_setter_pointers_t_must_be_less_than_or_equal_to_8_bytes);
/** \addtogroup ecma ECMA
* @{
@@ -50,164 +62,79 @@ JERRY_STATIC_ASSERT (sizeof (ecma_extended_object_t) - sizeof (ecma_object_t) <=
*/
/**
* Allocate memory for ecma-number
*
* @return pointer to allocated memory
* Template of an allocation routine.
*/
ecma_number_t *
ecma_alloc_number (void)
{
return (ecma_number_t *) jmem_pools_alloc (sizeof (ecma_number_t));
} /* ecma_alloc_number */
#define ALLOC(ecma_type) ecma_ ## ecma_type ## _t * \
ecma_alloc_ ## ecma_type (void) \
{ \
ecma_ ## ecma_type ## _t *p ## ecma_type = (ecma_ ## ecma_type ## _t *) jmem_pools_alloc (); \
\
JERRY_ASSERT (p ## ecma_type != NULL); \
\
return p ## ecma_type; \
}
/**
* Dealloc memory from an ecma-number
* Deallocation routine template
*/
void
ecma_dealloc_number (ecma_number_t *number_p) /**< number to be freed */
{
jmem_pools_free ((uint8_t *) number_p, sizeof (ecma_number_t));
} /* ecma_dealloc_number */
#define DEALLOC(ecma_type) void \
ecma_dealloc_ ## ecma_type (ecma_ ## ecma_type ## _t *p ## ecma_type) \
{ \
jmem_pools_free ((uint8_t *) p ## ecma_type); \
}
/**
* Allocate memory for ecma-object
*
* @return pointer to allocated memory
* Declaration of alloc/free routine for specified ecma-type.
*/
inline ecma_object_t * JERRY_ATTR_ALWAYS_INLINE
ecma_alloc_object (void)
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_allocate_object_bytes (sizeof (ecma_object_t));
#endif /* ENABLED (JERRY_MEM_STATS) */
#define DECLARE_ROUTINES_FOR(ecma_type) \
ALLOC (ecma_type) \
DEALLOC (ecma_type)
return (ecma_object_t *) jmem_pools_alloc (sizeof (ecma_object_t));
} /* ecma_alloc_object */
/**
* Dealloc memory from an ecma-object
*/
inline void JERRY_ATTR_ALWAYS_INLINE
ecma_dealloc_object (ecma_object_t *object_p) /**< object to be freed */
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_free_object_bytes (sizeof (ecma_object_t));
#endif /* ENABLED (JERRY_MEM_STATS) */
jmem_pools_free (object_p, sizeof (ecma_object_t));
} /* ecma_dealloc_object */
DECLARE_ROUTINES_FOR (object)
DECLARE_ROUTINES_FOR (number)
DECLARE_ROUTINES_FOR (collection_header)
DECLARE_ROUTINES_FOR (collection_chunk)
DECLARE_ROUTINES_FOR (string)
DECLARE_ROUTINES_FOR (getter_setter_pointers)
DECLARE_ROUTINES_FOR (external_pointer)
/**
* Allocate memory for extended object
*
* @return pointer to allocated memory
*/
inline ecma_extended_object_t * JERRY_ATTR_ALWAYS_INLINE
ecma_alloc_extended_object (size_t size) /**< size of object */
inline ecma_extended_object_t * __attr_always_inline___
ecma_alloc_extended_object (void)
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_allocate_object_bytes (size);
#endif /* ENABLED (JERRY_MEM_STATS) */
return jmem_heap_alloc_block (size);
return jmem_heap_alloc_block (sizeof (ecma_extended_object_t));
} /* ecma_alloc_extended_object */
/**
* Dealloc memory of an extended object
*/
inline void JERRY_ATTR_ALWAYS_INLINE
ecma_dealloc_extended_object (ecma_object_t *object_p, /**< extended object */
size_t size) /**< size of object */
inline void __attr_always_inline___
ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p) /**< property pair to be freed */
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_free_object_bytes (size);
#endif /* ENABLED (JERRY_MEM_STATS) */
jmem_heap_free_block (object_p, size);
jmem_heap_free_block (ext_object_p, sizeof (ecma_extended_object_t));
} /* ecma_dealloc_extended_object */
/**
* Allocate memory for ecma-string descriptor
*
* @return pointer to allocated memory
*/
inline ecma_string_t * JERRY_ATTR_ALWAYS_INLINE
ecma_alloc_string (void)
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_allocate_string_bytes (sizeof (ecma_string_t));
#endif /* ENABLED (JERRY_MEM_STATS) */
return (ecma_string_t *) jmem_pools_alloc (sizeof (ecma_string_t));
} /* ecma_alloc_string */
/**
* Dealloc memory from ecma-string descriptor
*/
inline void JERRY_ATTR_ALWAYS_INLINE
ecma_dealloc_string (ecma_string_t *string_p) /**< string to be freed */
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_free_string_bytes (sizeof (ecma_string_t));
#endif /* ENABLED (JERRY_MEM_STATS) */
jmem_pools_free (string_p, sizeof (ecma_string_t));
} /* ecma_dealloc_string */
/**
* Allocate memory for string with character data
*
* @return pointer to allocated memory
*/
inline ecma_string_t * JERRY_ATTR_ALWAYS_INLINE
ecma_alloc_string_buffer (size_t size) /**< size of string */
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_allocate_string_bytes (size);
#endif /* ENABLED (JERRY_MEM_STATS) */
return jmem_heap_alloc_block (size);
} /* ecma_alloc_string_buffer */
/**
* Dealloc memory of a string with character data
*/
inline void JERRY_ATTR_ALWAYS_INLINE
ecma_dealloc_string_buffer (ecma_string_t *string_p, /**< string with data */
size_t size) /**< size of string */
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_free_string_bytes (size);
#endif /* ENABLED (JERRY_MEM_STATS) */
jmem_heap_free_block (string_p, size);
} /* ecma_dealloc_string_buffer */
/**
* Allocate memory for ecma-property pair
*
* @return pointer to allocated memory
*/
inline ecma_property_pair_t * JERRY_ATTR_ALWAYS_INLINE
inline ecma_property_pair_t * __attr_always_inline___
ecma_alloc_property_pair (void)
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_allocate_property_bytes (sizeof (ecma_property_pair_t));
#endif /* ENABLED (JERRY_MEM_STATS) */
return jmem_heap_alloc_block (sizeof (ecma_property_pair_t));
} /* ecma_alloc_property_pair */
/**
* Dealloc memory of an ecma-property
*/
inline void JERRY_ATTR_ALWAYS_INLINE
inline void __attr_always_inline___
ecma_dealloc_property_pair (ecma_property_pair_t *property_pair_p) /**< property pair to be freed */
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_free_property_bytes (sizeof (ecma_property_pair_t));
#endif /* ENABLED (JERRY_MEM_STATS) */
jmem_heap_free_block (property_pair_p, sizeof (ecma_property_pair_t));
} /* ecma_dealloc_property_pair */
+61 -25
View File
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,72 +30,108 @@
*
* @return pointer to allocated memory
*/
ecma_object_t *ecma_alloc_object (void);
extern ecma_object_t *ecma_alloc_object (void);
/**
* Dealloc memory from an ecma-object
*/
void ecma_dealloc_object (ecma_object_t *object_p);
/**
* Allocate memory for extended object
*
* @return pointer to allocated memory
*/
ecma_extended_object_t *ecma_alloc_extended_object (size_t size);
/**
* Dealloc memory of an extended object
*/
void ecma_dealloc_extended_object (ecma_object_t *object_p, size_t size);
extern void ecma_dealloc_object (ecma_object_t *);
/**
* Allocate memory for ecma-number
*
* @return pointer to allocated memory
*/
ecma_number_t *ecma_alloc_number (void);
extern ecma_number_t *ecma_alloc_number (void);
/**
* Dealloc memory from an ecma-number
*/
void ecma_dealloc_number (ecma_number_t *number_p);
extern void ecma_dealloc_number (ecma_number_t *);
/**
* Allocate memory for header of a collection
*
* @return pointer to allocated memory
*/
extern ecma_collection_header_t *ecma_alloc_collection_header (void);
/**
* Dealloc memory from the collection's header
*/
extern void ecma_dealloc_collection_header (ecma_collection_header_t *);
/**
* Allocate memory for non-first chunk of a collection
*
* @return pointer to allocated memory
*/
extern ecma_collection_chunk_t *ecma_alloc_collection_chunk (void);
/**
* Dealloc memory from non-first chunk of a collection
*/
extern void ecma_dealloc_collection_chunk (ecma_collection_chunk_t *);
/**
* Allocate memory for ecma-string descriptor
*
* @return pointer to allocated memory
*/
ecma_string_t *ecma_alloc_string (void);
extern ecma_string_t *ecma_alloc_string (void);
/**
* Dealloc memory from ecma-string descriptor
*/
void ecma_dealloc_string (ecma_string_t *string_p);
extern void ecma_dealloc_string (ecma_string_t *);
/**
* Allocate memory for string with character data
* Allocate memory for getter-setter pointer pair
*
* @return pointer to allocated memory
*/
ecma_string_t *ecma_alloc_string_buffer (size_t size);
extern ecma_getter_setter_pointers_t *ecma_alloc_getter_setter_pointers (void);
/**
* Dealloc memory of a string with character data
* Dealloc memory from getter-setter pointer pair
*/
void ecma_dealloc_string_buffer (ecma_string_t *string_p, size_t size);
extern void ecma_dealloc_getter_setter_pointers (ecma_getter_setter_pointers_t *);
/**
* Allocate memory for external pointer
*
* @return pointer to allocated memory
*/
extern ecma_external_pointer_t *ecma_alloc_external_pointer (void);
/**
* Dealloc memory from external pointer
*/
extern void ecma_dealloc_external_pointer (ecma_external_pointer_t *);
/*
* Allocate memory for extended object
*
* @return pointer to allocated memory
*/
extern ecma_extended_object_t *ecma_alloc_extended_object (void);
/**
* Dealloc memory of an extended object
*/
extern void ecma_dealloc_extended_object (ecma_extended_object_t *);
/**
* Allocate memory for ecma-property pair
*
* @return pointer to allocated memory
*/
ecma_property_pair_t *ecma_alloc_property_pair (void);
extern ecma_property_pair_t *ecma_alloc_property_pair (void);
/**
* Dealloc memory from an ecma-property pair
*/
void ecma_dealloc_property_pair (ecma_property_pair_t *property_pair_p);
extern void ecma_dealloc_property_pair (ecma_property_pair_t *);
/**
* @}
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
#define ECMA_GC_H
#include "ecma-globals.h"
#include "jmem.h"
#include "jmem-allocator.h"
/** \addtogroup ecma ECMA
* @{
@@ -26,11 +26,11 @@
* @{
*/
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_run (void);
void ecma_free_unused_memory (jmem_pressure_t pressure);
extern void ecma_init_gc_info (ecma_object_t *);
extern void ecma_ref_object (ecma_object_t *);
extern void ecma_deref_object (ecma_object_t *);
extern void ecma_gc_run (jmem_free_unused_memory_severity_t);
extern void ecma_free_unused_memory (jmem_free_unused_memory_severity_t);
/**
* @}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+7 -11
View File
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,6 +39,7 @@
#include <math.h>
#include "config.h"
#include "ecma-helpers.h"
/** \addtogroup ecma ECMA
@@ -54,17 +56,11 @@
*/
/**
* Floating point format definitions (next float value)
* Floating point format definitions
*/
#define ECMA_NEXT_FLOAT(value) (nextafter ((value), INFINITY))
/**
* Floating point format definitions (previous float value)
*/
#define ECMA_PREV_FLOAT(value) (nextafter ((value), -INFINITY))
/**
* Value of epsilon
*/
#define ERROL0_EPSILON 0.0000001
/**
@@ -79,7 +75,7 @@ typedef struct
/**
* Normalize the number by factoring in the error.
*/
static inline void JERRY_ATTR_ALWAYS_INLINE
static inline void __attr_always_inline___
ecma_normalize_high_prec_data (ecma_high_prec_t *hp_data_p) /**< [in, out] float pair */
{
double val = hp_data_p->value;
@@ -91,7 +87,7 @@ ecma_normalize_high_prec_data (ecma_high_prec_t *hp_data_p) /**< [in, out] float
/**
* Multiply the high-precision number by ten.
*/
static inline void JERRY_ATTR_ALWAYS_INLINE
static inline void __attr_always_inline___
ecma_multiply_high_prec_by_10 (ecma_high_prec_t *hp_data_p) /**< [in, out] high-precision number */
{
double value = hp_data_p->value;
@@ -133,7 +129,7 @@ ecma_divide_high_prec_by_10 (ecma_high_prec_t *hp_data_p) /**< [in, out] high-pr
*
* @return number of generated digits
*/
inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
inline lit_utf8_size_t __attr_always_inline___
ecma_errol0_dtoa (double val, /**< ecma number */
lit_utf8_byte_t *buffer_p, /**< buffer to generate digits into */
int32_t *exp_p) /**< [out] exponent */
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +16,6 @@
#include "ecma-alloc.h"
#include "ecma-globals.h"
#include "ecma-objects.h"
#include "ecma-helpers.h"
/** \addtogroup ecma ECMA
@@ -26,184 +26,141 @@
*/
/**
* Create a native pointer property to store the native pointer and its type info.
*
* @return true - if property was just created with specified value,
* false - otherwise, if property existed before the call, it's value was updated
*/
bool
ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create property in */
void *native_p, /**< native pointer */
void *info_p) /**< native pointer's type info */
{
ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
bool is_new = (property_p == NULL);
ecma_native_pointer_t *native_pointer_p;
if (property_p == NULL)
{
ecma_property_value_t *value_p;
value_p = ecma_create_named_data_property (obj_p, name_p, ECMA_PROPERTY_CONFIGURABLE_WRITABLE, &property_p);
ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY (property_p);
native_pointer_p = jmem_heap_alloc_block (sizeof (ecma_native_pointer_t));
ECMA_SET_INTERNAL_VALUE_POINTER (value_p->value, native_pointer_p);
}
else
{
ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
ecma_native_pointer_t *iter_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value_p->value);
/* There should be at least 1 native pointer in the chain */
JERRY_ASSERT (iter_p != NULL);
while (true)
{
if (iter_p->info_p == info_p)
{
/* The native info already exists -> update the corresponding data */
iter_p->data_p = native_p;
return false;
}
if (iter_p->next_p == NULL)
{
/* The native info does not exist -> append a new element to the chain */
break;
}
iter_p = iter_p->next_p;
}
native_pointer_p = jmem_heap_alloc_block (sizeof (ecma_native_pointer_t));
iter_p->next_p = native_pointer_p;
}
native_pointer_p->data_p = native_p;
native_pointer_p->info_p = info_p;
native_pointer_p->next_p = NULL;
return is_new;
} /* ecma_create_native_pointer_property */
/**
* Get value of native package stored in the object's property with specified identifier
* Create internal property with specified identifier and store external pointer in the property.
*
* Note:
* property identifier should be one of the following:
* - LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
*
* @return native pointer data if property exists
* NULL otherwise
*/
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 */
{
ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
if (property_p == NULL)
{
return NULL;
}
ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
ecma_native_pointer_t *native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t,
value_p->value);
JERRY_ASSERT (native_pointer_p != NULL);
while (native_pointer_p != NULL)
{
if (native_pointer_p->info_p == info_p)
{
return native_pointer_p;
}
native_pointer_p = native_pointer_p->next_p;
}
return NULL;
} /* ecma_get_native_pointer_value */
/**
* Delete the previously set native pointer by the native type info from the specified object.
*
* Note:
* If the specified object has no matching native pointer for the given native type info
* the function has no effect.
*
* @return true - if the native pointer has been deleted succesfully
* false - otherwise
* @return true - if property was just created with specified value,
* false - otherwise, if property existed before the call, it's value was updated.
*/
bool
ecma_delete_native_pointer_property (ecma_object_t *obj_p, /**< object to delete property from */
void *info_p) /**< native pointer's type info */
ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to create property in */
ecma_internal_property_id_t id, /**< identifier of internal
* property to create */
ecma_external_pointer_t ptr_value) /**< value to store in the property */
{
ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p);
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);
if (property_p == NULL)
bool is_new;
ecma_property_t *prop_p = ecma_find_internal_property (obj_p, id);
if (prop_p == NULL)
{
prop_p = ecma_create_internal_property (obj_p, id);
is_new = true;
}
else
{
is_new = false;
}
JERRY_STATIC_ASSERT (sizeof (uint32_t) <= sizeof (ECMA_PROPERTY_VALUE_PTR (prop_p)->value),
size_of_internal_property_value_must_be_greater_than_or_equal_to_4_bytes);
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
ECMA_PROPERTY_VALUE_PTR (prop_p)->value = (ecma_value_t) ptr_value;
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
ecma_external_pointer_t *handler_p;
if (is_new)
{
handler_p = ecma_alloc_external_pointer ();
ECMA_SET_NON_NULL_POINTER (ECMA_PROPERTY_VALUE_PTR (prop_p)->value, handler_p);
}
else
{
handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t,
ECMA_PROPERTY_VALUE_PTR (prop_p)->value);
}
*handler_p = ptr_value;
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
return is_new;
} /* ecma_create_external_pointer_property */
/**
* Get value of external pointer stored in the object's property with specified identifier
*
* Note:
* property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
*
* @return true - if property exists and it's value is returned through out_pointer_p,
* false - otherwise (value returned through out_pointer_p is NULL).
*/
bool
ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get property value from */
ecma_internal_property_id_t id, /**< identifier of internal property
* to get value from */
ecma_external_pointer_t *out_pointer_p) /**< [out] value of the external pointer */
{
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);
ecma_property_t *prop_p = ecma_find_internal_property (obj_p, id);
if (prop_p == NULL)
{
*out_pointer_p = (ecma_external_pointer_t) NULL;
return false;
}
ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
ecma_native_pointer_t *native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t,
value_p->value);
ecma_native_pointer_t *prev_p = NULL;
*out_pointer_p = ECMA_PROPERTY_VALUE_PTR (prop_p)->value;
JERRY_ASSERT (native_pointer_p != NULL);
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
while (native_pointer_p != NULL)
{
if (native_pointer_p->info_p == info_p)
{
if (prev_p == NULL)
{
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);
jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
return true;
}
else
{
/* There are at least two native pointers and the first one should be deleted.
In this case the second element's data is copied to the head of the chain, and freed as well. */
ecma_native_pointer_t *next_p = native_pointer_p->next_p;
memcpy (native_pointer_p, next_p, sizeof (ecma_native_pointer_t));
jmem_heap_free_block (next_p, sizeof (ecma_native_pointer_t));
return true;
}
}
else
{
/* There are at least two native pointers and not the first element should be deleted.
In this case the current element's next element reference is copied to the previous element. */
prev_p->next_p = native_pointer_p->next_p;
jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
return true;
}
}
ecma_external_pointer_t *handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t,
ECMA_PROPERTY_VALUE_PTR (prop_p)->value);
*out_pointer_p = *handler_p;
prev_p = native_pointer_p;
native_pointer_p = native_pointer_p->next_p;
}
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
return false;
} /* ecma_delete_native_pointer_property */
return true;
} /* ecma_get_external_pointer_value */
/**
* Free memory associated with external pointer stored in the property
*
* Note:
* property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
*/
void
ecma_free_external_pointer_in_property (ecma_property_t *prop_p) /**< internal property */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
/* no additional memory was allocated for the pointer storage */
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
ecma_external_pointer_t *handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t,
ECMA_PROPERTY_VALUE_PTR (prop_p)->value);
ecma_dealloc_external_pointer (handler_p);
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
} /* ecma_free_external_pointer_in_property */
/**
* @}
+89 -38
View File
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,13 +32,11 @@ JERRY_STATIC_ASSERT (ECMA_DIRECT_SHIFT == ECMA_VALUE_SHIFT + 1,
JERRY_STATIC_ASSERT (((1 << (ECMA_DIRECT_SHIFT - 1)) | ECMA_TYPE_DIRECT) == ECMA_DIRECT_TYPE_SIMPLE_VALUE,
currently_directly_encoded_values_start_after_direct_type_simple_value);
/**
* Position of the sign bit in ecma-numbers
*/
#define ECMA_NUMBER_SIGN_POS (ECMA_NUMBER_FRACTION_WIDTH + \
ECMA_NUMBER_BIASED_EXP_WIDTH)
#if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
JERRY_STATIC_ASSERT (sizeof (ecma_number_t) == sizeof (uint32_t),
size_of_ecma_number_t_must_be_equal_to_4_bytes);
@@ -112,7 +111,7 @@ ecma_number_unpack (ecma_number_t num, /**< ecma-number */
*/
const int32_t ecma_number_exponent_bias = 127;
#elif ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
#elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
JERRY_STATIC_ASSERT (sizeof (ecma_number_t) == sizeof (uint64_t),
size_of_ecma_number_t_must_be_equal_to_8_bytes);
@@ -186,7 +185,7 @@ ecma_number_unpack (ecma_number_t num, /**< ecma-number */
*/
const int32_t ecma_number_exponent_bias = 1023;
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 */
/**
* Get fraction of number
@@ -240,7 +239,7 @@ ecma_number_get_sign_field (ecma_number_t num) /**< ecma-number */
fraction is filled with anything but not all zero bits,
* false - otherwise
*/
inline bool JERRY_ATTR_ALWAYS_INLINE
bool __attr_always_inline___
ecma_number_is_nan (ecma_number_t num) /**< ecma-number */
{
bool is_nan = (num != num);
@@ -293,7 +292,7 @@ ecma_number_make_infinity (bool sign) /**< true - for negative Infinity,
* @return true - if sign bit of ecma-number is set
* false - otherwise
*/
inline bool JERRY_ATTR_ALWAYS_INLINE
bool __attr_always_inline___
ecma_number_is_negative (ecma_number_t num) /**< ecma-number */
{
JERRY_ASSERT (!ecma_number_is_nan (num));
@@ -331,7 +330,7 @@ ecma_number_is_zero (ecma_number_t num) /**< ecma-number */
*
* @return true - if biased exponent is filled with 1 bits and
* fraction is filled with zero bits,
* false - otherwise
* false - otherwise.
*/
bool
ecma_number_is_infinity (ecma_number_t num) /**< ecma-number */
@@ -351,7 +350,7 @@ ecma_number_is_infinity (ecma_number_t num) /**< ecma-number */
*
* @return shift of dot in the fraction
*/
static int32_t
int32_t
ecma_number_get_fraction_and_exponent (ecma_number_t num, /**< ecma-number */
uint64_t *out_fraction_p, /**< [out] fraction of the number */
int32_t *out_exponent_p) /**< [out] exponent of the number */
@@ -362,7 +361,7 @@ ecma_number_get_fraction_and_exponent (ecma_number_t num, /**< ecma-number */
uint64_t fraction = ecma_number_get_fraction_field (num);
int32_t exponent;
if (JERRY_UNLIKELY (biased_exp == 0))
if (unlikely (biased_exp == 0))
{
/* IEEE-754 2008, 3.4, d */
if (ecma_number_is_zero (num))
@@ -410,7 +409,7 @@ ecma_number_get_fraction_and_exponent (ecma_number_t num, /**< ecma-number */
*
* @return ecma-number
*/
static ecma_number_t
ecma_number_t
ecma_number_make_normal_positive_from_fraction_and_exponent (uint64_t fraction, /**< fraction */
int32_t exponent) /**< exponent */
{
@@ -522,7 +521,7 @@ ecma_number_get_prev (ecma_number_t num) /**< ecma-number */
if (ecma_number_is_negative (num))
{
return -ecma_number_get_next (num);
return ecma_number_negate (ecma_number_get_next (num));
}
uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
@@ -557,7 +556,7 @@ ecma_number_get_next (ecma_number_t num) /**< ecma-number */
if (ecma_number_is_negative (num))
{
return -ecma_number_get_prev (num);
return ecma_number_negate (ecma_number_get_prev (num));
}
uint32_t biased_exp = ecma_number_get_biased_exponent_field (num);
@@ -583,6 +582,35 @@ ecma_number_get_next (ecma_number_t num) /**< ecma-number */
fraction);
} /* ecma_number_get_next */
/**
* Negate ecma-number
*
* @return negated number
*/
ecma_number_t
ecma_number_negate (ecma_number_t num) /**< ecma-number */
{
ecma_number_t negated = -num;
#ifndef JERRY_NDEBUG
bool sign;
uint32_t biased_exp;
uint64_t fraction;
ecma_number_unpack (num, &sign, &biased_exp, &fraction);
sign = !sign;
ecma_number_t negated_ieee754 = ecma_number_pack (sign, biased_exp, fraction);
JERRY_ASSERT (negated == negated_ieee754
|| (ecma_number_is_nan (negated)
&& ecma_number_is_nan (negated_ieee754)));
#endif /* !JERRY_NDEBUG */
return negated;
} /* ecma_number_negate */
/**
* Truncate fractional part of the number
*
@@ -610,7 +638,7 @@ ecma_number_trunc (ecma_number_t num) /**< ecma-number */
exponent);
if (sign)
{
return -tmp;
return ecma_number_negate (tmp);
}
else
{
@@ -643,42 +671,65 @@ ecma_number_calc_remainder (ecma_number_t left_num, /**< left operand */
&& !ecma_number_is_zero (right_num)
&& !ecma_number_is_infinity (right_num));
const ecma_number_t q = ecma_number_trunc (left_num / right_num);
ecma_number_t r = left_num - right_num * q;
const ecma_number_t q = ecma_number_trunc (ecma_number_divide (left_num, right_num));
ecma_number_t r = ecma_number_substract (left_num, ecma_number_multiply (right_num, q));
if (ecma_number_is_zero (r)
&& ecma_number_is_negative (left_num))
{
r = -r;
r = ecma_number_negate (r);
}
return r;
} /* ecma_number_calc_remainder */
/**
* ECMA-integer number multiplication.
* ECMA-number addition.
*
* @return number - result of addition.
*/
ecma_number_t
ecma_number_add (ecma_number_t left_num, /**< left operand */
ecma_number_t right_num) /**< right operand */
{
return left_num + right_num;
} /* ecma_number_add */
/**
* ECMA-number substraction.
*
* @return number - result of substraction.
*/
ecma_number_t
ecma_number_substract (ecma_number_t left_num, /**< left operand */
ecma_number_t right_num) /**< right operand */
{
return ecma_number_add (left_num, ecma_number_negate (right_num));
} /* ecma_number_substract */
/**
* ECMA-number multiplication.
*
* @return number - result of multiplication.
*/
inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
ecma_integer_multiply (ecma_integer_value_t left_integer, /**< left operand */
ecma_integer_value_t right_integer) /**< right operand */
ecma_number_t
ecma_number_multiply (ecma_number_t left_num, /**< left operand */
ecma_number_t right_num) /**< right operand */
{
#if defined (__GNUC__) || defined (__clang__)
/* Check if left_integer is power of 2 */
if (JERRY_UNLIKELY ((left_integer & (left_integer - 1)) == 0))
{
/* Right shift right_integer with log2 (left_integer) */
return ecma_make_integer_value (right_integer << (__builtin_ctz ((unsigned int) left_integer)));
}
else if (JERRY_UNLIKELY ((right_integer & (right_integer - 1)) == 0))
{
/* Right shift left_integer with log2 (right_integer) */
return ecma_make_integer_value (left_integer << (__builtin_ctz ((unsigned int) right_integer)));
}
#endif /* defined (__GNUC__) || defined (__clang__) */
return ecma_make_integer_value (left_integer * right_integer);
} /* ecma_integer_multiply */
return left_num * right_num;
} /* ecma_number_multiply */
/**
* ECMA-number division.
*
* @return number - result of division.
*/
ecma_number_t
ecma_number_divide (ecma_number_t left_num, /**< left operand */
ecma_number_t right_num) /**< right operand */
{
return left_num / right_num;
} /* ecma_number_divide */
/**
* @}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,26 +26,60 @@
* @{
*/
/**
* The type of ecma error and ecma collection chunk must be the same.
*/
JERRY_STATIC_ASSERT (ECMA_TYPE_ERROR == ECMA_TYPE_POINTER,
ecma_type_error_must_be_the_same_as_ecma_type_pointer);
/**
* Allocate a collection of ecma values.
*
* @return pointer to the collection's header
*/
ecma_collection_header_t *
ecma_new_values_collection (void)
ecma_new_values_collection (const ecma_value_t values_buffer[], /**< ecma values */
ecma_length_t values_number, /**< number of ecma values */
bool do_ref_if_object) /**< if the value is object value,
increase reference counter of the object */
{
ecma_collection_header_t *header_p;
header_p = (ecma_collection_header_t *) jmem_pools_alloc (sizeof (ecma_collection_header_t));
JERRY_ASSERT (values_buffer != NULL || values_number == 0);
header_p->item_count = 0;
header_p->first_chunk_cp = ECMA_NULL_POINTER;
header_p->last_chunk_cp = ECMA_NULL_POINTER;
const size_t values_in_chunk = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_collection_chunk_t, data) / sizeof (ecma_value_t);
ecma_collection_header_t *header_p = ecma_alloc_collection_header ();
header_p->unit_number = values_number;
jmem_cpointer_t *next_chunk_cp_p = &header_p->first_chunk_cp;
ecma_collection_chunk_t *last_chunk_p = NULL;
ecma_value_t *cur_value_buf_iter_p = NULL;
ecma_value_t *cur_value_buf_end_p = NULL;
for (ecma_length_t value_index = 0;
value_index < values_number;
value_index++)
{
if (cur_value_buf_iter_p == cur_value_buf_end_p)
{
ecma_collection_chunk_t *chunk_p = ecma_alloc_collection_chunk ();
ECMA_SET_POINTER (*next_chunk_cp_p, chunk_p);
next_chunk_cp_p = &chunk_p->next_chunk_cp;
cur_value_buf_iter_p = (ecma_value_t *) chunk_p->data;
cur_value_buf_end_p = cur_value_buf_iter_p + values_in_chunk;
last_chunk_p = chunk_p;
}
JERRY_ASSERT (cur_value_buf_iter_p + 1 <= cur_value_buf_end_p);
if (do_ref_if_object)
{
*cur_value_buf_iter_p++ = ecma_copy_value (values_buffer[value_index]);
}
else
{
*cur_value_buf_iter_p++ = ecma_copy_value_if_not_object (values_buffer[value_index]);
}
}
*next_chunk_cp_p = ECMA_NULL_POINTER;
ECMA_SET_POINTER (header_p->last_chunk_cp, last_chunk_p);
return header_p;
} /* ecma_new_values_collection */
@@ -54,44 +89,49 @@ ecma_new_values_collection (void)
*/
void
ecma_free_values_collection (ecma_collection_header_t *header_p, /**< collection's header */
uint32_t flags) /**< combination of ecma_collection_flag_t flags */
bool do_deref_if_object) /**< if the value is object value,
decrement reference counter of the object */
{
JERRY_ASSERT (header_p != NULL);
const size_t values_in_chunk = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_collection_chunk_t, data) / sizeof (ecma_value_t);
ecma_collection_chunk_t *chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t,
header_p->first_chunk_cp);
ecma_length_t value_index = 0;
jmem_pools_free (header_p, sizeof (ecma_collection_header_t));
if (chunk_p == NULL)
while (chunk_p != NULL)
{
return;
}
JERRY_ASSERT (value_index < header_p->unit_number);
do
{
ecma_value_t *item_p = chunk_p->items;
ecma_value_t *cur_value_buf_iter_p = (ecma_value_t *) chunk_p->data;
ecma_value_t *cur_value_buf_end_p = cur_value_buf_iter_p + values_in_chunk;
JERRY_ASSERT (!ecma_is_value_pointer (*item_p));
do
while (cur_value_buf_iter_p != cur_value_buf_end_p
&& value_index < header_p->unit_number)
{
if (!(flags & ECMA_COLLECTION_NO_COPY)
&& (!ecma_is_value_object (*item_p)
|| !(flags & ECMA_COLLECTION_NO_REF_OBJECTS)))
JERRY_ASSERT (cur_value_buf_iter_p < cur_value_buf_end_p);
if (do_deref_if_object)
{
ecma_free_value (*item_p);
ecma_free_value (*cur_value_buf_iter_p);
}
else
{
ecma_free_value_if_not_object (*cur_value_buf_iter_p);
}
item_p++;
cur_value_buf_iter_p++;
value_index++;
}
while (!ecma_is_value_pointer (*item_p));
ecma_collection_chunk_t *next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (*item_p);
jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t));
ecma_collection_chunk_t *next_chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t,
chunk_p->next_chunk_cp);
ecma_dealloc_collection_chunk (chunk_p);
chunk_p = next_chunk_p;
}
while (chunk_p != NULL);
ecma_dealloc_collection_header (header_p);
} /* ecma_free_values_collection */
/**
@@ -99,99 +139,233 @@ ecma_free_values_collection (ecma_collection_header_t *header_p, /**< collection
*/
void
ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< collection's header */
ecma_value_t value, /**< ecma value to append */
uint32_t flags) /**< combination of ecma_collection_flag_t flags */
ecma_value_t v, /**< ecma value to append */
bool do_ref_if_object) /**< if the value is object value,
increase reference counter of the object */
{
ecma_length_t item_index;
ecma_collection_chunk_t *chunk_p;
const size_t values_in_chunk = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_collection_chunk_t, data) / sizeof (ecma_value_t);
if (JERRY_UNLIKELY (header_p->item_count == 0))
size_t values_number = header_p->unit_number;
size_t pos_of_new_value_in_chunk = values_number % values_in_chunk;
values_number++;
if ((ecma_length_t) values_number == values_number)
{
item_index = 0;
chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t));
ECMA_SET_POINTER (header_p->first_chunk_cp, chunk_p);
header_p->last_chunk_cp = header_p->first_chunk_cp;
header_p->unit_number = (ecma_length_t) values_number;
}
else
{
item_index = header_p->item_count % ECMA_COLLECTION_CHUNK_ITEMS;
jerry_fatal (ERR_OUT_OF_MEMORY);
}
chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
header_p->last_chunk_cp);
ecma_collection_chunk_t *chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t,
header_p->last_chunk_cp);
if (JERRY_UNLIKELY (item_index == 0))
if (pos_of_new_value_in_chunk == 0)
{
/* all chunks are currently filled with values */
chunk_p = ecma_alloc_collection_chunk ();
chunk_p->next_chunk_cp = ECMA_NULL_POINTER;
if (header_p->last_chunk_cp == ECMA_NULL_POINTER)
{
JERRY_ASSERT (ecma_is_value_pointer (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS])
&& ecma_get_pointer_from_value (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS]) == NULL);
JERRY_ASSERT (header_p->first_chunk_cp == ECMA_NULL_POINTER);
ecma_collection_chunk_t *next_chunk_p;
next_chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t));
chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS] = ecma_make_pointer_value ((void *) next_chunk_p);
ECMA_SET_POINTER (header_p->last_chunk_cp, next_chunk_p);
chunk_p = next_chunk_p;
ECMA_SET_NON_NULL_POINTER (header_p->first_chunk_cp, chunk_p);
}
else
{
JERRY_ASSERT (ecma_is_value_pointer (chunk_p->items[item_index])
&& ecma_get_pointer_from_value (chunk_p->items[item_index]) == NULL);
ecma_collection_chunk_t *last_chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
header_p->last_chunk_cp);
JERRY_ASSERT (last_chunk_p->next_chunk_cp == ECMA_NULL_POINTER);
ECMA_SET_NON_NULL_POINTER (last_chunk_p->next_chunk_cp, chunk_p);
}
}
if (!(flags & ECMA_COLLECTION_NO_COPY)
&& (!ecma_is_value_object (value)
|| !(flags & ECMA_COLLECTION_NO_REF_OBJECTS)))
ECMA_SET_NON_NULL_POINTER (header_p->last_chunk_cp, chunk_p);
}
else
{
value = ecma_copy_value (value);
/* last chunk can be appended with the new value */
JERRY_ASSERT (chunk_p != NULL);
}
chunk_p->items[item_index] = value;
chunk_p->items[item_index + 1] = ecma_make_pointer_value (NULL);
header_p->item_count++;
ecma_value_t *values_p = (ecma_value_t *) chunk_p->data;
JERRY_ASSERT ((uint8_t *) (values_p + pos_of_new_value_in_chunk + 1) <= (uint8_t *) (chunk_p + 1));
if (do_ref_if_object)
{
values_p[pos_of_new_value_in_chunk] = ecma_copy_value (v);
}
else
{
values_p[pos_of_new_value_in_chunk] = ecma_copy_value_if_not_object (v);
}
} /* ecma_append_to_values_collection */
/**
* Initialize new collection iterator for the collection
* Remove last element of the collection
*
* @return pointer to the first item
* Warning:
* the function invalidates all iterators that are configured to access the passed collection
*/
ecma_value_t *
ecma_collection_iterator_init (ecma_collection_header_t *header_p) /**< header of collection */
void
ecma_remove_last_value_from_values_collection (ecma_collection_header_t *header_p) /**< collection's header */
{
if (JERRY_UNLIKELY (!header_p || header_p->item_count == 0))
JERRY_ASSERT (header_p != NULL && header_p->unit_number > 0);
const size_t values_in_chunk = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_collection_chunk_t, data) / sizeof (ecma_value_t);
size_t values_number = header_p->unit_number;
size_t pos_of_value_to_remove_in_chunk = (values_number - 1u) % values_in_chunk;
ecma_collection_chunk_t *last_chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
header_p->last_chunk_cp);
ecma_value_t *values_p = (ecma_value_t *) last_chunk_p->data;
JERRY_ASSERT ((uint8_t *) (values_p + pos_of_value_to_remove_in_chunk + 1) <= (uint8_t *) (last_chunk_p + 1));
ecma_value_t value_to_remove = values_p[pos_of_value_to_remove_in_chunk];
ecma_free_value (value_to_remove);
header_p->unit_number--;
if (pos_of_value_to_remove_in_chunk == 0)
{
return NULL;
ecma_collection_chunk_t *chunk_to_remove_p = last_chunk_p;
/* free last chunk */
if (header_p->first_chunk_cp == header_p->last_chunk_cp)
{
header_p->first_chunk_cp = ECMA_NULL_POINTER;
header_p->last_chunk_cp = ECMA_NULL_POINTER;
}
else
{
ecma_collection_chunk_t *chunk_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
header_p->first_chunk_cp);
while (chunk_iter_p->next_chunk_cp != header_p->last_chunk_cp)
{
chunk_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
chunk_iter_p->next_chunk_cp);
}
ecma_collection_chunk_t *new_last_chunk_p = chunk_iter_p;
JERRY_ASSERT (ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
new_last_chunk_p->next_chunk_cp) == chunk_to_remove_p);
ECMA_SET_NON_NULL_POINTER (header_p->last_chunk_cp, new_last_chunk_p);
new_last_chunk_p->next_chunk_cp = ECMA_NULL_POINTER;
}
ecma_dealloc_collection_chunk (chunk_to_remove_p);
}
} /* ecma_remove_last_value_from_values_collection */
/**
* Allocate a collection of ecma-strings.
*
* @return pointer to the collection's header
*/
ecma_collection_header_t *
ecma_new_strings_collection (ecma_string_t *string_ptrs_buffer[], /**< pointers to ecma-strings */
ecma_length_t strings_number) /**< number of ecma-strings */
{
JERRY_ASSERT (string_ptrs_buffer != NULL || strings_number == 0);
ecma_collection_header_t *new_collection_p;
new_collection_p = ecma_new_values_collection (NULL, 0, false);
for (ecma_length_t string_index = 0;
string_index < strings_number;
string_index++)
{
ecma_append_to_values_collection (new_collection_p,
ecma_make_string_value (string_ptrs_buffer[string_index]),
false);
}
ecma_collection_chunk_t *chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
header_p->first_chunk_cp);
return new_collection_p;
} /* ecma_new_strings_collection */
return chunk_p->items;
/**
* Initialize new collection iterator for the collection
*/
void
ecma_collection_iterator_init (ecma_collection_iterator_t *iterator_p, /**< context of iterator */
ecma_collection_header_t *collection_p) /**< header of collection */
{
iterator_p->header_p = collection_p;
iterator_p->next_chunk_cp = (collection_p != NULL ? collection_p->first_chunk_cp : JMEM_CP_NULL);
iterator_p->current_index = 0;
iterator_p->current_value_p = NULL;
iterator_p->current_chunk_end_p = NULL;
} /* ecma_collection_iterator_init */
/**
* Move collection iterator to next element if there is any.
*
* @return pointer to the next item
* @return true - if iterator moved,
* false - otherwise (current element is last element in the collection)
*/
ecma_value_t *
ecma_collection_iterator_next (ecma_value_t *ecma_value_p) /**< current value */
bool
ecma_collection_iterator_next (ecma_collection_iterator_t *iterator_p) /**< context of iterator */
{
JERRY_ASSERT (ecma_value_p != NULL);
ecma_value_p++;
if (JERRY_UNLIKELY (ecma_is_value_pointer (*ecma_value_p)))
if (iterator_p->header_p == NULL
|| unlikely (iterator_p->header_p->unit_number == 0))
{
ecma_value_p = ((ecma_collection_chunk_t *) ecma_get_pointer_from_value (*ecma_value_p))->items;
JERRY_ASSERT (ecma_value_p == NULL || !ecma_is_value_pointer (*ecma_value_p));
return ecma_value_p;
return false;
}
return ecma_value_p;
const size_t values_in_chunk = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_collection_chunk_t, data) / sizeof (ecma_value_t);
if (iterator_p->current_value_p == NULL)
{
JERRY_ASSERT (iterator_p->current_index == 0);
ecma_collection_chunk_t *first_chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
iterator_p->header_p->first_chunk_cp);
iterator_p->next_chunk_cp = first_chunk_p->next_chunk_cp;
iterator_p->current_value_p = (ecma_value_t *) &first_chunk_p->data;
iterator_p->current_chunk_end_p = (iterator_p->current_value_p + values_in_chunk);
}
else
{
if (iterator_p->current_index + 1 == iterator_p->header_p->unit_number)
{
return false;
}
JERRY_ASSERT (iterator_p->current_index + 1 < iterator_p->header_p->unit_number);
iterator_p->current_index++;
iterator_p->current_value_p++;
}
if (iterator_p->current_value_p == iterator_p->current_chunk_end_p)
{
ecma_collection_chunk_t *next_chunk_p = ECMA_GET_POINTER (ecma_collection_chunk_t,
iterator_p->next_chunk_cp);
JERRY_ASSERT (next_chunk_p != NULL);
iterator_p->next_chunk_cp = next_chunk_p->next_chunk_cp;
iterator_p->current_value_p = (ecma_value_t *) &next_chunk_p->data;
iterator_p->current_chunk_end_p = iterator_p->current_value_p + values_in_chunk;
}
else
{
JERRY_ASSERT (iterator_p->current_value_p < iterator_p->current_chunk_end_p);
}
return true;
} /* ecma_collection_iterator_next */
/**
File diff suppressed because it is too large Load Diff
+234 -313
View File
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +18,7 @@
#define ECMA_HELPERS_H
#include "ecma-globals.h"
#include "jmem.h"
#include "jmem-allocator.h"
#include "lit-strings.h"
/** \addtogroup ecma ECMA
@@ -50,13 +51,6 @@
*/
#define ECMA_SET_POINTER(field, non_compressed_pointer) JMEM_CP_SET_POINTER (field, non_compressed_pointer)
typedef enum
{
ECMA_STRING_FLAG_EMPTY = 0,
ECMA_STRING_FLAG_IS_ASCII,
ECMA_STRING_FLAG_MUST_BE_FREED
} ecma_string_flag_t;
/**
* Convert ecma-string's contents to a cesu-8 string and put it into a buffer.
*/
@@ -64,353 +58,280 @@ typedef enum
utf8_ptr, /**< [out] output buffer pointer */ \
utf8_str_size) /**< [out] output buffer size */ \
lit_utf8_size_t utf8_str_size; \
uint8_t utf8_ptr ## flags = ECMA_STRING_FLAG_EMPTY; \
const lit_utf8_byte_t *utf8_ptr = ecma_string_get_chars (ecma_str_ptr, &utf8_str_size, &utf8_ptr ## flags);
bool utf8_ptr ## must_be_freed; \
const lit_utf8_byte_t *utf8_ptr = ecma_string_raw_chars (ecma_str_ptr, &utf8_str_size, &utf8_ptr ## must_be_freed); \
utf8_ptr ## must_be_freed = false; /* it was used as 'is_ascii' in 'ecma_string_raw_chars', so we must reset it */ \
\
if (utf8_ptr == NULL) \
{ \
utf8_ptr = (const lit_utf8_byte_t *) jmem_heap_alloc_block (utf8_str_size); \
ecma_string_to_utf8_bytes (ecma_str_ptr, (lit_utf8_byte_t *) utf8_ptr, utf8_str_size); \
utf8_ptr ## must_be_freed = true; \
}
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
/**
* Set an internal property value of pointer
*/
#define ECMA_SET_INTERNAL_VALUE_POINTER(field, pointer) \
(field) = ((ecma_value_t) pointer)
/**
* Get an internal property value of pointer
*/
#define ECMA_GET_INTERNAL_VALUE_POINTER(type, field) \
((type *) field)
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
/**
* Set an internal property value of non-null pointer so that it will correspond
* to specified non_compressed_pointer.
*/
#define ECMA_SET_INTERNAL_VALUE_POINTER(field, non_compressed_pointer) \
ECMA_SET_NON_NULL_POINTER (field, non_compressed_pointer)
/**
* Get an internal property value of pointer from specified compressed pointer.
*/
#define ECMA_GET_INTERNAL_VALUE_POINTER(type, field) \
ECMA_GET_POINTER (type, field)
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
/**
* Free the cesu-8 string buffer allocated by 'ECMA_STRING_TO_UTF8_STRING'
*/
#define ECMA_FINALIZE_UTF8_STRING(utf8_ptr, /**< pointer to character buffer */ \
utf8_str_size) /**< buffer size */ \
if (utf8_ptr ## flags & ECMA_STRING_FLAG_MUST_BE_FREED) \
if (utf8_ptr ## must_be_freed) \
{ \
JERRY_ASSERT (utf8_ptr != NULL); \
jmem_heap_free_block ((void *) utf8_ptr, utf8_str_size); \
}
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
/**
* Set an internal property value from pointer.
*/
#define ECMA_SET_INTERNAL_VALUE_POINTER(field, pointer) \
(field) = ((ecma_value_t) pointer)
/**
* Set an internal property value from pointer. Pointer can be NULL.
*/
#define ECMA_SET_INTERNAL_VALUE_ANY_POINTER(field, pointer) \
(field) = ((ecma_value_t) pointer)
/**
* Convert an internal property value to pointer.
*/
#define ECMA_GET_INTERNAL_VALUE_POINTER(type, field) \
((type *) field)
/**
* Convert an internal property value to pointer. Result can be NULL.
*/
#define ECMA_GET_INTERNAL_VALUE_ANY_POINTER(type, field) \
((type *) field)
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
/**
* Set an internal property value from pointer.
*/
#define ECMA_SET_INTERNAL_VALUE_POINTER(field, pointer) \
ECMA_SET_NON_NULL_POINTER (field, pointer)
/**
* Set an internal property value from pointer. Pointer can be NULL.
*/
#define ECMA_SET_INTERNAL_VALUE_ANY_POINTER(field, pointer) \
ECMA_SET_POINTER (field, pointer)
/**
* Convert an internal property value to pointer.
*/
#define ECMA_GET_INTERNAL_VALUE_POINTER(type, field) \
ECMA_GET_NON_NULL_POINTER (type, field)
/**
* Convert an internal property value to pointer. Result can be NULL.
*/
#define ECMA_GET_INTERNAL_VALUE_ANY_POINTER(type, field) \
ECMA_GET_POINTER (type, field)
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
/**
* Convert boolean to bitfield value.
*/
#define ECMA_BOOL_TO_BITFIELD(x) ((x) ? 1 : 0)
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
/**
* 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) */
/**
* 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) */
/* ecma-helpers-value.c */
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);
bool JERRY_ATTR_CONST ecma_is_value_undefined (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_null (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_boolean (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_true (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_false (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_found (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_is_value_array_hole (ecma_value_t value);
extern bool ecma_is_value_direct (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_simple (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_empty (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_undefined (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_null (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_boolean (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_true (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_false (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_array_hole (ecma_value_t) __attr_pure___;
bool JERRY_ATTR_CONST ecma_is_value_integer_number (ecma_value_t value);
bool JERRY_ATTR_CONST ecma_are_values_integer_numbers (ecma_value_t first_value, ecma_value_t second_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)
bool JERRY_ATTR_CONST ecma_is_value_symbol (ecma_value_t value);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
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);
bool JERRY_ATTR_CONST ecma_is_value_pointer (ecma_value_t value);
extern bool ecma_is_value_integer_number (ecma_value_t) __attr_pure___;
extern bool ecma_are_values_integer_numbers (ecma_value_t, ecma_value_t) __attr_pure___;
extern bool ecma_is_value_float_number (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_number (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_string (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_object (ecma_value_t) __attr_pure___;
void ecma_check_value_type_is_spec_defined (ecma_value_t value);
extern void ecma_check_value_type_is_spec_defined (ecma_value_t);
ecma_value_t JERRY_ATTR_CONST ecma_make_boolean_value (bool boolean_value);
ecma_value_t JERRY_ATTR_CONST ecma_make_integer_value (ecma_integer_value_t integer_value);
ecma_value_t ecma_make_nan_value (void);
ecma_value_t ecma_make_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)
ecma_value_t JERRY_ATTR_PURE ecma_make_symbol_value (const ecma_string_t *ecma_symbol_p);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
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);
ecma_value_t JERRY_ATTR_PURE ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p);
ecma_value_t JERRY_ATTR_PURE ecma_make_pointer_value (const void *any_p);
ecma_integer_value_t JERRY_ATTR_CONST ecma_get_integer_from_value (ecma_value_t value);
ecma_number_t JERRY_ATTR_PURE ecma_get_float_from_value (ecma_value_t value);
ecma_number_t 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)
ecma_string_t JERRY_ATTR_PURE *ecma_get_symbol_from_value (ecma_value_t value);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
ecma_string_t JERRY_ATTR_PURE *ecma_get_prop_name_from_value (ecma_value_t value);
ecma_object_t JERRY_ATTR_PURE *ecma_get_object_from_value (ecma_value_t value);
ecma_error_reference_t JERRY_ATTR_PURE *ecma_get_error_reference_from_value (ecma_value_t value);
void * JERRY_ATTR_PURE ecma_get_pointer_from_value (ecma_value_t value);
ecma_value_t JERRY_ATTR_CONST ecma_invert_boolean_value (ecma_value_t value);
ecma_value_t ecma_copy_value (ecma_value_t value);
ecma_value_t ecma_fast_copy_value (ecma_value_t value);
ecma_value_t ecma_copy_value_if_not_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);
void ecma_free_value (ecma_value_t value);
void ecma_fast_free_value (ecma_value_t value);
void ecma_free_value_if_not_object (ecma_value_t value);
void ecma_free_number (ecma_value_t value);
lit_magic_string_id_t ecma_get_typeof_lit_id (ecma_value_t value);
extern ecma_value_t ecma_make_simple_value (const ecma_simple_value_t value) __attr_const___;
extern ecma_value_t ecma_make_boolean_value (bool) __attr_const___;
extern ecma_value_t ecma_make_integer_value (ecma_integer_value_t) __attr_const___;
extern ecma_value_t ecma_make_nan_value (void);
extern ecma_value_t ecma_make_number_value (ecma_number_t);
extern ecma_value_t ecma_make_int32_value (int32_t);
extern ecma_value_t ecma_make_uint32_value (uint32_t);
extern ecma_value_t ecma_make_string_value (const ecma_string_t *);
extern ecma_value_t ecma_make_object_value (const ecma_object_t *);
extern ecma_value_t ecma_make_error_value (ecma_value_t);
extern ecma_value_t ecma_make_error_obj_value (const ecma_object_t *);
extern ecma_integer_value_t ecma_get_integer_from_value (ecma_value_t) __attr_pure___;
extern ecma_number_t ecma_get_float_from_value (ecma_value_t) __attr_pure___;
extern ecma_number_t ecma_get_number_from_value (ecma_value_t) __attr_pure___;
extern uint32_t ecma_get_uint32_from_value (ecma_value_t) __attr_pure___;
extern ecma_string_t *ecma_get_string_from_value (ecma_value_t) __attr_pure___;
extern ecma_object_t *ecma_get_object_from_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_get_value_from_error_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_invert_boolean_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_copy_value (ecma_value_t);
extern ecma_value_t ecma_fast_copy_value (ecma_value_t);
extern ecma_value_t ecma_copy_value_if_not_object (ecma_value_t);
extern ecma_value_t ecma_update_float_number (ecma_value_t, ecma_number_t);
extern void ecma_value_assign_value (ecma_value_t *, ecma_value_t);
extern void ecma_value_assign_number (ecma_value_t *, ecma_number_t);
extern void ecma_value_assign_uint32 (ecma_value_t *, uint32_t);
extern void ecma_free_value (ecma_value_t);
extern void ecma_fast_free_value (ecma_value_t);
extern void ecma_free_value_if_not_object (ecma_value_t);
/* ecma-helpers-string.c */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
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) */
#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);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */
ecma_string_t *ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, lit_utf8_size_t string_size);
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)
ecma_string_t *ecma_new_ecma_string_from_code_units (ecma_char_t first_code_unit, ecma_char_t second_code_unit);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
ecma_string_t *ecma_new_ecma_string_from_uint32 (uint32_t uint32_number);
ecma_string_t *ecma_get_ecma_string_from_uint32 (uint32_t uint32_number);
ecma_string_t *ecma_new_ecma_string_from_number (ecma_number_t num);
ecma_string_t *ecma_get_magic_string (lit_magic_string_id_t id);
ecma_string_t *ecma_append_chars_to_string (ecma_string_t *string1_p,
const lit_utf8_byte_t *cesu8_string2_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);
ecma_number_t ecma_string_to_number (const ecma_string_t *str_p);
uint32_t ecma_string_get_array_index (const ecma_string_t *str_p);
extern ecma_string_t *ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *, lit_utf8_size_t);
extern ecma_string_t *ecma_new_ecma_string_from_code_unit (ecma_char_t);
extern ecma_string_t *ecma_new_ecma_string_from_uint32 (uint32_t);
extern ecma_string_t *ecma_new_ecma_string_from_number (ecma_number_t);
extern ecma_string_t *ecma_new_ecma_string_from_magic_string_id (lit_magic_string_id_t);
extern ecma_string_t *ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t);
extern ecma_string_t *ecma_new_ecma_length_string ();
extern ecma_string_t *ecma_concat_ecma_strings (ecma_string_t *, ecma_string_t *);
extern void ecma_ref_ecma_string (ecma_string_t *);
extern void ecma_deref_ecma_string (ecma_string_t *);
extern ecma_number_t ecma_string_to_number (const ecma_string_t *);
extern bool ecma_string_get_array_index (const ecma_string_t *, uint32_t *);
lit_utf8_size_t JERRY_ATTR_WARN_UNUSED_RESULT
ecma_string_copy_to_cesu8_buffer (const ecma_string_t *string_desc_p,
lit_utf8_byte_t *buffer_p,
lit_utf8_size_t buffer_size);
lit_utf8_size_t JERRY_ATTR_WARN_UNUSED_RESULT
ecma_string_copy_to_utf8_buffer (const ecma_string_t *string_desc_p,
lit_utf8_byte_t *buffer_p,
lit_utf8_size_t buffer_size);
lit_utf8_size_t
ecma_substring_copy_to_cesu8_buffer (const ecma_string_t *string_desc_p,
ecma_length_t start_pos,
ecma_length_t end_pos,
lit_utf8_byte_t *buffer_p,
lit_utf8_size_t buffer_size);
lit_utf8_size_t
ecma_substring_copy_to_utf8_buffer (const ecma_string_t *string_desc_p,
ecma_length_t start_pos,
ecma_length_t end_pos,
lit_utf8_byte_t *buffer_p,
lit_utf8_size_t buffer_size);
void ecma_string_to_utf8_bytes (const ecma_string_t *string_desc_p, lit_utf8_byte_t *buffer_p,
lit_utf8_size_t buffer_size);
const lit_utf8_byte_t *ecma_string_get_chars (const ecma_string_t *string_p, lit_utf8_size_t *size_p, uint8_t *flags_p);
bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id);
bool ecma_string_is_empty (const ecma_string_t *string_p);
bool ecma_string_is_length (const ecma_string_t *string_p);
extern lit_utf8_size_t __attr_return_value_should_be_checked___
ecma_string_copy_to_utf8_buffer (const ecma_string_t *, lit_utf8_byte_t *, lit_utf8_size_t);
extern void ecma_string_to_utf8_bytes (const ecma_string_t *, lit_utf8_byte_t *, lit_utf8_size_t);
extern const lit_utf8_byte_t *ecma_string_raw_chars (const ecma_string_t *, lit_utf8_size_t *, bool *);
extern void ecma_init_ecma_string_from_uint32 (ecma_string_t *, uint32_t);
extern void ecma_init_ecma_length_string (ecma_string_t *);
extern bool ecma_string_is_empty (const ecma_string_t *);
extern bool ecma_string_is_length (const ecma_string_t *);
jmem_cpointer_t ecma_string_to_property_name (ecma_string_t *prop_name_p, ecma_property_t *name_type_p);
ecma_string_t *ecma_string_from_property_name (ecma_property_t property, jmem_cpointer_t prop_name_cp);
lit_string_hash_t ecma_string_get_property_name_hash (ecma_property_t property, jmem_cpointer_t prop_name_cp);
uint32_t ecma_string_get_property_index (ecma_property_t property, jmem_cpointer_t prop_name_cp);
bool ecma_string_compare_to_property_name (ecma_property_t property, jmem_cpointer_t prop_name_cp,
const ecma_string_t *string_p);
extern bool ecma_compare_ecma_strings_equal_hashes (const ecma_string_t *, const ecma_string_t *);
extern bool ecma_compare_ecma_strings (const ecma_string_t *, const ecma_string_t *);
extern bool ecma_compare_ecma_strings_relational (const ecma_string_t *, const ecma_string_t *);
extern ecma_length_t ecma_string_get_length (const ecma_string_t *);
extern lit_utf8_size_t ecma_string_get_size (const ecma_string_t *);
extern ecma_char_t ecma_string_get_char_at_pos (const ecma_string_t *, ecma_length_t);
bool ecma_compare_ecma_strings (const ecma_string_t *string1_p, const ecma_string_t *string2_p);
bool ecma_compare_ecma_non_direct_strings (const ecma_string_t *string1_p, const ecma_string_t *string2_p);
bool ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, const ecma_string_t *string2_p);
ecma_length_t ecma_string_get_length (const ecma_string_t *string_p);
ecma_length_t ecma_string_get_utf8_length (const ecma_string_t *string_p);
lit_utf8_size_t ecma_string_get_size (const ecma_string_t *string_p);
lit_utf8_size_t ecma_string_get_utf8_size (const ecma_string_t *string_p);
ecma_char_t ecma_string_get_char_at_pos (const ecma_string_t *string_p, ecma_length_t index);
extern ecma_string_t *ecma_get_magic_string (lit_magic_string_id_t);
extern ecma_string_t *ecma_get_magic_string_ex (lit_magic_string_ex_id_t);
extern bool ecma_is_string_magic (const ecma_string_t *, lit_magic_string_id_t *);
lit_magic_string_id_t ecma_get_string_magic (const ecma_string_t *string_p);
lit_string_hash_t ecma_string_hash (const ecma_string_t *string_p);
ecma_string_t *ecma_string_substr (const ecma_string_t *string_p, ecma_length_t start_pos, ecma_length_t end_pos);
ecma_string_t *ecma_string_trim (const ecma_string_t *string_p);
extern lit_string_hash_t ecma_string_hash (const ecma_string_t *);
extern ecma_string_t *ecma_string_substr (const ecma_string_t *, ecma_length_t, ecma_length_t);
extern ecma_string_t *ecma_string_trim (const ecma_string_t *);
/* ecma-helpers-number.c */
ecma_number_t ecma_number_make_nan (void);
ecma_number_t ecma_number_make_infinity (bool sign);
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);
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_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,
lit_utf8_byte_t *out_digits_p,
int32_t *out_decimal_exp_p);
extern ecma_number_t ecma_number_make_nan (void);
extern ecma_number_t ecma_number_make_infinity (bool);
extern bool ecma_number_is_nan (ecma_number_t);
extern bool ecma_number_is_negative (ecma_number_t);
extern bool ecma_number_is_zero (ecma_number_t);
extern bool ecma_number_is_infinity (ecma_number_t);
extern int32_t
ecma_number_get_fraction_and_exponent (ecma_number_t, uint64_t *, int32_t *);
extern ecma_number_t
ecma_number_make_normal_positive_from_fraction_and_exponent (uint64_t, int32_t);
extern ecma_number_t
ecma_number_make_from_sign_mantissa_and_exponent (bool, uint64_t, int32_t);
extern ecma_number_t ecma_number_get_prev (ecma_number_t);
extern ecma_number_t ecma_number_get_next (ecma_number_t);
extern ecma_number_t ecma_number_negate (ecma_number_t);
extern ecma_number_t ecma_number_trunc (ecma_number_t);
extern ecma_number_t ecma_number_calc_remainder (ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_number_add (ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_number_substract (ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_number_multiply (ecma_number_t, ecma_number_t);
extern ecma_number_t ecma_number_divide (ecma_number_t, ecma_number_t);
extern lit_utf8_size_t ecma_number_to_decimal (ecma_number_t, lit_utf8_byte_t *, int32_t *);
/* ecma-helpers-values-collection.c */
ecma_collection_header_t *ecma_new_values_collection (void);
void ecma_free_values_collection (ecma_collection_header_t *header_p, uint32_t flags);
void ecma_append_to_values_collection (ecma_collection_header_t *header_p, ecma_value_t v, uint32_t flags);
extern ecma_collection_header_t *ecma_new_values_collection (const ecma_value_t[], ecma_length_t, bool);
extern void ecma_free_values_collection (ecma_collection_header_t *, bool);
extern void ecma_append_to_values_collection (ecma_collection_header_t *, ecma_value_t, bool);
extern void ecma_remove_last_value_from_values_collection (ecma_collection_header_t *);
extern ecma_collection_header_t *ecma_new_strings_collection (ecma_string_t *[], ecma_length_t);
ecma_value_t *
ecma_collection_iterator_init (ecma_collection_header_t *header_p);
ecma_value_t *
ecma_collection_iterator_next (ecma_value_t *iterator_p);
/**
* Context of ecma values' collection iterator
*/
typedef struct
{
ecma_collection_header_t *header_p; /**< collection header */
jmem_cpointer_t next_chunk_cp; /**< compressed pointer to next chunk */
ecma_length_t current_index; /**< index of current element */
const ecma_value_t *current_value_p; /**< pointer to current element */
const ecma_value_t *current_chunk_beg_p; /**< pointer to beginning of current chunk's data */
const ecma_value_t *current_chunk_end_p; /**< pointer to place right after the end of current chunk's data */
} ecma_collection_iterator_t;
extern void
ecma_collection_iterator_init (ecma_collection_iterator_t *, ecma_collection_header_t *);
extern bool
ecma_collection_iterator_next (ecma_collection_iterator_t *);
/* ecma-helpers.c */
ecma_object_t *ecma_create_object (ecma_object_t *prototype_object_p, size_t ext_object_size, ecma_object_type_t type);
ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p);
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);
ecma_object_type_t JERRY_ATTR_PURE ecma_get_object_type (const ecma_object_t *object_p);
ecma_object_t JERRY_ATTR_PURE *ecma_get_object_prototype (const ecma_object_t *object_p);
bool JERRY_ATTR_PURE ecma_get_object_is_builtin (const ecma_object_t *object_p);
void ecma_set_object_is_builtin (ecma_object_t *object_p);
uint8_t ecma_get_object_builtin_id (ecma_object_t *object_p);
ecma_lexical_environment_type_t JERRY_ATTR_PURE ecma_get_lex_env_type (const ecma_object_t *object_p);
ecma_object_t JERRY_ATTR_PURE *ecma_get_lex_env_outer_reference (const ecma_object_t *object_p);
ecma_property_header_t JERRY_ATTR_PURE *ecma_get_property_list (const ecma_object_t *object_p);
ecma_object_t JERRY_ATTR_PURE *ecma_get_lex_env_binding_object (const ecma_object_t *object_p);
extern ecma_object_t *ecma_create_object (ecma_object_t *, bool, bool, ecma_object_type_t);
extern ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *);
extern ecma_object_t *ecma_create_object_lex_env (ecma_object_t *, ecma_object_t *, bool);
extern bool ecma_is_lexical_environment (const ecma_object_t *) __attr_pure___;
extern bool ecma_get_object_extensible (const ecma_object_t *) __attr_pure___;
extern void ecma_set_object_extensible (ecma_object_t *, bool);
extern ecma_object_type_t ecma_get_object_type (const ecma_object_t *) __attr_pure___;
extern void ecma_set_object_type (ecma_object_t *, ecma_object_type_t);
extern ecma_object_t *ecma_get_object_prototype (const ecma_object_t *) __attr_pure___;
extern bool ecma_get_object_is_builtin (const ecma_object_t *) __attr_pure___;
extern void ecma_set_object_is_builtin (ecma_object_t *);
extern ecma_lexical_environment_type_t ecma_get_lex_env_type (const ecma_object_t *) __attr_pure___;
extern ecma_object_t *ecma_get_lex_env_outer_reference (const ecma_object_t *) __attr_pure___;
extern ecma_property_header_t *ecma_get_property_list (const ecma_object_t *) __attr_pure___;
extern ecma_object_t *ecma_get_lex_env_binding_object (const ecma_object_t *) __attr_pure___;
extern bool ecma_get_lex_env_provide_this (const ecma_object_t *) __attr_pure___;
ecma_property_value_t *
ecma_create_named_data_property (ecma_object_t *object_p, ecma_string_t *name_p, uint8_t prop_attributes,
ecma_property_t **out_prop_p);
ecma_property_value_t *
ecma_create_named_accessor_property (ecma_object_t *object_p, ecma_string_t *name_p, ecma_object_t *get_p,
ecma_object_t *set_p, uint8_t prop_attributes, ecma_property_t **out_prop_p);
ecma_property_t *
ecma_find_named_property (ecma_object_t *obj_p, ecma_string_t *name_p);
ecma_property_value_t *
ecma_get_named_data_property (ecma_object_t *obj_p, ecma_string_t *name_p);
extern ecma_property_t *ecma_create_internal_property (ecma_object_t *, ecma_internal_property_id_t);
extern ecma_property_t *ecma_find_internal_property (ecma_object_t *, ecma_internal_property_id_t);
extern ecma_property_t *ecma_get_internal_property (ecma_object_t *, ecma_internal_property_id_t);
void ecma_free_property (ecma_object_t *object_p, jmem_cpointer_t name_cp, ecma_property_t *property_p);
extern ecma_property_t *
ecma_create_named_data_property (ecma_object_t *, ecma_string_t *, uint8_t);
extern ecma_property_t *
ecma_create_named_accessor_property (ecma_object_t *, ecma_string_t *, ecma_object_t *, ecma_object_t *, uint8_t);
extern ecma_property_t *
ecma_find_named_property (ecma_object_t *, ecma_string_t *);
extern ecma_property_t *
ecma_get_named_property (ecma_object_t *, ecma_string_t *);
extern ecma_property_t *
ecma_get_named_data_property (ecma_object_t *, ecma_string_t *);
void ecma_delete_property (ecma_object_t *object_p, ecma_property_value_t *prop_value_p);
uint32_t ecma_delete_array_properties (ecma_object_t *object_p, uint32_t new_length, uint32_t old_length);
extern void ecma_free_property (ecma_object_t *, ecma_string_t *, ecma_property_t *);
void ecma_named_data_property_assign_value (ecma_object_t *obj_p, ecma_property_value_t *prop_value_p,
ecma_value_t value);
extern void ecma_delete_property (ecma_object_t *, ecma_property_t *);
ecma_object_t *ecma_get_named_accessor_property_getter (const ecma_property_value_t *prop_value_p);
ecma_object_t *ecma_get_named_accessor_property_setter (const ecma_property_value_t *prop_value_p);
void ecma_set_named_accessor_property_getter (ecma_object_t *object_p, ecma_property_value_t *prop_value_p,
ecma_object_t *getter_p);
void ecma_set_named_accessor_property_setter (ecma_object_t *object_p, ecma_property_value_t *prop_value_p,
ecma_object_t *setter_p);
bool ecma_is_property_writable (ecma_property_t property);
void ecma_set_property_writable_attr (ecma_property_t *property_p, bool is_writable);
bool ecma_is_property_enumerable (ecma_property_t property);
void ecma_set_property_enumerable_attr (ecma_property_t *property_p, bool is_enumerable);
bool ecma_is_property_configurable (ecma_property_t property);
void ecma_set_property_configurable_attr (ecma_property_t *property_p, bool is_configurable);
extern ecma_value_t ecma_get_named_data_property_value (const ecma_property_t *);
extern void ecma_set_named_data_property_value (ecma_property_t *, ecma_value_t);
extern void ecma_named_data_property_assign_value (ecma_object_t *, ecma_property_t *, ecma_value_t);
#if ENABLED (JERRY_LCACHE)
bool ecma_is_property_lcached (ecma_property_t *property_p);
void ecma_set_property_lcached (ecma_property_t *property_p, bool is_lcached);
#endif /* ENABLED (JERRY_LCACHE) */
extern ecma_value_t ecma_get_internal_property_value (const ecma_property_t *);
extern void ecma_set_internal_property_value (ecma_property_t *, ecma_value_t);
ecma_property_descriptor_t ecma_make_empty_property_descriptor (void);
void ecma_free_property_descriptor (ecma_property_descriptor_t *prop_desc_p);
extern ecma_object_t *ecma_get_named_accessor_property_getter (const ecma_property_t *);
extern ecma_object_t *ecma_get_named_accessor_property_setter (const ecma_property_t *);
extern void ecma_set_named_accessor_property_getter (ecma_object_t *, ecma_property_t *, ecma_object_t *);
extern void ecma_set_named_accessor_property_setter (ecma_object_t *, ecma_property_t *, ecma_object_t *);
extern bool ecma_is_property_writable (ecma_property_t *);
extern void ecma_set_property_writable_attr (ecma_property_t *, bool);
extern bool ecma_is_property_enumerable (ecma_property_t *);
extern void ecma_set_property_enumerable_attr (ecma_property_t *, bool);
extern bool ecma_is_property_configurable (ecma_property_t *);
extern void ecma_set_property_configurable_attr (ecma_property_t *, bool);
ecma_value_t ecma_create_error_reference (ecma_value_t value, bool is_exception);
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);
extern bool ecma_is_property_lcached (ecma_property_t *);
extern void ecma_set_property_lcached (ecma_property_t *, bool);
void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p);
void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p);
#if (JERRY_STACK_LIMIT != 0)
uintptr_t ecma_get_current_stack_usage (void);
#endif /* (JERRY_STACK_LIMIT != 0) */
extern ecma_property_descriptor_t ecma_make_empty_property_descriptor (void);
extern void ecma_free_property_descriptor (ecma_property_descriptor_t *);
extern ecma_property_descriptor_t ecma_get_property_descriptor_from_property (ecma_property_t *);
extern ecma_property_t *ecma_get_next_property_pair (ecma_property_pair_t *);
extern void ecma_bytecode_ref (ecma_compiled_code_t *);
extern void ecma_bytecode_deref (ecma_compiled_code_t *);
/* ecma-helpers-external-pointers.c */
bool ecma_create_native_pointer_property (ecma_object_t *obj_p, void *native_p, void *info_p);
ecma_native_pointer_t *ecma_get_native_pointer_value (ecma_object_t *obj_p, void *info_p);
bool ecma_delete_native_pointer_property (ecma_object_t *obj_p, void *info_p);
extern bool
ecma_create_external_pointer_property (ecma_object_t *, ecma_internal_property_id_t, ecma_external_pointer_t);
extern bool
ecma_get_external_pointer_value (ecma_object_t *, ecma_internal_property_id_t, ecma_external_pointer_t *);
extern void
ecma_free_external_pointer_in_property (ecma_property_t *);
/* ecma-helpers-conversion.c */
ecma_number_t ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, lit_utf8_size_t str_size);
lit_utf8_size_t ecma_uint32_to_utf8_string (uint32_t value, lit_utf8_byte_t *out_buffer_p, lit_utf8_size_t buffer_size);
uint32_t ecma_number_to_uint32 (ecma_number_t num);
int32_t ecma_number_to_int32 (ecma_number_t num);
lit_utf8_size_t ecma_number_to_utf8_string (ecma_number_t num, lit_utf8_byte_t *buffer_p, lit_utf8_size_t buffer_size);
extern ecma_number_t ecma_utf8_string_to_number (const lit_utf8_byte_t *, lit_utf8_size_t);
extern lit_utf8_size_t ecma_uint32_to_utf8_string (uint32_t, lit_utf8_byte_t *, lit_utf8_size_t);
extern uint32_t ecma_number_to_uint32 (ecma_number_t);
extern int32_t ecma_number_to_int32 (ecma_number_t);
extern lit_utf8_size_t ecma_number_to_utf8_string (ecma_number_t, lit_utf8_byte_t *, lit_utf8_size_t);
/* ecma-helpers-errol.c */
lit_utf8_size_t ecma_errol0_dtoa (double val, lit_utf8_byte_t *buffer_p, int32_t *exp_p);
extern lit_utf8_size_t ecma_errol0_dtoa (double, lit_utf8_byte_t *, int32_t *);
/**
* @}
+8 -17
View File
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,10 @@
#include "ecma-gc.h"
#include "ecma-helpers.h"
#include "ecma-init-finalize.h"
#include "ecma-lcache.h"
#include "ecma-lex-env.h"
#include "ecma-literal-storage.h"
#include "jmem.h"
#include "jcontext.h"
#include "jmem-allocator.h"
/** \addtogroup ecma ECMA
* @{
@@ -35,21 +35,10 @@
void
ecma_init (void)
{
ecma_lcache_init ();
ecma_init_global_lex_env ();
#if ENABLED (JERRY_PROPRETY_HASHMAP)
JERRY_CONTEXT (ecma_prop_hashmap_alloc_state) = ECMA_PROP_HASHMAP_ALLOC_ON;
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_HIGH_PRESSURE_GC;
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
#if (JERRY_STACK_LIMIT != 0)
volatile int 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) */
jmem_register_free_unused_memory_callback (ecma_free_unused_memory);
} /* ecma_init */
/**
@@ -58,9 +47,11 @@ ecma_init (void)
void
ecma_finalize (void)
{
jmem_unregister_free_unused_memory_callback (ecma_free_unused_memory);
ecma_finalize_global_lex_env ();
ecma_finalize_builtins ();
ecma_gc_run ();
ecma_gc_run (JMEM_FREE_UNUSED_MEMORY_SEVERITY_LOW);
ecma_finalize_lit_storage ();
} /* ecma_finalize */
+3 -3
View File
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,8 +23,8 @@
* @{
*/
void ecma_init (void);
void ecma_finalize (void);
extern void ecma_init (void);
extern void ecma_finalize (void);
/**
* @}
+77 -62
View File
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,35 +27,39 @@
* @{
*/
#if ENABLED (JERRY_LCACHE)
#ifndef CONFIG_ECMA_LCACHE_DISABLE
/**
* Mask for hash bits
*/
#define ECMA_LCACHE_HASH_MASK (ECMA_LCACHE_HASH_ROWS_COUNT - 1)
/**
* Bitshift index for creating property identifier
*/
#define ECMA_LCACHE_HASH_ENTRY_ID_SHIFT (8 * sizeof (jmem_cpointer_t))
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
/**
* Create property identifier
* Initialize LCache
*/
#define ECMA_LCACHE_CREATE_ID(object_cp, name_cp) \
(((ecma_lcache_hash_entry_id_t) (object_cp) << ECMA_LCACHE_HASH_ENTRY_ID_SHIFT) | (name_cp))
void
ecma_lcache_init (void)
{
#ifndef CONFIG_ECMA_LCACHE_DISABLE
memset (JERRY_HASH_TABLE_CONTEXT (table), 0, sizeof (jerry_hash_table_t));
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
} /* ecma_lcache_init */
#ifndef CONFIG_ECMA_LCACHE_DISABLE
/**
* Invalidate specified LCache entry
*/
static inline void JERRY_ATTR_ALWAYS_INLINE
static inline void __attr_always_inline___
ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to invalidate */
{
JERRY_ASSERT (entry_p != NULL);
JERRY_ASSERT (entry_p->id != 0);
JERRY_ASSERT (entry_p->object_cp != ECMA_NULL_POINTER);
JERRY_ASSERT (entry_p->prop_name_cp != ECMA_NULL_POINTER);
JERRY_ASSERT (entry_p->prop_p != NULL);
entry_p->id = 0;
entry_p->object_cp = ECMA_NULL_POINTER;
ecma_set_property_lcached (entry_p->prop_p, false);
} /* ecma_lcache_invalidate_entry */
@@ -63,40 +68,42 @@ ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to i
*
* @return row index
*/
static inline size_t JERRY_ATTR_ALWAYS_INLINE
static inline size_t __attr_always_inline___
ecma_lcache_row_index (jmem_cpointer_t object_cp, /**< compressed pointer to object */
jmem_cpointer_t name_cp) /**< compressed pointer to property name */
const ecma_string_t *prop_name_p) /**< proeprty name */
{
/* Randomize the property name with the object pointer using a xor operation,
/* Randomize the hash of the property name with the object pointer using a xor operation,
* so properties of different objects with the same name can be cached effectively. */
return (size_t) ((name_cp ^ object_cp) & ECMA_LCACHE_HASH_MASK);
return (size_t) ((ecma_string_hash (prop_name_p) ^ object_cp) & ECMA_LCACHE_HASH_MASK);
} /* ecma_lcache_row_index */
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
/**
* Insert an entry into LCache
*/
void
ecma_lcache_insert (ecma_object_t *object_p, /**< object */
jmem_cpointer_t name_cp, /**< property name */
ecma_string_t *prop_name_p, /**< property name */
ecma_property_t *prop_p) /**< property */
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (prop_name_p != NULL);
JERRY_ASSERT (prop_p != NULL && !ecma_is_property_lcached (prop_p));
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
|| ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_INTERNAL);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
#ifndef CONFIG_ECMA_LCACHE_DISABLE
jmem_cpointer_t object_cp;
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
size_t row_index = ecma_lcache_row_index (object_cp, name_cp);
ecma_lcache_hash_entry_t *entries_p = JERRY_CONTEXT (lcache) [row_index];
size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p);
ecma_lcache_hash_entry_t *entries_p = JERRY_HASH_TABLE_CONTEXT (table)[row_index];
uint32_t entry_index;
int32_t entry_index;
for (entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++)
{
if (entries_p[entry_index].id == 0)
if (entries_p[entry_index].object_cp == ECMA_NULL_POINTER)
{
break;
}
@@ -112,14 +119,17 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */
{
entries_p[i] = entries_p[i - 1];
}
entry_index = 0;
}
ecma_lcache_hash_entry_t *entry_p = entries_p + entry_index;
ECMA_SET_NON_NULL_POINTER (entry_p->object_cp, object_p);
ECMA_SET_NON_NULL_POINTER (entry_p->prop_name_cp, prop_name_p);
entry_p->prop_p = prop_p;
entry_p->id = ECMA_LCACHE_CREATE_ID (object_cp, name_cp);
ecma_set_property_lcached (entry_p->prop_p, true);
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
} /* ecma_lcache_insert */
/**
@@ -128,46 +138,49 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */
* @return a pointer to an ecma_property_t if the lookup is successful
* NULL otherwise
*/
inline ecma_property_t * JERRY_ATTR_ALWAYS_INLINE
inline ecma_property_t * __attr_always_inline___
ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
const ecma_string_t *prop_name_p) /**< property's name */
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (prop_name_p != NULL);
#ifndef CONFIG_ECMA_LCACHE_DISABLE
jmem_cpointer_t object_cp;
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
ecma_property_t prop_name_type;
jmem_cpointer_t prop_name_cp;
if (ECMA_IS_DIRECT_STRING (prop_name_p))
{
prop_name_type = (ecma_property_t) ECMA_GET_DIRECT_STRING_TYPE (prop_name_p);
prop_name_cp = (jmem_cpointer_t) ECMA_GET_DIRECT_STRING_VALUE (prop_name_p);
}
else
{
prop_name_type = ECMA_DIRECT_STRING_PTR;
ECMA_SET_NON_NULL_POINTER (prop_name_cp, prop_name_p);
}
size_t row_index = ecma_lcache_row_index (object_cp, prop_name_cp);
ecma_lcache_hash_entry_t *entry_p = JERRY_CONTEXT (lcache) [row_index];
size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p);
ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index];
ecma_lcache_hash_entry_t *entry_end_p = entry_p + ECMA_LCACHE_HASH_ROW_LENGTH;
ecma_lcache_hash_entry_id_t id = ECMA_LCACHE_CREATE_ID (object_cp, prop_name_cp);
ecma_string_container_t prop_container = ECMA_STRING_GET_CONTAINER (prop_name_p);
while (entry_p < entry_end_p)
{
if (entry_p->id == id && ECMA_PROPERTY_GET_NAME_TYPE (*entry_p->prop_p) == prop_name_type)
if (entry_p->object_cp == object_cp)
{
JERRY_ASSERT (entry_p->prop_p != NULL && ecma_is_property_lcached (entry_p->prop_p));
return entry_p->prop_p;
ecma_string_t *entry_prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
entry_p->prop_name_cp);
JERRY_ASSERT ((prop_name_p->hash & ECMA_LCACHE_HASH_MASK) == (entry_prop_name_p->hash & ECMA_LCACHE_HASH_MASK));
if (prop_name_p == entry_prop_name_p
|| (prop_container > ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING
&& prop_container == ECMA_STRING_GET_CONTAINER (entry_prop_name_p)
&& prop_name_p->u.common_field == entry_prop_name_p->u.common_field))
{
ecma_property_t *prop_p = entry_p->prop_p;
JERRY_ASSERT (prop_p != NULL && ecma_is_property_lcached (prop_p));
return prop_p;
}
else
{
/* They can be equal, but generic string comparison is too costly. */
}
}
entry_p++;
}
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
return NULL;
} /* ecma_lcache_lookup */
@@ -177,38 +190,40 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
*/
void
ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */
jmem_cpointer_t name_cp, /**< property name */
ecma_string_t *prop_name_p, /**< property's name */
ecma_property_t *prop_p) /**< property */
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (prop_name_p != NULL);
JERRY_ASSERT (prop_p != NULL && ecma_is_property_lcached (prop_p));
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
|| ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_INTERNAL);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
|| ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
#ifndef CONFIG_ECMA_LCACHE_DISABLE
jmem_cpointer_t object_cp;
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
size_t row_index = ecma_lcache_row_index (object_cp, name_cp);
ecma_lcache_hash_entry_t *entry_p = JERRY_CONTEXT (lcache) [row_index];
size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p);
ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index];
while (true)
for (uint32_t entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++)
{
/* The property must be present. */
JERRY_ASSERT (entry_p - JERRY_CONTEXT (lcache) [row_index] < ECMA_LCACHE_HASH_ROW_LENGTH);
if (entry_p->id != 0 && entry_p->prop_p == prop_p)
if (entry_p->object_cp != ECMA_NULL_POINTER && entry_p->prop_p == prop_p)
{
JERRY_ASSERT (entry_p->id == ECMA_LCACHE_CREATE_ID (object_cp, name_cp));
JERRY_ASSERT (ECMA_GET_NON_NULL_POINTER (ecma_string_t,
entry_p->prop_name_cp) == prop_name_p);
JERRY_ASSERT (entry_p->object_cp == object_cp);
ecma_lcache_invalidate_entry (entry_p);
return;
}
entry_p++;
}
} /* ecma_lcache_invalidate */
#endif /* ENABLED (JERRY_LCACHE) */
/* The property must be present. */
JERRY_UNREACHABLE ();
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
} /* ecma_lcache_invalidate */
/**
* @}
+5 -8
View File
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,13 +23,10 @@
* @{
*/
#if ENABLED (JERRY_LCACHE)
void ecma_lcache_insert (ecma_object_t *object_p, jmem_cpointer_t name_cp, ecma_property_t *prop_p);
ecma_property_t *ecma_lcache_lookup (ecma_object_t *object_p, const ecma_string_t *prop_name_p);
void ecma_lcache_invalidate (ecma_object_t *object_p, jmem_cpointer_t name_cp, ecma_property_t *prop_p);
#endif /* ENABLED (JERRY_LCACHE) */
extern void ecma_lcache_init (void);
extern void ecma_lcache_insert (ecma_object_t *, ecma_string_t *, ecma_property_t *);
extern ecma_property_t *ecma_lcache_lookup (ecma_object_t *, const ecma_string_t *);
extern void ecma_lcache_invalidate (ecma_object_t *, ecma_string_t *, ecma_property_t *);
/**
* @}
+265 -250
View File
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +14,6 @@
* limitations under the License.
*/
#include "ecma-alloc.h"
#include "ecma-literal-storage.h"
#include "ecma-helpers.h"
#include "jcontext.h"
@@ -25,6 +25,9 @@
* @{
*/
JERRY_STATIC_ASSERT (sizeof (ecma_lit_storage_item_t) <= sizeof (uint64_t),
size_of_ecma_lit_storage_item_t_must_be_less_than_or_equal_to_8_bytes);
/**
* Free string list
*/
@@ -47,7 +50,7 @@ ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list
ecma_lit_storage_item_t *prev_item = string_list_p;
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
jmem_pools_free (prev_item, sizeof (ecma_lit_storage_item_t));
jmem_pools_free (prev_item);
}
} /* ecma_free_string_list */
@@ -57,9 +60,6 @@ ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list
void
ecma_finalize_lit_storage (void)
{
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
ecma_free_string_list (JERRY_CONTEXT (symbol_list_first_p));
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
ecma_free_string_list (JERRY_CONTEXT (string_list_first_p));
ecma_free_string_list (JERRY_CONTEXT (number_list_first_p));
} /* ecma_finalize_lit_storage */
@@ -69,17 +69,12 @@ ecma_finalize_lit_storage (void)
*
* @return ecma_string_t compressed pointer
*/
ecma_value_t
jmem_cpointer_t
ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string to be searched */
lit_utf8_size_t size) /**< size of the string */
{
ecma_string_t *string_p = ecma_new_ecma_string_from_utf8 (chars_p, size);
if (ECMA_IS_DIRECT_STRING (string_p))
{
return ecma_make_string_value (string_p);
}
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
jmem_cpointer_t *empty_cpointer_p = NULL;
@@ -103,7 +98,7 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
{
/* Return with string if found in the list. */
ecma_deref_ecma_string (string_p);
return ecma_make_string_value (value_p);
return string_list_p->values[i];
}
}
}
@@ -117,11 +112,10 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
if (empty_cpointer_p != NULL)
{
*empty_cpointer_p = result;
return ecma_make_string_value (string_p);
return result;
}
ecma_lit_storage_item_t *new_item_p;
new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (sizeof (ecma_lit_storage_item_t));
ecma_lit_storage_item_t *new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc ();
new_item_p->values[0] = result;
for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
@@ -132,7 +126,7 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (string_list_first_p));
JERRY_CONTEXT (string_list_first_p) = new_item_p;
return ecma_make_string_value (string_p);
return result;
} /* ecma_find_or_create_literal_string */
/**
@@ -140,18 +134,11 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
*
* @return ecma_string_t compressed pointer
*/
ecma_value_t
jmem_cpointer_t
ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be searched */
{
ecma_value_t num = ecma_make_number_value (number_arg);
if (ecma_is_value_integer_number (num))
{
return num;
}
JERRY_ASSERT (ecma_is_value_float_number (num));
ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p);
jmem_cpointer_t *empty_cpointer_p = NULL;
@@ -172,12 +159,22 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
number_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
JERRY_ASSERT (ecma_is_value_float_number (value_p->u.lit_number));
if (ecma_get_float_from_value (value_p->u.lit_number) == number_arg)
if (ecma_is_value_integer_number (num))
{
ecma_free_value (num);
return value_p->u.lit_number;
if (value_p->u.lit_number == num)
{
return number_list_p->values[i];
}
}
else
{
if (ecma_is_value_float_number (value_p->u.lit_number)
&& ecma_get_float_from_value (value_p->u.lit_number) == ecma_get_float_from_value (num))
{
ecma_free_value (num);
return number_list_p->values[i];
}
}
}
}
@@ -185,7 +182,7 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
}
ecma_string_t *string_p = ecma_alloc_string ();
ecma_string_t *string_p = (ecma_string_t *) jmem_pools_alloc ();
string_p->refs_and_container = ECMA_STRING_REF_ONE | ECMA_STRING_LITERAL_NUMBER;
string_p->u.lit_number = num;
@@ -195,11 +192,10 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
if (empty_cpointer_p != NULL)
{
*empty_cpointer_p = result;
return num;
return result;
}
ecma_lit_storage_item_t *new_item_p;
new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (sizeof (ecma_lit_storage_item_t));
ecma_lit_storage_item_t *new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc ();
new_item_p->values[0] = result;
for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
@@ -210,289 +206,308 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (number_list_first_p));
JERRY_CONTEXT (number_list_first_p) = new_item_p;
return num;
return result;
} /* ecma_find_or_create_literal_number */
/**
* Log2 of snapshot literal alignment.
*/
#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG 1
#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG 2
/**
* Snapshot literal alignment.
*/
#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT (1u << JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG)
/**
* Literal offset shift.
*/
#define JERRY_SNAPSHOT_LITERAL_SHIFT (ECMA_VALUE_SHIFT + 1)
/**
* Literal value is number.
*/
#define JERRY_SNAPSHOT_LITERAL_IS_NUMBER (1u << ECMA_VALUE_SHIFT)
#if ENABLED (JERRY_SNAPSHOT_SAVE)
/**
* Append the value at the end of the appropriate list if it is not present there.
*/
void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appended */
ecma_collection_header_t *lit_pool_p) /**< list of known values */
{
/* Unlike direct numbers, direct strings are converted to character literals. */
if (!ecma_is_value_string (value) && !ecma_is_value_float_number (value))
{
return;
}
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
while (iterator_p != NULL)
{
/* Strings / numbers are direct strings or stored in the literal storage.
* Therefore direct comparison is enough to find the same strings / numbers. */
if (*iterator_p == value)
{
return;
}
iterator_p = ecma_collection_iterator_next (iterator_p);
}
ecma_append_to_values_collection (lit_pool_p, value, ECMA_COLLECTION_NO_COPY);
} /* ecma_save_literals_append_value */
/**
* Add names from a byte-code data to a list.
*/
void
ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_p, /**< byte-code data */
ecma_collection_header_t *lit_pool_p) /**< list of known values */
{
ecma_value_t *literal_p;
uint32_t argument_end = 0;
uint32_t register_end;
uint32_t const_literal_end;
uint32_t literal_end;
JERRY_ASSERT (compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) compiled_code_p;
uint8_t *byte_p = (uint8_t *) compiled_code_p;
literal_p = (ecma_value_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
register_end = args_p->register_end;
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))
{
argument_end = args_p->argument_end;
}
}
else
{
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) compiled_code_p;
uint8_t *byte_p = (uint8_t *) compiled_code_p;
literal_p = (ecma_value_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
register_end = args_p->register_end;
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))
{
argument_end = args_p->argument_end;
}
}
for (uint32_t i = 0; i < argument_end; i++)
{
ecma_save_literals_append_value (literal_p[i], lit_pool_p);
}
for (uint32_t i = 0; i < const_literal_end; i++)
{
ecma_save_literals_append_value (literal_p[i], lit_pool_p);
}
for (uint32_t i = const_literal_end; i < literal_end; i++)
{
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
literal_p[i]);
if ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
&& bytecode_p != compiled_code_p)
{
ecma_save_literals_add_compiled_code (bytecode_p, lit_pool_p);
}
}
if (argument_end != 0)
{
uint8_t *byte_p = (uint8_t *) compiled_code_p;
byte_p += ((size_t) compiled_code_p->size) << JMEM_ALIGNMENT_LOG;
literal_p = ((ecma_value_t *) byte_p) - argument_end;
for (uint32_t i = 0; i < argument_end; i++)
{
ecma_save_literals_append_value (literal_p[i], lit_pool_p);
}
}
} /* ecma_save_literals_add_compiled_code */
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
/**
* Save literals to specified snapshot buffer.
*
* Note:
* Frees 'lit_pool_p' regardless of success.
*
* @return true - if save was performed successfully (i.e. buffer size is sufficient),
* false - otherwise
* @return true, if save was performed successfully (i.e. buffer size is sufficient),
* false - otherwise.
*/
bool
ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list of known values */
uint32_t *buffer_p, /**< [out] output snapshot buffer */
ecma_save_literals_for_snapshot (uint8_t *buffer_p, /**< [out] output snapshot buffer */
size_t buffer_size, /**< size of the buffer */
size_t *in_out_buffer_offset_p, /**< [in,out] write position in the buffer */
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal identifiers
* to the literal offsets
* in snapshot */
uint32_t *out_map_len_p) /**< [out] number of literals */
uint32_t *out_map_len_p, /**< [out] number of literals */
uint32_t *out_lit_table_size_p) /**< [out] number of bytes, saved to snapshot buffer */
{
if (lit_pool_p->item_count == 0)
/* Count literals and literal space. */
uint32_t string_count = 0;
uint32_t number_count = 0;
uint32_t lit_table_size = 2 * sizeof (uint32_t);
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
while (string_list_p != NULL)
{
*out_map_p = NULL;
*out_map_len_p = 0;
}
uint32_t lit_table_size = 0;
size_t max_lit_table_size = buffer_size - *in_out_buffer_offset_p;
if (max_lit_table_size > (UINT32_MAX >> JERRY_SNAPSHOT_LITERAL_SHIFT))
{
max_lit_table_size = (UINT32_MAX >> JERRY_SNAPSHOT_LITERAL_SHIFT);
}
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
/* Compute the size of the literal pool. */
while (iterator_p != NULL)
{
if (ecma_is_value_float_number (*iterator_p))
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
lit_table_size += (uint32_t) sizeof (ecma_number_t);
}
else
{
ecma_string_t *string_p = ecma_get_string_from_value (*iterator_p);
if (string_list_p->values[i] != JMEM_CP_NULL)
{
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p),
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p),
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
string_count++;
}
}
/* Check whether enough space is available and the maximum size is not reached. */
if (lit_table_size > max_lit_table_size)
{
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
return false;
}
iterator_p = ecma_collection_iterator_next (iterator_p);
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
}
ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p);
while (number_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (number_list_p->values[i] != JMEM_CP_NULL)
{
lit_table_size += (uint32_t) sizeof (ecma_number_t);
number_count++;
}
}
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
}
/* Check whether enough space is available. */
if (*in_out_buffer_offset_p + lit_table_size > buffer_size)
{
return false;
}
/* Check whether the maximum literal table size is reached. */
if ((lit_table_size >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG) > UINT16_MAX)
{
return false;
}
uint32_t total_count = string_count + number_count;
lit_mem_to_snapshot_id_map_entry_t *map_p;
ecma_length_t total_count = lit_pool_p->item_count;
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
/* Set return values (no error is possible from here). */
JERRY_ASSERT ((*in_out_buffer_offset_p % sizeof (uint32_t)) == 0);
uint8_t *destination_p = (uint8_t *) (buffer_p + (*in_out_buffer_offset_p / sizeof (uint32_t)));
uint32_t literal_offset = 0;
buffer_p += *in_out_buffer_offset_p;
*in_out_buffer_offset_p += lit_table_size;
*out_map_p = map_p;
*out_map_len_p = total_count;
*out_lit_table_size_p = lit_table_size;
iterator_p = ecma_collection_iterator_init (lit_pool_p);
/* Write data into the buffer. */
/* Generate literal pool data. */
while (iterator_p != NULL)
/* The zero value is reserved for NULL (no literal)
* constant so the first literal must have offset one. */
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
((uint32_t *) buffer_p)[0] = string_count;
((uint32_t *) buffer_p)[1] = number_count;
buffer_p += 2 * sizeof (uint32_t);
string_list_p = JERRY_CONTEXT (string_list_first_p);
while (string_list_p != NULL)
{
map_p->literal_id = *iterator_p;
map_p->literal_offset = (literal_offset << JERRY_SNAPSHOT_LITERAL_SHIFT) | ECMA_TYPE_SNAPSHOT_OFFSET;
ecma_length_t length;
if (ecma_is_value_float_number (*iterator_p))
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
map_p->literal_offset |= JERRY_SNAPSHOT_LITERAL_IS_NUMBER;
if (string_list_p->values[i] != JMEM_CP_NULL)
{
map_p->literal_id = string_list_p->values[i];
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
ecma_number_t num = ecma_get_float_from_value (*iterator_p);
memcpy (destination_p, &num, sizeof (ecma_number_t));
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
length = JERRY_ALIGNUP (sizeof (ecma_number_t), JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
}
else
{
ecma_string_t *string_p = ecma_get_string_from_value (*iterator_p);
length = ecma_string_get_size (string_p);
ecma_length_t length = ecma_string_get_size (string_p);
*(uint16_t *) destination_p = (uint16_t) length;
*((uint16_t *) buffer_p) = (uint16_t) length;
ecma_string_to_utf8_bytes (string_p, buffer_p + sizeof (uint16_t), length);
ecma_string_to_utf8_bytes (string_p, destination_p + sizeof (uint16_t), length);
length = JERRY_ALIGNUP (sizeof (uint16_t) + length,
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
length = JERRY_ALIGNUP (sizeof (uint16_t) + length, JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
buffer_p += length;
literal_offset += length;
}
}
JERRY_ASSERT ((length % sizeof (uint16_t)) == 0);
destination_p += length;
literal_offset += length;
iterator_p = ecma_collection_iterator_next (iterator_p);
map_p++;
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
}
number_list_p = JERRY_CONTEXT (number_list_first_p);
while (number_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (number_list_p->values[i] != JMEM_CP_NULL)
{
map_p->literal_id = number_list_p->values[i];
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
number_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
ecma_number_t num = ecma_get_number_from_value (value_p->u.lit_number);
memcpy (buffer_p, &num, sizeof (ecma_number_t));
ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t),
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
buffer_p += length;
literal_offset += length;
}
}
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
}
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
return true;
} /* ecma_save_literals_for_snapshot */
#endif /* ENABLED (JERRY_SNAPSHOT_SAVE) */
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
#if ENABLED (JERRY_SNAPSHOT_EXEC) || ENABLED (JERRY_SNAPSHOT_SAVE)
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
/**
* Get the compressed pointer of a given literal.
* Helper function for ecma_load_literals_from_snapshot.
*
* @return literal compressed pointer
* Note: always inline because it is used only once.
*
* @return true, if load was performed successfully
* false - otherwise (i.e. buffer length is incorrect).
*/
ecma_value_t
ecma_snapshot_get_literal (const uint8_t *literal_base_p, /**< literal start */
ecma_value_t literal_value) /**< string / number offset */
static inline bool __attr_always_inline___
ecma_load_literals_from_buffer (const uint8_t *buffer_p, /**< buffer with literal table in snapshot */
uint32_t lit_table_size, /**< size of literal table in snapshot */
lit_mem_to_snapshot_id_map_entry_t *map_p, /**< literal map */
uint32_t string_count, /**< number of strings */
uint32_t number_count) /**< number of numbers */
{
JERRY_ASSERT ((literal_value & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET);
/* The zero value is reserved for NULL (no literal)
* constant so the first literal must have offset one. */
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
const uint8_t *literal_p = literal_base_p + (literal_value >> JERRY_SNAPSHOT_LITERAL_SHIFT);
if (literal_value & JERRY_SNAPSHOT_LITERAL_IS_NUMBER)
/* Load strings first. */
while (string_count > 0)
{
ecma_number_t num;
memcpy (&num, literal_p, sizeof (ecma_number_t));
return ecma_find_or_create_literal_number (num);
if (lit_table_size < literal_offset + sizeof (uint32_t))
{
/* Buffer is not sufficent. */
return false;
}
lit_utf8_size_t length = *((uint16_t *) buffer_p);
lit_utf8_size_t aligned_length = JERRY_ALIGNUP (sizeof (uint16_t) + length,
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
if (lit_table_size < literal_offset + aligned_length)
{
/* Buffer is not sufficent. */
return false;
}
map_p->literal_id = ecma_find_or_create_literal_string (buffer_p + sizeof (uint16_t), length);
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
buffer_p += aligned_length;
literal_offset += aligned_length;
string_count--;
}
uint16_t length = *(const uint16_t *) literal_p;
/* Load numbers. */
while (number_count > 0)
{
if (lit_table_size < literal_offset + sizeof (ecma_number_t))
{
/* Buffer is not sufficent. */
return false;
}
return ecma_find_or_create_literal_string (literal_p + sizeof (uint16_t), length);
} /* ecma_snapshot_get_literal */
ecma_number_t num;
memcpy (&num, buffer_p, sizeof (ecma_number_t));
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) || ENABLED (JERRY_SNAPSHOT_SAVE) */
map_p->literal_id = ecma_find_or_create_literal_number (num);
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t),
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
buffer_p += length;
literal_offset += length;
number_count--;
}
return (lit_table_size == (literal_offset + 2 * sizeof (uint32_t) - JERRY_SNAPSHOT_LITERAL_ALIGNMENT));
} /* ecma_load_literals_from_buffer */
/**
* Load literals from snapshot.
*
* @return true, if load was performed successfully (i.e. literals saved in the snapshot are consistent),
* false - otherwise (i.e. snapshot is incorrect).
*/
bool
ecma_load_literals_from_snapshot (const uint8_t *buffer_p, /**< buffer with literal table in snapshot */
uint32_t lit_table_size, /**< size of literal table in snapshot */
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal offsets
* in snapshot to identifiers
* of loaded literals in literal
* storage */
uint32_t *out_map_len_p) /**< [out] literals number */
{
*out_map_p = NULL;
if (lit_table_size < 2 * sizeof (uint32_t))
{
/* Buffer is not sufficent. */
return false;
}
uint32_t string_count = ((uint32_t *) buffer_p)[0];
uint32_t number_count = ((uint32_t *) buffer_p)[1];
buffer_p += 2 * sizeof (uint32_t);
uint32_t total_count = string_count + number_count;
lit_mem_to_snapshot_id_map_entry_t *map_p;
*out_map_len_p = total_count;
if (total_count == 0)
{
return true;
}
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
*out_map_p = map_p;
if (ecma_load_literals_from_buffer (buffer_p, lit_table_size, map_p, string_count, number_count))
{
return true;
}
jmem_heap_free_block (map_p, total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
*out_map_p = NULL;
return false;
} /* ecma_load_literals_from_snapshot */
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
/**
* @}
+18 -21
View File
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +18,7 @@
#define ECMA_LIT_STORAGE_H
#include "ecma-globals.h"
#include "jmem.h"
#include "jmem-allocator.h"
#include "lit-globals.h"
/** \addtogroup ecma ECMA
@@ -27,35 +28,31 @@
* @{
*/
#if ENABLED (JERRY_SNAPSHOT_SAVE)
/**
* Snapshot literal - offset map
*/
typedef struct
{
ecma_value_t literal_id; /**< literal id */
ecma_value_t literal_offset; /**< literal offset */
jmem_cpointer_t literal_id; /**< literal id */
jmem_cpointer_t literal_offset; /**< literal offset */
} lit_mem_to_snapshot_id_map_entry_t;
#endif /* ENABLED (JERRY_SNAPSHOT_SAVE) */
void ecma_finalize_lit_storage (void);
extern void ecma_finalize_lit_storage (void);
ecma_value_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, lit_utf8_size_t size);
ecma_value_t ecma_find_or_create_literal_number (ecma_number_t number_arg);
extern jmem_cpointer_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *, lit_utf8_size_t);
extern jmem_cpointer_t ecma_find_or_create_literal_number (ecma_number_t);
#if ENABLED (JERRY_SNAPSHOT_SAVE)
void ecma_save_literals_append_value (ecma_value_t value, ecma_collection_header_t *lit_pool_p);
void ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_p,
ecma_collection_header_t *lit_pool_p);
bool ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, uint32_t *buffer_p, size_t buffer_size,
size_t *in_out_buffer_offset_p, lit_mem_to_snapshot_id_map_entry_t **out_map_p,
uint32_t *out_map_len_p);
#endif /* ENABLED (JERRY_SNAPSHOT_SAVE) */
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
extern bool
ecma_save_literals_for_snapshot (uint8_t *, size_t, size_t *,
lit_mem_to_snapshot_id_map_entry_t **, uint32_t *, uint32_t *);
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
#if ENABLED (JERRY_SNAPSHOT_EXEC) || ENABLED (JERRY_SNAPSHOT_SAVE)
ecma_value_t
ecma_snapshot_get_literal (const uint8_t *literal_base_p, ecma_value_t literal_value);
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) || ENABLED (JERRY_SNAPSHOT_SAVE) */
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
extern bool
ecma_load_literals_from_snapshot (const uint8_t *, uint32_t,
lit_mem_to_snapshot_id_map_entry_t **, uint32_t *);
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
/**
* @}
-922
View File
@@ -1,922 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "jcontext.h"
#include "jerryscript.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-lex-env.h"
#include "ecma-module.h"
#include "ecma-objects.h"
#include "lit-char-helpers.h"
#include "vm.h"
#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
/**
* Takes a ModuleSpecifier and applies path normalization to it.
* It's not checked if the ModuleSpecifier is a valid path or not.
* Note: See 15.2.1.17
*
* @return pointer to ecma_string_t containing the normalized and zero terminated path
*/
ecma_string_t *
ecma_module_create_normalized_path (const uint8_t *char_p, /**< module specifier */
prop_length_t size) /**< size of module specifier */
{
JERRY_ASSERT (size > 0);
ecma_string_t *ret_p = NULL;
/* The module specifier is cesu8 encoded, we need to convert is to utf8, and zero terminate it,
* so that OS level functions can handle it. */
lit_utf8_byte_t *path_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (size + 1u);
lit_utf8_size_t utf8_size;
utf8_size = lit_convert_cesu8_string_to_utf8_string (char_p,
size,
path_p,
size);
path_p[utf8_size] = LIT_CHAR_NULL;
lit_utf8_byte_t *module_path_p = NULL;
lit_utf8_size_t module_path_size = 0;
/* Check if we have a current module, and use its path as the base path. */
JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p) != NULL);
if (JERRY_CONTEXT (module_top_context_p)->module_p != NULL)
{
JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p)->module_p->path_p != NULL);
module_path_size = ecma_string_get_size (JERRY_CONTEXT (module_top_context_p)->module_p->path_p);
module_path_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (module_path_size + 1);
lit_utf8_size_t module_utf8_size;
module_utf8_size = ecma_string_copy_to_utf8_buffer (JERRY_CONTEXT (module_top_context_p)->module_p->path_p,
module_path_p,
module_path_size);
module_path_p[module_utf8_size] = LIT_CHAR_NULL;
}
lit_utf8_byte_t *normalized_out_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (ECMA_MODULE_MAX_PATH);
size_t normalized_size = jerry_port_normalize_path ((const char *) path_p,
(char *) normalized_out_p,
ECMA_MODULE_MAX_PATH,
(char *) module_path_p);
if (normalized_size > 0)
{
/* Convert the normalized path to cesu8. */
ret_p = ecma_new_ecma_string_from_utf8_converted_to_cesu8 (normalized_out_p, (lit_utf8_size_t) (normalized_size));
}
jmem_heap_free_block (path_p, size + 1u);
jmem_heap_free_block (normalized_out_p, ECMA_MODULE_MAX_PATH);
if (module_path_p != NULL)
{
jmem_heap_free_block (module_path_p, module_path_size + 1);
}
return ret_p;
} /* ecma_module_create_normalized_path */
/**
* Checks if we already have a module request in the module list.
*
* @return pointer to found or newly created module structure
*/
ecma_module_t *
ecma_module_find_or_create_module (ecma_string_t * const path_p) /**< module path */
{
ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
while (current_p != NULL)
{
if (ecma_compare_ecma_strings (path_p, current_p->path_p))
{
return current_p;
}
current_p = current_p->next_p;
}
current_p = (ecma_module_t *) jmem_heap_alloc_block (sizeof (ecma_module_t));
memset (current_p, 0, sizeof (ecma_module_t));
ecma_ref_ecma_string (path_p);
current_p->path_p = path_p;
current_p->next_p = JERRY_CONTEXT (ecma_modules_p);
JERRY_CONTEXT (ecma_modules_p) = current_p;
return current_p;
} /* ecma_module_find_or_create_module */
/**
* Creates a module context.
*
* @return pointer to created module context
*/
static ecma_module_context_t *
ecma_module_create_module_context (void)
{
ecma_module_context_t *context_p = (ecma_module_context_t *) jmem_heap_alloc_block (sizeof (ecma_module_context_t));
memset (context_p, 0, sizeof (ecma_module_context_t));
return context_p;
} /* ecma_module_create_module_context */
/**
* Inserts a {module, export_name} record into a resolve set.
* Note: See 15.2.1.16.3 - resolveSet and exportStarSet
*
* @return true - if the set already contains the record
* false - otherwise
*/
bool
ecma_module_resolve_set_insert (ecma_module_resolve_set_t **set_p, /**< [in, out] resolve set */
ecma_module_t * const module_p, /**< module */
ecma_string_t * const export_name_p) /**< export name */
{
JERRY_ASSERT (set_p != NULL);
ecma_module_resolve_set_t *current_p = *set_p;
while (current_p != NULL)
{
if (current_p->record.module_p == module_p
&& ecma_compare_ecma_strings (current_p->record.name_p, export_name_p))
{
return false;
}
current_p = current_p->next_p;
}
ecma_module_resolve_set_t *new_p;
new_p = (ecma_module_resolve_set_t *) jmem_heap_alloc_block (sizeof (ecma_module_resolve_set_t));
new_p->next_p = *set_p;
new_p->record.module_p = module_p;
ecma_ref_ecma_string (export_name_p);
new_p->record.name_p = export_name_p;
*set_p = new_p;
return true;
} /* ecma_module_resolve_set_insert */
/**
* Cleans up contents of a resolve set.
*/
void
ecma_module_resolve_set_cleanup (ecma_module_resolve_set_t *set_p) /**< resolve set */
{
while (set_p != NULL)
{
ecma_module_resolve_set_t *next_p = set_p->next_p;
ecma_deref_ecma_string (set_p->record.name_p);
jmem_heap_free_block (set_p, sizeof (ecma_module_resolve_set_t));
set_p = next_p;
}
} /* ecma_module_resolve_set_cleanup */
/**
* Pushes a new resolve frame on top of a resolve stack and initializes it
* to begin resolving the specified exported name in the base module.
*/
void
ecma_module_resolve_stack_push (ecma_module_resolve_stack_t **stack_p, /**< [in, out] resolve stack */
ecma_module_t * const module_p, /**< base module */
ecma_string_t * const export_name_p) /**< exported name */
{
JERRY_ASSERT (stack_p != NULL);
ecma_module_resolve_stack_t *new_frame_p;
new_frame_p = (ecma_module_resolve_stack_t *) jmem_heap_alloc_block (sizeof (ecma_module_resolve_stack_t));
ecma_ref_ecma_string (export_name_p);
new_frame_p->export_name_p = export_name_p;
new_frame_p->module_p = module_p;
new_frame_p->resolving = false;
new_frame_p->next_p = *stack_p;
*stack_p = new_frame_p;
} /* ecma_module_resolve_stack_push */
/**
* Pops the topmost frame from a resolve stack.
*/
void
ecma_module_resolve_stack_pop (ecma_module_resolve_stack_t **stack_p) /**< [in, out] resolve stack */
{
JERRY_ASSERT (stack_p != NULL);
ecma_module_resolve_stack_t *current_p = *stack_p;
if (current_p != NULL)
{
*stack_p = current_p->next_p;
ecma_deref_ecma_string (current_p->export_name_p);
jmem_heap_free_block (current_p, sizeof (ecma_module_resolve_stack_t));
}
} /* ecma_module_resolve_stack_pop */
/**
* Resolves which module satisfies an export based from a specific module in the import tree.
* If no error occurs, out_record_p will contain a {module, local_name} record, which satisfies
* the export, or {NULL, NULL} if the export is ambiguous.
* Note: See 15.2.1.16.3
*
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
static ecma_value_t
ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
ecma_string_t * const export_name_p, /**< export name */
ecma_module_record_t *out_record_p) /**< [out] found module record */
{
ecma_module_resolve_set_t *resolve_set_p = NULL;
ecma_module_resolve_stack_t *stack_p = NULL;
bool found = false;
ecma_module_record_t found_record = { NULL, NULL };
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_module_resolve_stack_push (&stack_p, module_p, export_name_p);
while (stack_p != NULL)
{
ecma_module_resolve_stack_t *current_frame_p = stack_p;
ecma_module_t *current_module_p = current_frame_p->module_p;
JERRY_ASSERT (current_module_p->state >= ECMA_MODULE_STATE_PARSED);
ecma_module_context_t *context_p = current_module_p->context_p;
ecma_string_t *current_export_name_p = current_frame_p->export_name_p;
if (!current_frame_p->resolving)
{
current_frame_p->resolving = true;
/* 15.2.1.16.3 / 2-3 */
if (!ecma_module_resolve_set_insert (&resolve_set_p, current_module_p, current_export_name_p))
{
/* This is a circular import request. */
ecma_module_resolve_stack_pop (&stack_p);
continue;
}
if (context_p->local_exports_p != NULL)
{
/* 15.2.1.16.3 / 4 */
JERRY_ASSERT (context_p->local_exports_p->next_p == NULL);
ecma_module_names_t *export_names_p = context_p->local_exports_p->module_names_p;
while (export_names_p != NULL)
{
if (ecma_compare_ecma_strings (current_export_name_p, export_names_p->imex_name_p))
{
if (found)
{
/* This is an ambigous export. */
found_record.module_p = NULL;
found_record.name_p = NULL;
break;
}
/* The current module provides a direct binding for this export. */
found = true;
found_record.module_p = current_module_p;
found_record.name_p = export_names_p->local_name_p;
break;
}
export_names_p = export_names_p->next_p;
}
}
if (found)
{
/* We found a resolution for the current frame, return to the previous. */
ecma_module_resolve_stack_pop (&stack_p);
continue;
}
/* 15.2.1.16.3 / 5 */
ecma_module_node_t *indirect_export_p = context_p->indirect_exports_p;
while (indirect_export_p != NULL)
{
ecma_module_names_t *export_names_p = indirect_export_p->module_names_p;
while (export_names_p != NULL)
{
if (ecma_compare_ecma_strings (current_export_name_p, export_names_p->imex_name_p))
{
/* 5.2.1.16.3 / 5.a.iv */
ecma_module_resolve_stack_push (&stack_p,
indirect_export_p->module_request_p,
export_names_p->local_name_p);
}
export_names_p = export_names_p->next_p;
}
indirect_export_p = indirect_export_p->next_p;
}
/* We need to check whether the newly pushed indirect exports resolve to anything.
* Keep current frame in the stack, and continue from the topmost frame. */
continue;
} /* if (!current_frame_p->resolving) */
/* By the time we return to the current frame, the indirect exports will have finished resolving. */
if (found)
{
/* We found at least one export that satisfies the current request.
* Pop current frame, and return to the previous. */
ecma_module_resolve_stack_pop (&stack_p);
continue;
}
/* 15.2.1.16.3 / 6 */
if (ecma_compare_ecma_string_to_magic_id (current_export_name_p, LIT_MAGIC_STRING_DEFAULT))
{
ret_value = ecma_raise_syntax_error (ECMA_ERR_MSG ("No explicitly defined default export in module."));
break;
}
/* 15.2.1.16.3 / 7-8 */
if (!ecma_module_resolve_set_insert (&resolve_set_p,
current_module_p,
ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR)))
{
/* This is a circular import request. */
ecma_module_resolve_stack_pop (&stack_p);
continue;
}
/* Pop the current frame, we have nothing else to do here after the star export resolutions are queued. */
ecma_module_resolve_stack_pop (&stack_p);
/* 15.2.1.16.3 / 10 */
ecma_module_node_t *star_export_p = context_p->star_exports_p;
while (star_export_p != NULL)
{
JERRY_ASSERT (star_export_p->module_names_p == NULL);
/* 15.2.1.16.3 / 10.c */
ecma_module_resolve_stack_push (&stack_p, star_export_p->module_request_p, export_name_p);
star_export_p = star_export_p->next_p;
}
}
/* Clean up. */
ecma_module_resolve_set_cleanup (resolve_set_p);
while (stack_p)
{
ecma_module_resolve_stack_pop (&stack_p);
}
if (ECMA_IS_VALUE_ERROR (ret_value))
{
/* No default export was found */
return ret_value;
}
if (found)
{
*out_record_p = found_record;
}
else
{
ret_value = ecma_raise_syntax_error (ECMA_ERR_MSG ("Unexported or circular import request."));
}
return ret_value;
} /* ecma_module_resolve_export */
/**
* Resolves an export and adds it to the modules namespace object, if the export name is not yet handled.
* Note: See 15.2.1.16.2 and 15.2.1.18
*
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
static ecma_value_t
ecma_module_namespace_object_add_export_if_needed (ecma_module_t *module_p, /**< module */
ecma_string_t *export_name_p) /**< export name */
{
JERRY_ASSERT (module_p->namespace_object_p != NULL);
ecma_value_t result = ECMA_VALUE_EMPTY;
if (ecma_find_named_property (module_p->namespace_object_p, export_name_p) != NULL)
{
/* This export name has already been handled. */
return result;
}
ecma_module_record_t record;
result = ecma_module_resolve_export (module_p, export_name_p, &record);
if (ECMA_IS_VALUE_ERROR (result))
{
return result;
}
if (record.module_p == NULL)
{
/* 15.2.1.18 / 3.d.iv Skip ambiguous names. */
return result;
}
ecma_object_t *ref_base_lex_env_p;
ecma_value_t prop_value = ecma_op_get_value_lex_env_base (record.module_p->scope_p,
&ref_base_lex_env_p,
record.name_p);
ecma_property_t *new_property_p;
ecma_create_named_data_property (module_p->namespace_object_p,
export_name_p,
ECMA_PROPERTY_FIXED,
&new_property_p);
ecma_named_data_property_assign_value (module_p->namespace_object_p,
ECMA_PROPERTY_VALUE_PTR (new_property_p),
prop_value);
ecma_free_value (prop_value);
return result;
} /* ecma_module_namespace_object_add_export_if_needed */
/**
* Creates a namespace object for a module.
* Note: See 15.2.1.18
*
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
static ecma_value_t
ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
{
ecma_value_t result = ECMA_VALUE_EMPTY;
if (module_p->namespace_object_p != NULL)
{
return result;
}
JERRY_ASSERT (module_p->state == ECMA_MODULE_STATE_EVALUATED);
ecma_module_resolve_set_t *resolve_set_p = NULL;
ecma_module_resolve_stack_t *stack_p = NULL;
module_p->namespace_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE),
0,
ECMA_OBJECT_TYPE_GENERAL);
ecma_module_resolve_stack_push (&stack_p, module_p, ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR));
while (stack_p != NULL)
{
ecma_module_resolve_stack_t *current_frame_p = stack_p;
ecma_module_t *current_module_p = current_frame_p->module_p;
ecma_module_context_t *context_p = current_module_p->context_p;
ecma_module_resolve_stack_pop (&stack_p);
/* 15.2.1.16.2 / 2-3 */
if (!ecma_module_resolve_set_insert (&resolve_set_p,
current_module_p,
ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR)))
{
/* Circular import. */
continue;
}
if (context_p->local_exports_p != NULL)
{
/* 15.2.1.16.2 / 5 */
JERRY_ASSERT (context_p->local_exports_p->next_p == NULL);
ecma_module_names_t *export_names_p = context_p->local_exports_p->module_names_p;
while (export_names_p != NULL && ecma_is_value_empty (result))
{
result = ecma_module_namespace_object_add_export_if_needed (module_p,
export_names_p->imex_name_p);
export_names_p = export_names_p->next_p;
}
}
/* 15.2.1.16.2 / 6 */
ecma_module_node_t *indirect_export_p = context_p->indirect_exports_p;
while (indirect_export_p != NULL && ecma_is_value_empty (result))
{
ecma_module_names_t *export_names_p = indirect_export_p->module_names_p;
while (export_names_p != NULL && ecma_is_value_empty (result))
{
result = ecma_module_namespace_object_add_export_if_needed (module_p,
export_names_p->imex_name_p);
export_names_p = export_names_p->next_p;
}
indirect_export_p = indirect_export_p->next_p;
}
/* 15.2.1.16.2 / 7 */
ecma_module_node_t *star_export_p = context_p->star_exports_p;
while (star_export_p != NULL && ecma_is_value_empty (result))
{
JERRY_ASSERT (star_export_p->module_names_p == NULL);
/* 15.2.1.16.3/10.c */
ecma_module_resolve_stack_push (&stack_p,
star_export_p->module_request_p,
ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR));
star_export_p = star_export_p->next_p;
}
}
/* Clean up. */
ecma_module_resolve_set_cleanup (resolve_set_p);
while (stack_p)
{
ecma_module_resolve_stack_pop (&stack_p);
}
return result;
} /* ecma_module_create_namespace_object */
/**
* Evaluates an EcmaScript module.
*
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
static ecma_value_t
ecma_module_evaluate (ecma_module_t *module_p) /**< module */
{
JERRY_ASSERT (module_p->state >= ECMA_MODULE_STATE_PARSED);
if (module_p->state >= ECMA_MODULE_STATE_EVALUATING)
{
return ECMA_VALUE_EMPTY;
}
module_p->state = ECMA_MODULE_STATE_EVALUATING;
module_p->scope_p = ecma_create_decl_lex_env (ecma_get_global_environment ());
module_p->context_p->parent_p = JERRY_CONTEXT (module_top_context_p);
JERRY_CONTEXT (module_top_context_p) = module_p->context_p;
ecma_value_t ret_value;
ret_value = vm_run_module (module_p->compiled_code_p,
module_p->scope_p);
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
jerry_release_value (ret_value);
ret_value = ECMA_VALUE_EMPTY;
}
JERRY_CONTEXT (module_top_context_p) = module_p->context_p->parent_p;
ecma_bytecode_deref (module_p->compiled_code_p);
module_p->state = ECMA_MODULE_STATE_EVALUATED;
return ret_value;
} /* ecma_module_evaluate */
/**
* Connects imported values to the current context.
*
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
ecma_value_t
ecma_module_connect_imports (void)
{
ecma_module_context_t *current_context_p = JERRY_CONTEXT (module_top_context_p);
ecma_object_t *local_env_p = current_context_p->module_p->scope_p;
JERRY_ASSERT (ecma_is_lexical_environment (local_env_p));
ecma_module_node_t *import_node_p = current_context_p->imports_p;
while (import_node_p != NULL)
{
ecma_value_t result = ecma_module_evaluate (import_node_p->module_request_p);
if (ECMA_IS_VALUE_ERROR (result))
{
return result;
}
ecma_module_names_t *import_names_p = import_node_p->module_names_p;
while (import_names_p != NULL)
{
const bool is_namespace_import = ecma_compare_ecma_string_to_magic_id (import_names_p->imex_name_p,
LIT_MAGIC_STRING_ASTERIX_CHAR);
if (is_namespace_import)
{
result = ecma_module_create_namespace_object (import_node_p->module_request_p);
if (ECMA_IS_VALUE_ERROR (result))
{
return result;
}
ecma_op_create_mutable_binding (local_env_p, import_names_p->local_name_p, true /* is_deletable */);
ecma_op_set_mutable_binding (local_env_p,
import_names_p->local_name_p,
ecma_make_object_value (import_node_p->module_request_p->namespace_object_p),
false /* is_strict */);
}
else /* !is_namespace_import */
{
ecma_module_record_t record;
result = ecma_module_resolve_export (import_node_p->module_request_p, import_names_p->imex_name_p, &record);
if (ECMA_IS_VALUE_ERROR (result))
{
return result;
}
if (record.module_p == NULL)
{
return ecma_raise_syntax_error (ECMA_ERR_MSG ("Ambiguous import request."));
}
result = ecma_module_evaluate (record.module_p);
if (ECMA_IS_VALUE_ERROR (result))
{
return result;
}
ecma_object_t *ref_base_lex_env_p;
ecma_value_t prop_value = ecma_op_get_value_lex_env_base (record.module_p->scope_p,
&ref_base_lex_env_p,
record.name_p);
ecma_op_create_mutable_binding (local_env_p, import_names_p->local_name_p, true /* is_deletable */);
ecma_op_set_mutable_binding (local_env_p,
import_names_p->local_name_p,
prop_value,
false /* is_strict */);
ecma_free_value (prop_value);
}
import_names_p = import_names_p->next_p;
}
import_node_p = import_node_p->next_p;
}
return ECMA_VALUE_EMPTY;
} /* ecma_module_connect_imports */
/**
* Parses an EcmaScript module.
*
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
static jerry_value_t
ecma_module_parse (ecma_module_t *module_p) /**< module */
{
if (module_p->state >= ECMA_MODULE_STATE_PARSING)
{
return ECMA_VALUE_EMPTY;
}
module_p->state = ECMA_MODULE_STATE_PARSING;
module_p->context_p = ecma_module_create_module_context ();
lit_utf8_size_t module_path_size = ecma_string_get_size (module_p->path_p);
lit_utf8_byte_t *module_path_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (module_path_size + 1);
lit_utf8_size_t module_path_utf8_size;
module_path_utf8_size = ecma_string_copy_to_utf8_buffer (module_p->path_p,
module_path_p,
module_path_size);
module_path_p[module_path_utf8_size] = LIT_CHAR_NULL;
size_t source_size = 0;
uint8_t *source_p = jerry_port_read_source ((const char *) module_path_p, &source_size);
jmem_heap_free_block (module_path_p, module_path_size + 1);
if (source_p == NULL)
{
return ecma_raise_syntax_error (ECMA_ERR_MSG ("File not found."));
}
module_p->context_p->module_p = module_p;
module_p->context_p->parent_p = JERRY_CONTEXT (module_top_context_p);
JERRY_CONTEXT (module_top_context_p) = module_p->context_p;
#if ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER)
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
{
jerry_debugger_send_string (JERRY_DEBUGGER_SOURCE_CODE_NAME,
JERRY_DEBUGGER_NO_SUBTYPE,
module_path_p,
module_path_size - 1);
}
#endif /* ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER) */
JERRY_CONTEXT (resource_name) = ecma_make_string_value (module_p->path_p);
ecma_compiled_code_t *bytecode_data_p;
ecma_value_t ret_value = parser_parse_script (NULL,
0,
(jerry_char_t *) source_p,
source_size,
JERRY_PARSE_STRICT_MODE,
&bytecode_data_p);
JERRY_CONTEXT (module_top_context_p) = module_p->context_p->parent_p;
jerry_port_release_source (source_p);
if (ECMA_IS_VALUE_ERROR (ret_value))
{
return ret_value;
}
ecma_free_value (ret_value);
module_p->compiled_code_p = bytecode_data_p;
module_p->state = ECMA_MODULE_STATE_PARSED;
return ECMA_VALUE_EMPTY;
} /* ecma_module_parse */
/**
* Parses all referenced modules.
*
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
ecma_value_t
ecma_module_parse_modules (void)
{
ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
while (current_p != NULL)
{
ecma_value_t ret_value = ecma_module_parse (current_p);
if (ECMA_IS_VALUE_ERROR (ret_value))
{
return ret_value;
}
JERRY_ASSERT (ecma_is_value_empty (ret_value));
current_p = current_p->next_p;
}
return ECMA_VALUE_EMPTY;
} /* ecma_module_parse_modules */
/**
* Checks if indirect exports in the current context are resolvable.
* Note: See 15.2.1.16.4 / 9.
*
* @return ECMA_VALUE_ERROR - if an error occured
* ECMA_VALUE_EMPTY - otherwise
*/
ecma_value_t
ecma_module_check_indirect_exports (void)
{
ecma_module_node_t *indirect_export_p = JERRY_CONTEXT (module_top_context_p)->indirect_exports_p;
while (indirect_export_p != NULL)
{
ecma_module_names_t *name_p = indirect_export_p->module_names_p;
while (name_p != NULL)
{
ecma_module_record_t record;
ecma_value_t result = ecma_module_resolve_export (indirect_export_p->module_request_p,
name_p->local_name_p,
&record);
if (ECMA_IS_VALUE_ERROR (result))
{
return result;
}
if (record.module_p == NULL)
{
return ecma_raise_syntax_error (ECMA_ERR_MSG ("Ambiguous indirect export request."));
}
name_p = name_p->next_p;
}
indirect_export_p = indirect_export_p->next_p;
}
return ECMA_VALUE_EMPTY;
} /* ecma_module_check_indirect_exports */
/**
* Cleans up a list of module names.
*/
void
ecma_module_release_module_names (ecma_module_names_t *module_name_p) /**< first module name */
{
while (module_name_p != NULL)
{
ecma_module_names_t *next_p = module_name_p->next_p;
ecma_deref_ecma_string (module_name_p->imex_name_p);
ecma_deref_ecma_string (module_name_p->local_name_p);
jmem_heap_free_block (module_name_p, sizeof (ecma_module_names_t));
module_name_p = next_p;
}
} /* ecma_module_release_module_names */
/**
* Cleans up a list of module nodes.
*/
static void
ecma_module_release_module_nodes (ecma_module_node_t *module_node_p) /**< first module node */
{
while (module_node_p != NULL)
{
ecma_module_node_t *next_p = module_node_p->next_p;
ecma_module_release_module_names (module_node_p->module_names_p);
jmem_heap_free_block (module_node_p, sizeof (ecma_module_node_t));
module_node_p = next_p;
}
} /* ecma_module_release_module_nodes */
/**
* Cleans up a module context.
*/
static void
ecma_module_release_module_context (ecma_module_context_t *module_context_p) /**< modle context */
{
ecma_module_release_module_nodes (module_context_p->imports_p);
ecma_module_release_module_nodes (module_context_p->local_exports_p);
ecma_module_release_module_nodes (module_context_p->indirect_exports_p);
ecma_module_release_module_nodes (module_context_p->star_exports_p);
jmem_heap_free_block (module_context_p, sizeof (ecma_module_context_t));
} /* ecma_module_release_module_context */
/**
* Cleans up a module structure.
*/
static void
ecma_module_release_module (ecma_module_t *module_p) /**< module */
{
ecma_deref_ecma_string (module_p->path_p);
if (module_p->state >= ECMA_MODULE_STATE_PARSING)
{
ecma_module_release_module_context (module_p->context_p);
}
if (module_p->state >= ECMA_MODULE_STATE_EVALUATING)
{
ecma_deref_object (module_p->scope_p);
}
if (module_p->state >= ECMA_MODULE_STATE_PARSED
&& module_p->state < ECMA_MODULE_STATE_EVALUATED)
{
ecma_bytecode_deref (module_p->compiled_code_p);
}
if (module_p->namespace_object_p != NULL)
{
ecma_deref_object (module_p->namespace_object_p);
}
jmem_heap_free_block (module_p, sizeof (ecma_module_t));
} /* ecma_module_release_module */
/**
* Cleans up all modules if the current context is the root context.
*/
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)
{
ecma_module_t *next_p = current_p->next_p;
ecma_module_release_module (current_p);
current_p = next_p;
}
JERRY_CONTEXT (module_top_context_p) = NULL;
} /* ecma_module_cleanup */
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
-140
View File
@@ -1,140 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMA_MODULE_H
#define ECMA_MODULE_H
#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
#include "common.h"
#include "ecma-globals.h"
#define ECMA_MODULE_MAX_PATH 255u
/**
* Imported or exported names, such as "a as b"
* Note: See https://www.ecma-international.org/ecma-262/6.0/#table-39
* and https://www.ecma-international.org/ecma-262/6.0/#table-41
*/
typedef struct ecma_module_names
{
struct ecma_module_names *next_p; /**< next linked list node */
ecma_string_t *imex_name_p; /**< Import/export name of the item */
ecma_string_t *local_name_p; /**< Local name of the item */
} ecma_module_names_t;
typedef struct ecma_module ecma_module_t;
/**
* Module node to store imports / exports.
*/
typedef struct ecma_module_node
{
struct ecma_module_node *next_p; /**< next linked list node */
ecma_module_names_t *module_names_p; /**< names of the requested import/export node */
ecma_module_t *module_request_p; /**< module structure of the requested module */
} ecma_module_node_t;
/**
* Module context containing all import and export nodes.
*/
typedef struct ecma_module_context
{
struct ecma_module_context *parent_p; /**< parent context */
ecma_module_node_t *imports_p; /**< import item of the current context */
ecma_module_node_t *local_exports_p; /**< export item of the current context */
ecma_module_node_t *indirect_exports_p; /**< export item of the current context */
ecma_module_node_t *star_exports_p; /**< export item of the current context */
ecma_module_t *module_p; /**< module request */
} ecma_module_context_t;
/**
* An enum identifing the current state of the module
*/
typedef enum
{
ECMA_MODULE_STATE_INIT = 0, /**< module is initialized */
ECMA_MODULE_STATE_PARSING = 1, /**< module is currently being parsed */
ECMA_MODULE_STATE_PARSED = 2, /**< module has been parsed */
ECMA_MODULE_STATE_EVALUATING = 3, /**< module is currently being evaluated */
ECMA_MODULE_STATE_EVALUATED = 4, /**< module has been evaluated */
} ecma_module_state_t;
/**
* Module structure storing an instance of a module
*/
struct ecma_module
{
struct ecma_module *next_p; /**< next linked list node */
ecma_module_state_t state; /**< state of the mode */
ecma_string_t *path_p; /**< path of the module */
ecma_module_context_t *context_p; /**< module context of the module */
ecma_compiled_code_t *compiled_code_p; /**< compiled code of the module */
ecma_object_t *scope_p; /**< lexica lenvironment of the module */
ecma_object_t *namespace_object_p; /**< namespace import object of the module */
};
/**
* A record that can be used to store {module, identifier} pairs
*/
typedef struct ecma_module_record
{
ecma_module_t *module_p; /**< module */
ecma_string_t *name_p; /**< identifier name */
} ecma_module_record_t;
/**
* A list of module records that can be used to identify circular imports during resolution
*/
typedef struct ecma_module_resolve_set
{
struct ecma_module_resolve_set *next_p; /**< next in linked list */
ecma_module_record_t record; /**< module record */
} ecma_module_resolve_set_t;
/**
* A list that is used like a stack to drive the resolution process, instead of recursion.
*/
typedef struct ecma_module_resolve_stack
{
struct ecma_module_resolve_stack *next_p; /**< next in linked list */
ecma_module_t *module_p; /**< module request */
ecma_string_t *export_name_p; /**< export identifier name */
bool resolving; /**< flag storing wether the current frame started resolving */
} ecma_module_resolve_stack_t;
bool ecma_module_resolve_set_insert (ecma_module_resolve_set_t **set_p,
ecma_module_t * const module_p,
ecma_string_t * const export_name_p);
void ecma_module_resolve_set_cleanup (ecma_module_resolve_set_t *set_p);
void ecma_module_resolve_stack_push (ecma_module_resolve_stack_t **stack_p,
ecma_module_t * const module_p,
ecma_string_t * const export_name_p);
void ecma_module_resolve_stack_pop (ecma_module_resolve_stack_t **stack_p);
ecma_string_t *ecma_module_create_normalized_path (const uint8_t *char_p,
prop_length_t size);
ecma_module_t *ecma_module_find_or_create_module (ecma_string_t * const path_p);
ecma_value_t ecma_module_connect_imports (void);
ecma_value_t ecma_module_parse_modules (void);
ecma_value_t ecma_module_check_indirect_exports (void);
void ecma_module_release_module_names (ecma_module_names_t *module_name_p);
void ecma_module_cleanup (void);
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
#endif /* !ECMA_MODULE_H */
+72 -155
View File
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +18,6 @@
#include "ecma-helpers.h"
#include "ecma-property-hashmap.h"
#include "jrt-libc-includes.h"
#include "jcontext.h"
/** \addtogroup ecma ECMA
* @{
@@ -26,7 +26,7 @@
* @{
*/
#if ENABLED (JERRY_PROPRETY_HASHMAP)
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
/**
* Compute the total size of the property hashmap.
@@ -42,7 +42,7 @@
/**
* Stepping values for searching items in the hashmap.
*/
static const uint8_t ecma_property_hashmap_steps[ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS] JERRY_ATTR_CONST_DATA =
static const uint8_t ecma_property_hashmap_steps[ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS] JERRY_CONST_DATA =
{
3, 5, 7, 11, 13, 17, 19, 23
};
@@ -65,7 +65,7 @@ static const uint8_t ecma_property_hashmap_steps[ECMA_PROPERTY_HASHMAP_NUMBER_OF
#define ECMA_PROPERTY_HASHMAP_SET_BIT(byte_p, index) \
((byte_p)[(index) >> 3] = (uint8_t) ((byte_p)[(index) >> 3] | (1 << ((index) & 0x7))))
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
/**
* Create a new property hashmap for the object.
@@ -74,32 +74,23 @@ static const uint8_t ecma_property_hashmap_steps[ECMA_PROPERTY_HASHMAP_NUMBER_OF
void
ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
{
#if ENABLED (JERRY_PROPRETY_HASHMAP)
if (JERRY_CONTEXT (ecma_prop_hashmap_alloc_state) != ECMA_PROP_HASHMAP_ALLOC_ON)
{
return;
}
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
if (prop_iter_p == NULL)
{
return;
}
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
JERRY_ASSERT (ecma_get_property_list (object_p) != NULL);
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (ecma_get_property_list (object_p)));
uint32_t named_property_count = 0;
ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);
while (prop_iter_p != NULL)
{
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[i]);
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + i);
if (type != ECMA_PROPERTY_TYPE_SPECIAL)
if (type == ECMA_PROPERTY_TYPE_NAMEDDATA || type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
{
named_property_count++;
}
@@ -108,11 +99,6 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
prop_iter_p->next_property_cp);
}
if (named_property_count < (ECMA_PROPERTY_HASMAP_MINIMUM_SIZE / 2))
{
return;
}
/* The max_property_count must be power of 2. */
uint32_t max_property_count = ECMA_PROPERTY_HASMAP_MINIMUM_SIZE;
@@ -133,12 +119,10 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
memset (hashmap_p, 0, total_size);
hashmap_p->header.types[0] = ECMA_PROPERTY_TYPE_HASHMAP;
hashmap_p->header.types[1] = 0;
hashmap_p->header.types[0].type_and_flags = ECMA_PROPERTY_TYPE_HASHMAP;
hashmap_p->header.next_property_cp = object_p->property_list_or_bound_object_cp;
hashmap_p->max_property_count = max_property_count;
hashmap_p->null_count = max_property_count - named_property_count;
hashmap_p->unused_count = max_property_count - named_property_count;
jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1);
uint8_t *bits_p = (uint8_t *) (pair_list_p + max_property_count);
@@ -146,13 +130,20 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
uint8_t shift_counter = 0;
while (max_property_count > LIT_STRING_HASH_LIMIT)
if (max_property_count <= LIT_STRING_HASH_LIMIT)
{
shift_counter++;
max_property_count >>= 1;
hashmap_p->header.types[1].type_and_flags = 0;
}
else
{
while (max_property_count > LIT_STRING_HASH_LIMIT)
{
shift_counter++;
max_property_count >>= 1;
}
}
hashmap_p->header.types[1] = shift_counter;
hashmap_p->header.types[1].type_and_flags = shift_counter;
prop_iter_p = ecma_get_property_list (object_p);
ECMA_SET_POINTER (object_p->property_list_or_bound_object_cp, hashmap_p);
@@ -163,15 +154,18 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if (!ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[i]))
ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + i);
if (!(type == ECMA_PROPERTY_TYPE_NAMEDDATA || type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR))
{
continue;
}
ecma_property_pair_t *property_pair_p = (ecma_property_pair_t *) prop_iter_p;
ecma_string_t *name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_pair_p->names_cp[i]);
uint32_t entry_index = ecma_string_get_property_name_hash (prop_iter_p->types[i],
property_pair_p->names_cp[i]);
uint32_t entry_index = name_p->hash;
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
if (mask < LIT_STRING_HASH_LIMIT)
@@ -214,9 +208,9 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
prop_iter_p->next_property_cp);
}
#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */
#else /* CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
JERRY_UNUSED (object_p);
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
} /* ecma_property_hashmap_create */
/**
@@ -226,11 +220,12 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
void
ecma_property_hashmap_free (ecma_object_t *object_p) /**< object */
{
#if ENABLED (JERRY_PROPRETY_HASHMAP)
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
/* Property hash must be exists and must be the first property. */
ecma_property_header_t *property_p = ecma_get_property_list (object_p);
JERRY_ASSERT (property_p != NULL && property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP);
JERRY_ASSERT (property_p != NULL
&& ECMA_PROPERTY_GET_TYPE (property_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP);
ecma_property_hashmap_t *hashmap_p = (ecma_property_hashmap_t *) property_p;
@@ -238,9 +233,9 @@ ecma_property_hashmap_free (ecma_object_t *object_p) /**< object */
jmem_heap_free_block (hashmap_p,
ECMA_PROPERTY_HASHMAP_GET_TOTAL_SIZE (hashmap_p->max_property_count));
#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */
#else /* CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
JERRY_UNUSED (object_p);
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
} /* ecma_property_hashmap_free */
/**
@@ -252,11 +247,11 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
ecma_property_pair_t *property_pair_p, /**< property pair */
int property_index) /**< property index in the pair (0 or 1) */
{
#if ENABLED (JERRY_PROPRETY_HASHMAP)
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t,
object_p->property_list_or_bound_object_cp);
JERRY_ASSERT (hashmap_p->header.types[0] == ECMA_PROPERTY_TYPE_HASHMAP);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (hashmap_p->header.types + 0) == ECMA_PROPERTY_TYPE_HASHMAP);
/* The NULLs are reduced below 1/8 of the hashmap. */
if (hashmap_p->null_count < (hashmap_p->max_property_count >> 3))
@@ -268,7 +263,7 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
JERRY_ASSERT (property_index < ECMA_PROPERTY_PAIR_ITEM_COUNT);
uint32_t entry_index = ecma_string_hash (name_p);
uint32_t entry_index = name_p->hash;
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
uint32_t mask = hashmap_p->max_property_count - 1;
@@ -278,7 +273,7 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
}
else
{
entry_index <<= hashmap_p->header.types[1];
entry_index <<= hashmap_p->header.types[1].type_and_flags;
}
#ifndef JERRY_NDEBUG
@@ -311,9 +306,6 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
JERRY_ASSERT (hashmap_p->null_count > 0);
}
hashmap_p->unused_count--;
JERRY_ASSERT (hashmap_p->unused_count > 0);
if (property_index == 0)
{
*bits_p = (uint8_t) ((*bits_p) & ~mask);
@@ -322,40 +314,29 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */
{
*bits_p = (uint8_t) ((*bits_p) | mask);
}
#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */
#else /* CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
JERRY_UNUSED (object_p);
JERRY_UNUSED (name_p);
JERRY_UNUSED (property_pair_p);
JERRY_UNUSED (property_index);
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
} /* ecma_property_hashmap_insert */
/**
* Delete named property from the hashmap.
*
* @return ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP if hashmap should be recreated
* ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP otherwise
*/
ecma_property_hashmap_delete_status
void
ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
jmem_cpointer_t name_cp, /**< property name */
ecma_string_t *name_p, /**< name of the property */
ecma_property_t *property_p) /**< property */
{
#if ENABLED (JERRY_PROPRETY_HASHMAP)
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t,
object_p->property_list_or_bound_object_cp);
JERRY_ASSERT (hashmap_p->header.types[0] == ECMA_PROPERTY_TYPE_HASHMAP);
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (hashmap_p->header.types + 0) == ECMA_PROPERTY_TYPE_HASHMAP);
hashmap_p->unused_count++;
/* The NULLs are above 3/4 of the hashmap. */
if (hashmap_p->unused_count > ((hashmap_p->max_property_count * 3) >> 2))
{
return ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP;
}
uint32_t entry_index = ecma_string_get_property_name_hash (*property_p, name_cp);
uint32_t entry_index = name_p->hash;
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
uint32_t mask = hashmap_p->max_property_count - 1;
jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1);
@@ -367,7 +348,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
}
else
{
entry_index <<= hashmap_p->header.types[1];
entry_index <<= hashmap_p->header.types[1].type_and_flags;
JERRY_ASSERT (entry_index <= mask);
}
@@ -381,7 +362,6 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
if (pair_list_p[entry_index] != ECMA_NULL_POINTER)
{
size_t offset = 0;
if (ECMA_PROPERTY_HASHMAP_GET_BIT (bits_p, entry_index))
{
offset = 1;
@@ -392,11 +372,13 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
if ((property_pair_p->header.types + offset) == property_p)
{
JERRY_ASSERT (property_pair_p->names_cp[offset] == name_cp);
JERRY_ASSERT (ecma_compare_ecma_strings (ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_pair_p->names_cp[offset]),
name_p));
pair_list_p[entry_index] = ECMA_NULL_POINTER;
ECMA_PROPERTY_HASHMAP_SET_BIT (bits_p, entry_index);
return ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP;
return;
}
}
else
@@ -411,16 +393,14 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
JERRY_ASSERT (entry_index != start_entry_index);
#endif /* !JERRY_NDEBUG */
}
#else /* !ENABLED (JERRY_PROPRETY_HASHMAP) */
#else /* CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
JERRY_UNUSED (object_p);
JERRY_UNUSED (name_cp);
JERRY_UNUSED (name_p);
JERRY_UNUSED (property_p);
return ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP;
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
} /* ecma_property_hashmap_delete */
#if ENABLED (JERRY_PROPRETY_HASHMAP)
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
/**
* Find a named property.
*
@@ -429,7 +409,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */
ecma_property_t *
ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
ecma_string_t *name_p, /**< property name */
jmem_cpointer_t *property_real_name_cp) /**< [out] property real name */
ecma_string_t **property_real_name_p) /**< [out] property real name */
{
#ifndef JERRY_NDEBUG
/* A sanity check in debug mode: a named property must be present
@@ -448,11 +428,12 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[i]))
if (prop_pair_p->names_cp[i] != ECMA_NULL_POINTER)
{
if (ecma_string_compare_to_property_name (prop_iter_p->types[i],
prop_pair_p->names_cp[i],
name_p))
ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
prop_pair_p->names_cp[i]);
if (ecma_compare_ecma_strings (name_p, property_name_p))
{
property_found = true;
break;
@@ -465,7 +446,7 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
}
#endif /* !JERRY_NDEBUG */
uint32_t entry_index = ecma_string_hash (name_p);
uint32_t entry_index = name_p->hash;
uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)];
uint32_t mask = hashmap_p->max_property_count - 1;
jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1);
@@ -477,7 +458,7 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
}
else
{
entry_index <<= hashmap_p->header.types[1];
entry_index <<= hashmap_p->header.types[1].type_and_flags;
JERRY_ASSERT (entry_index <= mask);
}
@@ -486,62 +467,6 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
uint32_t start_entry_index = entry_index;
#endif /* !JERRY_NDEBUG */
if (ECMA_IS_DIRECT_STRING (name_p))
{
ecma_property_t prop_name_type = (ecma_property_t) ECMA_GET_DIRECT_STRING_TYPE (name_p);
jmem_cpointer_t property_name_cp = (jmem_cpointer_t) ECMA_GET_DIRECT_STRING_VALUE (name_p);
JERRY_ASSERT (prop_name_type > 0);
while (true)
{
if (pair_list_p[entry_index] != ECMA_NULL_POINTER)
{
size_t offset = 0;
if (ECMA_PROPERTY_HASHMAP_GET_BIT (bits_p, entry_index))
{
offset = 1;
}
ecma_property_pair_t *property_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_property_pair_t,
pair_list_p[entry_index]);
ecma_property_t *property_p = property_pair_p->header.types + offset;
JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (*property_p));
if (property_pair_p->names_cp[offset] == property_name_cp
&& ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == prop_name_type)
{
#ifndef JERRY_NDEBUG
JERRY_ASSERT (property_found);
#endif /* !JERRY_NDEBUG */
*property_real_name_cp = property_name_cp;
return property_p;
}
}
else
{
if (!ECMA_PROPERTY_HASHMAP_GET_BIT (bits_p, entry_index))
{
#ifndef JERRY_NDEBUG
JERRY_ASSERT (!property_found);
#endif /* !JERRY_NDEBUG */
return NULL;
}
/* Otherwise it is a deleted entry. */
}
entry_index = (entry_index + step) & mask;
#ifndef JERRY_NDEBUG
JERRY_ASSERT (entry_index != start_entry_index);
#endif /* !JERRY_NDEBUG */
}
}
while (true)
{
if (pair_list_p[entry_index] != ECMA_NULL_POINTER)
@@ -555,23 +480,16 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
ecma_property_pair_t *property_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_property_pair_t,
pair_list_p[entry_index]);
ecma_property_t *property_p = property_pair_p->header.types + offset;
ecma_string_t *property_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
property_pair_p->names_cp[offset]);
JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (*property_p));
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_PTR)
if (ecma_compare_ecma_strings (name_p, property_name_p))
{
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, property_pair_p->names_cp[offset]);
if (ecma_compare_ecma_non_direct_strings (prop_name_p, name_p))
{
#ifndef JERRY_NDEBUG
JERRY_ASSERT (property_found);
JERRY_ASSERT (property_found);
#endif /* !JERRY_NDEBUG */
*property_real_name_cp = property_pair_p->names_cp[offset];
return property_p;
}
*property_real_name_p = property_name_p;
return property_pair_p->header.types + offset;
}
}
else
@@ -581,7 +499,6 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
#ifndef JERRY_NDEBUG
JERRY_ASSERT (!property_found);
#endif /* !JERRY_NDEBUG */
return NULL;
}
/* Otherwise it is a deleted entry. */
@@ -594,7 +511,7 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
#endif /* !JERRY_NDEBUG */
}
} /* ecma_property_hashmap_find */
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
/**
* @}
+9 -22
View File
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,7 +37,6 @@ typedef struct
ecma_property_header_t header; /**< header of the property */
uint32_t max_property_count; /**< maximum property count (power of 2) */
uint32_t null_count; /**< number of NULLs in the map */
uint32_t unused_count; /**< number of unused entires in the map */
/*
* The hash is followed by max_property_count ecma_cpointer_t
@@ -53,27 +53,14 @@ typedef struct
*/
} ecma_property_hashmap_t;
/**
* Simple ecma values
*/
typedef enum
{
ECMA_PROPERTY_HASHMAP_DELETE_NO_HASHMAP, /**< object has no hashmap */
ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP, /**< object has hashmap */
ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP, /**< hashmap should be recreated */
} ecma_property_hashmap_delete_status;
extern void ecma_property_hashmap_create (ecma_object_t *);
extern void ecma_property_hashmap_free (ecma_object_t *);
extern void ecma_property_hashmap_insert (ecma_object_t *, ecma_string_t *, ecma_property_pair_t *, int);
extern void ecma_property_hashmap_delete (ecma_object_t *, ecma_string_t *, ecma_property_t *);
void ecma_property_hashmap_create (ecma_object_t *object_p);
void ecma_property_hashmap_free (ecma_object_t *object_p);
void ecma_property_hashmap_insert (ecma_object_t *object_p, ecma_string_t *name_p,
ecma_property_pair_t *property_pair_p, int property_index);
ecma_property_hashmap_delete_status ecma_property_hashmap_delete (ecma_object_t *object_p, jmem_cpointer_t name_cp,
ecma_property_t *property_p);
#if ENABLED (JERRY_PROPRETY_HASHMAP)
ecma_property_t *ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, ecma_string_t *name_p,
jmem_cpointer_t *property_real_name_cp);
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
extern ecma_property_t *ecma_property_hashmap_find (ecma_property_hashmap_t *, ecma_string_t *, ecma_string_t **);
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
/**
* @}
@@ -1,209 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-builtin-helpers.h"
#include "ecma-builtins.h"
#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) */
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-array-iterator-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID array_iterator_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup %arrayiteratorprototype% ECMA %ArrayIteratorPrototype% object built-in
* @{
*/
/**
* The %ArrayIteratorPrototype% object's 'next' routine
*
* See also:
* ECMA-262 v6, 22.1.5.2.1
*
* Note:
* Returned value must be freed with ecma_free_value.
*
* @return iterator result object, if success
* error - otherwise
*/
static ecma_value_t
ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< this argument */
{
/* 1 - 2. */
if (!ecma_is_value_object (this_val))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an object."));
}
ecma_object_t *obj_p = ecma_get_object_from_value (this_val);
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
/* 3. */
if (ecma_get_object_type (obj_p) != ECMA_OBJECT_TYPE_PSEUDO_ARRAY
|| ext_obj_p->u.pseudo_array.type != ECMA_PSEUDO_ARRAY_ITERATOR)
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an iterator."));
}
ecma_value_t iterated_value = ext_obj_p->u.pseudo_array.u2.iterated_value;
/* 4 - 5 */
if (ecma_is_value_empty (iterated_value))
{
return ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE);
}
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)))
{
length = ecma_typedarray_get_length (array_object_p);
}
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;
if (JERRY_UNLIKELY (index == ECMA_ITERATOR_INDEX_LIMIT))
{
/* After the ECMA_ITERATOR_INDEX_LIMIT limit is reached the [[%Iterator%NextIndex]]
property is stored as an internal property */
ecma_string_t *prop_name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ITERATOR_NEXT_INDEX);
ecma_value_t index_value = ecma_op_object_get (obj_p, prop_name_p);
if (!ecma_is_value_undefined (index_value))
{
index = (uint32_t) (ecma_get_number_from_value (index_value) + 1);
}
ecma_value_t put_result = ecma_op_object_put (obj_p,
prop_name_p,
ecma_make_uint32_value (index),
true);
JERRY_ASSERT (ecma_is_value_true (put_result));
ecma_free_value (index_value);
}
else
{
/* 11. */
ext_obj_p->u.pseudo_array.u1.iterator_index++;
}
if (index >= length)
{
ext_obj_p->u.pseudo_array.u2.iterated_value = ECMA_VALUE_EMPTY;
return ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE);
}
/* 7. */
uint8_t iterator_type = ext_obj_p->u.pseudo_array.extra_info;
if (iterator_type == ECMA_ITERATOR_KEYS)
{
/* 12. */
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);
/* 15. */
if (ECMA_IS_VALUE_ERROR (get_value))
{
return get_value;
}
ecma_value_t result;
/* 16. */
if (iterator_type == ECMA_ITERATOR_VALUES)
{
result = ecma_create_iter_result_object (get_value, ECMA_VALUE_FALSE);
}
else
{
/* 17.a */
JERRY_ASSERT (iterator_type == ECMA_ITERATOR_KEYS_VALUES);
/* 17.b */
ecma_value_t entry_array_value;
entry_array_value = ecma_create_array_from_iter_element (get_value,
ecma_make_uint32_value (index));
result = ecma_create_iter_result_object (entry_array_value, ECMA_VALUE_FALSE);
ecma_free_value (entry_array_value);
}
ecma_free_value (get_value);
return result;
} /* ecma_builtin_array_iterator_prototype_object_next */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
@@ -1,34 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* %ArrayIteratorPrototype% built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_ARRAY_ITERATOR_UL,
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_array_iterator_prototype_object_next, 0, 0)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
* Copyright 2015 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,14 +18,29 @@
* Array.prototype built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#if ENABLED (JERRY_BUILTIN_ARRAY)
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_ARRAY_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.4.4.1 */
// 15.4.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_ARRAY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
@@ -32,47 +48,39 @@ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
/* Number properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.4.4 */
// 15.4.4
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
0,
ECMA_PROPERTY_FLAG_WRITABLE)
/* 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_ARRAY_PROTOTYPE_TO_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL, ECMA_ARRAY_PROTOTYPE_TO_LOCALE_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_CONCAT, ECMA_ARRAY_PROTOTYPE_CONCAT, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_JOIN, ECMA_ARRAY_PROTOTYPE_JOIN, 1, 1)
ROUTINE (LIT_MAGIC_STRING_POP, ECMA_ARRAY_PROTOTYPE_POP, 0, 0)
ROUTINE (LIT_MAGIC_STRING_PUSH, ECMA_ARRAY_PROTOTYPE_PUSH, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_REVERSE, ECMA_ARRAY_PROTOTYPE_REVERSE, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SHIFT, ECMA_ARRAY_PROTOTYPE_SHIFT, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SLICE, ECMA_ARRAY_PROTOTYPE_SLICE, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SORT, ECMA_ARRAY_PROTOTYPE_SORT, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SPLICE, ECMA_ARRAY_PROTOTYPE_SPLICE, NON_FIXED, 2)
ROUTINE (LIT_MAGIC_STRING_UNSHIFT, ECMA_ARRAY_PROTOTYPE_UNSHIFT, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_INDEX_OF_UL, ECMA_ARRAY_PROTOTYPE_INDEX_OF, 2, 1)
ROUTINE (LIT_MAGIC_STRING_LAST_INDEX_OF_UL, ECMA_ARRAY_PROTOTYPE_LAST_INDEX_OF, NON_FIXED, 1)
/* Note these 3 routines must be in this order */
ROUTINE (LIT_MAGIC_STRING_EVERY, ECMA_ARRAY_PROTOTYPE_EVERY, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SOME, ECMA_ARRAY_PROTOTYPE_SOME, 2, 1)
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_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_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) */
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_array_prototype_object_to_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL, ecma_builtin_array_prototype_object_to_locale_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_CONCAT, ecma_builtin_array_prototype_object_concat, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_JOIN, ecma_builtin_array_prototype_join, 1, 1)
ROUTINE (LIT_MAGIC_STRING_POP, ecma_builtin_array_prototype_object_pop, 0, 0)
ROUTINE (LIT_MAGIC_STRING_PUSH, ecma_builtin_array_prototype_object_push, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_REVERSE, ecma_builtin_array_prototype_object_reverse, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SHIFT, ecma_builtin_array_prototype_object_shift, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SLICE, ecma_builtin_array_prototype_object_slice, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SORT, ecma_builtin_array_prototype_object_sort, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SPLICE, ecma_builtin_array_prototype_object_splice, NON_FIXED, 2)
ROUTINE (LIT_MAGIC_STRING_UNSHIFT, ecma_builtin_array_prototype_object_unshift, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_INDEX_OF_UL, ecma_builtin_array_prototype_object_index_of, 2, 1)
ROUTINE (LIT_MAGIC_STRING_LAST_INDEX_OF_UL, ecma_builtin_array_prototype_object_last_index_of, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_EVERY, ecma_builtin_array_prototype_object_every, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SOME, ecma_builtin_array_prototype_object_some, 2, 1)
ROUTINE (LIT_MAGIC_STRING_FOR_EACH_UL, ecma_builtin_array_prototype_object_for_each, 2, 1)
ROUTINE (LIT_MAGIC_STRING_MAP, ecma_builtin_array_prototype_object_map, 2, 1)
ROUTINE (LIT_MAGIC_STRING_FILTER, ecma_builtin_array_prototype_object_filter, 2, 1)
ROUTINE (LIT_MAGIC_STRING_REDUCE, ecma_builtin_array_prototype_object_reduce, NON_FIXED, 1)
ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_array_prototype_object_reduce_right, NON_FIXED, 1)
#endif /* ENABLED (JERRY_BUILTIN_ARRAY) */
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#if ENABLED (JERRY_BUILTIN_ARRAY)
#ifndef CONFIG_DISABLE_ARRAY_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
@@ -58,7 +58,7 @@ 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;
ecma_simple_value_t is_array = ECMA_SIMPLE_VALUE_FALSE;
if (ecma_is_value_object (arg))
{
@@ -66,11 +66,11 @@ ecma_builtin_array_object_is_array (ecma_value_t this_arg, /**< 'this' argument
if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_ARRAY_UL)
{
is_array = ECMA_VALUE_TRUE;
is_array = ECMA_SIMPLE_VALUE_TRUE;
}
}
return is_array;
return ecma_make_simple_value (is_array);
} /* ecma_builtin_array_object_is_array */
/**
@@ -107,4 +107,4 @@ ecma_builtin_array_dispatch_construct (const ecma_value_t *arguments_list_p, /**
* @}
*/
#endif /* ENABLED (JERRY_BUILTIN_ARRAY) */
#endif /* !CONFIG_DISABLE_ARRAY_BUILTIN */
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,14 +17,29 @@
* Array description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#if ENABLED (JERRY_BUILTIN_ARRAY)
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_ARRAY)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.4.3.1 */
// 15.4.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_ARRAY_PROTOTYPE,
ECMA_PROPERTY_FIXED)
@@ -32,7 +47,7 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
/* Number properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.4.3 */
// 15.4.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
@@ -41,6 +56,10 @@ NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
* (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)
#endif /* !(ENABLED (JERRY_BUILTIN_ARRAY)) */
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -1,146 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-builtin-helpers.h"
#include "ecma-builtins.h"
#include "ecma-exceptions.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-arraybuffer-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#include "jrt-libc-includes.h"
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-arraybuffer-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID arraybuffer_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup arraybufferprototype ECMA ArrayBuffer.prototype object built-in
* @{
*/
/**
* The ArrayBuffer.prototype.bytelength accessor
*
* See also:
* ES2015, 24.1.4.1
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_arraybuffer_prototype_bytelength_getter (ecma_value_t this_arg) /**< this argument */
{
if (ecma_is_value_object (this_arg))
{
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
if (ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL))
{
ecma_length_t len = ecma_arraybuffer_get_length (object_p);
return ecma_make_uint32_value (len);
}
}
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a ArrayBuffer object."));
} /* ecma_builtin_arraybuffer_prototype_bytelength_getter */
/**
* The ArrayBuffer.prototype object's 'slice' routine
*
* See also:
* ES2015, 24.1.4.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_arraybuffer_prototype_object_slice (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg1, /**< routine's first argument */
ecma_value_t arg2) /**< routine's second argument */
{
if (!ecma_is_value_object (this_arg))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not object."));
}
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
if (!ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an ArrayBuffer object."));
}
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);
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);
ECMA_OP_TO_NUMBER_FINALIZE (end_num);
}
ECMA_OP_TO_NUMBER_FINALIZE (start_num);
if (ret_value != ECMA_VALUE_EMPTY)
{
return ret_value;
}
JERRY_ASSERT (start <= len && end <= len);
ecma_length_t new_len = (end >= start) ? (end - start) : 0;
ecma_object_t *new_arraybuffer_p = ecma_arraybuffer_new_object (new_len);
lit_utf8_byte_t *old_buf = ecma_arraybuffer_get_buffer (object_p);
lit_utf8_byte_t *new_buf = ecma_arraybuffer_get_buffer (new_arraybuffer_p);
memcpy (new_buf, old_buf + start, new_len);
return ecma_make_object_value (new_arraybuffer_p);
} /* ecma_builtin_arraybuffer_prototype_object_slice */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
@@ -1,49 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* ArrayBuffer.prototype built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
/* Object properties:
* (property name, object pointer getter) */
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_ARRAYBUFFER,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* Readonly accessor properties */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BYTE_LENGTH_UL,
ecma_builtin_arraybuffer_prototype_bytelength_getter,
ECMA_PROPERTY_FIXED)
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
/* 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) */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_SLICE, ecma_builtin_arraybuffer_prototype_object_slice, 2, 2)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -1,103 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-builtins.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-arraybuffer-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-arraybuffer.inc.h"
#define BUILTIN_UNDERSCORED_ID arraybuffer
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup arraybuffer ECMA ArrayBuffer object built-in
* @{
*/
/**
* The ArrayBuffer object's 'isView' routine
*
* See also:
* ES2015 24.1.3.1
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_arraybuffer_object_is_view (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t arg) /**< argument 1 */
{
JERRY_UNUSED (this_arg);
JERRY_UNUSED (arg);
/* TODO: if arg has [[ViewArrayBuffer]], return true */
return ECMA_VALUE_FALSE;
} /* ecma_builtin_arraybuffer_object_is_view */
/**
* Handle calling [[Call]] of built-in ArrayBuffer object
*
* ES2015 24.1.2 ArrayBuffer is not intended to be called as
* a function and will throw an exception when called in
* that manner.
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_arraybuffer_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_raise_type_error (ECMA_ERR_MSG ("Constructor ArrayBuffer requires 'new'"));
} /* ecma_builtin_arraybuffer_dispatch_call */
/**
* Handle calling [[Construct]] of built-in ArrayBuffer object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_arraybuffer_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);
return ecma_op_create_arraybuffer_object (arguments_list_p, arguments_list_len);
} /* ecma_builtin_arraybuffer_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
@@ -1,46 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* ArrayBuffer built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
/* Object properties:
* (property name, object pointer getter) */
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_ARRAYBUFFER_PROTOTYPE,
ECMA_PROPERTY_FIXED)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
/* ES2015 24.1.3.1 */
ROUTINE (LIT_MAGIC_STRING_IS_VIEW_UL, ecma_builtin_arraybuffer_object_is_view, 1, 1)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#if ENABLED (JERRY_BUILTIN_BOOLEAN)
#ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
@@ -56,23 +56,27 @@
static ecma_value_t
ecma_builtin_boolean_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_TRY_CATCH (value_of_ret,
ecma_builtin_boolean_prototype_object_value_of (this_arg),
ret_value);
ecma_string_t *ret_str_p;
if (ecma_is_value_true (value_of_ret))
{
ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING_TRUE);
ret_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_TRUE);
}
else
{
JERRY_ASSERT (ecma_is_value_boolean (value_of_ret));
ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING_FALSE);
ret_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_FALSE);
}
ret_value = ecma_make_string_value (ret_str_p);
ECMA_FINALIZE (value_of_ret);
return ret_value;
@@ -96,19 +100,20 @@ ecma_builtin_boolean_prototype_object_value_of (ecma_value_t this_arg) /**< this
}
else if (ecma_is_value_object (this_arg))
{
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
if (ecma_object_class_is (object_p, LIT_MAGIC_STRING_BOOLEAN_UL))
if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_BOOLEAN_UL)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
JERRY_ASSERT (ecma_is_value_boolean (ext_object_p->u.class_prop.u.value));
JERRY_ASSERT (ecma_is_value_boolean (ecma_get_internal_property_value (prim_value_prop_p)));
return ext_object_p->u.class_prop.u.value;
return ecma_get_internal_property_value (prim_value_prop_p);
}
}
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a Boolean object."));
return ecma_raise_type_error (ECMA_ERR_MSG (""));
} /* ecma_builtin_boolean_prototype_object_value_of */
/**
@@ -117,4 +122,4 @@ ecma_builtin_boolean_prototype_object_value_of (ecma_value_t this_arg) /**< this
* @}
*/
#endif /* ENABLED (JERRY_BUILTIN_BOOLEAN) */
#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,14 +17,25 @@
* Boolean.prototype description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_id)
#endif /* !OBJECT_ID */
#if ENABLED (JERRY_BUILTIN_BOOLEAN)
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.6.4.1 */
// 15.6.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_BOOLEAN,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
@@ -34,6 +45,9 @@ OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_boolean_prototype_object_to_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_VALUE_OF_UL, ecma_builtin_boolean_prototype_object_value_of, 0, 0)
#endif /* ENABLED (JERRY_BUILTIN_BOOLEAN) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#if ENABLED (JERRY_BUILTIN_BOOLEAN)
#ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
@@ -59,14 +59,15 @@ ecma_builtin_boolean_dispatch_call (const ecma_value_t *arguments_list_p, /**< a
if (arguments_list_len == 0)
{
arg_value = ECMA_VALUE_UNDEFINED;
arg_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
}
else
{
arg_value = arguments_list_p[0];
}
return ecma_make_boolean_value (ecma_op_to_boolean (arg_value));
return ecma_make_simple_value (ecma_op_to_boolean (arg_value) ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
} /* ecma_builtin_boolean_dispatch_call */
/**
@@ -82,7 +83,7 @@ ecma_builtin_boolean_dispatch_construct (const ecma_value_t *arguments_list_p, /
if (arguments_list_len == 0)
{
return ecma_op_create_boolean_object (ECMA_VALUE_FALSE);
return ecma_op_create_boolean_object (ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE));
}
else
{
@@ -96,4 +97,4 @@ ecma_builtin_boolean_dispatch_construct (const ecma_value_t *arguments_list_p, /
* @}
*/
#endif /* ENABLED (JERRY_BUILTIN_BOOLEAN) */
#endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,14 +17,29 @@
* Boolean description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#if ENABLED (JERRY_BUILTIN_BOOLEAN)
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_BOOLEAN)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.6.3.1 */
// 15.6.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE,
ECMA_PROPERTY_FIXED)
@@ -32,11 +47,14 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
/* Number properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.6.3 */
// 15.6.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
#endif /* ENABLED (JERRY_BUILTIN_BOOLEAN) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
@@ -1,215 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-dataview-object.h"
#include "ecma-gc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
#ifdef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
#error "DataView builtin requires ES2015 TypedArray builtin"
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
#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_DATAVIEW_PROTOTYPE_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1,
ECMA_DATAVIEW_PROTOTYPE_BUFFER_GETTER,
ECMA_DATAVIEW_PROTOTYPE_BYTE_LENGTH_GETTER,
ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER,
ECMA_DATAVIEW_PROTOTYPE_GET_INT8,
ECMA_DATAVIEW_PROTOTYPE_GET_UINT8,
ECMA_DATAVIEW_PROTOTYPE_GET_INT16,
ECMA_DATAVIEW_PROTOTYPE_GET_UINT16,
ECMA_DATAVIEW_PROTOTYPE_GET_INT32,
ECMA_DATAVIEW_PROTOTYPE_GET_UINT32,
ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT32,
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT64,
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
ECMA_DATAVIEW_PROTOTYPE_SET_INT8,
ECMA_DATAVIEW_PROTOTYPE_SET_UINT8,
ECMA_DATAVIEW_PROTOTYPE_SET_INT16,
ECMA_DATAVIEW_PROTOTYPE_SET_UINT16,
ECMA_DATAVIEW_PROTOTYPE_SET_INT32,
ECMA_DATAVIEW_PROTOTYPE_SET_UINT32,
ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT32,
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT64,
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
};
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-dataview-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID dataview_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup dataviewprototype ECMA DataView.prototype object built-in
* @{
*/
/**
* Corresponding typedarray mappings for the {get,set}{[U]int, Float}{8, 16, 32, 64} routines
*/
static const uint8_t ecma_dataview_type_mapping[] =
{
ECMA_BUILTIN_ID_INT8ARRAY,
ECMA_BUILTIN_ID_UINT8ARRAY,
ECMA_BUILTIN_ID_INT16ARRAY,
ECMA_BUILTIN_ID_UINT16ARRAY,
ECMA_BUILTIN_ID_INT32ARRAY,
ECMA_BUILTIN_ID_UINT32ARRAY,
ECMA_BUILTIN_ID_FLOAT32ARRAY,
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
ECMA_BUILTIN_ID_FLOAT64ARRAY,
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
};
/**
* The DataView.prototype object's {buffer, byteOffset, byteLength} getters
*
* See also:
* ECMA-262 v6, 24.2.4.1
* ECMA-262 v6, 24.2.4.2
* ECMA-262 v6, 24.2.4.3
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_dataview_prototype_object_getters (ecma_value_t this_arg, /**< this argument */
uint16_t builtin_routine_id) /**< built-in wide routine identifier */
{
ecma_dataview_object_t *obj_p = ecma_op_dataview_get_object (this_arg);
if (JERRY_UNLIKELY (obj_p == NULL))
{
return ECMA_VALUE_ERROR;
}
switch (builtin_routine_id)
{
case ECMA_DATAVIEW_PROTOTYPE_BUFFER_GETTER:
{
ecma_object_t *buffer_p = obj_p->buffer_p;
ecma_ref_object (buffer_p);
return ecma_make_object_value (buffer_p);
}
case ECMA_DATAVIEW_PROTOTYPE_BYTE_LENGTH_GETTER:
{
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);
return ecma_make_uint32_value (obj_p->byte_offset);
}
}
} /* ecma_builtin_dataview_prototype_object_getters */
/**
* Dispatcher of the built-in's routines
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_dataview_prototype_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 */
{
ecma_value_t byte_offset = arguments_number > 0 ? arguments_list_p[0] : ECMA_VALUE_UNDEFINED;
switch (builtin_routine_id)
{
case ECMA_DATAVIEW_PROTOTYPE_BUFFER_GETTER:
case ECMA_DATAVIEW_PROTOTYPE_BYTE_LENGTH_GETTER:
case ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER:
{
return ecma_builtin_dataview_prototype_object_getters (this_arg, builtin_routine_id);
}
case ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT32:
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
case ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT64:
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
case ECMA_DATAVIEW_PROTOTYPE_GET_INT16:
case ECMA_DATAVIEW_PROTOTYPE_GET_INT32:
case ECMA_DATAVIEW_PROTOTYPE_GET_UINT16:
case ECMA_DATAVIEW_PROTOTYPE_GET_UINT32:
{
ecma_value_t little_endian = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_FALSE;
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8];
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, ECMA_VALUE_EMPTY, type);
}
case ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT32:
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
case ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT64:
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
case ECMA_DATAVIEW_PROTOTYPE_SET_INT16:
case ECMA_DATAVIEW_PROTOTYPE_SET_INT32:
case ECMA_DATAVIEW_PROTOTYPE_SET_UINT16:
case ECMA_DATAVIEW_PROTOTYPE_SET_UINT32:
{
ecma_value_t value_to_set = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_UNDEFINED;
ecma_value_t little_endian = arguments_number > 2 ? arguments_list_p[2] : ECMA_VALUE_FALSE;
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8];
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, little_endian, value_to_set, type);
}
case ECMA_DATAVIEW_PROTOTYPE_GET_INT8:
case ECMA_DATAVIEW_PROTOTYPE_GET_UINT8:
{
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_GET_INT8];
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, ECMA_VALUE_EMPTY, type);
}
default:
{
JERRY_ASSERT (builtin_routine_id == ECMA_DATAVIEW_PROTOTYPE_SET_INT8
|| builtin_routine_id == ECMA_DATAVIEW_PROTOTYPE_SET_UINT8);
ecma_value_t value_to_set = arguments_number > 1 ? arguments_list_p[1] : ECMA_VALUE_UNDEFINED;
uint8_t type = ecma_dataview_type_mapping[builtin_routine_id - ECMA_DATAVIEW_PROTOTYPE_SET_INT8];
return ecma_op_dataview_get_set_view_value (this_arg, byte_offset, ECMA_VALUE_FALSE, value_to_set, type);
}
}
} /* ecma_builtin_dataview_prototype_dispatch_routine */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
@@ -1,79 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* DataView.prototype built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v6, 24.2.3 */
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_DATAVIEW,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
/* 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) */
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_GET_FLOAT_32_UL, ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT32, 2, 1)
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
ROUTINE (LIT_MAGIC_STRING_GET_FLOAT_64_UL, ECMA_DATAVIEW_PROTOTYPE_GET_FLOAT64, 2, 1)
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
ROUTINE (LIT_MAGIC_STRING_GET_INT8_UL, ECMA_DATAVIEW_PROTOTYPE_GET_INT8, 1, 1)
ROUTINE (LIT_MAGIC_STRING_GET_INT16_UL, ECMA_DATAVIEW_PROTOTYPE_GET_INT16, 2, 1)
ROUTINE (LIT_MAGIC_STRING_GET_INT32_UL, ECMA_DATAVIEW_PROTOTYPE_GET_INT32, 2, 1)
ROUTINE (LIT_MAGIC_STRING_GET_UINT8_UL, ECMA_DATAVIEW_PROTOTYPE_GET_UINT8, 2, 1)
ROUTINE (LIT_MAGIC_STRING_GET_UINT16_UL, ECMA_DATAVIEW_PROTOTYPE_GET_UINT16, 2, 1)
ROUTINE (LIT_MAGIC_STRING_GET_UINT32_UL, ECMA_DATAVIEW_PROTOTYPE_GET_UINT32, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SET_FLOAT_32_UL, ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT32, 2, 1)
#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64)
ROUTINE (LIT_MAGIC_STRING_SET_FLOAT_64_UL, ECMA_DATAVIEW_PROTOTYPE_SET_FLOAT64, 2, 1)
#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */
ROUTINE (LIT_MAGIC_STRING_SET_INT8_UL, ECMA_DATAVIEW_PROTOTYPE_SET_INT8, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_INT16_UL, ECMA_DATAVIEW_PROTOTYPE_SET_INT16, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SET_INT32_UL, ECMA_DATAVIEW_PROTOTYPE_SET_INT32, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UINT8_UL, ECMA_DATAVIEW_PROTOTYPE_SET_UINT8, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UINT16_UL, ECMA_DATAVIEW_PROTOTYPE_SET_UINT16, 2, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UINT32_UL, ECMA_DATAVIEW_PROTOTYPE_SET_UINT32, 2, 1)
/* ECMA-262 v6, 24.2.4.1 */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BUFFER,
ECMA_DATAVIEW_PROTOTYPE_BUFFER_GETTER,
ECMA_PROPERTY_FIXED)
/* 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-262 v6, 24.2.4.3 */
ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_BYTE_OFFSET_UL,
ECMA_DATAVIEW_PROTOTYPE_BYTE_OFFSET_GETTER,
ECMA_PROPERTY_FIXED)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -1,71 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-builtins.h"
#include "ecma-exceptions.h"
#include "ecma-dataview-object.h"
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-dataview.inc.h"
#define BUILTIN_UNDERSCORED_ID dataview
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup dataview ECMA DataView object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in DataView object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_dataview_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_raise_type_error (ECMA_ERR_MSG ("Constructor DataView requires 'new'."));
} /* ecma_builtin_dataview_dispatch_call */
/**
* Handle calling [[Construct]] of built-in DataView object
*
* @return ecma value
*/
ecma_value_t
ecma_builtin_dataview_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_op_dataview_create (arguments_list_p, arguments_list_len);
} /* ecma_builtin_dataview_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
@@ -1,47 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* DataView built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
/* ECMA-262 v6, 23.1.2 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
3,
ECMA_PROPERTY_FIXED)
/* ECMA-262 v6, 23.1 */
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_DATAVIEW_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v6, 23.1.2.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_DATAVIEW_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,66 +18,80 @@
* Date.prototype built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#if ENABLED (JERRY_BUILTIN_DATE)
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_DATE_PROTOTYPE)
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_DATE,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ECMA_DATE_PROTOTYPE_TO_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_DATE_STRING_UL, ECMA_DATE_PROTOTYPE_TO_DATE_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_TIME_STRING_UL, ECMA_DATE_PROTOTYPE_TO_TIME_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL, ECMA_DATE_PROTOTYPE_TO_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_DATE_STRING_UL, ECMA_DATE_PROTOTYPE_TO_DATE_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_TIME_STRING_UL, ECMA_DATE_PROTOTYPE_TO_TIME_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_VALUE_OF_UL, ECMA_DATE_PROTOTYPE_GET_TIME, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_TIME_UL, ECMA_DATE_PROTOTYPE_GET_TIME, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_FULL_YEAR_UL, ECMA_DATE_PROTOTYPE_GET_FULL_YEAR, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_FULL_YEAR_UL, ECMA_DATE_PROTOTYPE_GET_UTC_FULL_YEAR, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_MONTH_UL, ECMA_DATE_PROTOTYPE_GET_MONTH, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_MONTH_UL, ECMA_DATE_PROTOTYPE_GET_UTC_MONTH, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_DATE_UL, ECMA_DATE_PROTOTYPE_GET_DATE, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_DATE_UL, ECMA_DATE_PROTOTYPE_GET_UTC_DATE, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_DAY_UL, ECMA_DATE_PROTOTYPE_GET_DAY, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_DAY_UL, ECMA_DATE_PROTOTYPE_GET_UTC_DAY, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_HOURS_UL, ECMA_DATE_PROTOTYPE_GET_HOURS, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_HOURS_UL, ECMA_DATE_PROTOTYPE_GET_UTC_HOURS, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_MINUTES_UL, ECMA_DATE_PROTOTYPE_GET_MINUTES, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_MINUTES_UL, ECMA_DATE_PROTOTYPE_GET_UTC_MINUTES, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_SECONDS_UL, ECMA_DATE_PROTOTYPE_GET_SECONDS, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_SECONDS_UL, ECMA_DATE_PROTOTYPE_GET_UTC_SECONDS, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_MILLISECONDS_UL, ECMA_DATE_PROTOTYPE_GET_MILLISECONDS, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_MILLISECONDS_UL, ECMA_DATE_PROTOTYPE_GET_UTC_MILLISECONDS, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_TIMEZONE_OFFSET_UL, ECMA_DATE_PROTOTYPE_GET_UTC_TIMEZONE_OFFSET, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SET_TIME_UL, ECMA_DATE_PROTOTYPE_SET_TIME, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_MILLISECONDS_UL, ECMA_DATE_PROTOTYPE_SET_MILLISECONDS, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_MILLISECONDS_UL, ECMA_DATE_PROTOTYPE_SET_UTC_MILLISECONDS, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_SECONDS_UL, ECMA_DATE_PROTOTYPE_SET_SECONDS, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_SECONDS_UL, ECMA_DATE_PROTOTYPE_SET_UTC_SECONDS, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_MINUTES_UL, ECMA_DATE_PROTOTYPE_SET_MINUTES, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_MINUTES_UL, ECMA_DATE_PROTOTYPE_SET_UTC_MINUTES, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_SET_HOURS_UL, ECMA_DATE_PROTOTYPE_SET_HOURS, NON_FIXED, 4)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_HOURS_UL, ECMA_DATE_PROTOTYPE_SET_UTC_HOURS, NON_FIXED, 4)
ROUTINE (LIT_MAGIC_STRING_SET_DATE_UL, ECMA_DATE_PROTOTYPE_SET_DATE, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_DATE_UL, ECMA_DATE_PROTOTYPE_SET_UTC_DATE, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_MONTH_UL, ECMA_DATE_PROTOTYPE_SET_MONTH, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_MONTH_UL, ECMA_DATE_PROTOTYPE_SET_UTC_MONTH, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_FULL_YEAR_UL, ECMA_DATE_PROTOTYPE_SET_FULL_YEAR, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_FULL_YEAR_UL, ECMA_DATE_PROTOTYPE_SET_UTC_FULL_YEAR, NON_FIXED, 3)
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)
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_date_prototype_to_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_DATE_STRING_UL, ecma_builtin_date_prototype_to_date_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_TIME_STRING_UL, ecma_builtin_date_prototype_to_time_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL, ecma_builtin_date_prototype_to_locale_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_DATE_STRING_UL, ecma_builtin_date_prototype_to_locale_date_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_LOCALE_TIME_STRING_UL, ecma_builtin_date_prototype_to_locale_time_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_VALUE_OF_UL, ecma_builtin_date_prototype_value_of, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_TIME_UL, ecma_builtin_date_prototype_get_time, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_FULL_YEAR_UL, ecma_builtin_date_prototype_get_full_year, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_FULL_YEAR_UL, ecma_builtin_date_prototype_get_utc_full_year, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_MONTH_UL, ecma_builtin_date_prototype_get_month, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_MONTH_UL, ecma_builtin_date_prototype_get_utc_month, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_DATE_UL, ecma_builtin_date_prototype_get_date, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_DATE_UL, ecma_builtin_date_prototype_get_utc_date, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_DAY_UL, ecma_builtin_date_prototype_get_day, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_DAY_UL, ecma_builtin_date_prototype_get_utc_day, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_HOURS_UL, ecma_builtin_date_prototype_get_hours, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_HOURS_UL, ecma_builtin_date_prototype_get_utc_hours, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_MINUTES_UL, ecma_builtin_date_prototype_get_minutes, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_MINUTES_UL, ecma_builtin_date_prototype_get_utc_minutes, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_SECONDS_UL, ecma_builtin_date_prototype_get_seconds, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_SECONDS_UL, ecma_builtin_date_prototype_get_utc_seconds, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_MILLISECONDS_UL, ecma_builtin_date_prototype_get_milliseconds, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_UTC_MILLISECONDS_UL, ecma_builtin_date_prototype_get_utc_milliseconds, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_TIMEZONE_OFFSET_UL, ecma_builtin_date_prototype_get_timezone_offset, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SET_TIME_UL, ecma_builtin_date_prototype_set_time, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_MILLISECONDS_UL, ecma_builtin_date_prototype_set_milliseconds, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_MILLISECONDS_UL, ecma_builtin_date_prototype_set_utc_milliseconds, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_SECONDS_UL, ecma_builtin_date_prototype_set_seconds, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_SECONDS_UL, ecma_builtin_date_prototype_set_utc_seconds, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_MINUTES_UL, ecma_builtin_date_prototype_set_minutes, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_MINUTES_UL, ecma_builtin_date_prototype_set_utc_minutes, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_SET_HOURS_UL, ecma_builtin_date_prototype_set_hours, NON_FIXED, 4)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_HOURS_UL, ecma_builtin_date_prototype_set_utc_hours, NON_FIXED, 4)
ROUTINE (LIT_MAGIC_STRING_SET_DATE_UL, ecma_builtin_date_prototype_set_date, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_DATE_UL, ecma_builtin_date_prototype_set_utc_date, 1, 1)
ROUTINE (LIT_MAGIC_STRING_SET_MONTH_UL, ecma_builtin_date_prototype_set_month, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_MONTH_UL, ecma_builtin_date_prototype_set_utc_month, 2, 2)
ROUTINE (LIT_MAGIC_STRING_SET_FULL_YEAR_UL, ecma_builtin_date_prototype_set_full_year, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_SET_UTC_FULL_YEAR_UL, ecma_builtin_date_prototype_set_utc_full_year, NON_FIXED, 3)
ROUTINE (LIT_MAGIC_STRING_TO_UTC_STRING_UL, ecma_builtin_date_prototype_to_utc_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_ISO_STRING_UL, ecma_builtin_date_prototype_to_iso_string, 0, 0)
ROUTINE (LIT_MAGIC_STRING_TO_JSON_UL, ecma_builtin_date_prototype_to_json, 1, 1)
#if ENABLED (JERRY_BUILTIN_ANNEXB)
#ifndef CONFIG_DISABLE_ANNEXB_BUILTIN
ROUTINE (LIT_MAGIC_STRING_GET_YEAR_UL, ECMA_DATE_PROTOTYPE_GET_YEAR, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SET_YEAR_UL, ECMA_DATE_PROTOTYPE_SET_YEAR, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TO_GMT_STRING_UL, ECMA_DATE_PROTOTYPE_TO_UTC_STRING, 0, 0)
ROUTINE (LIT_MAGIC_STRING_GET_YEAR_UL, ecma_builtin_date_prototype_get_year, 0, 0)
ROUTINE (LIT_MAGIC_STRING_SET_YEAR_UL, ecma_builtin_date_prototype_set_year, 1, 1)
ROUTINE (LIT_MAGIC_STRING_TO_GMT_STRING_UL, ecma_builtin_date_prototype_to_utc_string, 0, 0)
#endif /* ENABLED (JERRY_BUILTIN_ANNEXB) */
#endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */
#endif /* ENABLED (JERRY_BUILTIN_DATE) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,8 +14,6 @@
* limitations under the License.
*/
#include <math.h>
#include "ecma-alloc.h"
#include "ecma-builtin-helpers.h"
#include "ecma-conversion.h"
@@ -25,7 +24,7 @@
#include "ecma-try-catch-macro.h"
#include "lit-char-helpers.h"
#if ENABLED (JERRY_BUILTIN_DATE)
#ifndef CONFIG_DISABLE_DATE_BUILTIN
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
@@ -81,7 +80,7 @@ static ecma_value_t
ecma_date_construct_helper (const ecma_value_t *args, /**< arguments passed to the Date constructor */
ecma_length_t args_len) /**< number of arguments */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_number_t prim_value = ecma_number_make_nan ();
ECMA_TRY_CATCH (year_value, ecma_op_to_number (args[0]), ret_value);
@@ -183,7 +182,7 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
ecma_value_t arg) /**< string */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_number_t date_num = ecma_number_make_nan ();
/* Date Time String fromat (ECMA-262 v5, 15.9.1.15) */
@@ -265,44 +264,40 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
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 ();
}
/* 4.2 read seconds if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == ':')
{
/* eat up ':' */
date_str_curr_p++;
seconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
if (minutes < 0 || minutes > 59)
if (seconds < 0 || seconds > 59)
{
minutes = ecma_number_make_nan ();
seconds = ecma_number_make_nan ();
}
/* 4.2 read seconds if any */
/* 4.3 read milliseconds if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_p == ':')
&& *date_str_curr_p == '.')
{
/* eat up ':' */
/* eat up '.' */
date_str_curr_p++;
seconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2);
milliseconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 3);
if (seconds < 0 || seconds > 59)
if (milliseconds < 0)
{
seconds = ecma_number_make_nan ();
}
/* 4.3 read milliseconds if any */
if (date_str_curr_p < date_str_end_p
&& *date_str_curr_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_number_make_nan ();
}
}
}
@@ -325,11 +320,11 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */
else if (date_str_curr_p < date_str_end_p
&& (*date_str_curr_p == '+' || *date_str_curr_p == '-'))
{
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;
ecma_length_t remaining_length;
remaining_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)
if (remaining_length == 5)
{
bool is_negative = false;
@@ -405,7 +400,7 @@ ecma_builtin_date_utc (ecma_value_t this_arg, /**< this argument */
ecma_length_t args_number) /**< number of arguments */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (args_number < 2)
{
@@ -439,7 +434,7 @@ static ecma_value_t
ecma_builtin_date_now (ecma_value_t this_arg) /**< this argument */
{
JERRY_UNUSED (this_arg);
return ecma_make_number_value (floor (DOUBLE_TO_ECMA_NUMBER_T (jerry_port_get_current_time ())));
return ecma_make_number_value (DOUBLE_TO_ECMA_NUMBER_T (jerry_port_get_current_time ()));
} /* ecma_builtin_date_now */
/**
@@ -456,10 +451,10 @@ ecma_builtin_date_dispatch_call (const ecma_value_t *arguments_list_p, /**< argu
{
JERRY_UNUSED (arguments_list_p);
JERRY_UNUSED (arguments_list_len);
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ECMA_TRY_CATCH (now_val,
ecma_builtin_date_now (ECMA_VALUE_UNDEFINED),
ecma_builtin_date_now (ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED)),
ret_value);
ret_value = ecma_date_value_to_string (ecma_get_number_from_value (now_val));
@@ -481,16 +476,15 @@ ecma_value_t
ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_number_t prim_value_num = ECMA_NUMBER_ZERO;
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_DATE_PROTOTYPE);
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
sizeof (ecma_extended_object_t),
ECMA_OBJECT_TYPE_CLASS);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_UNDEFINED;
false,
true,
ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (prototype_obj_p);
if (arguments_list_len == 0)
{
@@ -529,7 +523,7 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
ECMA_FINALIZE (prim_comp_value);
}
else
else if (arguments_list_len >= 2)
{
ECMA_TRY_CATCH (time_value,
ecma_date_construct_helper (arguments_list_p, arguments_list_len),
@@ -540,6 +534,10 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
ECMA_FINALIZE (time_value);
}
else
{
prim_value_num = ecma_number_make_nan ();
}
if (ecma_is_value_empty (ret_value))
{
@@ -548,11 +546,16 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
prim_value_num = ecma_number_make_nan ();
}
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_DATE_UL;
ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_CLASS);
ecma_set_internal_property_value (class_prop_p, LIT_MAGIC_STRING_DATE_UL);
ecma_number_t *date_num_p = ecma_alloc_number ();
*date_num_p = prim_value_num;
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.u.value, date_num_p);
ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_DATE_FLOAT);
ecma_number_t *prim_value_num_p = ecma_alloc_number ();
*prim_value_num_p = prim_value_num;
ECMA_SET_INTERNAL_VALUE_POINTER (ECMA_PROPERTY_VALUE_PTR (prim_value_prop_p)->value, prim_value_num_p);
ret_value = ecma_make_object_value (obj_p);
}
@@ -571,4 +574,4 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
* @}
*/
#endif /* ENABLED (JERRY_BUILTIN_DATE) */
#endif /* !CONFIG_DISABLE_DATE_BUILTIN */
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2015 Samsung Electronics Co., Ltd.
* Copyright 2015 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,11 +18,26 @@
* Date built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#if ENABLED (JERRY_BUILTIN_DATE)
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* ECMA-262 v5, 15.9.4.1 */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_DATE)
// ECMA-262 v5, 15.9.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_DATE_PROTOTYPE,
ECMA_PROPERTY_FIXED)
@@ -34,6 +50,9 @@ ROUTINE (LIT_MAGIC_STRING_PARSE, ecma_builtin_date_parse, 1, 1)
ROUTINE (LIT_MAGIC_STRING_UTC_U, ecma_builtin_date_utc, NON_FIXED, 7)
ROUTINE (LIT_MAGIC_STRING_NOW, ecma_builtin_date_now, 0, 0)
#endif /* ENABLED (JERRY_BUILTIN_DATE) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
@@ -1,4 +1,5 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -55,54 +56,61 @@
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;
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
/* 2. */
// 2.
if (!ecma_is_value_object (this_arg))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an object."));
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
else
{
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
ecma_string_t *name_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAME);
ECMA_TRY_CATCH (name_get_ret_value,
ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_NAME),
ecma_op_object_get (obj_p, name_magic_string_p),
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);
ecma_string_t *error_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ERROR_UL);
name_to_str_completion = ecma_make_string_value (error_magic_string_p);
}
else
{
name_to_str_completion = ecma_op_to_string (name_get_ret_value);
}
if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (name_to_str_completion)))
if (unlikely (ECMA_IS_VALUE_ERROR (name_to_str_completion)))
{
ret_value = ecma_copy_value (name_to_str_completion);
}
else
{
ecma_string_t *message_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MESSAGE);
ECMA_TRY_CATCH (msg_get_ret_value,
ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_MESSAGE),
ecma_op_object_get (obj_p, message_magic_string_p),
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);
ecma_string_t *empty_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
msg_to_str_completion = ecma_make_string_value (empty_magic_string_p);
}
else
{
msg_to_str_completion = ecma_op_to_string (msg_get_ret_value);
}
if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (msg_to_str_completion)))
if (unlikely (ECMA_IS_VALUE_ERROR (msg_to_str_completion)))
{
ret_value = ecma_copy_value (msg_to_str_completion);
}
@@ -134,7 +142,7 @@ ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this
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);
lit_utf8_size_t bytes = ecma_string_copy_to_utf8_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);
@@ -149,7 +157,7 @@ ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this
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);
bytes = ecma_string_copy_to_utf8_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);
@@ -166,11 +174,15 @@ ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this
ecma_free_value (msg_to_str_completion);
ECMA_FINALIZE (msg_get_ret_value);
ecma_deref_ecma_string (message_magic_string_p);
}
ecma_free_value (name_to_str_completion);
ECMA_FINALIZE (name_get_ret_value);
ecma_deref_ecma_string (name_magic_string_p);
}
return ret_value;
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,22 +17,39 @@
* Error.prototype built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
#ifndef ROUTINE
# define ROUTINE(name, c_function_name, args_number, length_prop_value)
#endif /* !ROUTINE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_ERROR_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.11.4.1 */
// 15.11.4.1
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* ECMA-262 v5, 15.11.4.2 */
// 15.11.4.2
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_ERROR_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* ECMA-262 v5, 15.11.4.3 */
// 15.11.4.3
STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
LIT_MAGIC_STRING__EMPTY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
@@ -41,4 +58,9 @@ STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
* (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_builtin_error_prototype_object_to_string, 0, 0)
#include "ecma-builtin-helpers-macro-undefs.inc.h"
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,12 +17,29 @@
* Error built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#ifndef NUMBER_VALUE
# define NUMBER_VALUE(name, number_value, prop_attributes)
#endif /* !NUMBER_VALUE */
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_ERROR)
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
/* ECMA-262 v5, 15.11.3 */
// 15.11.3
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FIXED)
@@ -30,9 +47,14 @@ NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.7.3.1 */
// 15.7.3.1
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_ERROR_PROTOTYPE,
ECMA_PROPERTY_FIXED)
#include "ecma-builtin-helpers-macro-undefs.inc.h"
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#if ENABLED (JERRY_BUILTIN_ERRORS)
#ifndef CONFIG_DISABLE_ERROR_BUILTINS
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
@@ -34,4 +34,4 @@
#define BUILTIN_UNDERSCORED_ID eval_error_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
#endif /* ENABLED (JERRY_BUILTIN_ERRORS) */
#endif /* !CONFIG_DISABLE_ERROR_BUILTINS */
@@ -1,4 +1,4 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,28 +17,42 @@
* EvalError.prototype built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#ifndef OBJECT_ID
# define OBJECT_ID(builtin_object_id)
#endif /* !OBJECT_ID */
#if ENABLED (JERRY_BUILTIN_ERRORS)
#ifndef STRING_VALUE
# define STRING_VALUE(name, magic_string_id, prop_attributes)
#endif /* !STRING_VALUE */
#ifndef OBJECT_VALUE
# define OBJECT_VALUE(name, obj_builtin_id, prop_attributes)
#endif /* !OBJECT_VALUE */
/* Object identifier */
OBJECT_ID (ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE)
/* Object properties:
* (property name, object pointer getter) */
/* ECMA-262 v5, 15.11.7.8 */
// 15.11.7.8
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_EVAL_ERROR,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* ECMA-262 v5, 15.11.7.9 */
// 15.11.7.9
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_EVAL_ERROR_UL,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
/* ECMA-262 v5, 15.11.7.10 */
// 15.11.7.10
STRING_VALUE (LIT_MAGIC_STRING_MESSAGE,
LIT_MAGIC_STRING__EMPTY,
ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
#endif /* ENABLED (JERRY_BUILTIN_ERRORS) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
#undef OBJECT_ID
#undef SIMPLE_VALUE
#undef NUMBER_VALUE
#undef STRING_VALUE
#undef OBJECT_VALUE
#undef ROUTINE

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